feat(B.6 slice 1): ACDREAM_PROBE_AUTOWALK diagnostic baseline

Per the B.6 design spec (now retail-grounded on Option A), slice 1 is
pure-additive logging so the next session has a clean trace of what
ACE actually sends to the local player during a server-initiated
auto-walk.

New PhysicsDiagnostics.ProbeAutoWalkEnabled static flag, env-var-
initialized from ACDREAM_PROBE_AUTOWALK=1. Probe sites:

  [autowalk-out] on SendUse + SendPickUp — the packets that trigger
      ACE's CreateMoveToChain when the target is out of WithinUseRadius.
  [autowalk-mt]  on OnLiveMotionUpdated for _playerServerGuid only —
      captures MovementType + MoveToPath origin/min-dist/obj-dist +
      moveTowards + speed/runRate. Lets us see exactly the wire data
      retail's PerformMovement case 6 (0x00524440) was acting on.
  [autowalk-up]  on OnLivePositionUpdated for _playerServerGuid only —
      cadence + payload of ACE's position broadcasts during auto-walk.

No behavior change. All flags off by default; opt in with the env var
during a focused reproduction. Designed to be mirrored into DebugVM
checkbox state later (parallel to ProbeResolve / ProbeCell / ProbeBuilding)
but not wired yet — env-var-only for the first trace session.
This commit is contained in:
Erik 2026-05-14 17:59:57 +02:00
parent 9e1d33a5f7
commit eda8278a64
2 changed files with 77 additions and 0 deletions

View file

@ -3290,6 +3290,29 @@ public sealed class GameWindow : IDisposable
{
// Still update the stance echo (_playerMotionTableId, etc) via
// the paths above, but don't stomp the animation sequencer.
// B.6 slice 1 (2026-05-14): trace inbound motion for the
// local player so we can characterize what ACE sends during
// a server-initiated auto-walk. One line per inbound UM,
// gated on ACDREAM_PROBE_AUTOWALK=1.
if (AcDream.Core.Physics.PhysicsDiagnostics.ProbeAutoWalkEnabled)
{
string cmdHex = command.HasValue ? $"0x{command.Value:X4}" : "null";
string pathStr = update.MotionState.MoveToPath is { } p
? $"path=cell=0x{p.OriginCellId:X8},xyz=({p.OriginX:F2},{p.OriginY:F2},{p.OriginZ:F2}),minDist={p.MinDistance:F2},objDist={p.DistanceToObject:F2}"
: "path=null";
string spd = update.MotionState.ForwardSpeed is { } fs
? $"fwdSpd={fs:F2}"
: "fwdSpd=null";
string mtsSpd = update.MotionState.MoveToSpeed is { } ms
? $"mtSpd={ms:F2}"
: "mtSpd=null";
string mtsRun = update.MotionState.MoveToRunRate is { } mr
? $"mtRun={mr:F2}"
: "mtRun=null";
Console.WriteLine(System.FormattableString.Invariant(
$"[autowalk-mt] stance=0x{stance:X4} cmd={cmdHex} mt=0x{update.MotionState.MovementType:X2} isMoveTo={update.MotionState.IsServerControlledMoveTo} moveTowards={update.MotionState.MoveTowards} {pathStr} {spd} {mtsSpd} {mtsRun}"));
}
}
else
{
@ -4149,6 +4172,22 @@ public sealed class GameWindow : IDisposable
(lbY - _liveCenterY) * 192f,
0f);
var worldPos = new System.Numerics.Vector3(p.PositionX, p.PositionY, p.PositionZ) + origin;
// B.6 slice 1 (2026-05-14): trace inbound UpdatePosition cadence for
// the local player. Combined with [autowalk-mt] this answers
// whether ACE's broadcast frequency during a server-initiated
// auto-walk is dense enough to drive smooth visible motion (the
// Option C viability check from the design spec). Gated on
// ACDREAM_PROBE_AUTOWALK=1; skips remote entities.
if (update.Guid == _playerServerGuid
&& AcDream.Core.Physics.PhysicsDiagnostics.ProbeAutoWalkEnabled)
{
string velStr = update.Velocity is { } v
? $"vel=({v.X:F2},{v.Y:F2},{v.Z:F2})"
: "vel=null";
Console.WriteLine(System.FormattableString.Invariant(
$"[autowalk-up] cell=0x{p.LandblockId:X8} pos=({p.PositionX:F2},{p.PositionY:F2},{p.PositionZ:F2}) world=({worldPos.X:F2},{worldPos.Y:F2},{worldPos.Z:F2}) {velStr} grounded={update.IsGrounded}"));
}
var rot = new System.Numerics.Quaternion(p.RotationX, p.RotationY, p.RotationZ, p.RotationW);
DumpMovementTruthServerEcho(update, worldPos);
@ -8896,6 +8935,12 @@ public sealed class GameWindow : IDisposable
var body = AcDream.Core.Net.Messages.InteractRequests.BuildUse(seq, guid);
_liveSession.SendGameAction(body);
Console.WriteLine($"[B.4b] use guid=0x{guid:X8} seq={seq}");
if (AcDream.Core.Physics.PhysicsDiagnostics.ProbeAutoWalkEnabled)
{
string label = DescribeLiveEntity(guid);
Console.WriteLine(System.FormattableString.Invariant(
$"[autowalk-out] op=use target=0x{guid:X8} name=\"{label}\" seq={seq}"));
}
}
private void SendPickUp(uint itemGuid)
@ -8925,6 +8970,12 @@ public sealed class GameWindow : IDisposable
seq, itemGuid, _playerServerGuid, placement: 0);
_liveSession.SendGameAction(body);
Console.WriteLine($"[B.5] pickup item=0x{itemGuid:X8} container=0x{_playerServerGuid:X8} seq={seq}");
if (AcDream.Core.Physics.PhysicsDiagnostics.ProbeAutoWalkEnabled)
{
string label = DescribeLiveEntity(itemGuid);
Console.WriteLine(System.FormattableString.Invariant(
$"[autowalk-out] op=pickup target=0x{itemGuid:X8} name=\"{label}\" seq={seq}"));
}
}
private uint? SelectClosestCombatTarget(bool showToast)

