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

4.5 KiB
Raw Blame History

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 — 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.