Residual A (camera collision = verbatim SmartBox::update_viewer) is SHIPPED + user-kept (0ffc3f5/5177b54/9e70031). Wrap it and hand off to the render session: - New canonical handoff (docs/research/2026-06-05-render-residual-a-shipped-core- inside-render-handoff.md): what A shipped, what A EXPOSED (the render roots at the viewer cell — clipRoot=CameraCell, GameWindow.cs:7322 — and A made that cell accurate, so the PVS flood from the viewer cell doesn't reach the player's cell → cellar floor drops), the reframing (the user's "step C" = the CORE inside render / R1 completion, NOT R2 outside-looking-in), the evidence-first job, KEEP/DON'T, the kickoff prompt. - CLAUDE.md banner: A SHIPPED; next = core inside render (R1 completion). - Render redesign spec: 2026-06-05 sync note (A shipped; R1 is actually incomplete — the bleed + cellar-floor drop are the unfinished flood/seal; next is R1, not R2). The visible problems (bleed + the floor A exposed) are the same family: the inside path still draws the whole outdoor world instead of retail's "inside → DrawInside only". A faithful DrawInside seals them by construction (render spec 2026-06-02 §2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
15 KiB
Handoff — Render Residual A SHIPPED; next = the CORE inside render (R1 completion) — 2026-06-05
Canonical pickup for the next (render) session. Read this FIRST. Residual A (camera collision) is a faithful verbatim port of
SmartBox::update_viewer— shipped, tested, user-kept. It made the render's viewpoint accurate, which exposed the real next problem with precision: the inside render does not flood/seal correctly from the (now-correct) viewer cell. The "step C" the user asked for is therefore not the handoff-era "C / outside-looking-in" — it is the core inside render (R1 completion). Branchclaude/thirsty-goldberg-51bb9b. PowerShell on Windows; launch logs are UTF-16 (Select-String/rg --encoding utf-16-le, NOT GNU grep).
0. TL;DR
- SHIPPED (A): verbatim
SmartBox::update_viewer— indoor start-cell seated at the head-pivot (AdjustPosition→find_visible_child_cell) + the two fallbacks + cellId==0 snap-to-player. Commits0ffc3f5(spec) /5177b54(Core primitives) /9e70031(SweepEye orchestration). TDD, 11 new tests, no regression. User-kept (chose "Keep it" over revert). - The live-capture finding that scoped A: A's V1 sweep already contained the eye (
eyeInRoot=Y99.75%,viewerCellnever 0, indoor collide 97.6%). So A is a faithfulness completion, not a visible-bug fix. The dominant inside-cottage bluish void / see-through-to-other-buildings is NOT the camera — it is the render seal. - What A EXPOSED (the handoff's whole point): the render roots at the viewer cell
(
clipRoot = visibility.CameraCell, GameWindow.cs:7322; Phase W V1 "one viewpoint"). A made that cell accurate (the eye's real, collided cell). So when you stand in the cellar but the eye is up in the room,clipRoot = the room, and the PVS flood from the room does not reach the cellar → the cellar floor drops. Before A,viewerCell ≈ playerCell(the sweep started from the feet cell), which accidentally masked this. The user accepted this interim floor-drop to keep the faithful viewpoint. - NEXT = the core inside render (R1 completion): make
DrawInsideflood + seal correctly from the viewer cell. This fixes BOTH the bleed (point 1) AND the floor A exposed — they are the same family. The locked design already exists:docs/superpowers/specs/2026-06-02-render-pipeline-redesign-design.md. - Test baseline: Core 1326 pass / 4 fail (documented) / 1 skip; App 179 pass / 0 fail.
The 4 Core fails are pre-existing (2×
DoorBugTrajectoryReplayLiveCompare,BSPStepUpTests.D4,DoorCollisionApparatus).
1. What shipped — Residual A (verbatim SmartBox::update_viewer, pc:92761)
| Commit | What | Layer |
|---|---|---|
0ffc3f5 |
design spec (docs/superpowers/specs/2026-06-05-residual-a-camera-collision-design.md) |
docs |
5177b54 |
CellTransit.FindVisibleChildCell (CEnvCell::find_visible_child_cell pc:311397) + PhysicsEngine.AdjustPosition (CPhysicsObj::AdjustPosition pc:280009) |
Core |
9e70031 |
ResolveResult.Ok (surfaces find_valid_position != 0) + PhysicsCameraCollisionProbe.SweepEye orchestration (start-cell seating + fallback 1 + fallback 2 + cellId==0 snap-to-player) |
Core + App |
The orchestration mirrors update_viewer end-to-end: indoor (objcell_id >= 0x100) seats the sweep's
start cell at the head-pivot via AdjustPosition (the cellar lip: feet in the low connector, head
up at floor level); sweep pivot → sought-eye from that start; on success set_viewer(curr_pos),
viewer_cell = curr_cell; fallback 1 = AdjustPosition(sought_eye); fallback 2 / no-cell = snap to
player, viewer_cell = null. SweepEye gained a playerPos arg (for the snap).
Why A's visible payoff was nil this session (don't be surprised): the seating only differs from the
feet cell when the feet are in a thin connector cell while the head is in a taller neighbour (the lip
— a transient). Two live captures: in the cottage room every frame had start == cell (0 seated of
80,605); in the cellar the seating did fire (1,687 frames, start != cell). No fallback ever fired
(ok=False: 0). So A is faithful + correct; its job was to make the viewpoint accurate, which it did.
2. The exposure (READ THIS — it is the bridge to the next phase)
The render roots + projects from one viewpoint = the viewer cell (Phase W V1, GameWindow.cs:7322,
7330-7333: "the render root (clipRoot = the viewer cell). ONE viewpoint"). PortalVisibilityBuilder.Build(clipRoot, viewerEye, …)
floods the PVS from clipRoot.
A changed viewerCell from ≈ playerCell (V1, sweep from the feet cell) to the eye's actual cell
(seated at the pivot). Live proof, player in the cellar (playerCell=0xA9B40174):
[flap-cam] root=0xA9B40171 viewerCell=0xA9B40171 playerCell=0xA9B40174 eye=(155,12,96.5) player=(153,9,93) ×1466 frames
clipRoot = viewerCell = 0171 (the room, where the eye is) while the player is in 0174 (the cellar).
The PVS flood from the room does not reach the cellar → the cellar floor (the player's cell) is not
drawn → missing floor. This is exactly the spec's predicted symptom: §1.3 + §8 call the grey/missing
cellar floor a sealing bug (the closed cell mesh not covering pixels, OR the flood not reaching the
cell). Cause unconfirmed — confirm it first (evidence-first, §4 below).
The bleed (point 1: walls bluish, other buildings/particles/NPCs visible through them from inside)
is the same family: the inside path still draws the whole outdoor world then layers cell shells on
top, instead of retail's "inside → DrawInside only" (spec §2). A faithful DrawInside makes the bleed
impossible by construction.
3. The reframing — "C" is the CORE inside render, not outside-looking-in
The handoff-era residual letters (A camera / B particles / C outside-looking-in) map onto the locked
render spec's phases as: A camera (DONE), B → R1b (#104 particles), C → R2 (DrawPortal,
street→interior). R2 is a LATER phase. The visible problems the user is hitting — the bleed AND the
floor A exposed — are R1 (the core per-cell DrawInside flood+seal), which shipped only partially
(2026-06-03: the flap fix + basic shells + inside-looking-out, but NOT the "inside → DrawInside only"
inversion, NOT the general-case flood from viewerCell != playerCell). The next session finishes R1.
4. The job (next session) — evidence-first, then verbatim PView
- Read the locked design + its 4 research docs (in the spec's "Read first" list):
docs/superpowers/specs/2026-06-02-render-pipeline-redesign-design.md→docs/research/2026-06-02-render-pipeline-redesign-handoff.md(root cause, the three-gate failure) →…-retail-render-pipeline-full-reference.md(the PView +DrawCellsseal) →…-acdream-render-pipeline-inventory-and-failures.md(theWbDrawDispatcher.cs:1756bypass, the parallel BFS, the terrain Skip model) →…-render-reference-crosscheck.md(why WB two-pipe is wrong). - Confirm the floor cause FIRST (do NOT guess — spec §8): launch with
ACDREAM_PROBE_FLAP=1ACDREAM_PROBE_VIS=1ACDREAM_PROBE_SHELL=1; stand in the cellar, get the eye up in the room (viewerCell=room,playerCell=cellar). Read[vis](doesOrderedVisibleCellsinclude the cellar when rooted at the room?) +[shell](does the cellar shell draw?) + dump the cellar EnvCell mesh (is the floor polygon present + front-facing?). This decides: PVS-flood-not-reaching vs cell-mesh-not-sealing. Get a screenshot EARLY (memoryrender-one-gate). - Port the PView seal/flood verbatim (spec §2 + §4): the binary top-level decision (inside →
DrawInsideonly — removes the global outdoor pass → kills the bleed by construction) + the per-cellDrawInsideloop (landscape-through-door → conditional Z-only clear → per-cell shells → per-cell objects → per-cell particles). Retail anchors:RenderNormalMode0x453aa0,PView::DrawInside0x5a5860,ConstructView0x5a57b0,DrawCells0x5a4840 (spec §11 has the full index). - VALIDATE — visual gate (spec R1 gate): Holtburg cottage + cellar — sealed interior (opaque walls, solid floor, ceiling), sky/terrain through the door only, no bluish void, no bleed (no other buildings/particles/NPCs through walls), no terrain under the floor. Build + Core(1326p/4f/1s)/App(179p) green.
5. KEEP / DON'T-REDO
KEEP (do not reopen):
- Residual A (the 3 commits). The viewer cell is now accurate — that is the input the render needs. Do NOT revert it to mask the floor (the user explicitly chose to keep the faithful viewpoint).
- The Phase W V1 "one viewpoint" (clipRoot = viewer cell, project from the eye) — GameWindow.cs:7322-7338.
- The Stage-1 membership port + the blue-hole fix (
UpdatePlayerCurrCell, player-only render-root). PortalVisibilityBuilder/ClipFrame/EnvCellRenderer/TerrainModernRenderer/ the WB mesh pipeline (spec §3 KEEP).
DON'T:
- Don't re-add a
CurrCellwrite insideResolveWithTransition/ResolveCellId(the blue-hole clobber). - Don't reintroduce the WB two-pipe stencil /
isInsidegate / AABB grace-frame for the root (spec §8). - Don't relax the faithful terrain
Skipto "fix" the grey floor (spec §1.3 — it's a sealing bug, not a terrain-clip bug). - Don't jump to R2 (outside-looking-in /
DrawPortal) — R1 (the inside seal+flood) is first.
6. KEY FILES + ANCHORS
RENDER (the next phase)
src/AcDream.App/Rendering/GameWindow.cs (OnRender ~7300-7610) ← clipRoot=viewerCell (7322); binary decision lives here
src/AcDream.App/Rendering/PortalVisibilityBuilder.cs ← the PVS BFS (KEEP; the flood to harden/port)
src/AcDream.App/Rendering/InteriorRenderer.cs ← per-cell DrawInside loop (partial)
src/AcDream.App/Rendering/EnvCellRenderer.cs ← per-cell shell mesh (Render(pass,{cellId}))
src/AcDream.App/Rendering/WbDrawDispatcher.cs (~1756) ← the ParentCellId==null bypass to delete
src/AcDream.App/Rendering/ClipFrameAssembler.cs / CellVisibility.cs
docs/superpowers/specs/2026-06-02-render-pipeline-redesign-design.md ← LOCKED design (§2 model, §4 seal, §7 phases, §11 anchors)
CAMERA (A — shipped, the input)
src/AcDream.App/Rendering/PhysicsCameraCollisionProbe.cs ← SweepEye = verbatim update_viewer
src/AcDream.Core/Physics/CellTransit.cs FindVisibleChildCell ← pc:311397
src/AcDream.Core/Physics/PhysicsEngine.cs AdjustPosition ← pc:280009
PROBES
ACDREAM_PROBE_FLAP=1 [flap-cam] root/viewerCell/playerCell/eyeInRoot + [flap] PVS BFS + [flap-sweep] camera (start vs cell, ok)
ACDREAM_PROBE_VIS=1 [vis] OrderedVisibleCells + OutsideView
ACDREAM_PROBE_SHELL=1 [shell] per-cell shell draw
ACDREAM_PROBE_CELL=1 [cell-transit] player CellId changes
7. RUNNING THE CLIENT (PowerShell; +Acdream spawns in the Holtburg cottage)
$env:ACDREAM_DAT_DIR="$env:USERPROFILE\Documents\Asheron's Call"; $env:ACDREAM_LIVE="1"
$env:ACDREAM_TEST_HOST="127.0.0.1"; $env:ACDREAM_TEST_PORT="9000"
$env:ACDREAM_TEST_USER="testaccount"; $env:ACDREAM_TEST_PASS="testpassword"
$env:ACDREAM_PROBE_FLAP="1"; $env:ACDREAM_PROBE_VIS="1"; $env:ACDREAM_PROBE_SHELL="1"
dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug *>&1 | Tee-Object -FilePath launch.log
Build green BEFORE launching. Logs are UTF-16. Close gracefully (✕ / Alt+F4) so ACE clears the session in ~3-5s.
8. KICKOFF PROMPT (copy-paste for the next session)
Continue acdream M1.5 render work: the CORE INSIDE RENDER (R1 completion) — make DrawInside flood + seal
correctly from the viewer cell so the cottage/cellar interior is SEALED: no bluish void, no see-through-to-
other-buildings BLEED, and the CELLAR FLOOR draws. This is what the user means by "step C" — it is NOT the
handoff-era "C / outside-looking-in" (that is R2, a later phase). Branch claude/thirsty-goldberg-51bb9b
(do NOT branch/worktree; do NOT push without asking; NEVER git stash/gc). PowerShell on Windows; launch
logs are UTF-16 (Select-String / rg --encoding utf-16-le, NOT GNU grep). Use superpowers:systematic-
debugging; the render redesign DESIGN is already LOCKED (read the spec), so this is execution + an
evidence-first floor-cause confirmation, not a re-brainstorm.
READ FIRST (in order):
1. docs/research/2026-06-05-render-residual-a-shipped-core-inside-render-handoff.md (THIS handoff — what
A shipped, what A EXPOSED §2, the reframing §3, the job §4, KEEP/DON'T §5, files §6).
2. docs/superpowers/specs/2026-06-02-render-pipeline-redesign-design.md (the LOCKED design — §2 the one
model, §4 the seal mechanics, §7 phases/gates, §11 decomp anchors) + its 4 "Read first" research docs.
3. memory: reference_render_pipeline_state.md, feedback_render_one_gate.md,
feedback_render_downstream_of_membership.md, feedback_verify_render_seal_before_layering.md.
STATE: Residual A (camera collision) SHIPPED + user-kept (commits 0ffc3f5/5177b54/9e70031) — verbatim
SmartBox::update_viewer; the viewer cell is now ACCURATE. That accuracy EXPOSED the next problem: the
render roots at the viewer cell (clipRoot=visibility.CameraCell, GameWindow.cs:7322), and the PVS flood
from the viewer cell does NOT reach the player's cell when they differ (eye in the room, player in the
cellar → clipRoot=room → cellar floor not drawn). Same family as the bleed (the inside path still draws
the whole outdoor world instead of "inside → DrawInside only").
THE JOB (evidence-first, then verbatim PView):
1. Confirm the floor cause FIRST (spec §8 flags it unconfirmed): launch with ACDREAM_PROBE_FLAP/_VIS/_SHELL,
stand in the cellar with the eye up in the room (viewerCell=room, playerCell=cellar), read [vis]
(is the cellar in OrderedVisibleCells when rooted at the room?) + [shell] + dump the cellar EnvCell
mesh (floor poly present + front-facing?). Decide PVS-flood-not-reaching vs cell-mesh-not-sealing.
Screenshot EARLY.
2. Port the PView seal/flood verbatim (spec §2 + §4): the binary top-level decision (inside → DrawInside
ONLY — removes the global outdoor pass → kills the bleed by construction) + the per-cell DrawInside loop
(landscape-through-door → conditional Z-only clear → per-cell shells → per-cell objects → per-cell
particles). Anchors: RenderNormalMode 0x453aa0, PView::DrawInside 0x5a5860, ConstructView 0x5a57b0,
DrawCells 0x5a4840.
3. VALIDATE — visual gate: Holtburg cottage + cellar sealed (opaque walls, SOLID FLOOR, ceiling), sky/
terrain through the door only, NO bluish void, NO bleed. Build + Core(1326p/4f/1s)/App(179p) green.
DON'T: revert A to mask the floor (user chose to keep the faithful viewpoint); re-add a CurrCell write in
ResolveWithTransition/ResolveCellId (blue-hole); reintroduce the WB two-pipe / isInside gate / AABB grace
(spec §8); relax the faithful terrain Skip (spec §1.3 — it's a sealing bug); jump to R2 (outside-looking-in)
before R1 (the inside seal+flood) is done.
TEST BASELINE: Core 1326 pass / 4 fail (documented: 2× DoorBugTrajectoryReplay LiveCompare, BSPStepUpTests.D4,
DoorCollisionApparatus) / 1 skip. App 179 pass / 0 fail. Branch HEAD 9e70031 (+ this handoff commit).