acdream/docs/research/2026-07-03-r4-verify-session-handoff.md
Erik 304327b0a4 docs: R2-R4 visual pass PASSED (user-verified) - file #165 wall-swallow + #166 slope-landing sled; next entry R5
All four visual-pass items confirmed by the user's eyes (jump/ledge
momentum, run-in-circles blend, stop settle, retail-observer view of
+Acdream). Two observations filed from the pass:

- #165: retail movers observed from acdream penetrate walls a bit
  ("swallowed") instead of stopping flush - remote-DR collision class,
  PROBE_RESOLVE capture is the first investigative step.
- #166: downhill-jump landing glide+bounce (retail sled) absent - the
  register predicted this exact gap (AD-25 risk column) - composite of
  AD-25 + AP-7 + TS-4, retire together post-R6 per the user's
  "polish later" call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:59:45 +02:00

8.2 KiB
Raw Blame History

R4 live-verify session handoff — fresh-session entry point (2026-07-03, evening)

Successor to 2026-07-03-phase-r-session-handoff.md (whose postscripts summarize the same arc — this doc is the current entry point). Worktree vigorous-joliot-f0c3ad, branch claude/vigorous-joliot-f0c3ad, tree CLEAN at 3c866f95. Full suite green: 3,963 (+15 since the R4 handoff).

State

R4 is SHIPPED and user-verified live (V0V6 + five root-cause fixes the live pass exposed). Confirmed working by the user's eyes: local use-walk (turn-first, walk/run by distance, arrival, door opens once), door open + door SWING animation, remote (retail-client) close-range moveto walking, and remote run-distance movetos at correct animation pace AND speed (#160).

The five live fixes (trail, newest first — each is a real mechanism, no adaptations added)

Commit Root cause fixed
41006e79 #160 slow-motion remote runs: remote interps had NO weenie → retail's apply_run_to_command rate chain (weenie ? (InqRunRate() ?: my_run_rate) : 1.0, raw 305062-305076) took the degenerate 1.0 branch; the wire's MoveToRunRate (stored in MyRunRate by the mt-6/7 unpack, M13) was never consumed. Fix: RemoteWeenie (Core) — retail's per-object ACCWeenieObject stand-in; InqRunRate FAILS → my_run_rate fallback; IsThePlayer=false ends the "null weenie counts as the player" A3 reading.
350fb5e3 Door-swing snap (register TS-40): CMotionInterp's detached-object link-strip guard (physics_obj->cell == 0, raw @305627) was proxied by CellPosition.ObjCellId==0, seeded only by the local player's SnapToCell → every REMOTE body read "detached" and every dispatched transition link was stripped same-tick. Fix: explicit PhysicsBody.InWorld set by SnapToCell + RemoteMotion construction.
006cf659 Remote-player glide (partial) + door UMs dropped: (a) remote PLAYERS' MoveToManagers were never ticked (the V4 UseTime slot was NPC-only) — extracted TickRemoteMoveTo, now also in the grounded player-remote (L.3 M2) pipeline; (b) UP-less entities (doors) never got a RemoteMotion → since the S2b funnel cutover their UM motions were parsed and dropped — rm now created on first UM, with a LastServerPosTime>0 gate keeping UP-less bodies OUT of the dead-reckoning tick.
24569fd2 Moveto stall #2: login SetPosition ran before the DefaultSink bind in EnterPlayerModeNow → its StopCompletely A9 node had no completion partner → ONE immortal pending_motions node → wait-for-anims gate never opened. Fix: bind block moved above SetPosition; LoginQueue_DrainsToEmpty_UnderProductionFeed pins the invariant.
c2dc1a88 Moveto stall #1 (the big one): the R3 port MISREAD StopCompletely_Internal (0x0050ead0) as a velocity zero — it is CPartArray::StopCompletelyInternal (0x00518890) = MotionTableManager::PerformMovement(type 5), the ANIMATION-side stop whose UNCONDITIONALLY-queued entry is the matched pop for the A9 pending_motions node. Fix: IInterpretedMotionSink.StopCompletely() → the R2 manager's already-ported type-5 op. Also: retail's per-tick CheckForCompletedMotions slot (CPartArray::HandleMovement 0x00517d60) added to the controller tick, and the P1 autonomous-STORE family completed (unpack store 00509730, input-edge stores DoMotion@00510030/StopMotion@005100e0, section-2 stops per-frame stamping, speculative install stores false).

The queue model (the load-bearing mental model — do not relearn)

