# P1 visual gate — membership CONFIRMED live; the visible flap+void is the render half (P3/P4) 2026-06-03. Companion to the P1 membership finding ([`2026-06-03-p1-membership-swept-advance-handoff.md`](2026-06-03-p1-membership-swept-advance-handoff.md) — read its RESOLVED banner first). This note records the **visual-gate result** + the render-residual diagnosis, so the eventual P3/P4 work has a clean pickup. ## TL;DR - **P1 membership is correct — confirmed LIVE, not just in conformance.** Standing at / pacing the "Agent of Arcanum" doorway (`0031↔0170↔0171`) in the acdream client with `ACDREAM_PROBE_CELL=1`, the player `[cell-transit]` sequence is **clean + monotonic** and crosses at the **same Y thresholds as retail's captured golden**. Transitions fire only on CHARACTER movement (`reason=resolver`), never from camera-only movement. No ping-pong. - **The visible "flap" + purple void are the RENDER half, not membership.** They are the documented render residuals: **camera-collision (residual A → master-plan P3)** and the **PView seal (master-plan P4)**. - **User's intuition "transition feels tied to the camera, not the char" is CORRECT and retail-faithful** — for *rendering*. Retail keys the render on the camera's cell (the "viewer cell"); physics (where you walk) + lighting key on the player's cell. ## Visual-gate evidence (the player `[cell-transit]` log) ``` spawn: 0x00000000 → 0xA9B40031 @ (155.43, 17.87) teleport in: 0031 → 0170 @ Y15.97 → 0170 → 0171 @ Y15.08 out: 0171 → 0170 @ Y15.22 → 0170 → 0031 @ Y16.11 ... repeats cleanly for ~6 round trips, boundaries stable ... ``` Retail aligned golden boundaries (for comparison): enter room ~Y15.05–15.15, leave room ~Y15.18–15.23, leave building ~Y16.07–16.14, enter building ~Y15.96–16.06. acdream live matches. So the **player cell** is retail-faithful and camera-independent. ## What retail does (render vs physics) - **Render → viewer (camera) cell.** `SmartBox::RenderNormalMode` (`0x453aa0` pc:92635) decides `DrawInside(viewer_cell)` vs `LScape::draw` on which cell the **camera eye** is in, then the `PView` portal traversal floods visibility/seal from there. - **Physics + lighting → player cell.** Collision keys on the player's swept `curr_cell`; lighting on the player cell (`CellManager::ChangePosition`). So "what you SEE follows the camera" is the retail design (the V1 invariant acdream already adopts: render on viewer, lighting on player). The bug is NOT which cell drives the render — it's that two pieces of the camera-driven render aren't ported: 1. **The FLAP = camera-collision residual (master-plan P3 / residual A).** Retail's 3rd-person camera sweeps a small sphere backward from the head WITH collision (`SmartBox::update_viewer` `0x453ce0` pc:92761), so the eye stays snug to walls and inside a sensible cell. acdream's chase eye doesn't collide → it drifts through/behind the wall → when it crosses a cell boundary the viewer-cell flips → the doorway flap. Intermittent because it depends on where the eye lands. The handoff called camera-collision "the highest-leverage next step." 2. **The VOID = PView seal not ported (master-plan P4 / residual C).** Retail's `PView::DrawCells` draws opaque cell walls + clips terrain/sky to the doorway opening (sealed interior). acdream's render half isn't ported, so when the viewer-cell is wrong/unsealed you see the clear-color void with NPCs + brazier floating in it. ## Pickup for the render half (when P3/P4 are scheduled) - **P3 first (kills the flap):** port `SmartBox::update_viewer` (`0x453ce0` pc:92761) — the spring-arm viewer-sphere sweep with collision → stable `viewer_cell`; + `find_visible_child_cell` (`0x52dc50` pc:311397). Master-plan §2 C1/C3. - **P4 (kills the void):** port `PView` (`ConstructView`/`InitCell`/`ClipPortals`/`GetClip`/ `DrawCells`), replacing `PortalVisibilityBuilder`/`ProjectToNdc`/`ScreenPolygonClip`. Master-plan §2 D2–D9. - Apparatus ready: `ACDREAM_PROBE_CELL` (player `[cell-transit]`), `ACDREAM_PROBE_FLAP` (camera/viewer), the aligned golden + conformance gate (`tests/AcDream.Core.Tests/Conformance/`). ## Status / next P1 membership: **DONE** (correct by conformance + live visual gate). Per user direction (2026-06-03), **P2 door collision is next** (the 3 failing Core door tests + 2 BSPStepUp, issue #97 — the push-back bounce at the threshold; master-plan B3/B4). The render half (P3 camera → P4 PView) is the path to "indoor world feels right" and follows P2.