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>
103 lines
8.2 KiB
Markdown
103 lines
8.2 KiB
Markdown
# 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** (V0–V6 + 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).
|