View file

@ -94,4 +94,30 @@ public static class PhysicsDiagnostics
/// </para>
/// </summary>
public static ResolvedPolygon? LastBspHitPoly { get; set; }
/// <summary>
/// B.6 slice 1 (2026-05-14) — baseline trace for the local-player
/// server-initiated auto-walk path (issue #63). When true, the
/// following events emit one-line <c>[autowalk-*]</c> logs:
/// <list type="bullet">
/// <item><description><c>[autowalk-out]</c> on every <c>SendUse</c>
/// / <c>SendPickUp</c> the local player issues — these are the
/// packets that may trigger ACE's server-side <c>CreateMoveToChain</c>
/// when the target is out of <c>WithinUseRadius</c>.</description></item>
/// <item><description><c>[autowalk-mt]</c> on every inbound
/// <c>UpdateMotion</c> for the local player — captures the
/// <c>MovementType + MoveToPath + speed/runRate</c> ACE sends.</description></item>
/// <item><description><c>[autowalk-up]</c> on every inbound
/// <c>UpdatePosition</c> for the local player — answers "what's
/// ACE's broadcast cadence during auto-walk?"</description></item>
/// </list>
/// Initial state from <c>ACDREAM_PROBE_AUTOWALK=1</c>.
///
/// <para>
/// Spec: <c>docs/superpowers/specs/2026-05-14-phase-b6-design.md</c>
/// §"Required investigation".
/// </para>
/// </summary>
public static bool ProbeAutoWalkEnabled { get; set; } =
Environment.GetEnvironmentVariable("ACDREAM_PROBE_AUTOWALK") == "1";
}