Gait v5: display+travel from the LEG channel (kills the stutter class)
User-reported recurrence of "legs stutter and lose sync". Live [sync] showed
advSum/legSum drifting 5->92 during walk-up churn, then locking. Reproduced
headlessly (BT_FORCE_OSC throttle feathering + BT_FORCE_TURN + the new
per-frame BT_SYNC_LOG probe) and root-caused in two parts:
- SEED: the bring-up turn-in-place trigger arms only the LEG channel, so the
walk re-entry lands one frame apart -> a persistent clip phase offset.
- AMPLIFIER: with offset clips the two end-of-clip callbacks fire on different
frames; a demand change landing between them picks DIFFERENT next states
(one channel winds down, the other keeps walking) -> opposite-phase churn
(observed bs=6 ls=7 -- body on walk-R, leg on walk-L).
Under v4 (display+travel = BODY) the out-of-phase LEG pose showed through on
every frame the body didn't write joints (Standing/wind-down) = the visible
stutter/pop.
DISASM GROUND TRUTH (neither Advance fn has a static decomp caller; found by
byte-scanning the CODE section for e8 calls):
- master perf (0x4a9b5c gap) -> AdvanceLegAnimation @0x4aa399 (air @0x4aa388)
-> -dist/dt into localVelocity (+0x1cc): the LEG drives LOCAL travel and
(writing last) the displayed pose;
- IntegrateMotion (0x4ab1c8, body advance @0x4ab312, caller FUN_004ab430 =
the projected-origin updater) -> -dist/dt into projectedVelocity (+0x2a0):
the BODY is the dead-reckoning PROJECTOR -- locally invisible.
v4's reading of FUN_004ab430 as the travel source was wrong.
FIX: advance body FIRST (projection; its writes get overwritten), leg LAST
(displayed pose); travel = legAdv under the two-channel split. Display ==
travel through the LEG by construction -- body-channel drift can no longer
become visible, structurally (not by input-symmetry luck).
Verified: trn+feathering repro clean; straight drive locked (adv==proj);
solo goto=enemy kill chain intact; MP 2-node drive-to-range cross-pod kill
intact (241 hits, DESTROYED); no crashes. KB corrected (locomotion.md roles
+ P3_LOCOMOTION.md v5 entry). New gated instruments: BT_SYNC_LOG,
BT_FORCE_OSC.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9353d59eb9
commit
d4e139a0d9
@@ -360,3 +360,25 @@ The real gait finished-callback (was a `(void*)1` loop sentinel).
|
||||
spawn FACING (the authentic orientation exposed the old fixed-offset assumption).
|
||||
- Verified: env-free default run = full authentic chain, combat damage -> 0.933, 0 crashes; all =0
|
||||
fallbacks work. P3 is CLOSED for multiplayer purposes (the update-writer data is maintained).
|
||||
|
||||
### v5 (2026-07-09, task #49) — CHANNEL ROLES CORRECTED FROM RAW DISASM: display+travel = LEG
|
||||
User-reported recurrence of "legs stutter / lose sync" (live [sync]: advSum/legSum drifted 5->92 during
|
||||
walk-up churn then locked). Reproduced headlessly (BT_FORCE_OSC feathering + BT_FORCE_TURN; per-frame
|
||||
BT_SYNC_LOG probe): the SEED is the bring-up trn trigger arming only the LEG channel (walk re-entry lands
|
||||
1 frame apart -> clip phase offset); the AMPLIFIER is a demand change landing between the two channels'
|
||||
end-of-clip callbacks -> DIVERGENT next-state picks (one winds down, one keeps walking) -> opposite-phase
|
||||
churn (observed bs=6 ls=7). Under v4 (display+travel = body) the out-of-phase LEG pose showed through on
|
||||
every frame the body didn't write (Standing/wind-down) = the visible stutter.
|
||||
DISASM GROUND TRUTH (both Advance fns have NO static decomp caller; found by byte-scanning CODE for e8
|
||||
calls): the master perf (0x4a9b5c gap region) calls AdvanceLegAnimation @0x4aa399 (airborne @0x4aa388) and
|
||||
stores -dist/dt into localVelocity (+0x1cc) == the LEG drives local travel (and pose, writing last);
|
||||
IntegrateMotion (0x4ab1c8; body advance @0x4ab312; caller FUN_004ab430 = the projected-origin updater)
|
||||
stores -dist/dt into projectedVelocity (+0x2a0) == the BODY is the dead-reckoning PROJECTOR, locally
|
||||
invisible. v4's reading of 0x4ab430 as the travel source was WRONG.
|
||||
FIX (mech4.cpp): advance body FIRST (projection; writes overwritten), leg LAST (displayed pose); travel =
|
||||
legAdv under the two-channel split (travelAdv selector; single-channel path keeps adv). Display == travel
|
||||
through the LEG by construction; body drift can no longer show. VERIFIED: trn+feather repro clean; straight
|
||||
drive locked (adv==proj); solo goto=enemy kill chain intact; MP 2-node drive-to-range cross-pod kill intact
|
||||
(hdlr=241, DESTROYED). FOLLOW-UPS: wire the body adv into the named projectedVelocity member (the +0x2a0
|
||||
store, currently diagnostic-only); locate the authentic trn entry dispatcher (would also arm... TBD).
|
||||
New gated instruments: BT_SYNC_LOG (per-frame channel divergence), BT_FORCE_OSC=<s> (throttle feathering).
|
||||
|
||||
Reference in New Issue
Block a user