From b19f1d10ec234ceb420074ea59f34c67b48691f2 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 10 May 2026 15:51:46 +0200 Subject: [PATCH] docs(post-A.5 #52): close lifestone issue + update CLAUDE.md flight status Move ISSUE #52 from Active to Recently closed with full root-cause writeup referencing commit `e40159f`. Strip lifestone reference from CLAUDE.md "Currently in flight"; remaining post-A.5 polish scope is #53 (Tier 1 retry) + #54 (JobKind plumbing). Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 11 +++++++---- docs/ISSUES.md | 44 ++++++++++++++++++++------------------------ 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b4f0aba..dd52848 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -525,10 +525,13 @@ 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 + lifestone fix + JobKind plumbing.** -Open issues: #52 (lifestone missing), #53 (Tier 1 entity cache redo with animation-mutation -audit), #54 (JobKind plumbing through BuildLandblockForStreaming for proper far-tier skip). -After those three close, the next planned phase is N.6 (perf polish) — see roadmap for scope. +**Currently in flight: Post-A.5 polish — Tier 1 retry + JobKind plumbing.** +Open issues: #53 (Tier 1 entity cache redo with animation-mutation audit), #54 (JobKind +plumbing through BuildLandblockForStreaming for proper far-tier skip). +ISSUE #52 (lifestone missing) closed 2026-05-10 by commit `e40159f` — three real bugs +in the WB rendering migration's translucent pass (alpha-test discard, missing cull state, +missing `uDrawIDOffset` uniform). After #53/#54 close, the next planned phase is N.6 +(perf polish) — see roadmap for scope. **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 diff --git a/docs/ISSUES.md b/docs/ISSUES.md index 7d8586f..5f1390d 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -90,30 +90,6 @@ Copy this block when adding a new issue: --- -## #52 — A.5/lifestone-missing: Holtburg lifestone not rendering - -**Status:** OPEN -**Severity:** MEDIUM (visible missing landmark; lifestone is the player's respawn anchor and should always be visible) -**Filed:** 2026-05-10 -**Component:** streaming / rendering - -**Description:** The Holtburg lifestone (spinning blue crystal) has not rendered since earlier in A.5 development. Reproduce: launch live client, walk to Holtburg town center, look toward the lifestone position. Should see the spinning blue crystal; instead see nothing. - -**Root cause (suspected, two candidates):** - -1. Bug A's far-tier strip (commit `9217fd9`) may be incorrectly stripping a near-tier entity. The lifestone's server GUID is `0x5000000A`; its dat object may be registering via the `LandBlockInfo` path but getting stripped as if it were a far-tier entity due to a tier-classification race or incorrect LB-tier tracking. -2. Separate regression from earlier in the A.5 development chain — possibly introduced when entity registration was restructured during T13/T16 streaming controller wiring. - -**Investigation approach:** - -1. Add a `[STREAMING-DIAG]` log line when far-tier stripping drops an entity — log the entity's GfxObj ID and LB address so the lifestone's GfxObj ID appears in the log if it is being stripped. -2. If not in the strip log, check whether the lifestone's LB is registering as near-tier at all during first-tick bootstrap. -3. Bisect to find the commit that broke it if the above two checks don't isolate the cause. - -**Acceptance:** Launch live, walk to Holtburg center, spinning blue crystal visible at the lifestone position. No regression on other static entities in the area. - ---- - ## #50 — Road-edge tree at 0xA9B1 visible in acdream but not retail **Status:** OPEN @@ -1745,6 +1721,26 @@ Unverified. The likely culprits, ranked by suspected probability: # Recently closed +## #52 — [DONE 2026-05-10 · e40159f] A.5/lifestone-missing: Holtburg lifestone not rendering + +**Closed:** 2026-05-10 +**Commits:** `e40159f` (alpha-test discard removal + cull state restoration + uDrawIDOffset uniform) +**Component:** rendering / WbDrawDispatcher / shaders + +**Resolution.** Three independent root causes regressed with the WB rendering migration (Phase N.5 retirement amendment, commit `dcae2b6`, 2026-05-08). The original ISSUE #52 hypothesis (Bug A far-tier strip catching the lifestone) was wrong — the lifestone is server-spawned (WCID 509, Setup `0x020002EE`) and never goes through the far-tier strip. Real causes: + +1. **Alpha-test discard.** `mesh_modern.frag` transparent pass discarded fragments with `α >= 0.95`. The lifestone crystal core surface `0x080011DE` decoded with α≥0.95 across its visible surface, so 100% of the crystal's fragments were discarded — invisible. The original N.5 §2 rationale ("high-α belongs in opaque pass") doesn't hold for surfaces dat-flagged transparent: those pixels can't reach the opaque pass at all. Fix: remove the high-α discard from the transparent pass; keep `α < 0.05` as a fragment-cost optimization. + +2. **Cull state regression.** Legacy `StaticMeshRenderer` had Phase 9.2's `Enable(CullFace) + Back + CCW` setup at the top of its translucent pass (commit `6f1971a`, 2026-04-11) — fix for "lifestone crystal one face missing" reported at the time. When `dcae2b6` deleted the legacy renderer, the new `WbDrawDispatcher` never inherited that GL state, so closed-shell translucents composited back-faces over front-faces in iteration order under `DepthMask(false)`. Fix: re-establish Phase 9.2's exact setup at the top of Phase 8. + +3. **`uDrawIDOffset` indexing bug.** `gl_DrawIDARB` resets to 0 at the start of each `glMultiDrawElementsIndirect` call. The transparent pass starts at byte offset `_opaqueDrawCount * stride` in the indirect buffer, but the vertex shader read `Batches[gl_DrawIDARB]` directly — so transparent draws read from `Batches[0..transparentCount)` (the OPAQUE section) instead of `Batches[opaqueCount..end)`. The lifestone crystal's apparent texture flickered to whatever opaque batch sorted to index 0 each frame; with the player character in view, this often appeared as a lifestone wearing the player's body / face textures. Fix: add `uniform int uDrawIDOffset` to `mesh_modern.vert`, change `Batches[gl_DrawIDARB]` to `Batches[uDrawIDOffset + gl_DrawIDARB]`, and set the uniform per-pass in `WbDrawDispatcher` (0 for opaque, `_opaqueDrawCount` for transparent). Mirrors WorldBuilder's `BaseObjectRenderManager.cs:845`. + +**Verification.** User-confirmed visually via `+Acdream` test character at the Holtburg outdoor lifestone (Z=94 platform). Tests 1688/1696 passing (8 pre-existing physics/input failures unchanged). N.5b conformance sentinel 94/94 clean. + +**Lesson.** The WB rendering migration's "lift legacy state into the new dispatcher" was incomplete in two non-obvious ways: (a) GL state setup that lived inside legacy per-pass blocks, and (b) shader uniforms that the legacy per-draw flow didn't need but the multi-draw-indirect flow does. Future WB-migration work should systematically diff the legacy renderer's GL setup + shader I/O against the new dispatcher's. The `uDrawIDOffset` bug was particularly hidden because it only manifested for entities that mixed transparent draws with the visible opaque sort order — single-pass content (pure opaque or pure transparent) was unaffected. + +--- + ## #13 — [DONE 2026-05-10 · d3b58c9..078919c] PlayerDescription trailer past enchantments **Closed:** 2026-05-10