feat(L.2g-S5): delete player pace-inference layer; close #39 (DEV-2)

S0 wire probe (live capture, retail actor via ACE) refuted the premise
the #39 machinery was built on: walk<->run Shift toggles arrive as
EXPLICIT UMs (0x0005 <-> 0x0007@runRate) because retail's default-
difference packing baselines forward_command against Ready — W-held is
always packed, and ACE re-emits it unconditionally with the holdKey
upgrade (MovementData.cs:104-119). The frequent flags=0 autonomous UMs
are genuine keys-released / heading-only states; retail applies them as
full stops (InterpretedMotionState ctor 0x0051e8d0 defaults Ready +
move_to_interpreted_state 0x005289c0 flat copy).

Retail has NO pace->animation adaptation anywhere in its inbound
pipeline (two decomp dives + ACE cross-check, deviation map DEV-2), and
the refinement layer's 0.2s-grace re-promotion after legitimate Ready
UMs was itself the observed Ready<->Run thrash / rubber-band component.

Deleted: ApplyPlayerLocomotionRefinement, UmGraceSeconds,
PlayerRunPromoteSpeed/PlayerRunDemoteSpeed, RemoteMotion.LastUMTime,
the synth-player refinement call in OnLivePositionUpdated. Player-remote
cycles are now UM-driven only, exactly like retail. NPC PlanFromVelocity
path untouched (S6 unifies).

S0 findings + S1 live validation (0 false UM_STALE drops across 280 UMs)
recorded in docs/research/2026-07-02-inbound-motion-deviation-map.md.

fix #39: closed — root-cause narrative corrected, machinery removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-02 16:10:28 +02:00
parent cb74e64343
commit a2f8104cbf
3 changed files with 87 additions and 274 deletions

View file

@ -3108,7 +3108,20 @@ regression on the species that already render correctly.
## #39 — Run↔Walk cycle transition not visible on observed player remotes (acdream-as-observer)
**Status:** OPEN — VERIFY-PENDING (cases #1/#2/#4/#5 user-verified working 2026-05-06; cases #3/#6/#7 unverified in live test)
**Status:** CLOSED 2026-07-02 (superseded by L.2g; refinement machinery DELETED in the S5 commit)
**Closure note:** the root-cause narrative below is WRONG — the 2026-05-06
"wire goes silent on Shift toggle" finding was refuted at three oracles + a
fresh live capture (`docs/research/2026-07-02-inbound-motion-deviation-map.md`,
S0 section): retail sends a fresh MoveToState on HoldRun toggle while moving
(`CommandInterpreter` 0x006b37a8 → `SendMovementEvent`), ACE rebroadcasts every
MoveToState (`GameActionMoveToState.cs:36`), and the S0 capture shows explicit
`0x0005↔0x0007` UMs on each toggle. Retail has NO pace→cycle adaptation
anywhere (DEV-2). The `ApplyPlayerLocomotionRefinement` layer this issue added
was itself causing Ready↔Run thrash against legitimate flags=0 stop UMs and
was deleted; player-remote cycles are UM-driven only. Remaining transition
polish (funnel, stop path, link pose) is tracked as roadmap L.2g S2S4.
**Original status:** OPEN — VERIFY-PENDING (cases #1/#2/#4/#5 user-verified working 2026-05-06; cases #3/#6/#7 unverified in live test)
**Severity:** LOW (most cases now visibly correct after the 2026-05-06 fix sequence; remaining unverified cases are direction-flip — believed to work via direct UM but not explicitly exercised)
**Filed:** 2026-05-03
**Component:** physics / motion / animation

View file

@ -258,6 +258,46 @@ bookkeeping (DEV-7), and stop path (DEV-3) can be ported around it surgically;
and it is NOT a dead-reckoning-tuning problem — the chase is already retail,
it's the inputs (cycle + velocity source + stop signal) that deviate.
## S0 wire-probe RESULTS (2026-07-02, post-S1 live capture)
Observer acdream (+Acdream), actor retail-driven (guid 0x5000000B), structured
protocol incl. Shift toggles. 280 UMs captured (`launch-s0-wireprobe.log`).
1. **The wire is NOT silent — DEV-2's premise is dead.** Walk↔run toggles
arrive explicitly: `fwd=0x0005 fwdSpd=null(=1.0)` ↔ `fwd=0x0007
fwdSpd=2.85`. Root cause of the 2026-05-06 misreading: retail's
default-difference packing baselines `forward_command` against **Ready**
(`RawMotionState.Default`, our own D6.2b verbatim port) — W-held is
non-default and always packed, so ACE (`MovementData.cs:104-119`) always
re-emits it with the holdKey upgrade + run-skill speed.
2. **flags=0 "empty" autonomous UMs are frequent (127/209) and LEGITIMATE**
— they are genuine keys-released / heading-only MoveToState relays
(all-default raw state packs nothing; ACE `RawMotionState.Read` leaves
absent = Invalid; `MovementData` emits nothing). Retail semantics
(verified: `InterpretedMotionState` ctor 0x0051e8d0 defaults
`forward_command=Ready`; `MovementManager::unpack_movement` case 0
UnPacks into a default-constructed state;
`CMotionInterp::move_to_interpreted_state` 0x005289c0 does a FLAT
`copy_movement_from` + `apply_current_movement`): an empty UM = a real
full stop. acdream already maps it to Ready — but the DEV-2 refinement
then re-promotes the cycle from UP pace after the 0.2 s grace, producing
a Ready↔Run thrash against legitimate stop signals. That thrash is the
observed flicker/rubber-band component.
3. **S1 gate validated live**: 0 `[UM_STALE]` drops across 280 UMs;
movementSeq advances +1 per UM; byte-level layout confirmed
(`instanceSeq|movementSeq|serverControlSeq|isAutonomous` exactly where
the parser reads them).
4. Also confirmed in `unpack_movement` (0x00524440) for the S2 port: the
outer style u16 routes through `command_ids[]` and applies via
`DoMotion` ONLY when it differs from the current style; motionFlags
carries sticky-object (0x100 → `stick_to_object`) and standing_longjump
(0x200); the actions list is consumed under a 15-bit
`server_action_stamp` wraparound compare
(`move_to_interpreted_state` 0x005289c0, lines 305953-305989).
**Disposition: S5 = delete the player pace-inference layer** (executed in the
same session; NPC `PlanFromVelocity` path untouched — its unification is S6).
## Provenance
- Workflow `wf_b92a5670-283`: 4 read-only mappers (retail decomp / ACE port /