ship(post-A.5 #53): Tier 1 entity-classification cache — closes ISSUE #53

EntityClassificationCache keyed by (entityId, landblockHint) tuple lands
per spec docs/superpowers/specs/2026-05-10-issue-53-tier1-cache-design.md
+ plan docs/superpowers/plans/2026-05-10-issue-53-tier1-cache.md.

Perf result (horizon-safe preset + High quality, AMD Radeon RX 9070 XT
@ 1440p): entity dispatcher cpu_us median ~1200 us, p95 ~1500 us. 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). No BUDGET_OVER
flag across 30s+ standstill captures.

Visual gate cleared after 4 bug-fix iterations:
  - 71d0edc: namespace stab Ids globally (cross-LB id collision)
  - 95ebbf3: key cache by (entityId, landblockHint) tuple (defensive)
  - c55acdc: skip cache populate when classification is incomplete
  - f928e66: incomplete-entity flag must persist across same-entity tuples

User-confirmed visually via +Acdream test character: NPCs animate,
multi-part static buildings render fully (no airborne geometry, no
Z-fighting, no missing parts, no wrong textures), Nullified Statue of
a Drudge on top of the Foundry renders all parts, trees outside
Holtburg render with branches present.

Closes the post-A.5 polish phase. Issues #52, #54, #53 all closed.

Tests: 1711 passing, 8 pre-existing physics/input failures unchanged.
N.5b sentinel: 112/112 throughout.

Memory: ~/.claude/projects/.../memory/project_tier1_cache.md +
feedback_cache_per_tuple_pattern.md capture the audit-gap and per-tuple-
vs-per-entity recurring trap for future cache work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-11 00:09:57 +02:00
parent f928e66119
commit 110fb691a8
2 changed files with 77 additions and 34 deletions

View file

@ -525,14 +525,32 @@ 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: Post-A.5 polish — Tier 1 retry (only remaining priority).**
Open issues: #53 (Tier 1 entity cache redo with animation-mutation audit).
ISSUES #52 (lifestone missing) and #54 (JobKind plumbing) closed 2026-05-10. #52 by
commit `e40159f` — three real bugs in the WB rendering migration's translucent pass
(alpha-test discard, missing cull state, missing `uDrawIDOffset` uniform). #54 by
commit `bf31e59``LandblockStreamJobKind` plumbed through `BuildLandblockForStreaming`,
far-tier worker now does heightmap-only load (no `LandBlockInfo`, no `SceneryGenerator`).
After #53 closes, the next planned phase is N.6 (perf polish) — see roadmap for scope.
**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.
**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.
**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 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