acdream/docs/research/2026-06-03-p1-visual-gate-render-residuals.md
Erik f0d37d8955
Some checks failed
Copilot Setup Steps / copilot-setup-steps (push) Has been cancelled
docs(p1): visual-gate result — membership confirmed live; flap+void are render residuals
Standing/pacing the Agent of Arcanum doorway 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 aligned golden, firing only on character movement (never camera-only). So P1 membership
is correct LIVE, matching the conformance proof.

The visible flap + purple void are the RENDER half, not membership: the flap is the camera-collision
residual (chase eye drifts out of the player cell -> viewer-cell flips; master-plan P3,
SmartBox::update_viewer), the void is the unported PView seal (master-plan P4). The user's intuition
"transition feels tied to the camera" is retail-faithful: retail keys the render on the viewer
(camera) cell, physics+lighting on the player cell.

Per user direction, P2 door collision is next; the render half (P3 camera -> P4 PView) follows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 21:30:02 +02:00

74 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.0515.15, leave room
~Y15.1815.23, leave building ~Y16.0716.14, enter building ~Y15.9616.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 D2D9.
- 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.