pending_motions (interp) pops HEAD-ANY on each MotionDone; completions come from the manager's pending_animations entries. Every enqueue must have a completion partner (dispatch → manager entry). One orphan = permanent ≥1 backlog (later completions just relabel it) = MotionsPending true forever = BeginTurnToHeading's verbatim wait-for-anims gate wedges every moveto. Orphan producers found: StopCompletely-before-sink-bind and the misread StopCompletely_Internal. The [autowalk-gate] probe prints the whole gate state — it is how both wedges were pinned.

OPEN — next session picks up here (full trails in docs/ISSUES.md)

  1. #161 — remote jump landing stuck in the falling pose CLOSED 2026-07-03 b1cf0102, user live-verified. The prime suspect was right; the mechanism was a BN decomp artifact: retail REWRITES the apply pass's params word (raw 305778 smeared store, mask 0x37ff → ModifyInterpretedState=false; ACE MotionInterp.cs:444-449 confirms), so retail PRESERVES interpreted fwd through the fall and HitGround re-dispatches it (the landing-link exit). Also: both landing blocks cleared Gravity BEFORE Motion.HitGround() (whose verbatim state&0x400 gate then no-opped — fixed order, AP-81); K-fix17's SetCycle DID execute but re-set the clobbered Falling command — both copies deleted. NOTE: "HitGround raw @305949" below was a mislabel (that line is inside move_to_interpreted_state; real HitGround = 0x00528ac0 → apply_current_movement(0,0)). Full trail: ISSUES Recently-closed #161.
  2. #162 — glide-class adjudication CLOSED 2026-07-03, no adaptation. User A/B: retail does NOT glide (new-fact branch) — and post-#161 acdream doesn't either (user-verified walk/run-by-distance + clean mid-chain key takeover). Mechanism re-audit: head-interrupt + CancelMoveTo ports are retail-verbatim (retail's observer ALSO loses the armed moveto on the first reflection); ACE's mt-0 reflections carry the mover's real locomotion, so the legs stay correct after any cancel. The old glide was killed by the R4-V5 stack + #161's apply-pass params fix. Full evidence: ISSUES Recently-closed #162.
  3. #163 — strip the TEMPORARY diagnostics DONE 2026-07-03 ([autowalk-gate] + clock, [autowalk-feed], and the short-lived [MOVETO-CANCEL] probe; the durable ProbeAutoWalk family stays).
  4. Combined R2+R3+R4 visual-pass remainder PASSED 2026-07-03, user-verified (jump/ledge momentum, run-in-circles blend, stop settle, retail-observer view of +Acdream — all four "looks good"). Two observations filed from the pass: #165 (remote movers get "swallowed" into walls a bit instead of stopping flush — remote-DR collision, capture with PROBE_RESOLVE first) and #166 (slope-landing glide+bounce polish — the AD-25 + AP-7 + TS-4 composite, post-R6 by user's call). NEXT SESSION ENTERS AT R5 (MovementManager facade + StickyManager + ConstraintManager + full TargetManager — retires TS-39 + AP-79's adapter).

Session gotchas worth keeping

  • Evidence-first: two plausible-but-wrong theories (a per-tick apply_current_movement "pump" — retail's apply callers are EVENT-driven only; and "ACE chain broadcasts mt-0 locomotion" — it doesn't) were killed by the raw + wire captures. The [autowalk-gate] probe and the UM raw hex dumps (autonomy byte at offset +14) were the decisive tools.
  • Retail object-model completeness matters: two of the five fixes were "retail gives every placed object X and we only gave it to the player" (a weenie; a cell/InWorld). When a dispatch path behaves differently for remotes, check what retail's CPhysicsObj carries that our RemoteMotion lacks BEFORE suspecting the ported logic.
  • The launch recipe + graceful-close rules are unchanged (CLAUDE.md); the client locks builds — ask the user to close it, never kill.
  • Register: TS-40 added; TS-33 extended (orientation-diff gap); AP-79 covers both tracker instances; TS-36/AD-26 retired earlier today.

Key files this session touched

MotionInterpreter.cs (StopCompletely sink dispatch, InWorld guards), MoveToManager.cs (MoveToComplete widened to BeginNextNode completion), MotionTableDispatchSink.cs + InterpretedMotionFunnel.cs (StopCompletely sink op), PhysicsBody.cs (InWorld), RemoteWeenie.cs (new), PlayerMovementController.cs (UseTime slot + per-tick Check + edge autonomy stores + temp probe), GameWindow.cs (P1 gate + store, RouteServerMoveTo, TickRemoteMoveTo, rm-on-UM, EnterPlayerModeNow bind order, player tracker feed), tests: PlayerMoveToCutoverTests, MoveToManagerCompletionSeamTests, InWorldLinkGuardTests, RemoteWeenieRunRateTests, W6EdgeDrivenMovementTests (apply-pass form).