phase(N.4): SHIP — flag default-on + finalize plan + roadmap
Phase N.4 (Rendering Pipeline Foundation) ships. WbFoundationFlag flips to default-on (== "1" → != "0"). WB's ObjectMeshManager is now acdream's production mesh pipeline; WbDrawDispatcher is the production draw path. Legacy InstancedMeshRenderer is retained as ACDREAM_USE_WB_FOUNDATION=0 escape hatch until N.6 retires it. Visual verification at Holtburg passed: - Scenery (trees / rocks / fences / buildings) renders correctly - Characters connected with full close-detail geometry (Issue #47 preserved — GfxObjDegradeResolver path intact) - FPS substantially improved by grouped instanced draws + per-entity AABB cull + opaque front-to-back sort + palette-hash memoization Three high-value WB API gotchas surfaced during Task 26 visual verification and are now documented in CLAUDE.md "WB integration cribs" + plan Adjustments 7-9 + memory project_phase_n4_state.md: 1. ObjectMeshManager.IncrementRefCount only bumps a counter — does NOT trigger mesh loading. Call PrepareMeshDataAsync explicitly. 2. ObjectRenderBatch.SurfaceId is unset — read batch.Key.SurfaceId. 3. Modern rendering (GL 4.3 + bindless = every modern GPU) packs every mesh into ONE global VAO/VBO/IBO. Use glDrawElementsInstancedBaseVertex(BaseInstance) with FirstIndex + BaseVertex from the batch, not naive DrawElementsInstanced. Plan doc flipped to Final state. Roadmap N.4 → Live ✓; N.5 rebranded from "Terrain rendering" to "Modern rendering path" (bindless + multi-draw indirect on top of N.4's foundation; terrain rendering moves to N.5b). CLAUDE.md "Currently in flight" pointer updated to N.5. New memory file project_phase_n4_state.md preserves the three WB gotchas for cross-session continuity. n4-verify*.log added to .gitignore. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
573526dae5
commit
c44536451d
5 changed files with 178 additions and 58 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# acdream — strategic roadmap
|
||||
|
||||
**Status:** Living document. Updated 2026-05-08 for Phase N.3 shipping + N.4-N.9 strategy revision (rendering rebuild on shared WB infrastructure rather than independent substitutions).
|
||||
**Status:** Living document. Updated 2026-05-08 for Phase N.4 shipping (`WbMeshAdapter` + `WbDrawDispatcher` + `ACDREAM_USE_WB_FOUNDATION` default-on) + N.5 rebranded to "Modern rendering path" (bindless + multi-draw indirect on top of N.4's foundation).
|
||||
**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.
|
||||
|
||||
---
|
||||
|
|
@ -59,6 +59,7 @@
|
|||
| 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 ✓ |
|
||||
| N.1 | WorldBuilder-backed scenery (Chorizite/WorldBuilder fork as submodule, SceneryHelpers + TerrainUtils replace our inline ports) | Live ✓ |
|
||||
| N.3 | WorldBuilder-backed texture decode — `SurfaceDecoder` delegates INDEX16 / P8 / A8R8G8B8 / R8G8B8 / A8(+Additive) to `TextureHelpers.Fill*`; `isAdditive` threaded through (terrain alpha → `FillA8Additive`, non-additive entity surfaces → `FillA8`). R5G6B5 + A4R4G4B4 newly handled (previously magenta). X8R8G8B8, DXT1/3/5, SolidColor remain ours (no WB equivalent). 9 conformance tests prove byte-identical equivalence per format. | Live ✓ |
|
||||
| N.4 | Rendering pipeline foundation — adopted WB's `ObjectMeshManager` as the production mesh pipeline behind `ACDREAM_USE_WB_FOUNDATION` (default-on). `WbMeshAdapter` is the single seam (owns `ObjectMeshManager`, drains the staged-upload queue per frame, populates `AcSurfaceMetadataTable` with per-batch translucency / luminosity / fog metadata). `WbDrawDispatcher` is the production draw path: groups all visible (entity, batch) pairs, single-uploads the matrix buffer, fires one `glDrawElementsInstancedBaseVertexBaseInstance` per group with `BaseInstance` slicing into the shared instance VBO. `LandblockSpawnAdapter` + `EntitySpawnAdapter` bridge spawn lifecycle to WB ref-counts (atlas tier vs per-instance). Perf wins shipped as part of N.4: per-entity frustum cull, opaque front-to-back sort, palette-hash memoization (compute once per entity, reuse across batches). Visual verification at Holtburg passed: scenery + connected characters with full close-detail geometry (Issue #47 regression resolved). Legacy `InstancedMeshRenderer` retained as `ACDREAM_USE_WB_FOUNDATION=0` escape hatch until N.6. | Live ✓ |
|
||||
|
||||
Plus polish that doesn't get its own phase number:
|
||||
- FlyCamera default speed lowered + Shift-to-boost
|
||||
|
|
@ -604,36 +605,54 @@ for our deletions/additions; merge upstream `master` periodically.
|
|||
byte-identical equivalence per format** before substitution; updated
|
||||
`SurfaceDecoderTests` to match the new A8 split semantics. Visual
|
||||
verification at Holtburg passed 2026-05-08 — no texture regressions.
|
||||
- **N.4 — Rendering pipeline foundation.** **Rebranded from "object
|
||||
meshing" 2026-05-08 after brainstorm.** WB's `ObjectMeshManager` is
|
||||
not a static helper — it's a 2070-line stateful asset pipeline that
|
||||
owns GPU resources (VAO/VBO/IBO), an LRU cache + memory budget,
|
||||
background staging, a shared texture atlas, and a bindless rendering
|
||||
path. Adopting it wholesale is the foundation that N.5 + N.6 + N.7
|
||||
build on. Concretely: (1) integrate `ObjectMeshManager` +
|
||||
`TextureAtlasManager` as the shared infrastructure; (2) build a
|
||||
per-instance customization layer that threads `CreaturePalette` /
|
||||
`GfxObjRemapping` / `HiddenParts` / `TextureChanges` / `SubPalettes` /
|
||||
`AnimPartChange` through WB's atlas keys; (3) extend WB's
|
||||
`MeshBatchData` to carry our surface metadata (`Translucency` /
|
||||
`Luminosity` / `Diffuse` / `SurfOpacity` / `NeedsUvRepeat` /
|
||||
`DisableFog`) — likely a fork patch on the `acdream` branch; (4)
|
||||
decide animation cache strategy (per-frame transform via uniform/SSBO
|
||||
vs. cache invalidation); (5) adapter from our streaming loader's
|
||||
Setup/Static spawn events to WB's `IncrementRefCount` lifecycle.
|
||||
**Estimate: 3-4 weeks.** No visible change yet — visual verification =
|
||||
"world looks identical to before." Foundation enables the next phases.
|
||||
- **N.5 — Terrain rendering.** Wire WB's `TerrainRenderManager` +
|
||||
`LandSurfaceManager` + `TerrainGeometryGenerator` onto the foundation
|
||||
N.4 builds. Closes N.2's deferred terrain math substitution: visual
|
||||
mesh and physics both switch to WB's `CalculateSplitDirection` +
|
||||
`GetHeight` + `GetNormal` in lockstep, resolving ISSUE #51. **Estimate:
|
||||
2-3 weeks** (was 3-4 — atlas + GPU pipeline already in place from N.4).
|
||||
- **✓ SHIPPED — N.4 — Rendering pipeline foundation.** Shipped 2026-05-08.
|
||||
WB's `ObjectMeshManager` is integrated as the production mesh pipeline
|
||||
behind `ACDREAM_USE_WB_FOUNDATION=1` (default-on). The integration is
|
||||
three pieces: `WbMeshAdapter` (single seam owning the WB pipeline,
|
||||
drains the staged-upload queue per frame, populates
|
||||
`AcSurfaceMetadataTable` for translucency / luminosity / fog),
|
||||
`WbDrawDispatcher` (production draw path — groups all visible
|
||||
(entity, batch) pairs, uploads matrices in a single `glBufferData`,
|
||||
fires one `glDrawElementsInstancedBaseVertexBaseInstance` per group
|
||||
with `BaseInstance` slicing the shared instance VBO), and the
|
||||
`LandblockSpawnAdapter` + `EntitySpawnAdapter` bridge that wires our
|
||||
streaming loader to WB's `IncrementRefCount` / `PrepareMeshDataAsync`
|
||||
lifecycle (atlas tier vs per-instance customized).
|
||||
Issue #47 (close-detail mesh) preserved; sky pass structurally
|
||||
independent of the WB foundation. Perf wins shipped as part of N.4:
|
||||
per-entity AABB frustum cull, opaque front-to-back sort, palette-hash
|
||||
memoization. Legacy `InstancedMeshRenderer` retained as flag-off
|
||||
fallback until N.6 fully retires it. Plan archived at
|
||||
`docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md`.
|
||||
- **N.5 — Modern rendering path.** **Rebranded from "Terrain rendering"
|
||||
2026-05-08 after N.4 perf review.** N.4 left two big remaining wins
|
||||
on the table that pair naturally: (1) bindless textures via
|
||||
`GL_ARB_bindless_texture` (WB already populates
|
||||
`ObjectRenderBatch.BindlessTextureHandle`; switch our shader to
|
||||
consume per-instance handles, eliminate 100% of `glBindTexture`
|
||||
calls), and (2) `glMultiDrawElementsIndirect` (one GL call per pass
|
||||
instead of one per group; build a `DrawElementsIndirectCommand`
|
||||
buffer, fire one indirect draw, the driver pulls everything). Both
|
||||
require shader changes (same shader, in fact — bindless + indirect
|
||||
are the same modern path WB uses internally). Together they target a
|
||||
2-5× CPU win on draw-heavy scenes (Holtburg courtyard, Foundry,
|
||||
dense dungeons). Also folds in: persistent-mapped instance VBO
|
||||
(`glBufferStorage` + `MAP_PERSISTENT_BIT | MAP_COHERENT_BIT` + ring
|
||||
buffer + sync) and texture pre-warm at landblock load (smooths
|
||||
streaming-boundary hitches). **Estimate: 2-3 weeks.**
|
||||
- **N.5b — Terrain rendering on N.5 path.** Wire WB's
|
||||
`TerrainRenderManager` + `LandSurfaceManager` + `TerrainGeometryGenerator`
|
||||
onto the modern rendering path. Closes N.2's deferred terrain math
|
||||
substitution: visual mesh and physics both switch to WB's
|
||||
`CalculateSplitDirection` + `GetHeight` + `GetNormal` in lockstep,
|
||||
resolving ISSUE #51. **Estimate: 1-2 weeks** (was 2-3 — modern path
|
||||
primitives already in place from N.5).
|
||||
- **N.6 — Static objects rendering.** Wire WB's
|
||||
`StaticObjectRenderManager` onto N.4's foundation; replace our
|
||||
`StaticMeshRenderer` + `InstancedMeshRenderer`. Mostly draw
|
||||
orchestration at this point — most of the substance landed in N.4.
|
||||
**Estimate: 1-2 weeks** (was 2-3).
|
||||
`StaticObjectRenderManager` onto the modern rendering path; **fully
|
||||
delete** legacy `StaticMeshRenderer` + `InstancedMeshRenderer` (they
|
||||
remain as `ACDREAM_USE_WB_FOUNDATION=0` escape hatches through N.5).
|
||||
Mostly draw orchestration at this point — most of the substance
|
||||
landed in N.4 + N.5. **Estimate: 1-2 weeks** (was 2-3).
|
||||
- **N.7 — EnvCells / dungeons.** Replace EnvCell rendering with WB's
|
||||
`EnvCellRenderManager` + `PortalRenderManager` on top of N.4's
|
||||
foundation. **Estimate: 1-2 weeks** (was 2-3 — naturally smaller now
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue