# 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: 1. **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.)* 2. **Just inside:** you see **only the outdoor world background + NPCs/particles/doors** — no interior shell sealing you in. 3. **Inside → looking out:** sky is visible, but you see **houses and trees through the ground**. 4. **On the cellar stairs:** the cellar walls show, but the **floor is grey**, and NPCs / particles / doors show **through the walls above**. 5. **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 fix `59f3a13` holds; 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=3`** cells 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). **Zero `zh>0`** (no missing-texture cases). **Zero `tr`** (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 == null` stabs/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:** 1. **Two visibility computations, not one.** `PortalVisibilityBuilder.Build` (the faithful PView BFS) feeds the shell + terrain + sky gates. But the **entity** gate reads `CellVisibility.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 one `cell_draw_list`, and every cell's objects are drawn (and only those) — there is no second gate.** 2. **No "closed interior occluder" model.** Retail's interior render is *sealed by construction*: it draws the visible cells (whose `drawing_bsp` are closed boxes — floor, walls, ceiling), draws `LScape` only 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_list` fix (`59f3a13`). `[cell-transit]` confirms correct cell tracking. Do not reopen. - **`PortalVisibilityBuilder`** (the PView BFS) — produces the correct visible set + OutsideView + `OrderedVisibleCells`, with `seen`-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, so `sky.vert` clips 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 the `CellVisibility.ComputeVisibilityFromRoot` entity 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=null` entities (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) 1. **One cell graph, one membership answer, render obeys it.** Physics tracks `curr_cell` through the sweep; the camera tracks `viewer_cell`; both resolve via the same `CObjCell::GetVisible`. 2. **The top-level decision is BINARY** (`RenderNormalMode @ 0x453aa0`): viewer in an outdoor landcell → `LScape::draw` (full landscape). Viewer in an EnvCell → **`DrawInside` only.** 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.* 3. **`DrawInside` = one PView portal flood** (`ConstructView → DrawCells`) producing the `cell_draw_list` + per-cell clip regions + **one** `outside_view`. 4. **Exit portals (`other_cell_id == 0xffffffff`) pull the landscape INTO the indoor traversal** — `ClipPortals` (pc:433662) copies the doorway clip region into `outside_view`. The outdoors is seen *only* through that clipped region. 5. **The seal sequence in `DrawCells`** (when `outside_view.view_count > 0`): `LScape::draw` **clipped to the doorway** → conditional **Z-ONLY** `Clear(4,…)` (NOT color) → exit-portal stencil → `DrawEnvCell` (closed geometry) → per-cell objects. 6. **No blue clear-color hole by construction** — the only clear is depth-only + conditional; the doorway shows real terrain because LScape drew there first. 7. **Ceilings/walls sealed by dat geometry** — `drawing_bsp` is a closed box; portal holes are stencil-masked, never filled; there is no "cap the ceiling" step. 8. **VISIBILITY *IS* THE CULL.** Only `cell_draw_list` cells render, and only **their** `object_list` objects (drawn with `PortalList` set). There is **no second "draw all entities then gate them" pass.** → no wall/object/particle bleed, by construction. 9. **Outside-looking-in is the mirror image** — `DrawPortal @ 0x5a5ab0` runs `ConstructView(CBldPortal)` + `DrawCells` to render the interior through the door's clip, the **same** machinery. 10. **Dungeons are emergent** — all-EnvCell, `seen_outside == 0`, no exit portals → `outside_view` stays 0 → `LScape::draw` is 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 on `seen_outside`, `grab_visible_cells`, pre-position terrain. - **CL-C PView traversal:** BFS, InitCell, ClipPortals (both branches), AddViewToPortals/AddToCell, `update_count` watermark, GetClip. *(`PortalVisibilityBuilder` already 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`), the `SeenOutside` terrain gate, the `OtherCellId==0xFFFF` exit-portal sentinel, the WB **mesh pipeline** (keep — it's just GL plumbing), `EnvCellRenderer.PrepareRenderBatches(filter)`, entity outdoor-slot routing via `WbDrawDispatcher.ResolveEntitySlot`. - **AVOID (do not reintroduce):** WB `RenderInsideOut`/`RenderOutsideIn` stencil two-pipe, `BuildingPortalGPU`/`RenderBuildingStencilMask`, any `isInside` / `cameraInsideBuilding` gate, 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.EntityPassesVisibleCellGate` hits an **unconditional `return true` at `WbDrawDispatcher.cs:1756`** for entities with `ParentCellId == null` (outdoor scenery: houses, trees, landblock stabs). The `IsShellScopedSet` anchor-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 by `PortalVisibilityBuilder`. They are not the same answer. Retail has ONE (§5.1 fact 8). - **🟠 Terrain `Skip` over-aggression:** `TerrainClipMode.Skip` fires whenever the exit portal is not in the current view — correct for a true dungeon, but it removes the terrain floor for a `seen_outside=true` cottage 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 → None` double-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`, then `dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug 2>&1 | Tee-Object -FilePath launch.log`, in the background. The character `+Acdream` spawns at the Holtburg cottage (`0xA9B40031`, outdoor); walk in to reach `0170→0171→0175→0174`. - **Probes** (env vars; the log is **UTF-16** — read with PowerShell `Select-String` or 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-cell `gfx 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 `PrintWindow` approach 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 `RenderInsideOut` stencil 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:1756` outdoor-scenery bypass, the `CullMode.Landblock→None` double-sided stopgap, U.5 outside-looking-in.