docs(hygiene): reconcile CLAUDE.md + roadmap; triage 16 → 12 open issues

CLAUDE.md:
- "Currently in flight" (was NONE) → C.1.5b with pickup-doc link
- Added C.1.5a + N.6 slice 1 + post-A.5 polish ship paragraphs
- "Next planned phase" (was N.6) → ranked candidate list
- Collapsed Tier 1 + 4 historical phase paragraphs into
  roadmap-table pointer (signal density +; line count ~net zero)
- Fixed broken project_ui_architecture.md Memory-crib reference

Roadmap header: dated 2026-05-10 → 2026-05-11 with "since the last
update" delta. New Phase C.1.5 sliced sub-piece in Phases ahead.

ISSUES.md triage:
- Closed #37 (humanoid coat — resolved by #47 GfxObjDegradeResolver),
  #49 + #50 (scenery placement — accepted WB-vs-retail divergence).
- Promoted #36 (sky-PES dispatch) to Phase C.1.5c; #2/#28/#29
  auto-close when that phase ships.
- Downgraded #39 (Run↔Walk cycle) to LOW + VERIFY-PENDING.
- Cross-referenced #41 + #46 to Phase L.2 motion conformance.
- Anti-coupling note on #4 (NOT in C.1.5c cluster).
- Chore tag on #3 (single-commit clock-drift fix).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-11 23:34:01 +02:00
parent ad261539d6
commit 55dc861724
3 changed files with 159 additions and 72 deletions

128
CLAUDE.md
View file

