docs: handoff for inbound animation+position verbatim retail port
Fresh-session handoff for the INBOUND (remote-entity) motion arc. Captures the
symptom (walk<->run transition without stopping = interpreter reacts too slowly
-> animation+position desync compounding through turns; plus sliding + stop
position errors), the root-cause hypothesis (acdream lacks retail's CMotionInterp/
CSequence motion-transition state machine: pending_motions/MotionDone), the
pre-paid research (2026-06-04 sequencer deep-dive, 2026-06-26 audit D7-D12), the
decomp anchors, the inbound code map, the /investigate-then-port plan, the
live-capture setup, and the discipline reminders (report-only, surgical
sequencer integration, decomp-verbatim). Prior outbound/local arc shipped clean
through d34721fa.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d34721fa94
commit
b60b9b4a21
1 changed files with 156 additions and 0 deletions
156
docs/research/2026-07-02-inbound-motion-verbatim-port-handoff.md
Normal file
156
docs/research/2026-07-02-inbound-motion-verbatim-port-handoff.md
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
# 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.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue