Output of a brainstorming session after Phase 6/7.1/9.1/9.2 shipped and the lifestone crystal bug was isolated. Two documents: 1. docs/plans/2026-04-11-roadmap.md — strategic roadmap replacing the stale post-Phase-5 version. Reflects what's actually shipped, reorganizes upcoming work into Phases A (Foundation), B (Gameplay), C (Polish — includes VFX/particles, dynamic lights, palette tuning, double-sided translucents), D (UI + Sound), and E (long-tail). Updates the "when will my complaint be fixed" quick-lookup with the correct phase for portals (VFX, not shader tricks as previously claimed), smoke, fireplace fire, and everything we fixed this session. Phase ordering: A → B → (C/D in parallel) → E. 2. docs/superpowers/specs/2026-04-11-foundation-phase-design.md — detailed implementation spec for Phase A only. Covers the four sub-pieces (streaming landblock loader, frustum culling, net I/O thread, async dat decoding folded into the streaming worker), their components, data flow, error handling, testing strategy, and commit-point ordering. Includes non-goals to prevent scope creep. No code changes yet. The spec goes to user review next, then into the writing-plans skill for a detailed implementation plan. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
11 KiB
acdream — strategic roadmap
Status: Living document. Updated 2026-04-11 after Phase 6, 7.1, 9.1, 9.2 landed.
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 ✓ |
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 (next)
Goal: walk across 10+ landblocks without crashes, without hitches at landblock boundaries, and without framerate cratering.
Sub-pieces:
- A.1 — Streaming landblock loader. Runtime-configurable visible window (default 5×5,
ACDREAM_STREAM_RADIUSenv var override). Center follows the camera offline and the player in live mode. Background worker thread loads landblocks CPU-side (dats, scenery, interior, entities); the render thread drains a completion outbox and performs GPU upload. Unloads happen atradius + 1distance to avoid churn. - A.2 — Frustum culling + LOD. Per-landblock AABB test against the view frustum in
StaticMeshRenderer.Draw, skipping drawn entities in culled landblocks. Per-entity culling deferred. No LOD mesh levels yet — that's Phase C or later. - A.3 — Background net I/O thread.
WorldSessionruns its receive loop on a dedicated thread; parsed game messages are posted to a concurrent queue the render thread drains fromOnUpdate. Event invocations still happen on the render thread (preserves existing handler assumptions). Removes packet drops under frame stalls. - 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:
- B.1 — Outbound ack pump. Background timer that sends sequence acks every ~250ms. Without this the server drops idle clients after ~30s regardless of any other activity.
- B.2 —
PlayerAutonomousMoveoutbound. Wire WASD + camera state (or a dedicated player-controlled movement mode) to an outbound movement message so the server's view of the character matches ours. - B.3 — Collision against terrain. Required for the server to accept moves at all — ACE rejects client positions that are inside geometry or in disallowed Z ranges. Minimum viable: sample the terrain heightmap beneath the player and clamp Z. Proper: walk the
CellBSP/PhysicsBSPwe already parse. - B.4 —
Use/UseWithTarget/PickUp. Outbound interaction messages. Drives opening doors, looting, talking to vendors. - B.5 — Chat.
SendTell,SendChatoutbound + receive/display inbound (display side depends on Phase D.1).
References:
references/ACE/Source/ACE.Server/Network/Handlers/MovementHandler.csreferences/ACE/Source/ACE.Server/Network/Handlers/UseObjectHandler.csreferences/holtburger/src/session/send.rsfor 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:
- C.1 — VFX / particle system.
PhysicsScriptparser, per-entityParticleEmitterstate, billboarded-quad particle renderer that lives in the Phase 9.1/9.2 translucent pass. Delivers portal swirls, chimney smoke, and fireplace flames in one implementation. - 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
CullModeand 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.csfor the emitter schemareferences/ACViewer/ACViewer/Physics/Particles/for the visual modelreferences/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/ParticleBatcher.csfor 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.
Sub-pieces:
- D.1 — 2D ortho overlay + font rendering. Separate shader and render pass drawn after 3D. Font: FreeType via Silk.NET bindings, or bitmap fonts as a simpler first pass.
- D.2 — Chat window + nameplates. First UI widgets. Chat consumes Phase B.5 messages; nameplates render per-entity 3D-to-2D projected labels.
- D.3 — Inventory / character / spell panels. Requires a widget framework (layout, focus, input routing). Scope unbounded — ship minimum viable first.
- D.4 — Sound.
SoundTableparser,Sounddat decode, audio engine (OpenAL via Silk.NET.OpenAL), per-entity 3D positional audio, optional music.
Acceptance: see other players' chat in a chat window, see nameplates above NPCs, hear footsteps and sword hits.
Phase E — Long-tail
Not detailed here; each gets its own brainstorm when it becomes relevant.
- Dungeon landblocks (
0xAAAA0000family) + teleport-on-door-click + server-side portal handling - Phase 7.2 multi-floor stair walking — cells reachable via portals the cell-walker doesn't cross
- Player character full rig (held weapons, spell effects, death/revive animation)
- Weather + day/night cycle
- Spellcasting pipeline
- Group/fellowship UI
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.mdis updated when a phase ships.MEMORY.mdis the index. CLAUDE.mddiscipline. 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 | Phase A (Foundation) |
| Frame hitch crossing landblock boundary | Phase A |
| Walking around doesn't move me on the server | Phase B (Gameplay) |
| Can't talk to NPCs | Phase B |
| Can't open a door | Phase B |
| Portals render as a rotating black disk | Phase C.1 (VFX) |
| Chimneys have no smoke | Phase C.1 |
| Houses have no fireplace fire | Phase C.1 |
| No fireplace / torch lighting | Phase C.2 |
| Skin/hair color slightly off | Phase C.3 |
| No chat window | Phase D.2 |
| No sound | Phase D.4 |
| Dungeons / foundry interior missing | Phase E |
If you see something not on this list, add it here and assign a phase.