fix(R4-V5): moveto stall #2 - login SetPosition ran before the sink bind, orphaning one immortal pending_motions node
The c2dc1a88 wedge fix paired every StopCompletely A9 node with a
completable motion-table type-5 entry via DefaultSink?.StopCompletely()
- but EnterPlayerModeNow called the initial SetPosition (whose teleport
idle is StopCompletely, R3-W6) BEFORE the sequencer/DefaultSink bind
block, so the login A9 node dispatched against a NULL sink and stayed
an orphan. Head-pop-any semantics mean a queue with one orphan never
reaches empty again (later completions just relabel the backlog), so
MotionsPending stayed true at every UseTime and the MoveToManager's
retail wait-for-anims gate (BeginTurnToHeading) never opened: every
server MoveTo armed (movingTo=True, Initialized=True, tracker fed,
node plan built) and the body never moved.
Pinned live by the [autowalk-gate] probe: type=MoveToObject init=True
contact=True motionsPending=True pm=[0x41000003] nodes=[TurnToHeading,
MoveToPosition] curCmd=0 - identical every half-second, forever.
Fix: the sequencer/sink bind block in EnterPlayerModeNow moves ABOVE
the initial physics Resolve + SetPosition (no data dependency - the
block only needs playerEntity/_animatedEntities). Teleport-arrival
SetPositions were already safe (sink long bound). Test rigs
(PlayerMoveToCutoverTests.MakeRig, W6EdgeDrivenMovementTests) mirror
the fixed order, and a new LoginQueue_DrainsToEmpty_UnderProductionFeed
test pins the invariant the probe caught: after login, pending_motions
must reach EMPTY under the production completion feed.
The [autowalk-gate]/[autowalk-feed] diagnostics stay in for the live
verify pass (TEMPORARY-tagged; strip when #5 closes). Full suite
green: 3,958.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
c2dc1a889c
commit
24569fd2a1
4 changed files with 90 additions and 26 deletions
|
|
@ -198,6 +198,8 @@ public sealed class PlayerMovementController
|
|||
private bool _prevTurnLeftHeld;
|
||||
private bool _prevTurnRightHeld;
|
||||
private bool _prevRunHeld;
|
||||
// TEMPORARY diagnostic clock (2026-07-03 moveto-stall investigation).
|
||||
private float _lastAutowalkGateLogTime = float.MinValue;
|
||||
|
||||
// Heartbeat timer.
|
||||
// Cadence is 1.0 sec to match holtburger's
|
||||
|
|
@ -526,6 +528,22 @@ public sealed class PlayerMovementController
|
|||
// slot drains.
|
||||
_motion.CheckForCompletedMotions?.Invoke();
|
||||
|
||||
// TEMPORARY diagnostic (2026-07-03 moveto-stall investigation,
|
||||
// strip when closed): every gate input the armed moveto's per-tick
|
||||
// drive depends on, ~2 Hz while armed, ProbeAutoWalk-gated.
|
||||
if (PhysicsDiagnostics.ProbeAutoWalkEnabled
|
||||
&& MoveTo is { } mtDiag && mtDiag.IsMovingTo()
|
||||
&& _simTimeSeconds - _lastAutowalkGateLogTime > 0.5f)
|
||||
{
|
||||
_lastAutowalkGateLogTime = _simTimeSeconds;
|
||||
var pmParts = new System.Collections.Generic.List<string>();
|
||||
foreach (var n in _motion.PendingMotions) pmParts.Add($"0x{n.Motion:X8}");
|
||||
var nodeParts = new System.Collections.Generic.List<string>();
|
||||
foreach (var n in mtDiag.PendingActions) nodeParts.Add(n.Type.ToString());
|
||||
Console.WriteLine(System.FormattableString.Invariant(
|
||||
$"[autowalk-gate] type={mtDiag.MovementTypeState} init={mtDiag.Initialized} tlid=0x{mtDiag.TopLevelObjectId:X8} contact={_body.InContact} motionsPending={_motion.MotionsPending()} pm=[{string.Join(",", pmParts)}] nodes=[{string.Join(",", nodeParts)}] curCmd=0x{mtDiag.CurrentCommand:X8} auxCmd=0x{mtDiag.AuxCommand:X8} fwd=0x{_motion.InterpretedState.ForwardCommand:X8} pos=({Position.X:F1},{Position.Y:F1}) yaw={Yaw:F2}"));
|
||||
}
|
||||
|
||||
// Portal-space guard: while teleporting, no input is processed and
|
||||
// no physics is resolved. Return a zero-movement result so the caller
|
||||
// can detect the frozen state (MotionStateChanged = false, no commands).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue