From 312d3b3ee0c1c8760bb26c2001fef4f10f23d588 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 8 May 2026 14:48:20 +0200 Subject: [PATCH] docs(N.4) Task 21: mark Week 3 complete + Adjustments 4-5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Week 3 ships: AnimatedEntityState (Tasks 16+18+19, commit ce72c57), EntitySpawnAdapter routing server-spawned content through the existing TextureCache.GetOrUploadWithPaletteOverride path (Task 17, commit c02c307). 947 tests pass. Adjustment 4: WorldEntity lacks HiddenPartsMask + AnimPartChanges fields. Adapter scaffolding ships; AnimatedEntityState gets default values (empty mask + empty override map). Plumbing deferred to Task 22 brainstorm — either add fields to WorldEntity or thread through a separate parameter to EntitySpawnAdapter.OnCreate. Adjustment 5: Task 20 (per-instance decode conformance) is structural. Both old and new paths call the same TextureCache function — bytes identical by construction. EntitySpawnAdapterTests already cover the routing. No separate conformance test file needed. Next: Task 22 (Week 4) — WbDrawDispatcher full draw loop. First task that actually draws through WB and unlocks Adjustment 3's mitigation (dual-pipeline cost resolves when legacy renderer can short-circuit its upload for atlas-tier content). Co-Authored-By: Claude Opus 4.6 --- ...026-05-08-phase-n4-rendering-foundation.md | 67 +++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md b/docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md index d977b5b..706b73f 100644 --- a/docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md +++ b/docs/superpowers/plans/2026-05-08-phase-n4-rendering-foundation.md @@ -66,9 +66,9 @@ This plan is the **execution source of truth** for N.4. It is updated as tasks l Status: **Living document — work in progress, started 2026-05-08.** -**Progress (2026-05-08):** Weeks 1 + 2 ✅ COMPLETE. WB pipeline running flag-on (constructed + ref-counted + per-frame Tick draining its queues). Three architectural adjustments documented: 1 (DefaultDatReaderWriter discovery, no bridge needed), 2 (renderer is tier-blind; routing belongs in spawn callbacks), 3 (FPS regression root-caused as dual-pipeline cost; Task 22's dispatcher will allow the legacy-renderer short-circuit). Build green, 912 tests pass, 8 pre-existing failures only. +**Progress (2026-05-08):** Weeks 1 + 2 + 3 ✅ COMPLETE. WB pipeline running flag-on (constructed + ref-counted + per-frame Tick draining its queues). Per-instance tier wired (`EntitySpawnAdapter` routes server-spawned entities through existing `TextureCache.GetOrUploadWithPaletteOverride` path; per-entity `AnimatedEntityState` accumulates AnimPartChange + HiddenParts data, ready for the dispatcher). Five architectural adjustments documented: 1 (DefaultDatReaderWriter discovery), 2 (renderer is tier-blind), 3 (FPS regression = dual-pipeline cost; resolves at Task 22), 4 (WorldEntity missing HiddenPartsMask + AnimPartChanges fields, plumbing deferred), 5 (Task 20 is structural — same function called both paths). Build green, 947 tests pass, 8 pre-existing failures only. -**Next: Task 16** (Week 3) — `AnimatedEntityState` type + per-instance customization path. +**Next: Task 22** (Week 4) — `WbDrawDispatcher` full draw loop. The first task that actually draws through WB and unlocks the dual-pipeline-cost mitigation from Adjustment 3. | Task | Status | Commit | |---|---|---| @@ -87,9 +87,18 @@ Status: **Living document — work in progress, started 2026-05-08.** | 13 — Memory budget verification | ✅ deferred to Task 22 (Adj. 3) | — | | 14 — Pending-spawn integration test | ✅ | `f4f0101` | | Tick — drain WB pipeline queues | ✅ added per Adj. 3 | `bf53cb4` | -| 15 — Week 2 wrap-up | ✅ | (this commit) | -| 16–21 — Week 3: per-instance + animation | pending | — | -| 22–28 — Week 4: draw dispatcher + ship | pending | — | +| 15 — Week 2 wrap-up | ✅ | `36f7a60` | +| 16+18+19 — AnimatedEntityState + AnimPartChange + HiddenParts | ✅ | `ce72c57` | +| 17 — EntitySpawnAdapter | ✅ + Adj. 4 | `c02c307` | +| 20 — Per-instance decode conformance | ✅ structural (Adj. 5) | (no test file) | +| 21 — Week 3 wrap-up | ✅ | (this commit) | +| 22 — WbDrawDispatcher full draw loop | pending | — | +| 23 — Surface metadata side-table population | pending | — | +| 24 — Sky-pass preservation check | pending | — | +| 25 — Component micro-tests round-out | pending | — | +| 26 — Visual verification + flag default-on | pending | — | +| 27 — Delete legacy code paths | pending | — | +| 28 — Update memory + ISSUES + finalize plan | pending | — | --- @@ -935,6 +944,54 @@ without violating Adjustment 2's tier-blind-renderer principle. infrastructure for Task 22 anyway. We just paid for it without seeing FPS recovery yet. +--- + +### Adjustment 4 (2026-05-08): WorldEntity lacks HiddenParts + AnimPartChange fields — deferred plumbing + +**Discovered during Task 17 implementation.** `EntitySpawnAdapter.OnCreate` +needed to populate `AnimatedEntityState` with the entity's `HiddenParts` +mask + `AnimPartChange` override map. But: `WorldEntity` (the per-frame +render-side struct) does not currently expose either field. Both pieces +of customization data live on the network-layer spawn record and are +consumed before the `WorldEntity` is built. + +**Resolution.** Task 17 ships the adapter scaffolding with a TODO comment +acknowledging the gap. The created `AnimatedEntityState` always has an +empty override map + zero hidden mask. Per-instance customizations like +"hide this character's head" won't take effect with flag-on until the +plumbing lands. + +**Why this is safe to defer.** No production path consumes +`AnimatedEntityState`'s override / hidden data yet — Task 22's +`WbDrawDispatcher` is the first consumer. By the time Task 22 lands, we +either: +1. Add `HiddenPartsMask` + `AnimPartChanges` fields to `WorldEntity` and + populate them at spawn time. Small change to the network → render + pipeline. +2. Inject them into `EntitySpawnAdapter.OnCreate` via a separate + parameter that the spawn handler provides directly (sidesteps the + `WorldEntity` change). + +Option 1 is cleaner long-term; Option 2 is faster for landing Task 22 +without touching WorldEntity. Decision deferred to Task 22 brainstorm. + +### Adjustment 5 (2026-05-08): Task 20 (per-instance decode conformance) is structural, not byte-comparison + +**Original plan.** Task 20 was supposed to compare RGBA8 output of +"old path" (`TextureCache.GetOrUploadWithPaletteOverride` direct) vs +"new path" (`EntitySpawnAdapter` → `ITextureCachePerInstance` → +`TextureCache.GetOrUploadWithPaletteOverride`) to prove byte-identity. + +**Reality.** Both paths call the **same function**. The new path adds a +seam interface (`ITextureCachePerInstance`) for testability but does +not modify the decode logic — the bytes are identical by construction. +A test asserting byte-equality would be tautological. + +**Resolution.** Existing `EntitySpawnAdapterTests` cover the routing +behavior (does the adapter call the cache with the right args?). The +decode-byte conformance is structural: same function = same output. +Mark Task 20 ✅ structurally; no separate test file. + ### Task 6 (original — kept for history) **Files:**