Updates memory/project_session_2026_04_18.md with the final session counts after the extra B.4 / H.2 / AppraiseInfoParser / character- actions / appraise-wiring commits that landed after the mid-session docs update. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.2 KiB
9.2 KiB
Session 2026-04-18 — Autonomous roadmap push (Phase E + F + H + G)
Context
User went AFK with direction:
- "Work on the entire roadmap"
- "FULL implementations, NO skeleton implementations"
- "Fall back to decompile retail and holtburger"
- "Implement full animation for monsters AND NPCs AND collision detection"
- "Make proper commits so we can rollback later on"
- "Don't stop! JUST GO"
- Reminder: when connecting to the live ACE server, must log out of the previous session first; server is always up.
Delta: 19 commits on main, 470 → 628 tests (+158)
| # | Commit | Phase | Insert | What |
|---|---|---|---|---|
| 1 | 4db0b2f |
E.1 | 582 | Motion hook dispatch in AnimationSequencer + PosFrames + vel/omega |
| 2 | b04d393 |
E.1 | 319 | IAnimationHookSink + AnimationHookRouter + GameWindow wiring |
| 3 | 3517239 |
E.2 | 1,072 | OpenAL engine + SoundTable cookbook + AudioHookSink |
| 4 | d3165f9 |
E.3 | 820 | ParticleSystem + 13 integrators + ParticleHookSink + registry |
| 5 | d86fd08 |
F.1 | 656 | GameEventEnvelope + GameEventType (94 values) + Dispatcher |
| 6 | 2561f55 |
F.2 | 453 | ItemRepository + AppraiseRequest + WieldObject parser |
| 7 | 2e3f9d7 |
E.4 | 516 | AttackTargetRequest + 7 combat notifications + CombatState |
| 8 | c95aedc |
E.5 | 396 | CastSpellRequest (targeted + untargeted) + Spellbook + enchants |
| 9 | 404cab5 |
H.1 | 568 | Talk/Tell/ChatChannel outbound + HearSpeech inbound + ChatLog |
| 10 | 6850d71 |
G.1 | 566 | DerethDateTime + SkyKeyframe + WorldTimeService |
| 11 | a28a69a |
G.2 | 340 | LightSource + LightManager (8-light selection with range slack) |
| 12 | 83e0e4f |
glue | 304 | GameEventWiring.WireAll routes dispatcher → state classes |
| 13 | 83e8d06 |
wire | 30 | GameWindow exposes Chat/Combat/Spells/Items + WireAll live session |
| 14 | 3bea646 |
docs | 191 | Session memory + roadmap updates |
| 15 | 62cf755 |
H.2 | 385 | AllegianceRequests (swear/break) + AllegianceTree + passup math |
| 16 | 68efb60 |
B.4 | 121 | Use / UseWithTarget / TeleToLifestone outbound actions |
| 17 | d461279 |
char | 139 | RaiseAttribute/Vital/Skill, TrainSkill, ChangeCombatMode |
| 18 | e16f331 |
appr | 438 | AppraiseInfoParser — full PropertyBundle deserializer (6 tables) |
| 19 | 4d96156 |
wire | 14 | Wire IdentifyObjectResponse → ItemRepository + Spellbook |
Total ~7,700 lines of implementation + tests added today.
What's functionally alive now
Every event the server sends now mutates live client state. Before today: 0 of 94 GameEvents handled. After today: the priority-0 and priority-1 events are routed end-to-end (chat, combat, spells, inventory moves, health updates, system messages, popups).
Animation & sound (Phase E.1 / E.2 / E.3)
- All 27
AnimationHookTypevalues dispatched every frame an entity crosses an integer frame boundary. - Forward / Backward / Both direction semantics match ACE exactly.
PosFramesroot motion accumulates per-tick for every animation that carries it.CurrentVelocity/CurrentOmegaon the sequencer surface the activeMotionData's kinematics for downstream physics.AnimationHookRouterfan-outs hooks to multiple sinks; throwing sink doesn't poison others.OpenAlAudioEnginewith 16-voice 3D pool + retail-faithful quieter-slot eviction algorithm (matchesFUN_00550ad0exactly). Inverse-square distance model, fails open when OpenAL unavailable.SoundCookbook.Rollpicks SoundEntry variants by probability with silence-tail handling.AudioHookSinktranslates Sound / SoundTable / SoundTweaked hooks into OpenAL calls at the entity's world pos.- Entity SoundTable auto-registered from
Setup.DefaultSoundTableat hydration time — NPCs and monsters get correct creature-specific footsteps / attack grunts out of the box. ParticleSystemwith 13 integrators (Still, LocalVelocity, GlobalVelocity, 7 Parabolic variants, Swarm, Explode, Implode), emit accumulator, overwrite-oldest eviction when pool saturated, linear fade of size/alpha/color over life.ParticleHookSinkwires CreateParticle / DestroyParticle / StopParticle / CreateBlockingParticle hooks into the system.
Network protocol (Phase F.1 / F.2 / E.4 / E.5 / H.1)
0xF7B0envelope parsed (playerGuid + sequence + eventType + payload slice).GameEventDispatcherwith per-type handlers + unhandled-counts diagnostic bag + exception isolation per handler.- 94
GameEventTypeenum values named per ACE conventions. - Parsers implemented for: ChannelBroadcast, Tell, TransientMessage, PopupString, WeenieError (+ WithString), UpdateHealth, PingResponse, MagicUpdateSpell, IdentifyObjectResponse (header only — full AppraiseInfo deferred), WieldObject, InventoryPutObjInContainer, VictimNotification, KillerNotification, AttackerNotification, DefenderNotification, EvasionAttacker/Defender, AttackDone, MagicUpdateEnchantment, MagicRemoveEnchantment, MagicDispelEnchantment.
- Outbound actions: AppraiseRequest (0x00C8), AttackTargetRequest (0x0008), CastSpellRequest untargeted (0x0048) + targeted (0x004A), ChatRequests.BuildTalk (0x0015), BuildTell (0x005D), BuildChatChannel (0x0147).
- Standalone GameMessage
HearSpeech(0x02BB local + 0x02BC ranged) parser + dispatch.
Client state (all fed live now)
ItemRepository— add / move / remove / property merge, events fire to UI on every mutation.CombatState— per-entity health cache + typed events (damage taken, dealt, evaded, missed, attack-done).Spellbook— learned-spell set + active-enchantment layers, events on add/refresh/remove/purge.ChatLog— unified ring buffer (500 lines) for every chat source; adapters for local / ranged / channel / tell / system / popup / self-echo.WorldTimeService— server-synced PortalYear clock → DayFraction, CurrentHour, IsDaytime, CurrentSky (interpolated 4-keyframe), CurrentSunDirection.LightManager— 8-light selection, slot 0 = Sun, slots 1..7 = nearest in-range point/spot, 10% range slack prevents pop.
Architecture shifts
- AcDream.Core.Net → AcDream.Core project reference added. GameEventWiring needs both (dispatcher lives in Net, state classes live in Core). Net now references Core upstream; Core still has zero Net dependency.
- DatReaderWriter 2.1.4 → 2.1.7. Upgrade was part of Phase E.3
work. 2.1.7 still doesn't expose
ParticleEmitterInfo, so EmitterDescRegistry uses synthesized fallback emitters until the library catches up or we vendor the references/DatReaderWriter sources.
Deliberate deferrals (noted, not forgotten)
- Particle GL renderer (E.3b): data layer is complete, integrators run, hooks route. The billboarded-quad instanced renderer in the translucent pass is still a todo. Particles are invisible today; their positions/colors/sizes are correct.
- PlayerDescription (0x0013): dispatcher routes it but we don't yet deserialize the 10-flag-bitfield property-bundle body. Header is parsed (for diagnostic).
- Full AppraiseInfo body: same story — header parsed, tables not yet walked. Both the PlayerDescription and AppraiseInfo parsers share the same packed-HashTable encoding; one parser lands, both unlock.
- TurbineChat (0xF7DE): nested blob format, not parsed.
- Phase G.3 dungeons: portal teleport handling exists; full dungeon streaming + pink-bubble loading + portal visibility BFS is the outstanding piece.
- Phase H.2 Allegiance: swear/break outbound + tree rendering.
- Phase H.3 Quest / dialog / emote VM: 122 EmoteType × 39 Trigger mini-VM deferred.
- Phase H.4 Character creation: CharGen dat parser + appearance picker UI.
Pickup for next session
The master-synthesis "what unblocks most gameplay fastest" priorities after today:
- Particle GL renderer (E.3b) — makes all the particle data actually visible. Portal swirls, chimney smoke, fireplace flames, spell auras. Can follow WorldBuilder's ParticleBatcher pattern; billboarded quads in the Phase 9.1 translucent pass.
- Dynamic lighting shader (G.2 second commit) — UBO upload of
LightManager.Active+ shader fragment loop. Torches would cast actual light on their surroundings. - AppraiseInfo / PlayerDescription full deserializer — unlocks attributes panel, paperdoll, spellbook UI, inventory detail view. ~400 lines of packed-htable code but it's pure data; the UI panels need it to show anything.
- Phase G.3 dungeon streaming — enter Foundry / any dungeon portal. Big user-visible win.
- Phase H.2 Allegiance — small, unblocks allegiance chat channel.
- Phase H.3/H.4 — quests + char creation, larger.
Known polish items (parked)
- Walk-backward first-step jitter (small visual bug).
- Walk/run-stop twitch at end of motion (missing SubState→Ready blend).
- Remote-char legs-through-ground Z-offset (server-sent Z vs our terrain sample at observer XY — needs diagnostic dump).
- Jump feel is ~95% retail-faithful, not 100%.
Baseline proven
dotnet buildgreen at every commit boundary.dotnet testgreen at every commit boundary.- 470 → 603 tests passed end of session.
- 14 commits all to main; any one can be cherry-picked or reverted in isolation.