# Handoff: inbound animation + position — verbatim retail port Date: 2026-07-02 Branch: `claude/vigorous-joliot-f0c3ad` (clean; prior arc all committed through `d34721fa`) Mode for the new session: **/investigate first (report-only), then port on approval.** ## What just shipped (context — the OUTBOUND / LOCAL half is done) This session made acdream's *outbound* wire and *local-player* motion retail-faithful, verified against live ACE + user/retail-observer sign-off: - **L.1b** `2c8620ea` — dual `IMotionCommandCatalog` (AceModern runtime / Retail2013 conformance, full `command_ids[0x198]` extraction). - **L.2b** `78e163a4` + sign-off `f271a49e` — outbound wire parity (D1 default-difference `RawMotionState::Pack`, D3 contact/longjump byte, D4 `JumpPack`). - **D6** `4ed27836` (pseudocode) + `0f099bb6` (D6.2a) + `47407506` (sign-off) + `d34721fa` (D6.2b) — ported `CMotionInterp::adjust_motion` / `apply_run_to_command` / `apply_raw_movement` / `get_state_velocity` and unified the local player's velocity + turn + jump + wire onto one input-built `RawMotionState` at `forward_speed=1.0`. Backward/strafe-left no longer zero; strafe retail-exact; turn omega from interpreted `turn_speed`. - **Key wire finding:** ACE **recomputes** the broadcast run speed from run skill (echo-test confirmed) and auto-upgrades `WalkForward+HoldKey.Run → RunForward`. The wire sends raw `forward_speed=1.0`. (Crib: `claude-memory/project_retail_motion_outbound.md`.) **That was OUTBOUND + LOCAL. This handoff is the INBOUND / REMOTE half.** ## The goal Port retail's **incoming (inbound) handling of animation + position VERBATIM** into acdream — but **surgically**, targeted at where acdream deviates (not a blind wholesale sequencer rewrite; a rushed sequencer swap has "broken everything" in a past session — integrate carefully). Strict standard: no approximations; retail decomp / ACE / DAT as oracles; parity tests before behavior changes. ## The symptom (the acceptance oracle — user's live observation) Watching a **remote player** (inbound motion) in acdream: - Overall "works OK" but **not polished**. Some **sliding** and some **position errors once the entity stops**. - **The worst offender:** transitioning **walk↔run WITHOUT stopping** — the motion **interpreter reacts too slowly**, and this **throws all animation + position off afterward**, compounding as the entity keeps **running around + turning**. The error accumulates through subsequent motion. Fixing the walk↔run-transition responsiveness (and the resulting animation + position desync) IS the acceptance test. ## Root-cause hypothesis (UNCONFIRMED — verify in the investigation first) acdream's motion sequencer does not implement retail's motion-**transition** state machine. Retail's `CMotionInterp` doesn't just swap the animation cycle on a motion change — it **appends** the new motion to a `CSequence` and transitions through it with `pending_motions` / `MotionDone` bookkeeping. If acdream applies a walk↔run change abruptly/late (snap `SetCycle`) instead of sequencing it, the animation cycle and the dead-reckoned position drift apart and the error accumulates. The 2026-06-04 deep-dive already ranked missing `pending_motions` / `MotionDone` as **HIGH**. ## Pre-paid research to leverage (READ THESE) 1. **`docs/research/2026-06-04-animation-sequencer-deep-dive.md`** — START HERE. Retail `CMotionInterp` + `CSequence` + hook-dispatch state graph + 8 ranked divergences (missing `pending_motions`/`MotionDone` HIGH; frame-swap class; link→cycle boundary). **Verify its findings against the CURRENT code — the L.1 animation work may have closed some gaps since 2026-06-04; do not trust its line numbers.** 2. `docs/research/2026-06-26-movement-animation-retail-parity-audit.md` — the inbound divergences: **D7** (animation split from retail motion flow), **D8** (force-walk / `MoveToManager` approximate), **D9** (inbound `TurnToObject`/ `TurnToHeading` types 8/9 dropped — CONFIRMED live: `mt=0x09` arrives and just `SetCycle(Ready)` instead of turning), **D10** (spawn-time MoveTo weak), **D11** (sequence/autonomy parsed then discarded), **D12** (jump/contact gates simplified). 3. `docs/research/2026-07-01-d6-motion-interp-pseudocode.md` — the OUTBOUND/local `CMotionInterp` port already done; inbound uses the SAME machinery (`get_state_velocity`, `adjust_motion`, `apply_raw_movement` now exist in `src/AcDream.Core/Physics/MotionInterpreter.cs`). ## Decomp anchors (the oracle; grep `docs/research/named-retail/acclient_2013_pseudo_c.txt`) - `CMotionInterp::apply_current_movement` (~line 305713 — sequences style / forward-falling / sidestep / turn / actions), `DoInterpretedMotion` (~305575), `CMotionTable::GetObjectSequence` (~298636). - `CSequence` append/advance/update (~lines 301622, 301777, 301839, 302425). - The 2026-06-04 deep-dive has the full CMotionInterp/CSequence address list. - `acclient.h` for the structs; Ghidra HTTP bridge at `http://127.0.0.1:8081` (decompile-by-address) if it's up. ## Where the inbound code lives (starting points to map) - `src/AcDream.App/Rendering/GameWindow.cs` — inbound remote-entity motion: `OnLiveMotionUpdated`, the remote `SetCycle` / `ObservedOmega` seeding (~4815-4856), dead-reckoned position + omega application (~9750-9865), the `[SETCYCLE]`/`[SCFAST]`/`[SCFULL]`/`[OMEGA_DIAG]`/`[VEL_DIAG]`/`[SEQSTATE]`/ `[UPCYCLE]` diagnostics. - `src/AcDream.Core/Physics/AnimationSequencer.cs` — the cycle/action sequencer. - `src/AcDream.Core/Physics/MotionInterpreter.cs` — interpreted state (now has the D6 `adjust_motion`/`apply_raw_movement`/`get_state_velocity`). - `src/AcDream.Core/Physics/RemoteMoveToDriver.cs` — remote MoveTo + `TurnRateFor`. - `src/AcDream.Core.Net/Messages/UpdateMotion.cs`, `UpdatePosition.cs`, `MoveToState.cs` — inbound parsing. ## The plan for the new session 1. **/investigate (report-only):** produce a ranked **deviation map** — where acdream's inbound animation + position handling deviates from retail's `CMotionInterp`/`CSequence`, **anchored on the walk↔run transition-lag symptom** (not a whole-system rewrite). Parallel research agents are a good fit. Optionally corroborate with a live capture (below). Deliver the report + recommended verbatim-port slices; get explicit approval before edits. 2. **Port (after approval):** verbatim-port the deviating retail mechanisms — most likely the `CSequence` motion-queue / transition + `pending_motions` / `MotionDone`, and the inbound position/dead-reckoning where it deviates. Tests-first (parity tests before behavior). **Integrate the sequencer SURGICALLY** — change the minimum; do not replace the whole transform/cycle pipeline at once. 3. **Verify:** the walk↔run transition is smooth and no cascading animation/position desync — user visual + retail-observer side-by-side. ## Live-capture setup (structured testing) - acdream = **OBSERVER** (login as `+Acdream`); the **other player driven from a retail client** (retail packets = ground truth, so any render artifact is a pure acdream inbound bug). - Launch env (PowerShell): the standard live vars + `ACDREAM_DUMP_MOTION=1` + `ACDREAM_REMOTE_VEL_DIAG=1` (heavy; dumps `[UM_RAW]`/`[SETCYCLE]`/`[OMEGA_DIAG]`/`[VEL_DIAG]`/`[SEQSTATE]`/`[UPCYCLE]` so you can correlate each inbound packet with what acdream renders). - Structured protocol, one motion at a time: walk-straight (start→stop), run-straight, turn-in-place, curved path, idle, **walk↔run toggle (the key one)**, abrupt-stop-from-run. - NOTE: `+Acdream` had `run=15225` (GM-buffed) this session → absolute speeds unrepresentative; judge **relative** behavior + transitions. ## Housekeeping - **Close the running observer acdream client before the new session rebuilds** (it locks `AcDream.App.exe`; `dotnet build` fails with the DLL-copy lock otherwise — the user closes it, we do NOT kill it). - A background research agent (mapping acdream's inbound animation handling) was in-flight when this session stopped — orphaned; the new session re-does the mapping cleanly. ## Discipline reminders - The user's side-by-side retail observations are **axioms** (retail-oracle); once a mechanism plan exists, artifacts become acceptance tests, not new investigations (no whack-a-mole). - Report-only until fixes approved. Decomp-verbatim. Tests-first. - Every deviation the port introduces/retires updates `docs/architecture/retail-divergence-register.md` in the same commit.