phase(A.5): SHIP — two-tier streaming + horizon LOD + Quality Preset system

Final state: A.5 delivers a 2.3 km terrain horizon (radius=4 near + 12
far) with off-thread mesh build, fog blend at the N₁ boundary, mipmaps
+ 16x anisotropic on terrain, MSAA 4x + A2C foliage, depth-write audit
+ lock-in test, BUDGET_OVER diag flag, and a full Quality Preset system
(Low/Medium/High/Ultra) with env-var overrides + F11 mid-session
re-apply.

Acceptance:
- N.5b conformance sentinel: 89+ tests passing (TerrainSlot,
  TerrainModernConformance, Wb*, MatrixComposition, TextureCacheBindless,
  SplitFormulaDivergence). All clean.
- Build green; ~999 tests passing across all projects; 8 pre-existing
  physics/input failures unchanged (out of A.5 scope).
- Standstill at horizon-safe preset (radius=4/12, MSAA off, A2C off,
  aniso 4x), Holtburg, AMD Radeon RX 9070 XT @ 1440p:
  entity dispatcher cpu_us median ~3.5ms, p95 ~4ms (~200-240 FPS).
  Terrain dispatcher cpu_us median ~21µs (well under 1ms budget).
- Visual gate (partial): horizon visible at ~2.3km; fog blend smooths
  N₁ boundary cleanly; system stable through walking traverse.
  Lifestone missing — known issue from earlier in development chain,
  deferred to post-A.5 (ISSUE #52).

Two post-T26 perf bug fixes that were structural to A.5's promise:
- (Bug A, 9217fd9) Far-tier worker now strips entities. Without this,
  T13/T16 shipped only the controller side of two-tier; the worker
  loaded full entity layers for far-tier LBs. Result was ~71K entities
  in GpuWorldState instead of ~10K — a 5x perf regression. Patch is
  at the worker-output level; cleaner JobKind plumbing through
  BuildLandblockForStreaming is post-A.5 (ISSUE #54).
- (Bug B, 0ad8c99) WalkEntities switched from per-frame fresh-list
  allocation to a caller-provided scratch list reused across frames.
  Eliminated ~480 KB / frame GC pressure on the render thread.

Tier 1 entity-classification cache attempted as ship-prep polish
(commit 3639a6f) but reverted (9b49009) — caching meshRef.PartTransform
froze the per-frame animation pose. Retry is a post-A.5 phase with
animation-mutation audit + animated-bypass design (ISSUE #53).

Decisions (per spec §4):
- N₁=4 (full detail, 81 LBs), N₂=12 (terrain only, 544 LBs).
- Bucketing Change #1 (animated-walk fix in WalkEntities) +
  Change #2 (cached AABB on WorldEntity) shipped. Change #3
  (sub-LB cell cull) NOT shipped — budget hit without it.
- Single-worker off-thread mesh build (Q6 Option A).
- Hysteresis radius+2 on both tiers (Q7 Option A).
- Mipmaps + 16x anisotropic + A2C with MSAA 4x + depth-write audit
  all shipped (Q8 Option C).
- Acceptance gate: refresh-rate-relative + per-preset (Q9 Option B
  reshape after Quality Preset addition).
- Quality Preset system (T22.5, mid-execution scope add): Low /
  Medium / High / Ultra with per-preset radii + MSAA + anisotropic +
  A2C + completions; 6 env-var overrides; settings.json persistence;
  F11 mid-session re-apply.

Deferred to post-A.5 polish phase:
- Tier 1 retry with animation audit (ISSUE #53)
- Lifestone missing (ISSUE #52)
- JobKind plumbing through BuildLandblockForStreaming (ISSUE #54)
- Tier 2 (static/dynamic group split) — multi-week phase
- Tier 3 (GPU compute culling) — multi-week phase
- Re-test full High preset (crashed at original attempt; should work
  post-Bug-A; not retested)

Spec: docs/superpowers/specs/2026-05-09-phase-a5-two-tier-streaming-design.md
Plan: docs/superpowers/plans/2026-05-09-phase-a5-two-tier-streaming.md
Perf-tier roadmap: docs/plans/2026-05-10-perf-tiers-2-3-roadmap.md
Memory: ~/.claude/projects/.../memory/project_phase_a5_state.md (5 gotchas)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-10 10:08:13 +02:00
parent d93d823539
commit 9245db5b04

Diff content is not available