@ -147,9 +147,10 @@ time using dat assets); ImGui persists forever as the
`ACDREAM_DEVTOOLS=1` overlay. **All plugin-facing UI targets
`AcDream.UI.Abstractions` — never import a backend namespace from a
panel.** Full design: `docs/plans/2026-04-24-ui-framework.md`.
Memory cribs: `memory/project_ui_architecture.md` (architecture),
`memory/project_chat_pipeline.md` (chat pipeline as of Phase I),
`memory/project_input_pipeline.md` (input pipeline as of Phase K).
Memory cribs: `memory/project_chat_pipeline.md` (chat pipeline as of
Phase I), `memory/project_input_pipeline.md` (input pipeline as of
Phase K). UI architecture full design at
[`docs/plans/2026-04-24-ui-framework.md`](docs/plans/2026-04-24-ui-framework.md).
**Input pipeline:** `src/AcDream.UI.Abstractions/Input/` (action enum,
`KeyChord`, `KeyBindings`, multicast `InputDispatcher` with scope
@ -525,68 +526,75 @@ acdream's plan lives in two files committed to the repo:
acceptance criteria. Do not drift from the spec without explicit user
approval.
**Currently in flight: NONE — Post-A.5 polish phase COMPLETE 2026-05-11.**
All three post-A.5 issues closed: #52 (lifestone, `e40159f`), #54 (JobKind, `bf31e59`),
#53 (Tier 1 entity cache, `f928e66`). Phase A.5 + post-A.5 polish together comprise
the streaming + rendering perf foundation for the project.
**Currently in flight: Phase C.1.5b — issue #56 (per-part transforms for
multi-emitter PES) + EnvCell static-object `DefaultScript` walker.**
Pickup at [`docs/plans/2026-05-12-phase-c1.5b-handoff.md`](docs/plans/2026-05-12-phase-c1.5b-handoff.md).
#56 first per the C.1.5a final reviewer — every multi-emitter PES on a
multi-part entity (portals, chimneys, fireplaces) currently collapses
its emitters to entity root because `ParticleHookSink` ignores
`CreateParticleHook.PartIndex`. The mechanism is correct end-to-end;
the part-relative transform application is the gap.
**Tier 1 entity-classification cache (#53) shipped 2026-05-11.** New
`EntityClassificationCache` keyed by `(entityId, landblockHint)` tuple at
`src/AcDream.App/Rendering/Wb/EntityClassificationCache.cs`; the dispatcher's static-
entity slow path populates flat `CachedBatch[]` (one entry per (partIdx, batchIdx)
with part-relative `RestPose` + resolved `BindlessTextureHandle`), and the cache-hit
fast path skips classification entirely on subsequent frames. Animated entities
(`_animatedEntities`) bypass the cache. Invalidation fires on live-entity despawn
(`RemoveLiveEntityByServerGuid`) and LB demote/unload (`RemoveEntitiesFromLandblock`).
Entity dispatcher cpu_us **median ~1200 µs / p95 ~1500 µs** at horizon-safe preset
on AMD Radeon RX 9070 XT @ 1440p — down from ~3500m / ~4000p95 pre-Tier-1
(~66% / ~63% reduction). Well under the A.5 spec budget (median ≤ 2.0 ms, p95 ≤ 2.5 ms).
The implementation required 4 bug-fix iterations after the spec landed (stab Id
namespacing → cache tuple-key → drudge incomplete-classification → mid-list null-
renderData); see `docs/ISSUES.md` #53 closure entry for the lessons.
**Phase C.1.5a (portal PES wiring) shipped 2026-05-11** (merge `88bda12`).
Server-spawned `WorldEntity` entities fire their `Setup.DefaultScript`
through `PhysicsScriptRunner` on enter-world via the new ~70-line
`EntityScriptActivator` ([src/AcDream.App/Rendering/Vfx/EntityScriptActivator.cs](src/AcDream.App/Rendering/Vfx/EntityScriptActivator.cs)).
Visual-verified at the Holtburg Town network portal: 10-hook portal
script fires end-to-end with correct color, persistence, orientation,
multi-emitter dispatch. Known visual gap filed as #56 (per-part
transform handling); resolution is slice A of C.1.5b. Plan archived at
[`docs/superpowers/plans/2026-05-12-phase-c1.5a-portals.md`](docs/superpowers/plans/2026-05-12-phase-c1.5a-portals.md).
**Next planned phase: N.6 (perf polish) — see `docs/plans/2026-04-11-roadmap.md`.**
Alternative escalation path: Tier 2 (static/dynamic split with persistent groups,
~2 weeks) or Tier 3 (GPU compute culling, ~1 month) per
`docs/plans/2026-05-10-perf-tiers-2-3-roadmap.md`. With the Tier 1 dispatcher at
~1.2 ms, the project comfortably hits 200-400 FPS at radius=12 standstill;
escalation makes sense only if user wants 500+ FPS sustained.
**Phase N.6 slice 1 (gpu_us fix + radius=12 perf baseline) shipped
2026-05-11** (merge `9b447d4`). Fixed `gpu_us` double-buffering in
`WbDrawDispatcher` (ring-of-3 query slots, read-before-overwrite,
vendor-neutral). Captured authoritative perf baseline at Holtburg radii
4 / 8 / 12. **Conclusion: CPU dominates GPU by 3050× at every radius**;
GPU sits at 3.6% of frame budget; per-LB walk is the next bottleneck.
Baseline-doc recommendation: do C.1.5 next, then a reduced-scope slice 2
(atlas + persistent-mapped buffers dropped from slice-2 scope). Baseline
at [`docs/plans/2026-05-11-phase-n6-perf-baseline.md`](docs/plans/2026-05-11-phase-n6-perf-baseline.md).
Plan archived at [`docs/superpowers/plans/2026-05-11-phase-n6-slice1.md`](docs/superpowers/plans/2026-05-11-phase-n6-slice1.md).
Issue #55 filed (static-entity slow path reports ~1.45M `meshMissing`
per 5s at r4 standstill — diagnostic, not a visible regression).
**Phase A.5 (Two-tier Streaming + Horizon LOD) shipped 2026-05-10.**
N₁=4 near-tier (81 LBs, full detail) + N₂=12 far-tier (544 LBs, terrain only); fog
horizon; QualityPreset system (Low/Medium/High/Ultra) with env-var overrides; F11
mid-session reapply. Two post-ship-prep bugs fixed: Bug A (far-tier worker was loading
full entity layer — ~71K entities, ~5x perf regression vs spec), Bug B (WalkEntities
per-frame list alloc — ~480 KB/frame GC pressure). Tier 1 entity cache reverted (animation
regression; see #53). Plan archived at
[`docs/superpowers/plans/2026-05-09-phase-a5-two-tier-streaming.md`](docs/superpowers/plans/2026-05-09-phase-a5-two-tier-streaming.md).
**Post-A.5 polish phase complete 2026-05-11.** All three post-A.5
issues closed: #52 (lifestone, `e40159f`), #54 (JobKind, `bf31e59`),
#53 (Tier 1 entity cache, `f928e66`). Phase A.5 + post-A.5 polish
together comprise the streaming + rendering perf foundation for the
project.
**Phase N.5b (Terrain on Modern Rendering Path) shipped 2026-05-09.**
`TerrainModernRenderer` mirrors WB's `TerrainRenderManager` pattern
(single global VBO/EBO + slot allocator + bindless atlas +
`glMultiDrawElementsIndirect`) but consumes `LandblockMesh.Build` so
retail's `FSplitNESW` formula is preserved (Path C; closes ISSUE #51).
Path A (substitute WB's `CalculateSplitDirection`) killed by 49.98%
divergence vs retail in
[`tests/AcDream.Core.Tests/Terrain/SplitFormulaDivergenceTest.cs`](tests/AcDream.Core.Tests/Terrain/SplitFormulaDivergenceTest.cs).
At radius=5 in Holtburg modern is ~4× SLOWER on CPU than the legacy
chunked path was; architectural wins manifest at higher radius. Honest
perf baseline at
[`docs/plans/2026-05-09-phase-n5b-perf-baseline.md`](docs/plans/2026-05-09-phase-n5b-perf-baseline.md).
Plan archived at
[`docs/superpowers/plans/2026-05-09-phase-n5b-terrain-modern.md`](docs/superpowers/plans/2026-05-09-phase-n5b-terrain-modern.md).
**After C.1.5b, candidate next phases (in rough preference order):**
- **Triage the chronic open-issue list** in `docs/ISSUES.md`#2 (lightning),
#4 (sky horizon-glow), #28 (aurora), #29 (cloud thinness), #37 (humanoid
coat), #50 (stray tree), #41 (remote-motion blips) have been open since
April/early-May and keep getting deferred. Either link each to a future
phase or downgrade. ~1 hour, surfaces what's chronic vs. linked-to-a-phase.
- **More Phase C visual-fidelity work** (C.2 dynamic point lights, C.3
palette tuning, C.4 double-sided translucent polys) closing the
"world reads as old / broken vs. retail" backlog.
- **N.6 slice 2** at reduced scope (atlas opportunities only — persistent-
mapped buffers and other slice-2 items dropped per slice-1 baseline doc).
- **Perf tiers 2/3** (`docs/plans/2026-05-10-perf-tiers-2-3-roadmap.md`)
only if user wants sustained 500+ FPS. With Tier 1 dispatcher at ~1.2 ms
the project comfortably hits 200-400 FPS at radius=12 standstill;
escalation is optional from here.
**Phase N.5 (Modern Rendering Path) shipped + amended 2026-05-08.** `WbDrawDispatcher`
on bindless textures + `glMultiDrawElementsIndirect`. CPU dispatcher 1.23ms/frame
at Holtburg (~810 fps). **Ship amendment:** `InstancedMeshRenderer`,
`StaticMeshRenderer`, `WbFoundationFlag` deleted in same phase — modern path is
mandatory; missing bindless throws at startup. Plan archived at
[`docs/superpowers/plans/2026-05-08-phase-n5-modern-rendering.md`](docs/superpowers/plans/2026-05-08-phase-n5-modern-rendering.md).
**Phase N.4 (Rendering Pipeline Foundation) shipped 2026-05-08.** WB's
`ObjectMeshManager` is integrated and is the production rendering path
(mandatory as of N.5 ship amendment). Plan archived at
[`docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md`](docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md).
**Earlier rendering + streaming arc (2026-05-08 → 2026-05-10).**
Phases **N.4 → N.5 → N.5b → A.5** shipped the modern rendering
pipeline + two-tier streaming foundation: WB `ObjectMeshManager` as
production mesh path (N.4); bindless + `glMultiDrawElementsIndirect`
for entities (N.5, ~12-15 GL calls/frame) and terrain via Path C
preserving retail's `FSplitNESW` formula (N.5b, closes #51); two-tier
streaming N₁=4 / N₂=12 + QualityPreset system (A.5). Modern path is
mandatory as of N.5 ship amendment — `InstancedMeshRenderer`,
`StaticMeshRenderer`, `WbFoundationFlag` all deleted; missing bindless
throws at startup. Detail + decomp anchors + plan archives in roadmap
shipped-table rows 6366 at `docs/plans/2026-04-11-roadmap.md`.
Engineering gotchas (bindless Dispose order, texture target lock-in,
`uvec2` sampler-handle pattern, WB-vs-retail formula divergence)
documented inline at the relevant call sites and in
`feedback_wb_migration_*.md` memory entries.
**Rules:**