acdream/docs/plans/2026-04-11-roadmap.md
Erik 77b59d89e2 docs(roadmap): Phase M — Network Stack Conformance plan
Adds the Phase M planning entry: replace the happy-path WorldSession
shape with a holtburger-aligned reliable network stack while keeping
acdream's stricter checksum verification + live ACE compatibility.
Lays out M.1–M.x sub-lanes (audit/parity map, layer extraction,
reliability core, etc.).

Detailed spec to land at
docs/superpowers/specs/2026-05-02-network-stack-conformance.md
before implementation starts. Holtburger is the client-behavior
oracle for this phase.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 16:14:05 +02:00

52 KiB
Raw Permalink Blame History

acdream — strategic roadmap

Status: Living document. Updated 2026-05-02 for Phase M network-stack conformance planning. Purpose: One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under docs/superpowers/specs/, not in this file.


Phases already shipped

Phase What landed Verification
1 Terrain rendering, plugin host scaffold Visual ✓
2a Static stabs/buildings (126 entities) Visual ✓
2b Textured 3×3 landblock grid + FlyCamera + IGameState Visual ✓
2c Procedural scenery (419 trees/rocks/bushes) Visual ✓
2d Interior EnvCell walker (475 static interior objects) Visual ✓
3a/3b Directional sun lighting + per-vertex terrain normals Visual ✓
3c Per-cell terrain texture blending (alpha atlas) Visual ✓
4 Full UDP codec + handshake + character login + WorldSession Live ✓
5 ObjDesc: AnimPartChange + TextureChanges + SubPalettes + ObjScale + Placement.Resting Live ✓
6.1 Idle motion frame resolution (MotionResolver MVP) Live ✓
6.2 Server-sent MovementData stance + forward command honored Live ✓
6.3 Server-supplied MotionTableId override (fixes drudge statue) Live ✓
6.4 Per-frame animation playback (breathing, idle cycles) Live ✓
6.5 Slerp between keyframes for smooth animation Live ✓
6.6 UpdateMotion (0xF74C) parser + dispatch to animation tick Live ✓
6.7 UpdatePosition (0xF748) parser + position reseating Live ✓
7.1 EnvCell room geometry — walls/floors/ceilings via CellStruct + Environment dats Visual ✓
9.1 Translucent render pass (AlphaBlend / Additive / InvAlpha + per-kind blend funcs) Visual ✓
9.2 Back-face culling in translucent pass (fixes lifestone crystal) Visual ✓
A.1 Streaming landblock loader — runtime-configurable visible window (default 5×5, ACDREAM_STREAM_RADIUS), camera-centered offline / player-centered live, hysteresis-based unloads, pending-spawn list for late CreateObject events Live ✓
A.2 Frustum culling — per-landblock AABB test (Gribb-Hartmann), terrain + static-mesh renderers skip culled landblocks, perf overlay in window title Visual ✓
A.3 Background net receive thread — dedicated daemon thread buffers UDP into Channel, render thread drains Visual ✓
B.3 Physics MVP resolver foundation — terrain contact, CellSurface prototype, streaming-populated collision inputs, and first PhysicsEngine resolver path. Not the complete retail collision system. Tests ✓
B.2 Player movement mode — Tab-toggled WASD ground walking, walk/run/idle animations, third-person chase camera, MoveToState + AutonomousPosition outbound, portal entry. Outdoor-only MVP. Live ✓
D.1 2D ortho overlay + font rendering (StbTrueTypeSharp atlas + TextRenderer + DebugOverlay) Visual ✓
E.1 Motion-hook expansion — AnimationSequencer fires all 27 hook types per crossed frame; PosFrames root motion + vel/omega exposure; IAnimationHookSink + AnimationHookRouter fan-out Tests ✓
E.2 Audio engine — OpenAL 16-voice 3D pool with retail-faithful quieter-slot eviction, SoundTable cookbook (probability-weighted variant picking), Wave PCM decoder, AudioHookSink wiring Tests ✓
E.3 Particle system (data layer) — ParticleSystem with 13 motion integrators, EmitterDescRegistry, ParticleHookSink wiring all CreateParticle / DestroyParticle / StopParticle hooks Tests ✓
E.4 Combat notifications + outbound — AttackTargetRequest (0x0008), 7 combat notification parsers (Victim/Defender/Attacker/Evasion/AttackDone/UpdateHealth), CombatState per-entity health tracker Tests ✓
E.5 Spell cast wire — CastSpellRequest targeted (0x004A) + untargeted (0x0048), Spellbook (learned spells + active-enchantment layers), 5 enchantment GameEvent parsers Tests ✓
F.1 GameEvent (0xF7B0) envelope dispatcher — all 94 sub-opcodes routed, exception-isolated handler registry, unhandled-count diagnostic bag; 18 event-payload parsers Tests ✓
F.2 Item model + Appraise — ItemRepository with move/equip/property events, AppraiseRequest (0x00C8), IdentifyObjectResponse header, WieldObject + InventoryPutObjInContainer Tests ✓
G.1 Sky + day/night — DerethDateTime (retail-exact 7620-tick calendar + 16-hour names + PY year), SkyStateProvider (4-keyframe default with angular-wrap lerp), WorldTimeService (server-synced clock with real-time advance) Tests ✓
G.2 Dynamic lighting (selection) — LightSource + LightManager with retail 8-light cap, range-squared with 1.1× slack, slot 0 reserved for Sun, OwnerId-keyed unregister Tests ✓
G.1+ Full sky visuals + weather + dynamic-light shader — SkyDescLoader parses Region 0x13000000 dat keyframes with retail fog fields (start/end/mode); WeatherSystem picks Clear/Overcast/Rain/Snow/Storm deterministically per in-game day with 10s fade; SkyRenderer draws far-plane-1e6 celestial meshes with UV scroll; SceneLightingUbo binds at std140 location=1 with 8 Light slots + fog + lightning flash; terrain.vert + mesh.frag + mesh_instanced.frag + sky.frag all consume the shared UBO; LightingHookSink auto-registers Setup.Lights per entity + flips IsLit on SetLightHook; ParticleRenderer renders rain/snow billboards; F7 cycles day time override, F10 cycles weather; WorldSession surfaces server time via ServerTimeUpdated (ConnectRequest + TimeSync flag) Tests ✓
H.1 Chat window — wire layer + panel + outbound input + holtburger inbound parity all shipped (I.1-I.7). Talk (0x0015) / Tell (0x005D) / ChatChannel (0x0147) outbound + EmoteText (0x01E0) / SoulEmote (0x01E2) / ServerMessage (0xF7E0) / PlayerKilled (0x019E) / TurbineChat (0xF7DE) / SetTurbineChatChannels (0x0295) inbound; ChatPanel with Enter-to-submit input + slash commands; CombatChatTranslator posts combat events as chat lines. Live ✓
Glue GameEventWiring.WireAll — single-call registration mapping parsed GameEvents → Core state classes (ChatLog, CombatState, Spellbook, ItemRepository); GameWindow exposes state classes + wires them to live session Tests ✓
D.2a UI scaffold — AcDream.UI.Abstractions stable contract (IPanel / IPanelHost / IPanelRenderer / ICommandBus + VitalsVM / VitalsPanel); AcDream.UI.ImGui backend on ImGui.NET + Silk.NET.OpenGL.Extensions.ImGui (pivoted from Hexa.NET.ImGui on 2026-04-25 — Hexa's native OpenGL3 backend resolves GL via GLFW/SDL and crashed 0xC0000005 without them); VitalsPanel wired into GameWindow behind ACDREAM_DEVTOOLS=1 with ImGui.WantCaptureKeyboard WASD suppression. 11 new tests. Live ✓
I.1 IPanelRenderer widget extension — TextColored / Checkbox / Combo / InputTextSubmit / BeginTable + ~9 more widget signatures on IPanelRenderer; matching ImGuiPanelRenderer impls. Foundation for I.2 + I.4. Tests ✓
I.2 DebugPanel migration — replaced 473-LOC StbTrueTypeSharp DebugOverlay with AcDream.UI.Abstractions/Panels/Debug/DebugPanel (collapsing-headers + diagnostics checkboxes + combat-event tail). DebugOverlay.cs deleted; TextRenderer + BitmapFont retained for the future world-space HUD (D.6). Live ✓
I.3 LiveCommandBus + WorldSession.SendTalk / SendTell / SendChannel — replaces NullCommandBus.Instance with a real handler-registry ICommandBus. New SendChatCmd record + ChannelResolver legacy-id mapping (per holtburger). 3-line wrappers around existing ChatRequests.BuildTalk/Tell/ChatChannel. Tests ✓
I.4 ChatPanel input field + slash commands — Enter-to-submit input field; ChatInputParser recognises /say /t /tell /r /g /f /a /m /p /v /cv /lfg /trade /role /society /olthoi; ChatVM.LastIncomingTellSender tracks for /r reply. ImGui.WantCaptureKeyboard already suppresses WASD on focus. Live ✓
I.5 Holtburger inbound chat parity + Windows-1252 codec — EmoteText (0x01E0), SoulEmote (0x01E2), ServerMessage (0xF7E0), PlayerKilled (0x019E) parsers + WeenieError routing through GameEventWiring. Global string codec switch from Encoding.ASCII to Encoding.GetEncoding(1252) so accented names round-trip per retail + holtburger. Tests ✓
I.6 TurbineChat codec + ChatChannelInfo — full 0xF7DE codec with three payload variants (EventSendToRoom, RequestSendToRoomById, Response), UTF-16LE strings with variable-length prefix, SetTurbineChatChannels (0x0295) parser, unified ChatChannelInfo (Legacy + Turbine variants), TurbineChatState. ACE doesn't host a TurbineChat server — codec is ready when retail-emulating servers exist. Tests ✓
I.7 CombatChatTranslator — retail-faithful combat-text formatters into ChatLog ("You hit drudge for 50 slashing damage (87%)"). Subscribes to CombatState's DamageTaken / DamageDealtAccepted / EvadedIncoming / MissedOutgoing / AttackDone / KillLanded; templates ported verbatim from holtburger panels/chat.rs:221-308. Tests ✓
K Input architecture — Action enum, KeyChord, KeyBindings, multicast InputDispatcher with scope-stack + modal capture, retail-default keymap (152 bindings), keybinds.json persistence, F11 Settings panel with click-to-rebind + conflict detection, main menu bar + View menu Live ✓
L.0 Full retail-style Settings interface — F11 tabbed panel with 6 tabs (Keybinds + Display + Audio + Gameplay + Chat + Character). settings.json at %LOCALAPPDATA%\acdream\, per-toon Character keying (swapped on EnterWorld). Display GL knobs (Resolution / Fullscreen / VSync / FOV / ShowFps) + Audio (Master / SFX) live-wired; Gameplay / Chat / Character settings persist for server-sync wiring later. Tab API extension to IPanelRenderer; chat Copy mode (read-only multi-line); per-panel layout reset; FramebufferResize handler keeps GL viewport + camera aspect + panel positions in sync. Live ✓
C.1 PES particle system + sky-pass refinements — retail-faithful ParticleEmitterInfo unpack with all 13 motion integrators (Particle::Init/Update ports of 0x0051c290/0x0051c930), PhysicsScriptRunner with CallPES self-loop semantics, ParticleHookSink with EmitterDied cleanup, instanced billboard ParticleRenderer with material-derived blend (DAT emitters never default additive — pulled from particle GfxObj surface), global back-to-front sort, BC clipmap alpha-keying, AttachLocal is_parent_local=1 live-parent follow via UpdateEmitterAnchor. Sky pass: Translucent+ClipMap → alpha-blend cloud sheet (matches D3DPolyRender::SetSurface 0x0059c4d0), raw-Additive fog-skip (matches 0x0059c882), per-keyframe SkyObjectReplace Translucency/Luminosity/MaxBright divide-by-100, bit 0x01 pre/post-scene split (matches GameSky::CreateDeletePhysicsObjects 0x005073c0), Setup-backed (0x020xxxxx) sky objects via SetupMesh.Flatten, persistent GL sampler objects (Wrap + ClampToEdge) replace per-frame wrap-mode mutation (ported from WorldBuilder's OpenGLGraphicsDevice), post-scene Z-offset gated on (Properties & 4) != 0 && (Properties & 8) == 0 per GameSky::UpdatePosition 0x00506dd0. Sky-PES playback disabled by default (named-retail proves GameSky drops pes_id); ACDREAM_ENABLE_SKY_PES=1 opens the experimental path. 1325 → 1331 tests. Live ✓

Plus polish that doesn't get its own phase number:

  • FlyCamera default speed lowered + Shift-to-boost
  • SurfaceDecoder: PFID_P8 / PFID_R8G8B8 / PFID_X8R8G8B8 decoders
  • GfxObjMesh: emit both pos and neg sides of double-sided polygons
  • EnvCell mesh Z-lift to fix ground-floor / terrain flicker

Phases ahead — agreed order

Phase A — Foundation (in progress)

Goal: walk across 10+ landblocks without crashes, without hitches at landblock boundaries, and without framerate cratering.

Sub-pieces:

  • ✓ SHIPPED — A.1 — Streaming landblock loader. Runtime-configurable visible window (default 5×5, ACDREAM_STREAM_RADIUS env var override). Center follows the fly camera offline and the server-sent player position in live mode. Currently runs synchronously on the render thread — the original async-worker design hit DatCollection's lack of thread safety and was reverted for correctness. The Channel-based outbox API is preserved so async loading can return cleanly when Phase A.3 introduces a thread-safe dat wrapper. Pending-spawn list in GpuWorldState parks live CreateObject events whose target landblock hasn't been streamed in yet and back-fills them when it arrives, so spawn-vs-streaming races are no longer racy at all. MaxCompletionsPerFrame=4 spreads the 5×5 first-frame load over ~7 frames (~116ms) to avoid GPU OOM.
  • ✓ SHIPPED — A.2 — Frustum culling. Per-landblock AABB test (Gribb-Hartmann plane extraction + positive-vertex AABB test) in both TerrainRenderer.Draw and StaticMeshRenderer.Draw. Per-entity culling deferred. LOD deferred to Phase C. Performance overlay in window title shows FPS, frame time, visible/total landblock ratio, entity count, animated count. ~160fps uncapped at 5×5 radius.
  • ✓ SHIPPED — A.3 — Background net receive thread. Dedicated daemon thread continuously pulls raw UDP datagrams from the kernel buffer into a Channel<byte[]>. Render thread's Tick() drains the channel. All decode, fragment assembly, ISAAC crypto, event dispatch, and ack-sending remain on the render thread — minimal change that prevents packet drops during frame stalls. Thread starts after EnterWorld() completes; PumpOnce() during handshake still reads the socket directly.
  • A.4 — Async dat decoding. Folded into the streaming worker — it's the worker's read path, not a separate subsystem. Called out here because regressions in dat caching could land on this surface.

Acceptance:

  • Walk across 10+ landblocks in any direction, no crashes, no empty voids.
  • Landblock-boundary crossings produce no visible hitch.
  • Runtime window radius toggleable via environment variable.

Detailed spec: docs/superpowers/specs/2026-04-11-foundation-phase-design.md


Phase B — Gameplay / interaction

Goal: actually play the game — walk the character on the server, click NPCs, pick up items, chat, basic combat loop.

Sub-pieces:

  • ✓ SHIPPED — B.1 — Outbound ack pump. Shipped as Phase 4.9 — per-packet ACK_SEQUENCE, not periodic. Server no longer drops idle clients.
  • ✓ SHIPPED — B.2 — Player movement mode. Tab-toggled WASD ground walking with collision-resolved outdoor terrain, walk/run/idle/turn-right animations, third-person chase camera, outbound MoveToState (0xF61C) + AutonomousPosition (0xF753) server messages, portal entry works. Outdoor→indoor transition disabled for MVP (CellSurface floor polygons too aggressive without portal-based detection). Minor polish remaining: strafe animation, turn-left animation. Spec: docs/superpowers/specs/2026-04-12-player-movement-design.md.
  • ✓ SHIPPED — B.3 — Physics MVP resolver foundation. Terrain contact, CellSurface prototype, streaming-populated collision inputs, and first PhysicsEngine resolver path. This shipped enough foundation for outdoor walking and early portal experiments, but it is not the complete retail collision system. Current conformance work lives under Phase L.2 — Movement & Collision Conformance. Spec history: docs/superpowers/specs/2026-04-12-physics-collision-engine-design.md.
  • B.4 — Use / UseWithTarget / PickUp. Outbound interaction messages. Drives opening doors, looting, talking to vendors.
  • B.5 — Chat. SendTell, SendChat outbound + receive/display inbound (display side depends on Phase D.1).

References:

  • references/ACE/Source/ACE.Server/Network/Handlers/MovementHandler.cs
  • references/ACE/Source/ACE.Server/Network/Handlers/UseObjectHandler.cs
  • references/holtburger/src/session/send.rs for outbound packet-building patterns

Acceptance: walk on-server with your character, open a door, talk to an NPC, send a chat message and see the echo.


Phase C — Polish / visuals

Goal: close the visible gaps that make the world read as "old / broken" compared to retail.

Sub-pieces:

  • ✓ SHIPPED — C.1 — VFX / particle system + sky-pass refinements. Retail-faithful ParticleEmitterInfo runtime + 13-type motion integrator port + PhysicsScript runner + instanced billboard renderer with material-derived blend + global back-to-front sort + AttachLocal live-parent follow. Sky-pass refinements: Translucent+ClipMap alpha-blend, raw-Additive fog-skip, per-keyframe SkyObjectReplace divide-by-100, sampler-object wrap selection (ported from WorldBuilder), gated post-scene Z-offset. Sky-PES disabled by default — named-retail decomp proves GameSky drops pes_id. Portal swirls, chimney smoke, fireplace flames still need a Phase C.1.5 follow-up to wire entity-attached emitters to retail effect IDs (the data layer is ready; only the wiring is deferred). Lands as merge feat(vfx): Phase C.1 — PES particle renderer + post-review fixes (ec1bbb4) + refactor(sky): replace per-frame wrap-mode mutation with persistent samplers (3d21c13).
  • C.2 — Dynamic point lights. Fireplaces and lamps need local lighting; small upgrade to the mesh shader to accumulate N (e.g., 4) nearest point lights per draw. Uniform-buffer or UBO-friendly layout.
  • C.3 — Palette range tuning. Small per-range offset/length tweaks to match retail skin/hair/eye colors. Mostly diff and verify work, no architecture change.
  • C.4 — Double-sided translucent polys. Edge case left by Phase 9.2: neg-side translucent polys are culled because cull is always BACK. Fix by tracking per-sub-mesh CullMode and flipping GL state per draw (or drawing twice with opposite cull). Minor.
  • C.5 — Shadow mapping (optional). Deferred unless it becomes a bottleneck in screenshots — dynamic shadows are a known complexity trap.

References:

  • references/ACE/Source/ACE.DatLoader/FileTypes/PhysicsScript.cs for the emitter schema
  • references/ACViewer/ACViewer/Physics/Particles/ for the visual model
  • references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/ParticleBatcher.cs for the Silk.NET-flavored implementation

Acceptance: portals look like swirly gates, chimneys smoke, fireplaces burn, character skin matches retail screenshots.


Phase D — UI / HUD + Sound

Goal: chat window, nameplates, inventory, and audio. Can run concurrently with Phase B or C because it doesn't touch gameplay/net/rendering surfaces.

Updated 2026-04-24 — staged backend strategy. We split Phase D into two stages so game logic can be validated quickly without waiting for the full retail-look custom toolkit. See docs/plans/2026-04-24-ui-framework.md for the full design. Short version:

  1. D.2a — ImGui as the short-term backend. Wire up in days, iterate game logic (chat-send, inventory actions, vitals HUD reading real state) in weeks. Looks like a debugger; that's fine. (Shipped 2026-04-25 on ImGui.NET + Silk.NET.OpenGL.Extensions.ImGui after a day-one pivot away from Hexa.NET.ImGui; see shipped table.)
  2. Stable AcDream.UI.Abstractions layer — ViewModels + Commands + IPanel / IPanelRenderer interfaces. Backend-agnostic. Plugin API publishes against this layer and never sees ImGui.
  3. D.2b onward — custom retail-look backend using dat assets (icons, panels, fonts). Swap one panel at a time; ImGui stays forever as the ACDREAM_DEVTOOLS=1 overlay for packet trace / state dump / dat browser.

Every sub-piece below (D.3 AcFont, D.4 dat sprites, D.5 core panels, D.6 HUD, D.7 cursors) ships against the abstraction layer, so it doesn't matter which backend is drawing when the port lands.

Sub-pieces:

  • D.1 — 2D ortho overlay + font rendering. SHIPPED 2026-04-17 as the dev-facing debug overlay (StbTrueTypeSharp system-font atlas + TextRenderer + DebugOverlay).
  • ✓ SHIPPED — D.2a — ImGui scaffold + AcDream.UI.Abstractions layer. Shipped 2026-04-25. Wires ImGui as the short-term backend behind ACDREAM_DEVTOOLS=1. Defines IPanel / IPanelHost / IPanelRenderer / ICommandBus + the first ViewModel (VitalsVM) in the new AcDream.UI.Abstractions project. First real panel: VitalsPanel reading HP from CombatState.GetHealthPercent. Backend pivoted Hexa.NET.ImGui → ImGui.NET + Silk.NET.OpenGL.Extensions.ImGui during integration — Hexa's native OpenGL3 backend does its own GL function resolution via GLFW/SDL and crashed with 0xC0000005 in ImGuiImplOpenGL3.InitNative against Silk.NET (no GLFW/SDL present). The Silk.NET extension is purpose-built for this scenario and is the ImGui.NET mitigation path that docs/plans/2026-04-24-ui-framework.md already called out as a "one-morning operation". Stam/Mana return float? null in D.2a because absolute values need LocalPlayerState + PlayerDescription (0x0013) parsing (filed post-D.2a). 11 new AcDream.UI.Abstractions.Tests green.
  • D.2b — Custom retail-look backend. Implements the same IPanel / IPanelRenderer contracts using a custom retained-mode toolkit sourced from retail dat assets. Requires D.2a shipped. Panels get reskinned one at a time; ImGui stays as the ACDREAM_DEVTOOLS=1 overlay forever. The original 2026-04-17 scaffold research (UiRoot / UiElement / UiPanel / UiHost + retail event codes + focus / drag-drop state machine + WorldMouseFallThrough) is the implementation foundation here — see docs/research/retail-ui/.
  • D.3 — AcFont from portal.dat. Replace stb_truetype system font with retail Font DBObjs (0x40000000..0x40000FFF) baked from RenderSurface source sheets — see research slice 03 §4. Preserves retail visual identity. (D.2b dependency — needs the custom renderer.)
  • D.4 — Dat sprites + 9-slice panel backgrounds. Load RenderSurface (0x06xxxxxx) as GL textures; add DrawSprite to UiRenderContext. Enables retail panel art. (D.2b dependency.)
  • D.5 — Core panels. Attributes (chunk_00470000.c:FUN_0047ba70), Skills (same), Paperdoll (chunk_004A0000.c:FUN_004A5200), Inventory, Spellbook (chunk_004C0000.c), Fellowship, Allegiance. Each uses the port sketches in slice 05. (Targets AcDream.UI.Abstractions — ships with D.2a using ImGui-rendered widgets; reskinned by D.2b.) The chat panel originally listed under D.5 shipped early in Phase I (I.4 input + I.7 combat translator superseded the chat-panel design here); this entry now covers Attributes / Skills / Paperdoll / Inventory / Spellbook / Fellowship / Allegiance only.
  • D.6 — HUD. Vital orbs (scissor-rect partial fill, dat sprites 0x060013B2), radar (0x06001388 / 0x06004CC1, 1.18× range factor), compass strip (scrolling U), target name plate, damage floaters, selection indicator. See slice 06. (Targets AcDream.UI.Abstractions — ships with D.2a; reskinned by D.2b.) Phase I.2 retired the StbTrueTypeSharp DebugOverlay but kept TextRenderer + BitmapFont alive specifically for D.6's world-space HUD elements (damage floaters, name plates) — they need raw GL text drawing that ImGui can't reach into the 3D scene.
  • D.7 — Cursor manager. OS + dat-sourced custom cursors (FUN_0043c1c0 GDI HCURSOR builder pattern from slice 03). (D.2b dependency.)
  • D.8 — Sound. Superseded — shipped as Phase E.2 (SoundTable/Sound dat decode, OpenAL 16-voice engine, per-entity 3D positional audio via AudioHookSink). Entry kept here for history; see the shipped table.

Reference docs: docs/research/retail-ui/00-master-synthesis.md + slices 01-06. Every AC-specific behavior has a decompiled FUN_ / DAT_ citation.

Acceptance: chat messages display in a retail-style panel, health/stamina/mana orbs fill correctly, attributes panel shows player stats, inventory opens with drag-drop working, and sound plays on hit/footstep.


Phase E — "Feel alive" — motion hooks + audio + VFX

Unlocks the sensory layer: footsteps, swing whooshes, impact sparks, spell auras. All three systems share animation-hook delivery as the trigger source — motion hooks are the blocker.

Research backing: docs/research/deepdives/00-master-synthesis.md + R3 + R4 + R5.

  • E.1 — Motion-hook expansion. Extend MotionInterpreter + AnimationSequencer to deliver all 27 AnimationHookType values (Sound=1, SoundTable=2, CreateParticle=18, AttackFrame=20, SoundTweaked=21, …) during frame advance. See r03-motion-animation.md.
  • E.2 — Audio engine. AudioEngine via Silk.NET.OpenAL, inverse-square CPU falloff, 16-voice pool. SoundTable + Wave dat decoders. Motion-hook wiring for footsteps + attacks. See r05-audio-sound.md.
  • E.3 — Particle system. ParticleSystem on Silk.NET GL (port WorldBuilder's ParticleBatcher). 13 motion-type integrators. PhysicsScript dispatcher tied to motion-hooks. See r04-vfx-particles.md.

Acceptance: walk around, footstep sounds per material; swing a weapon, hear whoosh; combat impact shows sparks + hit sound.

Phase F — Fight + cast + gear

Core gameplay loop on top of Phase E.

Research: R1 + R2 + R6 + R8 + UI slices 04/05.

  • F.1 — GameEvent envelope dispatcher. 94 sub-opcodes in 0xF7B0. Zero handled today. Start with PlayerDescription (0x0013) + property-update events. See r08-network-protocol-atlas.md.
  • F.2 — Item + inventory model. ItemInstance / Container / PropertyBundle. Appraise round-trip (0x00C80x00C9). Burden math. See r06-items-inventory.md + src/AcDream.Core/Items/.
  • F.3 — Combat math + damage flow. Damage formula, per-body-part AL, crit, hit-chance sigmoid. Server broadcasts damage events; client displays + HP bar. See r02-combat-system.md + src/AcDream.Core/Combat/.
  • F.4 — Spell cast state machine. SpellCastStateMachine + active buff tracking. Buffs + recalls first, projectile spells later. Fizzle sigmoid + mana conversion. See r01-spell-system.md + src/AcDream.Core/Spells/.
  • F.5 — Core panels. Attributes / Skills / Paperdoll / Inventory / Spellbook — using the retail-ui framework from Phase D.2. See 05-panels.md under retail-ui. (Targets AcDream.UI.Abstractions; unblocked by D.2a — ships with ImGui widgets — and reskinned when D.2b lands.)

Acceptance: equip a weapon, swing at a monster, see damage numbers, buff yourself, recall to the lifestone.

Phase G — World systems

Research: R9 + R12 + R13.

  • ✓ SHIPPED — G.1 — Sky + weather + day-night. Deterministic client-side from Portal Year time. Sky dome geometry + keyframe gradients + rain/snow particles. See r12-weather-daynight.md. Full data + visual stack shipped: Region dat loader, keyframe interp, WeatherSystem with 5-kind PDF + transitions + storm flashes, WorldSession→WorldTimeService sync via ConnectRequest+TimeSync, SkyRenderer with sky-object arcs + UV scroll, rain/snow billboard renderer, F7/F10 debug cycle keys.
  • ✓ SHIPPED — G.2 — Dynamic lighting. 8-light D3D-style fixed pipeline. Hard-cutoff at Range, no attenuation inside. Cell ambient. Shader UBO per frame. See r13-dynamic-lighting.md. SceneLightingUbo std140 at binding=1 feeds terrain + mesh + mesh_instanced + sky shaders. LightingHookSink auto-registers Setup.Lights at entity stream-in, flips IsLit on SetLightHook, unregisters on landblock unload.
  • G.3 — Dungeon streaming + portal space. EnvCellStreamer, portal-visibility BFS, PlayerTeleport (0xF751) handling with LoginComplete re-send, "pink bubble" loading state. Blocked on L.2e for trustworthy cell_bsp, indoor/outdoor portal transit, adjacent-cell ownership, and building entry/exit collision boundaries. See r09-dungeon-portal-space.md.

Acceptance: walk outside at dusk, see the sky gradient + sun moving; enter a torch-lit dungeon via portal; leave back to daylight.

Phase H — Social + progression

Research: R7 + R10 + R11 + UI slice 05.

  • ✓ SHIPPED — H.1 — Chat window. UI panel + all 6 wire opcodes (Channel, Tell, System, HearSpeech, HearRangedSpeech, TurbineChat). Wire layer + panel + outbound input + holtburger inbound parity + combat translator all shipped across I.1-I.7 on 2026-04-25. Targets AcDream.UI.Abstractions; will be reskinned when D.2b's custom retail-look toolkit lands.
  • H.2 — Allegiance. Tree model + XP pass-up math + 5 allegiance chat channels + MOTD. See r11-allegiance.md.
  • H.3 — Emote scripts + quests + dialogs. 122 EmoteType × 39 Trigger mini-VM. Contract tracker UI. NPC dialog rendered via chat with <Tell:…> markup. See r10-quest-dialogs.md.
  • H.4 — Character creation. 0xE000002 CharGen dat + 13 heritages + templates + appearance picker + preview renderer. See r07-character-creation.md.

Acceptance: create a character from scratch, talk to an NPC, get + complete a quest, gain XP that passes up to the patron.

Phase I — UI consolidation + complete chat system

Goal: retire the dual UI stack (custom StbTrueTypeSharp DebugOverlay + ImGui) in favour of ImGui hosting all dev/debug surfaces, then finish the chat system end-to-end (input, slash commands, holtburger inbound parity, combat translator). After this phase, dev tools live in one place and chat works the way retail + holtburger expect.

Sub-pieces (all ✓ SHIPPED 2026-04-25):

  • ✓ SHIPPED — I.1 — IPanelRenderer widget extension. Adds TextColored, Checkbox, Combo, InputTextSubmit, BeginTable + ~9 more widget signatures to IPanelRenderer and matching ImGuiPanelRenderer impls. Foundation for I.2 (DebugPanel) and I.4 (chat input). Commit b131514.
  • ✓ SHIPPED — I.2 — DebugPanel migration. Replaces the 473-LOC StbTrueTypeSharp DebugOverlay with AcDream.UI.Abstractions/Panels/Debug/DebugPanel (collapsing-headers + diagnostics checkboxes + combat-event tail). DebugOverlay.cs deleted; TextRenderer + BitmapFont retained for the future world-space HUD (D.6 — damage floaters, name plates). Commit 56037a4.
  • ✓ SHIPPED — I.3 — LiveCommandBus + WorldSession.Send{Talk,Tell,Channel}. Replaces NullCommandBus.Instance with a real handler-registry ICommandBus. New SendChatCmd record + ChatChannelKind enum + ChannelResolver legacy-id mapping (per holtburger). WorldSession.SendTalk / SendTell / SendChannel are 3-line wrappers around existing ChatRequests.BuildTalk/Tell/ChatChannel. Commit 8e6e5a0.
  • ✓ SHIPPED — I.4 — ChatPanel input field + slash commands. Enter-to-submit input field on ChatPanel; ChatInputParser recognises /say /t /tell /r /g /f /a /m /p /v /cv /lfg /trade /role /society /olthoi; ChatVM.LastIncomingTellSender tracks for /r reply. ImGui.WantCaptureKeyboard already suppresses WASD on input focus. Commit f14296c.
  • ✓ SHIPPED — I.5 — Holtburger inbound chat parity + Windows-1252. EmoteText (0x01E0), SoulEmote (0x01E2), ServerMessage (0xF7E0), PlayerKilled (0x019E) parsers + WeenieError routing through GameEventWiring. Global string codec switch from Encoding.ASCII to Encoding.GetEncoding(1252) so accented names round-trip per retail + holtburger. Commit ff5ed9e.
  • ✓ SHIPPED — I.6 — TurbineChat codec + ChatChannelInfo. Full 0xF7DE codec with three payload variants (EventSendToRoom, RequestSendToRoomById, Response), UTF-16LE strings with variable-length prefix, SetTurbineChatChannels (0x0295) parser, unified ChatChannelInfo (Legacy + Turbine variants), TurbineChatState. ACE doesn't host a TurbineChat server — codec is ready when retail-emulating servers exist. Commit ca968fc.
  • ✓ SHIPPED — I.7 — CombatChatTranslator. Retail-faithful combat-text formatters into ChatLog ("You hit drudge for 50 slashing damage (87%)"). Subscribes to CombatState's DamageTaken / DamageDealtAccepted / EvadedIncoming / MissedOutgoing / AttackDone / KillLanded; templates ported verbatim from holtburger panels/chat.rs:221-308. Commit 3d26c8e.
  • ✓ SHIPPED — I.8 — Docs alignment. Roadmap (this file) + docs/ISSUES.md issues #14-#20 closed + memory/project_chat_pipeline.md crib + MEMORY.md index entry + CLAUDE.md UI strategy paragraph all updated to reflect Phase I shipped state. Commit (this commit).

Acceptance (verified 2026-04-25):

  • All ImGui dev panels open with ACDREAM_DEVTOOLS=1: VitalsPanel + ChatPanel + DebugPanel.
  • Old DebugOverlay.cs is deleted; TextRenderer / BitmapFont still compile for D.6.
  • /say hello in chat sends a Talk packet; local echo lands in the panel.
  • Attacking a creature produces "You hit Drudge for 12 slashing damage (87%)" lines in chat.
  • Accented character names round-trip through the wire correctly (CP1252).

Memory crib: memory/project_chat_pipeline.md.


Phase K — Input architecture + retail bindings + Settings panel

Goal: retire the hardcoded WASD-style scheme; ship retail-faithful bindings as the default; let users remap any action via an in-game Settings panel; auto-enter player mode at login; replace mouse-X-yaw with retail's MMB-hold mouse-look.

Sub-pieces (all ✓ SHIPPED 2026-04-26):

  • ✓ SHIPPED — K.1a — Input architecture skeleton. Action enum, multicast InputDispatcher with scope stack, KeyChord / Binding / KeyBindings, Silk.NET adapters, parallel to existing handlers — no behavior change. Commit 84512d3.
  • ✓ SHIPPED — K.1b — Cut handlers over to dispatcher. Drop the legacy mouse-X-character-yaw path, fix WantCaptureMouse gating, single input path. Commit 256e962.
  • ✓ SHIPPED — K.1c — Retail-default keymap + JSON persistence. ~149 bindings matching docs/research/named-retail/retail-default.keymap.txt + JSON load/save with merge-over-defaults migration at %LOCALAPPDATA%\acdream\keybinds.json. Acdream debug F-keys relocated to Ctrl+F* to avoid retail conflicts. Commit da18910.
  • ✓ SHIPPED — K.2 — Login flow + MMB mouse-look + free-fly button. Auto-enter player mode at login (one-shot guard reusing the existing Tab handler), MMB-hold mouse-look (retail's CameraInstantMouseLook — cursor-locked camera + character yaw drive together), DebugPanel "Toggle Free-Fly Mode" button, Tab → ToggleChatEntry → ChatPanel.FocusInput(). Commit af74eac.
  • ✓ SHIPPED — K.3 — Settings panel + Keybindings UI + roadmap/issues update. SettingsPanel with click-to-rebind UX (modal capture via InputDispatcher.BeginCapture, Esc cancels, conflict-detection- with-confirmation prompt, draft / Save / Cancel semantics), F11 toggle + ImGui MainMenuBar entry, per-action / per-section / reset-all-defaults buttons. Roadmap + ISSUES + memory crib + CLAUDE.md updated in this commit. Commit (this commit).

Acceptance (verified 2026-04-26):

  • Login → spawn at the character's actual world position in chase camera (NOT Holtburg orbit). Tab not required.
  • W = run forward; X = run back; A/D = turn; Z/C = strafe; Alt+A/D/Left/Right = strafe (alternate); Q = autorun; Space = jump; Shift = walk modifier; S = stop; Y/G/H/B = postures.
  • Mouse alone does NOT drive character yaw. MMB-hold = cursor-locked camera + character yaw drive together. RMB and LMB are SelectRight / SelectLeft per retail.
  • F11 / View → Settings opens panel. Click "Rebind" next to any action → press a key → if conflict, prompt. Save writes %LOCALAPPDATA%\acdream\keybinds.json. Restart preserves customizations.
  • Mode-dependent combat keys (Insert/PgUp/Delete/End/PgDn) bound but dormant — light up in Phase L when CombatState.CurrentMode is wired (issue #L.3).

Memory crib: memory/project_input_pipeline.md.


Phase L.1 — Animation system completion

Status: IN PROGRESS on feature/animation-system-complete.

Goal: complete the retail-faithful animation surface beyond the locomotion/jump K-fix series: combat swings, spell casting, emotes, death, item-use, NPC/monster special actions, remote observer parity, and the remaining floating-point polish around style transitions, modifiers, action queues, speed scaling, and PosFrame root motion.

Plan of record: docs/plans/animation-system-audit.md.

Coupling to L.2: L.1 owns animation/motion parity. L.2 owns collision, contact truth, movement packets, and server-visible placement. They meet where root motion or observer movement changes the predicted body path; any such change must keep both phase plans in sync.

Sub-pieces:

  • L.1a — Audit & inventory. Map retail named-decomp evidence, ACE cross-references, existing acdream hook points, and current gaps for each animation category. Output: docs/plans/animation-system-audit.md.
  • L.1b — Command router + motion-state cleanup. Extract tested SetCycle vs PlayAction routing, add missing MotionCommand constants, and split death Sanctuary action from persistent Dead substate.
  • L.1c — Combat animation wiring. Combat mode tracking, draw/sheath style transitions, attack swings by stance/power/height, hit reactions, evades/blocks/parries, and death handoff.
  • L.1d — Spell casting wiring. Cast command classification, windup, release, fizzle/interruption, recoil, and school/effect distinctions.
  • L.1e — Emotes + postures. Outbound slash emotes, inbound command-list emotes, and persistent sit/lie/kneel/sleep states.
  • L.1f — NPC/monster + item-use coverage. Scripted gestures, monster special actions, potion/food/scroll/recall cycles, and remote parity.
  • L.1g — Polish + conformance. Style-transition chain, durable modifiers/action queues, root-motion handling, speed scaling, and broad synthetic MotionTable tests.

Acceptance:

  • dotnet build and dotnet test green at each commit.
  • Test count grows by at least 30 with one representative cycle/action test per major animation category.
  • Every AC-specific behavior cites named retail decomp or ACE/holtburger cross-reference evidence in code comments, tests, or commit notes.
  • User visual sign-off for local and remote attack, spell, emote, death, and item-use animation parity before marking shipped.

Phase L.2 — Movement & Collision Conformance

Status: ACTIVE.

Goal: make acdream's movement and collision behavior retail-faithful across terrain, buildings, walls, roof edges, cell seams, portal boundaries, outbound movement packets, and server correction. This is the holistic bucket for the work previously scattered across B.3 physics follow-ups, L.1 motion coupling, and G.3 dungeon/portal ownership.

Plan of record: docs/plans/2026-04-29-movement-collision-conformance.md.

Current foundation: PhysicsEngine.ResolveWithTransition, BSPQuery, TransitionTypes, PhysicsDataCache, and ShadowObjectRegistry exist and are active. They are partial retail ports and diagnostic scaffolding, not yet the final collision system.

Sub-lanes:

  • L.2a — Truth & diagnostics. Local placement/contact/cell logs, object-hit probes, correction-delta diagnostics, retail-observer capture workflow, and real-DAT fixture capture.
  • L.2b — Movement wire/contact authority. Fix outbound contact truth, full-cell id handling, packet cadence, and routine server correction handling.
  • L.2c — Transition parity: edge/slide/neg-poly. Port and test retail edge_slide, cliff_slide, precipice_slide, step-up/down slide, and NegPolyHit dispatch behavior.
  • L.2d — Shape fidelity: sphere/cylsphere/building objects. Finish CSphere / CCylSphere parity, live-entity object shapes, building object collision identity, and Setup.Radius fallback audit.
  • L.2e — Cell ownership: outdoor seams, CELLARRAY, cell_bsp. Update low outdoor cell id across 24m seams, port adjacent-cell checks, activate cell_bsp, and hand G.3 a trustworthy building/portal boundary model.
  • L.2f — Real-DAT and live retail-observer conformance. Promote synthetic tests to real-world fixtures and verify local acdream view plus retail observer view. ACE accepting a position is a compatibility check, not proof of fine-grained retail collision parity.

Acceptance:

  • A developer can trace the active movement path: input/motion -> body prediction -> ResolveWithTransition -> contact/cell result -> outbound packets -> server echo/correction.
  • Buildings, edge-slide, wall-slide, cell seams, packet authority, and dungeon portal ownership each have an L.2 lane.
  • Every AC-specific algorithm port cites named retail decomp, or a documented fallback when named retail lacks the body.
  • dotnet build and dotnet test are green for each implementation slice.

Phase M — Network Stack Conformance

Status: PLANNED.

Goal: replace the current happy-path WorldSession networking shape with a proper AC client network stack that reaches functional parity with references/holtburger/ while preserving acdream's stricter packet checksum verification and live ACE compatibility. This phase owns packet reliability, ordered delivery, retransmission, ACK piggybacking, echo/keepalive, typed message/action routing, diagnostics, and the migration of low-level network responsibilities out of the render tick.

Why now: The Phase 4/A.3 stack is good enough for local ACE smoke testing: login, ISAAC, checksums, per-packet ACKs, fragments, movement, chat, combat, and object updates all work. It is not yet a complete client network runtime. Compared with holtburger it lacks ordered S2C delivery, retransmit request handling, outbound packet caching/retransmission, ACK piggybacking, EchoRequest/EchoResponse handling, runtime ping/timeout policy, and a typed protocol/action layer. These gaps will become expensive as movement, dungeons, inventory, combat, and plugins depend on stable packet semantics.

Plan of record: create docs/superpowers/specs/2026-05-02-network-stack-conformance.md before implementation starts. Treat holtburger as the client-behavior oracle for this phase; cross-check wire details against named retail, ACE, Chorizite, and AC2D before porting.

Sub-lanes:

  • M.1 — Audit & parity map. Produce a source-by-source comparison of acdream AcDream.Core.Net and holtburger holtburger-session, holtburger-protocol, and holtburger-core networking code. Inventory each packet flag, optional header, session transition, control packet, fragment path, game message, and game action. Mark each as parity, partial, missing, or intentional divergence.
  • M.2 — Layer extraction. Split the low-level stack under WorldSession into testable components: INetTransport, PacketCodec, ReliablePacketSession, FragmentSession, GameMessageSession, and the high-level WorldSession behavior layer. Preserve existing public events and live-client call sites during the migration.
  • M.3 — Reliability core. Port holtburger-style sequence tracking: last-delivered server sequence, duplicate/old-packet suppression, out-of-order buffering, missing-sequence detection, throttled RequestRetransmit, outbound packet cache, server-requested C2S retransmit, RejectRetransmit handling, and retransmission checksum recomputation.
  • M.4 — ACK and control-packet policy. Replace standalone-only ACKs with queued ACK state, ACK piggybacking on normal outbound packets, standalone ACK flush when idle, and clean handling for ACK-only packets. Add EchoRequest / EchoResponse and idle ping/timeout behavior matching holtburger unless named retail proves a different cadence.
  • M.5 — Fragment and payload completeness. Keep inbound multi-fragment assembly, add TTL/eviction diagnostics for orphaned partials, implement outbound multi-fragment splitting when payloads exceed the current single fragment limit, and verify fragment id/sequence/queue behavior against holtburger, ACE, and retail evidence.
  • M.6 — Typed protocol surface. Introduce typed GameMessage and GameAction routing modeled on holtburger. Migrate current builders and parsers first: login complete, DDD, movement, chat/TurbineChat, combat, spellcast, item/appraise, object/update/motion/position, and teleport. Unknown opcodes must remain observable and non-fatal.
  • M.7 — Runtime loop and diagnostics. Move decode/order/reassembly/control handling out of the render tick into a dedicated network runtime that emits clean session events through channels. Add byte counters, packet trace hooks, optional capture/replay fixtures, idle/disconnect state, and dev-panel diagnostics suitable for packet debugging.
  • M.8 — Conformance tests and live validation. Add deterministic unit tests for checksum, ISAAC key consumption, optional headers, ordering, retransmit, ACK piggybacking, echo, fragments, typed actions, and login flow. Add replay/capture tests from holtburger-style fixtures where possible. Finish with dotnet build, dotnet test, local ACE login, chat, movement, combat action smoke test, reconnect test, and user visual sign-off where networking affects the running client.

Non-goals:

  • Do not reimplement ACE server behavior.
  • Do not replace acdream's stricter inbound checksum verification unless named retail proves it is wrong.
  • Do not rewrite renderer/gameplay systems as part of this phase; migrate network call sites through compatibility adapters first.
  • Do not remove unknown-message visibility. Plugins and devtools need packet trace surfaces even when parsers are incomplete.

Acceptance:

  • acdream has a layered, testable network stack rather than one monolithic WorldSession.
  • Every holtburger session capability has an acdream equivalent, an explicit test, or a documented intentional divergence with retail/ACE evidence.
  • Packet ordering, retransmit, outbound cache, ACK piggybacking, echo/keepalive, fragment assembly/splitting, and typed message/action routing are covered by tests.
  • Live ACE loop succeeds: login, enter world, movement, chat, combat action, teleport/reconnect, and clean logout.
  • dotnet build and dotnet test are green for every implementation slice.

Phase J — Long-tail (deferred / low-priority)

Not detailed here; each gets its own brainstorm when it becomes relevant.

  • Player character full rig (held weapons, spell effects, death/revive animation)
  • Group/fellowship UI
  • Trade window (multi-player confirms)
  • Salvage + tinker UI
  • House ownership + hooks
  • Society UI
  • GM visible tools (we explicitly don't build GM powers; but DEV-mode tools like teleport anywhere are useful)

Phase R — Retail research infrastructure

Goal: sustainable, scalable access to retail-client decompilation — named symbols, struct layouts, wire schemas — so every future port is a 5-second grep instead of 30-minute archaeology.

Sub-pieces:

  • ✓ SHIPPED — R.1 — Named-retail corpus committed. Shipped 2026-04-25 (commit a9a01d8). docs/research/named-retail/{acclient_2013_pseudo_c.txt, acclient.h, acclient.c} + docs/research/data/spells.csv + vendored references/actestclient/. 1.4 M lines of named pseudo-C (99.6% function naming) + 70K lines of verbatim retail headers + 3,956 spells with Family for buff stacking + machine-readable wire schema in messages.xml.
  • ✓ SHIPPED — R.2 — pdb-extract tool + JSON sidecars. Shipped 2026-04-25 (commit 69d884a). tools/pdb-extract/pdb_extract.py reads refs/acclient.pdb (Sept 2013 EoR build) and emits symbols.json (18,366 named functions) + types.json (5,371 named struct types) to docs/research/named-retail/. Pure Python, no deps, runs in <1 s.
  • ✓ SHIPPED — R.3 — actestclient vendored. Shipped 2026-04-25 alongside R.1. references/actestclient/ (covered by references/ gitignore) includes the canonical messages.xml AC-protocol wire schema.

Acceptance: Step 0 of CLAUDE.md's development workflow points at named-retail/ first; subsequent issue closures (#6 / #7 / #9 / #11) all consume this foundation.

Effects on other phases: Issue closures unblocked by Phase R land under their existing letter phases (#6 enchantment buffs → Phase D / F.5 maintenance; #7 PlayerDescription trailer → Phase H.1 / F.2 maintenance). The PDB symbols + headers also accelerate any future port in any phase — no separate listing here.


Cross-cutting work tracked in parallel

  • Test coverage. Each phase lands with unit + integration tests in tests/. Current count: 98 Core + 96 Core.Net = 194. Keep the ratio as new phases land.
  • Memory files. Project state under memory/project_phase_*_state.md is updated when a phase ships. MEMORY.md is the index.
  • CLAUDE.md discipline. Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first.

Explicitly out of scope

  • Server emulation — we use ACE for server, never reimplement.
  • Account creation — direct user to ACE tooling.
  • Anti-cheat / GM tools / live-ops — irrelevant for personal use.
  • Cross-platform support — Windows-only; the dat path assumptions depend on retail Windows install layout. Silk.NET is cross-platform but we don't promise.
  • Custom game content — this is a client for existing AC data, not a toolchain.

"When will my specific complaint be fixed?" — quick lookup

Observation Phase
Drudge statue in wrong pose 6.3 FIXED
Characters in T-pose / wrong idle 6.1 FIXED
No breathing on NPCs 6.4 + sentinel fix FIXED
Lifestone crystal has one side missing 9.2 FIXED
Ground floor flickering with terrain 7.1 FIXED
Houses missing second floors / walls 7.1 FIXED ✓ (interior mesh landed)
Character clothing missing / wrong 5 FIXED
Statue wrong color / wrong scale 5 FIXED
Holtburg sign half-buried 5 FIXED
Can't walk past the loaded 3×3 window A.1 FIXED ✓ (5×5 default, ACDREAM_STREAM_RADIUS to tune)
Frame hitch crossing landblock boundary Phase A.3 (synchronous loader for now; async returns when DatCollection is thread-safe)
Walking around doesn't move me on the server Phase B.2/B.3 FIXED ✓ for coarse server movement; fine retail collision parity is Phase L.2
Packet loss / out-of-order UDP causes stale or missing world updates Phase M.3
Server asks for retransmit and client doesn't resend cached packets Phase M.3
ACKs are standalone-only instead of piggybacked like a full client Phase M.4
Echo / idle keepalive / reconnect behavior is incomplete Phase M.4 + M.7
Large outbound game messages exceed the current single-fragment path Phase M.5
Network protocol coverage is spread across ad-hoc builders/parsers Phase M.6
Sliding along buildings / walls feels wrong Phase L.2c + L.2d
Roof edge / cliff / precipice blocks or slides wrong Phase L.2c
Crossing outdoor cell seams reports the wrong cell Phase L.2e
Can't talk to NPCs Phase H.3 (emote scripts + dialogs)
Can't open a door Phase F (object-use action)
Portals render as a rotating black disk Phase E.3 (particle system)
Chimneys have no smoke Phase E.3
Houses have no fireplace fire Phase E.3
No fireplace / torch lighting Phase G.2 (shipped; Setup.Lights auto-register, 8-light cap with hard-cutoff)
Skin/hair color slightly off Phase C.3
No chat window Phase H.1 / I.1-I.7 FIXED
Chat? You can finally type and send messages I.4 FIXED ✓ (shipped 2026-04-25)
Combat doesn't show in the chat log I.7 FIXED
Accented character names show as ? or garbled I.5 FIXED ✓ (Windows-1252 codec)
No sound Phase E.2
Dungeons / foundry interior missing Phase G.3 after L.2e cell/building ownership
Can't fight monsters Phase F.3 (combat math + damage)
Can't cast spells Phase F.4
No inventory panel Phase F.2 + F.5
No character creation — must use ACE admin Phase H.4
Sky is a flat color Phase G.1 (shipped; F7 cycles time, F10 cycles weather)
Can't join allegiance Phase H.2
No quest tracker Phase H.3

If you see something not on this list, add it here and assign a phase.