docs: Phase R session handoff — fresh session picks up at V4 smoke verdict → R4-V5
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7016b26ce7
commit
e4553a0262
1 changed files with 144 additions and 0 deletions
144
docs/research/2026-07-03-phase-r-session-handoff.md
Normal file
144
docs/research/2026-07-03-phase-r-session-handoff.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
# Phase R handoff — fresh-session entry point (2026-07-03)
|
||||
|
||||
**Read this first, then the plan of record**
|
||||
(`docs/plans/2026-07-02-retail-motion-animation-rewrite.md`). This session
|
||||
ran the R2→R4 arc of the Phase R mandate; the fresh session picks up at
|
||||
**R4-V4 smoke verification → R4-V5**.
|
||||
|
||||
## The mandate (user, standing)
|
||||
|
||||
Total overhaul of movement + animation as a VERBATIM retail port — all
|
||||
movement, inbound and outbound, all animation, for players/NPCs/monsters.
|
||||
No guessing, no approximations, no bandaids. The user cancelled the /loop
|
||||
self-scheduling near the end of this session — **work continues on user
|
||||
prompts, not self-scheduled wakeups**, but the drive-autonomously rules in
|
||||
CLAUDE.md still apply within a turn.
|
||||
|
||||
## State at handoff (worktree `vigorous-joliot-f0c3ad`, branch `claude/vigorous-joliot-f0c3ad`)
|
||||
|
||||
- Tree: CLEAN at `7016b26c` (only `v4-smoke.log` untracked — session
|
||||
scratch, delete freely). Full suite green: **3,948 tests**
|
||||
(385 Net + 425 UI + 713 App + 2,425 Core, +4 pre-existing skips).
|
||||
- **R1 ✅ R2 ✅ R3 ✅ shipped** (trail + commit SHAs recorded in the plan
|
||||
doc's stage entries). **R4: V0–V4 shipped, V5+V6 remain.**
|
||||
- A smoke client was launched with the V4 build (`ACDREAM_DUMP_MOTION=1`,
|
||||
log `v4-smoke.log` in the worktree root, UTF-16) — **the user had NOT yet
|
||||
reported an NPC-behavior verdict at handoff time.** First order of
|
||||
business: get that verdict (or relaunch and ask). Watch items: NPC
|
||||
chase/wander legs, turn-to-face, melee-range stop distance (arrival is
|
||||
now retail cylinder distance — the old max() gate is gone).
|
||||
|
||||
## What just landed (this session, newest first)
|
||||
|
||||
| Commit | What |
|
||||
|---|---|
|
||||
| `7016b26c` | **R4-V4** remote cutover: per-remote MoveToManager; RemoteMoveToDriver + PlanMoveToStart DELETED; P4 TargetTracker adapter; retail unpack_movement dispatch (head-interrupt every UM; mt 6–9 never touch the interpreted funnel) |
|
||||
| `a144e873` | **R4-V3** wire: mt 8/9 parsing (TurnToPathData), raw bitfield surfaced, mt-0 sticky trailer |
|
||||
| `addc8e97` | **R4-V2** the verbatim MoveToManager (33 members, 101 tests; seams listed in its final report — ctor takes the interp + 14 providers; the identity-quaternion TDD catch) |
|
||||
| `e0d2492c` | **R4-V1** command-selection family (GetCommand + CanCharge fast-path; MoveToMath incl. the Ghidra-confirmed heading_diff mirror) |
|
||||
| `386b1ce5` | **R4-V0** pins P1–P7 (see below) |
|
||||
| `988304e1` | R4 research base (`docs/research/2026-07-03-r4-moveto/` — decomp, ACE cross-ref, port plan) |
|
||||
| `30115d96` | **W6b fix** — the "press W and stop instantly" live regression (see gotchas) |
|
||||
| `fb7beb70`…`8eff3978` | R3 W0–W7 + R2 Q0–Q6 (see the plan doc's stage trails) |
|
||||
|
||||
## NEXT: R4-V5 — LOCAL PLAYER cutover (the delicate one)
|
||||
|
||||
Spec: `docs/research/2026-07-03-r4-moveto/r4-port-plan.md` §3 V5.
|
||||
**ONE commit, GameWindow + PlayerMovementController, do NOT fan out**
|
||||
(feedback_dont_parallelize_coupled_plan_slices). Shape:
|
||||
|
||||
- The player gets a MoveToManager bound like remotes (the
|
||||
EnsureRemoteMotionBindings block at GameWindow is the reference wiring;
|
||||
the player's Motion/seams already exist from R3 — DefaultSink is bound,
|
||||
`_playerController.Motion` exposed).
|
||||
- **B.6 auto-walk DELETED**: `DriveServerAutoWalk` + `BeginServerAutoWalk`
|
||||
+ the `_autoWalk*` fields + the local mt-6 branch in GameWindow
|
||||
(`BeginServerAutoWalk` call site) + the two relocated constants
|
||||
(`AutoWalkArrivalEpsilon`, `AutoWalkTurnRateFor` — marked V5-scope in the
|
||||
controller).
|
||||
- **P1 pin applies here**: port the missing tail of retail's
|
||||
`CPhysics::SetObjectMovement` gate — DROP any 0xF74C event whose wire
|
||||
`IsAutonomous` byte is set when guid == local player (parsed at
|
||||
`UpdateMotion.cs` isAutonomous, relayed by WorldSession, consumed
|
||||
NOWHERE yet). That's what makes retail's unconditional head-interrupt
|
||||
safe against ACE's mt-0 echo. `V0-pins.md` P1 has the full adjudication +
|
||||
the LoseControlToServer note. This RETIRES the informal
|
||||
"don't cancel on non-MoveTo" comment block in the local UM branch.
|
||||
- TS-36 retires (InterruptCurrentMovement bound for the player);
|
||||
AD-26 retires; AD-27/AP-23 re-anchor.
|
||||
- Movement keys auto-cancel a server MoveTo (retail: the CommandInterpreter
|
||||
DoMotion's cancel bit → interrupt → CancelMoveTo — the edge-driven W6
|
||||
input already calls DoMotion with ctor-default params whose CancelMoveTo
|
||||
is TRUE, so this may fall out for free — verify, don't assume).
|
||||
- Tests: the V2 harness pattern for the player-side bind; the W6
|
||||
edge-driven regression suite (`W6EdgeDrivenMovementTests.cs`) is the
|
||||
template for controller-level tests with a real sink.
|
||||
- Then **V6**: register/roadmap/plan/memory sweep (V6 spec in the plan).
|
||||
After V6, R4 is done → R5 (MovementSystem facade + StickyManager +
|
||||
ConstraintManager + TargetManager full port), R6 (per-tick
|
||||
UpdateObjectInternal order — retires the 300ms stop window, PlanFromVelocity
|
||||
AP-80, ObservedOmega AP-76, AP-75/AP-77 velocity adaptations), R7
|
||||
(outbound cadence TS-33), R8 (audit + final visual pass).
|
||||
|
||||
## Pending user verifications (visual passes)
|
||||
|
||||
1. **V4 smoke verdict** (see above — NPC movement).
|
||||
2. **R2+R3 combined visual pass** (task #9): jump instant-Falling engage,
|
||||
walk-off-ledge momentum (NEW behavior), running-in-circles blend, stop
|
||||
settle, strafe pacing (EXPECTED-DIFF: #45's 1.248× factor retired —
|
||||
local now matches remotes), retail-observer view (no rubber-band).
|
||||
Partially confirmed ("works a lot better now") after the W6b fix.
|
||||
|
||||
## Load-bearing gotchas from this session (do not relearn these)
|
||||
|
||||
1. **BN hoisted-register artifact class** (caused the W6b live bug): the
|
||||
pseudo-C renders pre-call register caches as post-call field reads.
|
||||
`ApplyInterpretedMovement` must ENTRY-CACHE the axis values — the style
|
||||
dispatch's `ApplyMotion(style)` resets forward to Ready (verbatim,
|
||||
raw 0051ea6c) and retail self-heals via the cached fwd re-apply. The
|
||||
183-case suite can NOT catch sink-result-dependent bugs: its
|
||||
RecordingSink's bool return doesn't mirror the real
|
||||
MotionTableDispatchSink (style dispatches return TRUE → the resetting
|
||||
state-write runs). Regression suite: `W6EdgeDrivenMovementTests.cs`.
|
||||
2. **The dispatch RESULT gates queue+state writes** (W5 discovery):
|
||||
`IInterpretedMotionSink.ApplyMotion/StopMotion` return bool for this
|
||||
reason — documented on the interface.
|
||||
3. **Retail's echo discriminator is the wire autonomous byte** (V0 P1):
|
||||
not a workaround — `CPhysics::SetObjectMovement` 0x00509690's final
|
||||
branch. Port it in V5, don't invent gating.
|
||||
4. **MoveToManager entry points never drain pending_actions** — re-issues
|
||||
MUST route through `PerformMovement` (V2 finding, tested).
|
||||
5. **`default(Quaternion)` is zero, not identity** — heading math reads
|
||||
90° off a zero quat (V2 TDD catch; `IdentityPosition` constant).
|
||||
6. **fail_progress_count is WRITE-ONLY in retail** — there is no MoveTo
|
||||
give-up threshold; do not invent one.
|
||||
7. **Delegation pattern that works**: sonnet implementers against
|
||||
committed pinned specs (research → pins with adversarial verify →
|
||||
implement → orchestrator independently verifies scope + suite +
|
||||
spot-checks against the raw decomp → commit). GameWindow/controller
|
||||
coupled surgery stays with the orchestrator. Workflow tool for
|
||||
research fan-outs (r3/r4 extraction + pin workflows are the templates).
|
||||
8. **py (not python) exists on this box**; logs from Tee-Object are
|
||||
UTF-16; heredocs with quotes inside python strings break — write
|
||||
scripts to the scratchpad with the Write tool and run `py file.py`.
|
||||
9. **Ghidra MCP** (port 8080/8081, needs the user to open patchmem.gpr):
|
||||
used live this session for heading_diff/get_desired_heading
|
||||
(`ghidra-confirmations.md`). Ask the user to open it when a BN garble
|
||||
blocks a pin.
|
||||
10. **ACE session care**: graceful client close (CloseMainWindow) or ACE
|
||||
holds the session ~3 min (exit 29 on relaunch). Don't kill clients
|
||||
the user launched — ask.
|
||||
|
||||
## Key file map (R4 additions)
|
||||
|
||||
- `src/AcDream.Core/Physics/Motion/MoveToManager.cs` + `MoveToNode.cs` —
|
||||
the V2 port (seams doc'd on the ctor).
|
||||
- `src/AcDream.Core/Physics/Motion/MoveToMath.cs` — heading/cylinder math
|
||||
+ `OriginToWorld` (relocated from the deleted RemoteMoveToDriver).
|
||||
- `src/AcDream.Core/Physics/Motion/MovementParameters.cs` — `GetCommand` /
|
||||
`FromWire` / `FromWireTurnTo` / `GetDesiredHeading` / `TowardsAndAway`.
|
||||
- `docs/research/2026-07-03-r4-moveto/` — decomp + ACE cross-ref +
|
||||
port plan + `V0-pins.md` + `ghidra-confirmations.md`.
|
||||
- GameWindow: `EnsureRemoteMotionBindings` (the full per-remote wiring
|
||||
reference), the remote UM dispatch (mt 6–9 vs mt-0 funnel), the
|
||||
per-tick tracker+UseTime block.
|
||||
Loading…
Add table
Add a link
Reference in a new issue