acdream/docs/research/2026-07-06-177-stairs-pickup-handoff.md
Erik 0cbe1102d9 docs(#177): mark stairs pickup-handoff SUPERSEDED (flood theory disproven)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 10:10:53 +02:00

137 lines
8.2 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.

> **🅿️ SUPERSEDED 2026-07-07 — #177 is PARKED and this doc's premise is WRONG.** The
> "portal-visibility miss" framing below was DISPROVEN by a live retail cdb trace
> (retail's flood collapses identically to ours). Do NOT follow the flood/clip workflow
> here. Current truth + the fresh lead (step statics) live in **ISSUES #177 (session-3 +
> 3b blocks)** and the render digest top banner. Kept only for the apparatus map.
# Pickup handoff — #177 dungeon stairs pop in/out (portal-visibility miss at the stair cells)
**Paste the companion prompt (bottom) into a fresh session.** Read this file, then
`claude-memory/project_render_pipeline_digest.md` (top banners), then **ISSUES #177**
(full entry — including the superseded lighting attribution and why it was re-attributed
to VISIBILITY at the 2026-07-06 gate).
## TL;DR — what #177 is
Facility Hub (0x8A02), the staircase connecting two levels (corridor 0x0178 → ramp
0x0182 → lower room 0x0183): (a) **invisible looking into the stair room from the
corridor**, (b) **pops into existence on entering the room**, (c) **the last step
vanishes running down**. The 2026-07-06 gate PROVED this is NOT lighting (the A7
visible-cell light fix shipped and the stairs were still missing looking back from the
corridor) — it is a **portal-flood admission miss**: the stair cells are not reached by
`PortalVisibilityBuilder` from the viewer's cell until the viewer crosses in. The
digest tags it "#119 class, dungeon edition; floor-portal level links."
**Acceptance:** the staircase renders whenever its room is visible through the
connecting opening, and stays rendered through the full descent.
## Where to start (the apparatus already exists)
1. **`tests/AcDream.App.Tests/Rendering/Issue176177FacilityHubFloodReplayTests.cs`** —
headless flood replays against the REAL dat, with two scenarios written for exactly
this issue and never fully mined:
- Scenario A (stair approach): eye in corridor 0x0178 at several x positions +
pitches, printing whether ramp 0x0182 / lower 0x0183 are admitted.
- Scenario B (descent): eye path down the ramp, printing per-step admitted-set
diffs (the "last step vanishes" case).
**Run these FIRST** — the miss should reproduce headlessly, and the printed
admitted sets name which portal hop fails.
2. **`Issue181VisFlapReplayTests.cs`** — the same-file pattern for perturbation
sweeps + per-cell view-region AREA measurement (the shoelace diagnostic). Cell
**0x8A020181** — right next to the stair complex 0x0182/0x0183 — rides a
knife-edge zero-area admission; the #177 miss and the #181 sliver are plausibly
the SAME flood defect seen two ways (a floor-portal chain that clips to nothing
from above).
3. **The builder:** `src/AcDream.App/Rendering/PortalVisibilityBuilder.cs`. The
admission gates per portal hop, in order: the side test (`CameraOnInteriorSide`,
PortalSideEpsilon 0.01 — AP-19), then `ClipPortalAgainstView` (homogeneous clip
against the parent's accumulated region; `clippedRegion.Count == 0` ⇒ the flood
stops there). For a DOWNWARD stair chain the suspect class is the FLOOR-portal
hop: a horizontal portal seen edge-on from the corridor clips to ~zero area
(exactly the 0x0181 sliver signature) and the chain below never floods.
`ACDREAM_A8_DUMP_PV=1` dumps per-portal census + EXIT-PROJ/EXIT-CLIP lines for
the camera cell (first 2 builds per cell).
4. **Retail oracle:** retail PView floods portals with per-poly clip
(`polyClipFinish` — the W=0 clip pseudocode doc 2026-06-11) and DOES show stair
rooms through their openings. If our clip collapses a genuinely-visible aperture
to zero, compare `ClipPortalAgainstView` against `PView::ClipPortals`/`GetClip`
(decomp:433572) at the failing hop's exact geometry. #119's lesson applies:
visibility must derive from the same data that gets drawn
(`feedback_culling_bounds_from_drawn_data`).
## What tonight's #180/#181 session gives you for free
- All camera/sweep mechanisms are Ghidra-verified faithful (stateful sought,
adjust_to_plane, adjust_sphere_to_poly, viewer radius-anchored stepping) — commits
`48aaab81`/`f10fe4e9`/`3f34bca0`. The camera's `ViewerCellId` is trustworthy; the
render roots at it (Option A).
- The wall-pressed camera wanders ~0.5 mm/frame in a bit-exact 12-frame limit cycle
(`Issue181WallPressEquilibriumTests` — measured, all local algorithms verified;
plausibly retail-class). Any admission knife-edge within that wobble band flaps
~10 Hz (`[flap]` vis 31↔32, whole-session). For #177 this matters at stair
THRESHOLDS: expect flappy admission exactly at descent transitions.
- Lighting is now retail-shaped: resident+player-anchored pool (d8984e87), idempotent
re-apply (`87cddce2`), stationary fixtures on the verified static curve
(`233b469b`). Do NOT re-open lighting for #177 — the gate already refuted it.
- **#181 is PARKED** (see its ISSUES entry for the still-open leads). Do not resume
it inside the #177 arc; if stair work surfaces new flicker evidence, append to
#181's entry instead.
## Watchouts
- The old #177 root-cause text (128-cap light eviction) is SUPERSEDED — kept in the
entry for history. The re-attribution is the ⚠️ UPDATE block at the top of #177.
- The flood replay's ViewProj must match production FOV/aspect (π/3, 16:9) — the
Issue181 test does; the older Issue176177 scenarios use 1.2 rad / 1280×720 (fine
for admission questions, but keep in mind for NDC-sensitive comparisons).
- `Issue120ReciprocalPingPongTests.LoadAllInteriorCells` + `CornerFloodReplayTests.
ResolveDatDir` are the shared fixtures loaders (App.Tests); Core.Tests has its own
`ConformanceDats`.
- A client may be running — the user manages its lifecycle; ASK before rebuilding if
the App DLL is locked (MSB3027 = lock, not code).
## State
- Branch `claude/vigorous-joliot-f0c3ad` @ `233b469b`+ (this handoff's commit).
Suites green: Core 2600+2skip / App 733+2skip / UI 425 / Net 385 / Content 56.
- Test char spawns in the Facility Hub corridor (0x8A020142 area); the stair complex
is 0x0178/0x0182/0x0183 (+0x0181 adjacent).
- Launch recipe + graceful-close rules: CLAUDE.md "Running the client". The
GDI-capture + keybd_event autonomous visual loop scripts live in this session's
scratchpad (capture-still.ps1, imgdiff.ps1, imgdiffmap.ps1, crop.ps1) — recreate
from the #180 handoff's recipe if the scratchpad is gone.
## Companion prompt (paste into the fresh session)
```
Fix #177 — Facility Hub stairs pop in/out across levels (invisible from the
corridor, pop on entry, last step vanishes running down). The 2026-07-06 gate
re-attributed this from lighting to a PORTAL-FLOOD ADMISSION MISS at the stair
cells (0x8A020178 corridor → 0x0182 ramp → 0x0183 lower; 0x0181 adjacent) — do
NOT re-open lighting (gate-refuted; the A7 fixes are in and verified).
READ FIRST, in order:
1. docs/research/2026-07-06-177-stairs-pickup-handoff.md (apparatus map, the
#181 park boundary, watchouts)
2. claude-memory/project_render_pipeline_digest.md (top banners)
3. docs/ISSUES.md #177 (the ⚠️ UPDATE block supersedes the old root cause)
START by running the existing headless replays (Issue176177FacilityHubFloodReplay
Tests Scenarios A/B — real dat, no client): they print per-pose admitted sets for
the stair cells and should reproduce the miss offline. Then trace the failing
portal hop through PortalVisibilityBuilder's gates (side test → ClipPortalAgainst
View; the floor-portal seen edge-on clipping to ~zero area is the suspect class —
the same signature as #181's 0x0181 sliver next door). Retail oracle for the clip:
PView::ClipPortals/GetClip (decomp:433572) + the 2026-06-11 polyClipFinish W=0
pseudocode doc. Workflow: replay → identify the gate → read retail → pseudocode →
port → the replays become pins → autonomous visual loop (stair approach/descent
drive) → user gate.
#181 (the pressed-camera flicker) is PARKED with its evidence ledger in ISSUES —
if stair work surfaces flicker evidence, append there; don't resume it in this arc.
State: branch claude/vigorous-joliot-f0c3ad, suites green (Core 2600+2skip / App
733+2skip). Test char spawns in the Facility Hub corridor. A client may be
running — the user manages its lifecycle; ASK before rebuilding if the App DLL
is locked.
```