The Phase W indoor seal did NOT land. The 2026-06-02 visual gate proved the interior render is fundamentally broken (#78: transparent walls, outdoor terrain + scenery entities bleeding in, grey floors, no outside-looking-in). Stage 4 (sky-through-door clip) was real but a top layer on a base that never sealed. DECISIVE EVIDENCE (committed in the handoff): the PVS computes correctly AND the cell shells render correctly (opaque, textured, complete — the [shell] probe shows zero NOSNAP / zero missing-texture). The failure is the SEAL + three inconsistent gates — concretely the WbDrawDispatcher.cs:1756 ParentCellId==null -> return true bypass draws outdoor scenery indoors, and the indoor path draws the outdoor world then gates it instead of running ONLY DrawInside. Retail, when inside, runs ONE PView flood: visibility IS the cull; the landscape enters only through clipped exit portals + a conditional depth-only clear. Dossier (per the user's mandate: NO shortcuts/bandaids, port from retail, redesign the whole pipeline if needed, brainstorm first): - Master handoff (root cause + retail target + reusable-vs-redesign + apparatus + do-not-repeat + copy-paste pickup prompt). - Huge staged redesign plan R0(brainstorm)->R1(one visibility authority, kill the bleed)->R2(indoor=DrawInside-only)->R3(the seal, DrawCells port)->R4(per-cell object/particle clip)->R5(outside-looking-in)->R6(dungeons)->R7(polish/conformance). Each ends at a user visual gate. - 3 research docs: full retail render pipeline reference (705 lines, decomp-verified), acdream pipeline inventory + failure map, reference cross-check (WB two-pipe is the wrong model). #78 promoted to the redesign. The 5 remaining Core test failures are pre-existing physics/collision bugs, none render-related. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
28 KiB
Render Pipeline Redesign — Master Handoff (2026-06-02)
Canonical pickup for the full render-pipeline redesign. Phase W's interior "seal" did not land. The single final visual verification (user, 2026-06-02) proved the indoor render is fundamentally broken (issue #78 — outdoor geometry visible inside EnvCells — plus transparent walls, missing-floor appearance, entity/scenery bleed, and no outside-looking-in). This document consolidates ALL research + the decisive live diagnostic evidence + the retail-faithful target + the mandate.
Read order for the next session: this doc → the 3 research docs (§5–§7 links) → then BRAINSTORM (
superpowers:brainstorming) the architecture before writing any code. The plan in §10 is the spine; the brainstorm refines it with the user.
0. The mandate (user, 2026-06-02 — NON-NEGOTIABLE)
Quoting the user's intent directly:
- FULLY WORKING outdoor, indoor, and dungeon rendering. No flaps, no missing textures, no transparent walls, no ground/terrain texture leaking into the cellar, no bleed-through. Outside, inside, portal transitions, dungeons, particle clipping — EVERYTHING.
- No shortcuts. No bandaids. No quick fixes. "If you have choices of doing something fast when it might not be the best way or the most architecturally correct way, never take that way." If the correct way is slower, take it anyway.
- If you have to refactor and redesign the whole pipeline, DO THAT.
- Port from retail decomp where needed — it is the oracle (
docs/research/named-retail/). - If you need more research mid-session, do it — never guess.
- Start with a brainstorm before implementing.
This supersedes the incremental "wire 3 gaps" framing of the Phase W render plan. The render half of Phase W is reopened as a ground-up, retail-faithful redesign.
1. Current broken state — the visual gate (2026-06-02, Holtburg cottage)
The user walked the cottage and reported five distinct failures:
- Outdoor → looking through an open door/window: interior walls are transparent (you see into/through the house). (= outside-looking-in not implemented; deferred U.5.)
- Just inside: you see only the outdoor world background + NPCs/particles/doors — no interior shell sealing you in.
- Inside → looking out: sky is visible, but you see houses and trees through the ground.
- On the cellar stairs: the cellar walls show, but the floor is grey, and NPCs / particles / doors show through the walls above.
- In the cellar: you see the grey world instead of the floor.
Net: the interior is not a sealed space. This is issue #78 ("outdoor geometry visible inside EnvCells") in full, plus entity/scenery bleed and the missing outside-looking-in path.
2. Decisive live evidence — the root cause is PROVEN (not theorized)
Captured this session via the in-tree probes (ACDREAM_PROBE_CELL / _VIS / _SHELL),
read from the UTF-16 Tee-Object logs. These three facts together pinpoint the cause:
2.1 The visibility math is CORRECT
[cell-transit]shows the player moving cleanly through the cottage cells:0xA9B40031(outdoor) →0170(vestibule) →0171(room) →0175(stairs) →0174(cellar). Membership works (the Stage-1/2 fix59f3a13holds; some doorway flips are the player genuinely crossing the threshold, not a strobe).[vis]shows the right visible set + portal openings, e.g.:root=0xA9B40171 cells=2 ids=[0171,0170] outside(polys=1,planes=4)— from the room, the exit portal to outdoors IS detected (terrain/sky can draw through it).root=0xA9B40174 cells=1 ids=[0174] outside(polys=0,planes=0)— the cellar is correctly sealed (no exit portal in view → terrain Skip).- Per-cell clip-plane counts are populated.
max filter=3cells in any single frame.
⇒ The PVS (PortalVisibilityBuilder) is not the bug. It computes the correct answer.
2.2 The cell shells RENDER CORRECTLY — opaque, textured, complete
The [shell] probe (added for #78) emits, per opaque pass, the actual geometry drawn.
Distinct patterns observed (frequency × line):
205977x filter=1 ... tris=2 [0xA9B40174:gfx=1 tf=1 batch=3 idx=42 tr=0 zh=0] (cellar: 14 tris)
1476x filter=3 ... tris=48 [0xA9B40171:...idx=270 tr=0 zh=0] [0173:idx=24] [0172:idx=144] (room+subcells: 90+8+48 tris)
130x filter=1 ... tris=38 [0xA9B40171:...idx=270 tr=0 zh=0] (room: 90 tris)
125x filter=2 ... [0xA9B40174:idx=42] [0xA9B40175:idx=24] (cellar+stairs)
75x filter=1 ... [0xA9B40175:idx=24] (stairs)
- Zero
NOSNAP(no "geometry not prepared" cases). Zerozh>0(no missing-texture cases). Zerotr(all opaque). Every visible cell draws its full, textured mesh. - Per the probe's own diagnosis tree:
idx>0 + zh=0 + tr=0⇒ "opaque geometry IS drawn, with valid textures — the fault is DEPTH/OCCLUSION, or the geometry isn't the wall."
⇒ The shells are not the bug either. They draw fine. This was NEVER a shader/texture/ missing-mesh problem (which is what naive guesses would chase).
2.3 So the failure is the SEAL + the GATES
Putting 2.1 + 2.2 together with the symptoms: the visible cells draw correctly, but
- only ≤3 cells' shells draw, and they do not form a closed opaque occluder over the rest of the world, so the outdoor scene shows through wherever indoor geometry isn't;
- the outdoor terrain + outdoor scenery entities (the "houses and trees through the
ground" =
ParentCellId == nullstabs/scenery) are not culled or depth-occluded when you're indoors — they draw and win; - outside-looking-in draws no interior at all (no exterior→interior portal path; U.5).
This is the three-inconsistent-gates failure (see §3), the exact problem the project's
own memory (render — one gate (PView)) flags as the core unsolved indoor-render issue —
"the week of 2026-05-25→31 made no indoor-render progress because the pipeline had 3
inconsistent gates (terrain/shell/entity)."
3. Root-cause analysis — three inconsistent gates, no closed-occluder seal
acdream's render loop gates four classes of geometry, from inconsistent sources:
| Geometry | Gate in code | Source of truth | Problem |
|---|---|---|---|
| Terrain | terrainClipMode (Skip/Scissor/Planes) |
ClipFrameAssembler ← PortalVisibilityBuilder OutsideView |
OK-ish, but only one of several gates |
| Cell shells | envCellShellFilter = clipAssembly.CellIdToSlot.Keys |
PortalVisibilityBuilder |
Draws ≤3 cells; never forms a closed occluder |
| Entities (incl. outdoor scenery, doors, NPCs) | visibility?.VisibleCellIds |
CellVisibility.ComputeVisibilityFromRoot — a different traversal |
Disagrees with the shell/terrain gate; outdoor scenery (ParentCellId=null) not culled indoors |
| Particles | (none) | — | Issue #104 — no cell clip at all |
| Sky/weather | drawSkyThisFrame (Stage 4) |
ClipFrameAssembler |
The only consistent one — but a top layer |
Two distinct architecture defects:
-
Two visibility computations, not one.
PortalVisibilityBuilder.Build(the faithful PView BFS) feeds the shell + terrain + sky gates. But the entity gate readsCellVisibility.ComputeVisibilityFromRoot— an older, separate visibility path. They are not guaranteed to agree, and the entity one does not properly cull outdoor scenery when indoors. Retail has ONE traversal (PView) that produces onecell_draw_list, and every cell's objects are drawn (and only those) — there is no second gate. -
No "closed interior occluder" model. Retail's interior render is sealed by construction: it draws the visible cells (whose
drawing_bspare closed boxes — floor, walls, ceiling), drawsLScapeonly through exit-portal clip regions, does a conditional Z-only clear at the doorway, and draws each cell's objects clipped to that cell. The outdoor world is never drawn behind a wall because the traversal simply never visits it and the closed cells occlude it. acdream instead draws the outdoor world (terrain + scenery) and then a few cell shells on top, relying on depth/gates that don't hold — so the world bleeds through.
The fix is not another gate or another clip. It is to make the render obey ONE
visibility answer for ALL geometry, with the interior sealed by drawing closed cells +
clipping LScape through portals — i.e., port retail's PView::DrawCells faithfully.
4. Reusable vs Redesign (from the live evidence; research doc B §5 deepens this)
KEEP (proven correct, build on these):
- Cell membership — the transition-owned
find_cell_listfix (59f3a13).[cell-transit]confirms correct cell tracking. Do not reopen. PortalVisibilityBuilder(the PView BFS) — produces the correct visible set + OutsideView +OrderedVisibleCells, withseen-HashSet termination (#102 closed). This is the single visibility authority the redesign should route EVERYTHING through.- The sky/weather NDC-clip insight (Stage 4,
ce2edad/b595cfb): OutsideView clip planes are screen-space half-spaces → projection-independent, sosky.vertclips the dome exactly. Reusable once the base seals; keep the commits. ClipFrame/ClipPlaneSet/ClipFrameAssembler/PortalView— the clip-plane machinery + the per-cell NDC regions. Reusable.- Cell shell rendering (
EnvCellRenderer) — draws correct opaque textured geometry. Keep; the bug is what gets drawn around it, not the shells. - The diagnostic apparatus —
ACDREAM_PROBE_CELL/VIS/SHELL+ the[shell]diagnosis tree. Indispensable; see §8.
REDESIGN (the broken parts):
- The gating. Collapse the two visibility computations into ONE (
PortalVisibilityBuilder's visible set), and route terrain + shells + entities + particles through it. Delete theCellVisibility.ComputeVisibilityFromRootentity path (or make it the same answer). - The interior seal — adopt retail's closed-cell + LScape-through-portal + Z-clear model so the outdoor world is never drawn behind a wall (occlusion by construction, not by gate).
- Outdoor-scenery gating —
ParentCellId=nullentities (houses, trees, stabs) must be culled / occluded when indoors and not visible through a portal. - Particle cell-clip (#104) — particles need a cell and must clip to the visible set.
- Outside-looking-in (U.5) — the exterior→interior portal path (look into a building from outside and see its sealed interior, not transparent walls).
- Dungeons (#95) — validate BFS convergence + the no-landscape path on a real dungeon.
5. The retail-faithful target architecture
→ Full reference: docs/research/2026-06-02-retail-render-pipeline-full-reference.md (research doc A —
verified against the named-retail pseudo-C + acclient.h this session).
5.1 The ten load-bearing retail facts (THE architecture to port)
- One cell graph, one membership answer, render obeys it. Physics tracks
curr_cellthrough the sweep; the camera tracksviewer_cell; both resolve via the sameCObjCell::GetVisible. - The top-level decision is BINARY (
RenderNormalMode @ 0x453aa0): viewer in an outdoor landcell →LScape::draw(full landscape). Viewer in an EnvCell →DrawInsideonly. It is NOT "draw outdoors then draw cells on top." When inside, the full outdoor scene is never drawn. ← This single fact is the inversion of acdream's bug. DrawInside= one PView portal flood (ConstructView → DrawCells) producing thecell_draw_list+ per-cell clip regions + oneoutside_view.- Exit portals (
other_cell_id == 0xffffffff) pull the landscape INTO the indoor traversal —ClipPortals(pc:433662) copies the doorway clip region intooutside_view. The outdoors is seen only through that clipped region. - The seal sequence in
DrawCells(whenoutside_view.view_count > 0):LScape::drawclipped to the doorway → conditional Z-ONLYClear(4,…)(NOT color) → exit-portal stencil →DrawEnvCell(closed geometry) → per-cell objects. - No blue clear-color hole by construction — the only clear is depth-only + conditional; the doorway shows real terrain because LScape drew there first.
- Ceilings/walls sealed by dat geometry —
drawing_bspis a closed box; portal holes are stencil-masked, never filled; there is no "cap the ceiling" step. - VISIBILITY IS THE CULL. Only
cell_draw_listcells render, and only theirobject_listobjects (drawn withPortalListset). There is no second "draw all entities then gate them" pass. → no wall/object/particle bleed, by construction. - Outside-looking-in is the mirror image —
DrawPortal @ 0x5a5ab0runsConstructView(CBldPortal)+DrawCellsto render the interior through the door's clip, the same machinery. - Dungeons are emergent — all-EnvCell,
seen_outside == 0, no exit portals →outside_viewstays 0 →LScape::drawis never called → no terrain/sky, automatically.
Plus: BFS convergence is watermark-bounded by per-cell portal_view_type.update_count
(the retail replacement for a fixed reprocess cap — fixes #102 and the dungeon PVS blowup
#95); find_visible_child_cell @ 0x52dc50 resolves child cells via the portal/stab graph +
BSP point_in_cell (never AABB); each cell carries three BSPs (drawing_bsp render /
physics_bsp collision / cell_bsp containment).
5.2 The porting checklist (doc A §7 — the spine of the plan)
- CL-A Membership foundation (physics owns the cell): swept-cell return, exit-portal
crossing, interior-wins + prune, commit-on-difference. (Largely DONE —
59f3a13.) - CL-B Render-root unification: single decision, root at physics
CurrCell, child-cell via graph, landscape keep/release onseen_outside,grab_visible_cells, pre-position terrain. - CL-C PView traversal: BFS, InitCell, ClipPortals (both branches), AddViewToPortals/AddToCell,
update_countwatermark, GetClip. (PortalVisibilityBuilderalready covers much of this.) - CL-D Seal mechanics in DrawCells: LScape-through-door FIRST, conditional Z-only clear, exit-portal stencil, closed-geometry draw, per-cell clipped objects, self-contained GL state.
- CL-E Outside-looking-in: DrawPortal, ConstructView(CBldPortal) recursion, separate outdoor pview.
- CL-F Entity/particle cell clipping: graph placement, draw only visible cells, portal-clip straddlers.
- CL-G Conformance/acceptance: cottage sealed + sky-through-door, dungeon sealed + no terrain, outside-looking-in, headless asserts.
The redesign verdict: acdream must stop drawing the outdoor world and then gating it.
When the viewer is in an EnvCell, it must run one DrawInside flood that draws only the
visible cells + their objects, pulling LScape in only through clipped exit portals. The cull
is the visibility. Everything in §3 ("three inconsistent gates") collapses into this.
6. Reference cross-check
→ Full cross-check: docs/research/2026-06-02-render-reference-crosscheck.md (research doc C).
WorldBuilder is the wrong model and must NOT be re-adopted for the seal (10-point verdict):
WB has a hard isInside branch switching two completely different render paths (retail has
one); WB's "seal" is a per-building GPU stencil from portal-polygon rasters (flat,
building-granularity) whereas retail's is a CPU-derived OutsideView clip polygon from the
recursive per-portal BFS; WB's flap is inherent — the isInside branch flips at the
doorway and the two stencil setups tear on that frame; WB clips one stencil per building
(per-portal precision is impossible); WB works for a static dat-viewer but is
architecturally wrong for a live client that crosses thresholds; grafting onto WB's
two-pipe is not recoverable — the retail PView port is the correct fix.
- ADOPT: retail PView BFS (already in acdream as
PortalVisibilityBuilder), theSeenOutsideterrain gate, theOtherCellId==0xFFFFexit-portal sentinel, the WB mesh pipeline (keep — it's just GL plumbing),EnvCellRenderer.PrepareRenderBatches(filter), entity outdoor-slot routing viaWbDrawDispatcher.ResolveEntitySlot. - AVOID (do not reintroduce): WB
RenderInsideOut/RenderOutsideInstencil two-pipe,BuildingPortalGPU/RenderBuildingStencilMask, anyisInside/cameraInsideBuildinggate, ACViewer brute-force all-cells draw, any AABB grace-frame fallback for the visibility root.
7. Current pipeline inventory + failure map
→ Full inventory: docs/research/2026-06-02-acdream-render-pipeline-inventory-and-failures.md (research doc B).
7.1 The concrete bugs (file:line — these are the mechanisms behind §1's symptoms)
- 🔴 THE outdoor-scenery bleed ("houses/trees through the ground"):
WbDrawDispatcher.EntityPassesVisibleCellGatehits an unconditionalreturn trueatWbDrawDispatcher.cs:1756for entities withParentCellId == null(outdoor scenery: houses, trees, landblock stabs). TheIsShellScopedSetanchor-cull branch that should gate them is dead code (always false since U.1 deleted shell sets). ⇒ outdoor stabs always draw, even inside a sealed cellar. This is the #1 visible bleed. - 🔴 Two visibility computations: the entity gate is fed by
CellVisibility.VisibleCellIds(a parallel, separate BFS), while shells + terrain are fed byPortalVisibilityBuilder. They are not the same answer. Retail has ONE (§5.1 fact 8). - 🟠 Terrain
Skipover-aggression:TerrainClipMode.Skipfires whenever the exit portal is not in the current view — correct for a true dungeon, but it removes the terrain floor for aseen_outside=truecottage when the player faces away from the door. (In the retail model this is moot: terrain is only ever drawn through an exit-portal clip, never as a floor under the interior.) - 🟠 Particles: no cell gate at all (#104).
- 🟠
CullMode.Landblock → Nonedouble-sided stopgap (EnvCellRenderer.cs:~1210) — cells draw double-sided to dodge a winding issue; a redesign should resolve the actual winding. - 🟠 Outside-looking-in (U.5): no outdoor-root shell pass → transparent walls through a door.
7.2 The gate table (the inconsistency, from B)
| Geometry | Gate | Fed by | Verdict |
|---|---|---|---|
| Terrain | TerrainClipMode |
PortalVisibilityBuilder |
over-aggressive Skip; wrong model (floor vs portal-clip) |
| Cell shells | envCellShellFilter |
PortalVisibilityBuilder |
correct geometry, but never a closed occluder |
| Entities | CellVisibility.VisibleCellIds |
parallel BFS | wrong source + null-ParentCell bypass = bleed |
| Particles | (none) | — | #104 |
| Sky/weather | drawSkyThisFrame |
PortalVisibilityBuilder |
the only consistent one (Stage 4) |
7.3 KEEP (from B): PortalVisibilityBuilder, ClipFrame/ClipFrameAssembler/ClipPlaneSet,
Stage-4 sky/weather clip + doorway Z-clear, EnvCellRenderer geometry/MDI path,
TerrainModernRenderer, ResolveEntitySlot (correct for indoor statics), all probes.
7.4 REDESIGN/FIX (from B): (a) delete the ParentCellId==null → return true bypass + gate
outdoor stabs; (b) feed entity dispatch from pvFrame.OrderedVisibleCells, not the parallel
CellVisibility BFS; (c) fix terrain Skip/model; (d) particle cell-gate (#104); (e) resolve
the double-sided stopgap; (f) implement U.5 outside-looking-in.
8. Diagnostic apparatus (use it — evidence-first, always)
- Launch (per CLAUDE.md "Running the client"): set
ACDREAM_LIVE=1, host/port/user/pass,ACDREAM_DAT_DIR, thendotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug 2>&1 | Tee-Object -FilePath launch.log, in the background. The character+Acdreamspawns at the Holtburg cottage (0xA9B40031, outdoor); walk in to reach0170→0171→0175→0174. - Probes (env vars; the log is UTF-16 — read with PowerShell
Select-Stringor the ripgrep Grep tool, NOT GNU grep):ACDREAM_PROBE_CELL=1→[cell-transit](membership; low volume, decisive).ACDREAM_PROBE_VIS=1→[vis](the PVS frame: root cell, visible cells, OutsideView poly/plane counts, per-cell plane counts).ACDREAM_PROBE_SHELL=1→[shell](per opaque pass:filter,drawCalls,inst,tris, and per-cellgfx tf batch idx tr zh). Diagnosis tree:NOSNAP/gfx=0⇒ no geometry prepared;idx>0 + zh>0⇒ prepared but missing texture (invisible);idx>0 + zh=0 + tr=0⇒ opaque drawn, fault is depth/occlusion or wrong geometry. ⚠ Unthrottled — fires every frame (183K lines in a short walk). Filter in PowerShell.
- Screenshots: Windows blocks foreground-steal from a background process; capturing the
AcDream window reliably needs the user to foreground it (or a
PrintWindowapproach that is unreliable for GL surfaces). Prefer the probes + the user's description for render bugs. tools/A8CellAudit+ the committed doorway fixture remain for offline membership checks.
9. Do-NOT-repeat / settled facts
- Do not chase shaders/textures/missing-meshes for #78. The
[shell]evidence proves shells draw opaque + textured + complete. The bug is the seal + the gating, not the shells. - Do not add another gate, scissor, or clip layer on top. That is the failed incremental approach. The redesign collapses to ONE visibility answer + a closed-occluder seal.
- Do not reintroduce WorldBuilder's
RenderInsideOutstencil two-pipe (abandoned 2026-05-30; reference-divergent from retail). Port retail's recursive PView. - Do not reopen the membership fix (
59f3a13) —[cell-transit]confirms it works. - My mistake this session (learn from it): I trusted the prior handoff's "render infra
already exists, just wire 3 gaps" framing and built the Stage-4 sky-through-door clip on
top without verifying the base seal end-to-end (I can't see the screen; I leaned on the
test suite + a smoke-launch). The visual gate correctly caught that the premise was wrong.
Lesson: for a render seal, get the user's eyes (or the
[shell]/[vis]evidence) on the ACTUAL sealed result EARLY, before building layers on top. A green test suite proves nothing about whether the interior looks sealed. - Stage-4 commits are kept (
ce2edad,a8b831c,872dd34,21609a7,4bc99fc,b595cfb) — the sky NDC-clip + the green-tests triage are real and reusable; they are a top layer that becomes correct once the base seals. The 5 remaining Core test failures are pre-existing physics/collision bugs (2 step-up gaps incl. a regression from A6.P4's door fix; 3 door-collision apparatus / A6.P5), none Phase-W's, flagged not fixed.
10. The redesign plan
→ docs/superpowers/plans/2026-06-02-render-pipeline-redesign-plan.md (the huge staged plan).
Stages: R0 brainstorm/lock → R1 one-visibility-authority (kill the outdoor-scenery bleed)
→ R2 indoor = DrawInside-only (stop drawing the outdoor world indoors) → R3 the seal
(DrawCells faithful port: LScape-through-door → Z-only clear → closed cells) → R4 per-cell
object + particle clip → R5 outside-looking-in (U.5 / DrawPortal) → R6 dungeons → R7
polish + conformance. Each ends at a user visual gate. The core inversion: when inside, run
ONLY the PView flood — visibility IS the cull; the outdoor world enters only through clipped exit
portals.
11. Pickup prompt (copy-paste for the next session)
RENDER PIPELINE REDESIGN — full retail-faithful rewrite of the world render (outdoor + indoor +
dungeon + portals + particles). Continue on branch claude/thirsty-goldberg-51bb9b (do NOT
branch/worktree; do NOT push without asking; NEVER git stash/gc — a shared stash is under
investigation). Use PowerShell on Windows; the launch logs are UTF-16 (read with Select-String /
the ripgrep Grep tool, NOT GNU grep).
MANDATE (user, non-negotiable): FULLY WORKING outdoor + indoor + dungeon rendering — no flaps, no
missing textures, no transparent walls, no terrain leaking into cellars, no entity/particle
bleed-through, outside-looking-in works. NO shortcuts, NO bandaids, NO quick fixes; take the
architecturally-correct path even if slower; redesign the whole pipeline if needed; PORT FROM
RETAIL; do more research mid-session rather than guess; START WITH A BRAINSTORM.
READ FIRST (in order):
1. docs/research/2026-06-02-render-pipeline-redesign-handoff.md (THIS handoff: §2 proven evidence,
§3 root cause = three inconsistent gates + no closed-occluder seal, §5 retail target + porting
checklist CL-A..G, §9 do-not-repeat).
2. docs/research/2026-06-02-retail-render-pipeline-full-reference.md (the retail PView pipeline to
port — the seal mechanics in DrawCells).
3. docs/research/2026-06-02-acdream-render-pipeline-inventory-and-failures.md (the concrete bugs:
the WbDrawDispatcher.cs:1756 ParentCellId==null bypass = the outdoor bleed; the parallel
visibility BFS; terrain Skip model).
4. docs/research/2026-06-02-render-reference-crosscheck.md (why WB's two-pipe stencil is the wrong
model — do NOT reintroduce it).
5. THE PLAN: docs/superpowers/plans/2026-06-02-render-pipeline-redesign-plan.md (stages R0..R7).
PROVEN ROOT CAUSE (don't re-investigate): the PVS computes correctly and the cell shells render
correctly (opaque, textured, complete — [shell] probe). The failure is the SEAL + the GATING:
acdream draws the outdoor world (terrain + scenery ENTITIES that aren't culled) and then a few cell
shells on top, relying on three inconsistent gates. Retail, when inside, runs ONLY DrawInside (one
PView flood) — visibility IS the cull, and the landscape enters only through clipped exit portals.
That inversion is the redesign.
DO NEXT:
1. Phase R0 — BRAINSTORM the §1 architecture (handoff §5 / plan §1) with the user; resolve the open
questions (plan §3); write the per-phase design spec. NO code until the design is locked.
2. Then execute R1→R7 (plan §2), each retail-anchored, each ending at a user visual gate. R1 (one
visibility authority + kill the WbDrawDispatcher.cs:1756 bypass) kills the headline bleed first.
EVIDENCE-FIRST: launch per CLAUDE.md "Running the client" with ACDREAM_PROBE_CELL/VIS/SHELL=1; walk
the Holtburg cottage (spawn 0xA9B40031 outdoor → 0170 vestibule → 0171 room → 0175 stairs → 0174
cellar). The [shell] diagnosis tree + [vis] OutsideView counts are decisive. GET THE USER'S EYES on
the actual sealed result at every visual gate — never declare a seal off the test suite (that was
the mistake that produced this handoff).
KEEP (don't rewrite): PortalVisibilityBuilder (the PVS), ClipFrame/ClipFrameAssembler/ClipPlaneSet,
EnvCellRenderer mesh path, TerrainModernRenderer, the WB mesh pipeline, the membership fix (59f3a13),
the Stage-4 sky NDC-clip + doorway Z-clear (ce2edad/b595cfb). The work is RESTRUCTURING THE
ORCHESTRATION + the entity/particle draw to be per-cell, not a from-scratch rewrite.
TEST STATE: full suite green except 5 pre-existing Core failures (2 step-up gaps incl. an A6.P4 door
regression; 3 door-collision apparatus / A6.P5) — none render-related, flagged in the handoff, do not
chase as part of this work.
12. Session ledger (2026-06-02, render half)
- Stage 4 (sky/weather portal clip + Z-clear + green-tests triage) shipped:
ce2edad,a8b831c,872dd34,21609a7,4bc99fc,b595cfb. Real + reusable, but a top layer — the base seal was never working (#78). Visual gate FAILED → this redesign handoff. - Research this session: retail pipeline reference (doc A), acdream inventory+failures (doc B), reference cross-check (doc C), this master handoff, the redesign plan.
- Issues to file/track: #78 (the core seal — now the redesign target), #95 (dungeon BFS), #104
(particle cell-clip), the
WbDrawDispatcher.cs:1756outdoor-scenery bypass, theCullMode.Landblock→Nonedouble-sided stopgap, U.5 outside-looking-in.