acdream/src/AcDream.App
Erik d2ccc80e59 fix(#170): refresh remote body velocity from get_state_velocity (kill the attack glide)
Root cause (confirmed by a live ACDREAM_DUMP_MOTION capture of Mite Scamp
0x80000244 + the retail decomp): a chasing+attacking creature's attacks arrive
as the ForwardCommand of frequent mt-0 InterpretedMotionState UMs (66 attack UMs
0x62/63/64 vs 2 mt-6 chase MoveTos in the capture). Retail's get_state_velocity
(0x00527d50) computes the body's translation velocity from the current forward
command: WalkForward→3.12×spd, RunForward→4.0×spd, and 0 for everything else
(an attack) — so the creature plants its feet. acdream ALREADY has a faithful
get_state_velocity (returns 0 for a non-locomotion command; cross-checked vs
holtburger grounded_local_velocity's `_ => zero`), but it was never WIRED to the
remote body for entities with an animation sink: apply_current_movement's sink
path (all remotes have a DefaultSink) dispatches the animation and early-returns
BEFORE the set_local_velocity(get_state_velocity()) write, which lives only in
the no-sink fallback (MotionInterpreter ~1702). So a remote NPC's body.Velocity
was never recomputed from its motion state and kept the STALE run velocity from
the last chase — the body dead-reckoned forward at ~4 m/s while playing an
idle+attack pose ("glides after me").

Fix: after apply_current_movement in the grounded remote-NPC dead-reckon path
(GameWindow ~9992, restricted to remotes by serverGuid != player and to grounded
by OnWalkable), refresh rm.Body via set_local_velocity(get_state_velocity()) —
the exact write retail's apply_current_movement performs, reusing the verbatim
ported get_state_velocity. An attack forward command now resolves to 0, so the
creature stops and swings in place; RunForward still yields the run velocity.
Narrowest safe seam: the local player (which also has a sink) is excluded by the
loop's player guard, so its PlayerMovementController velocity path is untouched.

The earlier suspicion (#159 combat-command numbering) was a red herring — the
scamp's 0x62/63/64 were always in the correct block and the planner is unwired;
the wire even carries full attack variety, so "uniform" was the visual artifact
of rapid attacks over a gliding idle base, not a classification bug.

Tests: MotionVelocityPipelineTests.AttackForwardCommand_ZeroVelocity (4 cases)
pins get_state_velocity → 0 for the attack forward commands the fix depends on.
Core suite 2503 green. Visual gate pending (retail side-by-side: creature should
plant + step, not glide).

Ref: docs/research/named-retail get_state_velocity 0x00527d50; ISSUES #170.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 09:56:40 +02:00
..
Audio feat(audio): Phase E.2 OpenAL engine + SoundTable cookbook + hook wiring 2026-04-18 16:38:26 +02:00
Input chore: #163 strip R4-V5 temp diagnostics; docs: close #162 (no adaptation) 2026-07-03 17:38:41 +02:00
Net refactor(app): extract LiveSessionController for network-side session lifecycle (Step 2) 2026-05-17 16:15:57 +02:00
Plugins feat(D.2b): IUiRegistry plugin UI surface + buffered drain into UiHost 2026-06-14 17:46:37 +02:00
Rendering fix(#170): refresh remote body velocity from get_state_velocity (kill the attack glide) 2026-07-04 09:56:40 +02:00
Streaming fix(streaming): recover the player from the pending bucket — invisible-player / world-not-loading bug 2026-07-03 22:03:44 +02:00
Studio feat(ui): importer Fix C — per-element dat FontDid resolver (studio path); character level uses its retail font 2026-06-26 10:30:13 +02:00
UI fix(studio): Character window polish — XP-label left-align, smaller icons/tighter rows, selection bar full-width + top/bottom 2026-06-26 12:01:42 +02:00
AcDream.App.csproj feat(D.2b): MarkupDocument (XML -> UiElement tree); vitals panel from vitals.xml 2026-06-14 17:38:07 +02:00
Program.cs feat(studio): StudioWindow + LayoutSource — render a dat panel standalone 2026-06-25 14:26:47 +02:00
RuntimeOptions.cs feat(D.2b): flip vitals to the LayoutDesc importer; retire hand-authored vitals.xml 2026-06-15 16:30:24 +02:00