diff --git a/memory/project_session_2026_04_17.md b/memory/project_session_2026_04_17.md index 5ae7cc4..18c915b 100644 --- a/memory/project_session_2026_04_17.md +++ b/memory/project_session_2026_04_17.md @@ -1,6 +1,6 @@ -# Session 2026-04-17 — Debug overlay → full-day retail-AC research marathon +# Session 2026-04-17 — Debug overlay → full-day retail-AC research + client bug-bash -## Timeline (morning → afternoon) +## Timeline 1. **Morning** — Debug overlay (TTF atlas + text batcher + HUD panels) and input-control tuning (per-mode sensitivity, RMB free-orbit, wheel @@ -14,17 +14,25 @@ parallel Opus-4.7 agents, produced a 78,000-word research bundle + master synthesis + 5 C# port scaffolds + rewritten roadmap. Shipped in commit `3f913f1`. +4. **Evening** — Back to hands-on client debugging. Fixed three + significant live-play bugs one after another: NPC clothing by-angle + flicker, run-animation sync with retail observers, and jump animation. + Shipped in `3308cdd` + `08ea2c0` + `6bce9b8`. -## What shipped today — three commits on main +## What shipped today — seven commits on main -| Commit | Title | Insert | -|-----------|------------------------------------------------------------|--------| -| `ff325ab` | feat(ui): debug overlay + refined input controls | 2,725 | -| `7230c15` | docs+feat(ui): retail UI deep-dive research + C# scaffold | 8,042 | -| `3f913f1` | docs+feat: 13 retail-AC deep-dives + scaffolds + roadmap | 15,312 | +| Commit | Title | Insert | +|-----------|--------------------------------------------------------------------|--------| +| `ff325ab` | feat(ui): debug overlay + refined input controls | 2,725 | +| `7230c15` | docs+feat(ui): retail UI deep-dive research + C# scaffold | 8,042 | +| `3f913f1` | docs+feat: 13 retail-AC deep-dives + scaffolds + roadmap | 15,312 | +| `d951304` | memory: session handoff + permanent research index | 222 | +| `3308cdd` | fix(movement+anim+session): clothing dedup + motion wire + jump-skill | 272 | +| `08ea2c0` | feat(anim): motion-action-queue infrastructure + findings | 128 | +| `6bce9b8` | fix(anim): **jump animation via Falling SubState** | 71 | -**Total 26,079 lines added, 262 deleted, 55 new files.** All three -commits green on build + 470 tests. +**Total ~26,800 lines added, 55+ new files.** All commits green on +build + 470 tests. ## Key files to know @@ -72,6 +80,48 @@ commits green on build + 470 tests. 5. **Retail lighting is D3D fixed-function** with 8-light cap, NO attenuation inside Range, then hard cutoff. "Feels right" not physical. +6. **Retail jumps are a SubState swap, not an Action.** + `MotionCommand.Falling (0x40000015)` is a SubState cycle whose + motion-table Links carry the leap-up AND landing transitions. No + action-queue port was needed; `SetCycle(Falling)` while airborne + + normal SetCycle on land gives retail-faithful jump animation. + Costly lesson: I first tried Action (mask 0x10) + Modifier (mask + 0x20) routing and broke the character into a torso. Empirical + motion-table dump is always worth more than my guesses. +7. **ACE's MovementData only computes ForwardSpeed for the + WalkForward/WalkBackwards branch.** Sending `RunForward` directly + leaves observers at `speed=0`. Correct wire format is + `WalkForward + HoldKey.Run + ForwardSpeed=runRate` — ACE + auto-upgrades to `RunForward` for broadcast. Our own client uses + a separate LocalAnimationCommand to play the RunForward cycle + locally while the wire stays WalkForward. +8. **Instance batching by GfxObjId alone is catastrophic for NPCs.** + Every humanoid shares the same body GfxObjs; grouping them all + into one DrawInstanced batch and using the first entry's texture + for the whole batch meant whoever sorted first at a given camera + angle "won" the palette. Fixed by keying instance groups on + `(GfxObjId, PaletteHash XOR SurfaceOverridesHash)`. + +## Client state at end of session + +Client runs, connects to local ACE, in-world as `+Acdream`. Working: +- Player moves, turns, strafes, jumps, lands. Jump animation plays via + Falling SubState. Run animation broadcasts correctly to retail + observers (WalkForward + HoldKey.Run wire format). +- Holtburg NPCs render with correct clothing / palette, stable across + camera angles (instance-batching dedup fix). +- Debug overlay: F1 help, F2 collision wireframes, F3 dump, F4/F5/F6 + panel toggles, F8/F9 sensitivity tuning. +- Mouse: per-mode sensitivity (Chase 0.15x, Fly/Orbit 1.0x), RMB + free-orbit, wheel zoom. + +Known small issues (non-blocking): +- Walk-backward animation's first step has a tiny jitter. +- Running → stopping has a slight twitch (missing SubState→Ready link + blend). +- Some retail chars have legs through the ground (Z-offset bug — + parked for later diagnosis). +- Jump feel is 95% retail, not 100%. ## Pickup for next session @@ -86,6 +136,8 @@ commits green on build + 470 tests. | Enter a dungeon | Phase G.3 dungeon streaming (R9) | | See a sky | Phase G.1 weather/day-night (R12) | | Create a character in-client | Phase H.4 CharCreate (R7) | +| Polish animation (backward jitter + stop twitch) | Link-cycle walker for SubState→Ready transitions | +| Remote-char feet in ground | Z-offset diagnosis (compare server-sent Z vs our terrain at observer XY) | The **master synthesis** (`docs/research/deepdives/00-master-synthesis.md` §10) recommends a specific week-by-week sequence if the user wants @@ -102,3 +154,22 @@ one-thing-at-a-time focus. toolkit approach is the only viable path. - **Network protocol atlas (R8)** is the single biggest unblocker — nearly every other system depends on opcodes we don't handle. +- **Diagnostic dumps > guessing.** The jump-animation saga took 4 + launches + reverts before I added a diagnostic that dumped the + actual Links dict contents. That one dump (revealing + `Links[0x003D0007]` had an inner entry `0x40000015 Falling`) + instantly showed the right approach. Trust empirical motion-table + contents over any assumption about retail structure. Add dumps + liberally when the code is non-cooperative; remove when verified. +- **Retail animation lexicon:** Style (mask 0x80), SubState (0x40), + Modifier (0x20), Action (0x10). SubStates are looping cycles + (Ready/Walk/Run/Falling/Crouch). Modifiers overlay on a cycle. + Actions are transitions held in the Links dict (emotes, attacks). + For any new animation: dump the motion table, find where the + target motion lives, use SetCycle if it's in Cycles or the + Links/Modifiers path if it's transitional. +- **Wire-format vs local-animation separation:** we now route the + wire ForwardCommand separately from the local animation command + (RunForward cycle locally, WalkForward+HoldKey.Run on wire). + Matching ACE's broadcast expectations and retail client expectations + simultaneously sometimes requires two independent command streams.