Separates what is measured (eye smooth + 1um at rest -> not jitter) from the leading-but-unproven hypothesis (clip edge-on) and the NOT-ruled-out alternative (camera position: retail eye collided/head-on 93%, ours floats edge-on). The one 'clean' pass had ratio 4.2x back-and-forth, so the flood claim is indicated not proven. Lists the verify-first steps before any R-A2b fix. Counters this session's pattern of overclaiming then refuting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
13 KiB
HANDOFF — Indoor crossing flap: MEASURED vs HYPOTHESIS vs OPEN (read before ANY code)
Date: 2026-06-08 (late). Branch: claude/thirsty-goldberg-51bb9b.
HEAD: the docs(render): plan status commit (after c7069cf). Working tree clean.
⚠️ 0. CALIBRATION NOTE — read this first
This session's diagnosis of the indoor flap shifted four times as measurements came in:
per-building → camera-jitter (R-A4) → camera swept/published eye → flood edge-on. Each
"confident" claim was refuted by the NEXT measurement, in the same session. The author (me) also
stated a final scoreboard ("conclusively pinned / camera ruled out") with more confidence than the
data earns.
So this handoff is structured to prevent the next session from inheriting an overclaim:
- §2 = MEASURED (high confidence, with the data + file refs).
- §3 = LEADING HYPOTHESIS (medium — explicitly NOT isolated).
- §4 = ALTERNATIVE NOT RULED OUT (a real competing explanation I waved away).
- §5 = WHAT TO VERIFY FIRST — do this BEFORE building anything. Do not trust §3 until §5 confirms it.
- §6 = DO-NOT (genuinely refuted, high confidence — safe to not re-try).
The honest one-liner: the flap is a motion-time grey-flash at openings; eye-jitter-at-rest is ruled out (measured); but whether the cause is the clip math at edge-on (§3) or the camera not pulling the eye in like retail (§4) is NOT yet disambiguated — the one "clean" pass wasn't clean enough (it had back-and-forth). Disambiguate (§5) before choosing the fix.
1. What SHIPPED this session (all green, visual-confirmed by the user)
| Commit | What | Verified |
|---|---|---|
7fe9809 |
R-A1 — canonicalize outdoor root on LoadedCell.IsOutdoorNode (behavior-preserving) |
tests |
c62663d |
R-A2 — per-building floods (ConstructViewBuilding; OutdoorCellNode portal-less; per-building merge in RetailPViewRenderer.DrawInside) |
user: outside-looking-in flap GONE |
2ec189c |
R-A2 seam fix — flood null-BuildingId cells (don't drop) |
user: missing textures GONE |
3c178b2 |
tools/cdb/flap-cam-measure.cdb — retail eye + CameraManager capture |
apparatus |
c7069cf |
[flap-sweep] probe: F6 in=(desiredEye) / out=(eye) |
apparatus |
docs… |
plan-doc STATUS note (R-A4 ruled out) | docs |
Test baseline: App ~Rendering 207, Core PlayerMovementControllerTests 14. Build green.
Plan: docs/superpowers/plans/2026-06-08-full-retail-render-port-option-a.md.
The user's remaining symptom (verbatim): "grey background color flapping entrances between rooms and cellar entrance and when going outside." I.e., the clear/background color flashes through openings during MOTION; at rest it does not flap.
2. MEASURED FACTS (high confidence — data + file refs)
2.1 acdream eye at REST ≈ 1 µm stable (NOT a jitter problem)
flap-cam-measure.log (acdream run, user held completely still, 768 samples). Last 150 frames:
in (desiredEye) Y range 0.000 mm (1 distinct value); out (eye) Y range 0.001 mm (2 distinct);
pulledIn=0. → The convergence snap (RetailChaseCamera.ApplyConvergenceSnap, SnapEpsilon 0.0004)
holds; there is no at-rest jitter. (acdream at rest is actually steadier than retail's settled eye.)
2.2 The earlier "~1.3 mm jitter at rest" was MOTION misread as rest
launch-flap-pin2.log [pv-input] showed ~1.3 mm; that was during the crossing. The F2-precision print
rounded sub-cm walking to "d=0", which I mis-analyzed as a static eye. The flap is motion-time only.
2.3 On a (mostly) one-way pass: eye SMOOTH, but visible-cell count OSCILLATES
launch-camprobe.log, the clean-pass tail (~25.7k sweep frames):
- Eye: 3D path = 34.1 m, net = 8.2 m (ratio 4.2×), direction reversals X=3, Y=18 (i.e. few large direction changes — the motion is smooth, not jittery).
- Visible cells (
[flap] vis=): oscillated 414× between 1 and 6; 648clip=0events. Distribution1:4084 2:6300 3:3860 4:10634 5:439 6:427. Roots:0171(room) 21396,0031(outdoor) 4084, others tiny. - ⚠️ CAVEAT (why this is NOT isolated): ratio 4.2× means the pass was not purely one-way — it had
back-and-forth + indoor↔outdoor. The 414 oscillations therefore mix (a) indoor-flood oscillation
(root
0171, vis 2↔6) AND (b) indoor↔outdoor root swaps (0171↔0031, the "going outside" grey; the 4084 vis=1 frames are root0031= legitimately just the outdoor node). These were not separated. So "smooth eye + oscillating vis ⇒ flood bug" is indicated but not proven — some of the oscillation is the back-and-forth and the root-swap.
2.4 Retail eye at the cottage doorway: COLLIDED 93%, settled jitter ~tens of µm
flap-cam-measure.log (retail, acclient.exe, PDB MATCH refs/acclient.pdb), 768 samples:
pub != sought716/768 = 93% COLLIDED — retail's boom hits the cottage; the eye is pulled toward the player (a more head-on view of the doorway, not floating 3 m back).- Settled jitter (quarters Q2–Q4) ≈ 93 µm; Q1's 1.4 mm was the user walking up (settling motion), verified by the quarter split.
- Offsets:
CameraManager.t_stiffness@+0x08,r_stiffness@+0x0c,viewer_offset@+0x48;SmartBox.camera_manager@+0xa0. acdream's damping already matches retail's formula (alpha = clamp(stiffness·dt·10,0,1), stiffness 0.45) —RetailChaseCamera.ComputeDampingAlpha.
3. LEADING HYPOTHESIS (medium confidence — NOT isolated; see §2.3 caveat)
The flood/clip's "is the room behind this opening visible?" decision is non-monotonic near a
doorway's EDGE-ON angle. The portal projects to an on-screen area that hovers at ~zero (coin-on-edge);
small smooth eye steps flip the clip 0↔nonzero → the cell behind drops → grey flash. This matches the
"grey at room↔room / cellar entrances." Mechanism candidates inside this hypothesis: ProjectToClip /
ClipToRegion collapsing at edge-on (PortalProjection.cs), and/or the band-aids MaxReprocessPerCell
(D4) + EyeInsidePortalOpening (D5) re-processing differently frame-to-frame during motion.
4. ALTERNATIVE NOT RULED OUT (a real competing explanation)
The edge-on viewing might be a CONSEQUENCE of the camera not pulling the eye in like retail. §2.4:
retail's eye is collided 93% (head-on); acdream's [flap-sweep] showed it uncollided much more
often (floats free, 3 m back → edge-on view of the doorway). A doorway viewed edge-on is exactly when
the clip collapses. So the root cause could be camera collision / eye position (acdream's spring-arm
not pulling in where retail's does), NOT the clip math.
- What IS ruled out: eye-jitter / wobble / at-rest instability (§2.1, §2.3 — smooth + 1 µm).
- What is NOT ruled out: eye position (collision pull-in). These are different. I conflated them in the scoreboard. Disambiguate in §5.2.
- Separately, the "going outside" grey is the root
0171↔0031wholesale swap (§2.3) — likely a distinct sub-issue (indoor↔outdoor root transition), not the same as the room↔room edge-on flap.
5. VERIFY FIRST — before building ANY fix (this is the anti-overclaim gate)
- Isolate pure indoor-flood oscillation. Do a genuinely one-way, slow walk through ONE
interior doorway (room→room), no going outside, no back-and-forth, camera fixed. Capture
ACDREAM_PROBE_FLAP=1. Confirm whethervis(root0171only) oscillates 2↔6 for a monotonic eye (check[flap-sweep] out=is monotonic — ratio ≈ 1, ~0 reversals). If it does NOT oscillate when the eye is truly monotonic → the flap was the back-and-forth / root-swap, not a flood bug (then §3 is wrong). The clean pass in §2.3 had ratio 4.2× — not clean enough to conclude. - Disambiguate clip-math (§3) vs camera-position (§4). At the SAME interior doorway, measure
acdream's eye-to-doorway angle vs retail's (collided) — is acdream viewing it edge-on where retail
views it head-on (because retail's eye is pulled in)? Add the doorway-plane signed distance + the
collide state to
[flap-sweep]. If acdream floats edge-on where retail pulls in → the fix is the camera collision, not the flood. - Read retail's edge-on clip handling (the fix ORACLE — do NOT guess the fix without this):
PView::GetClip(0x5a4320, decomp ~:432344),PView::ClipPortals(0x5a5520,:433572),ACRender::polyClipFinish(the w=0 clip,:702749). Questions: does retail's clip collapse to zero at edge-on like ours, or stay robust? Does retail keep a flooded cell once added? Cross-checkPortalProjection.cs(our port — handoff says it's faithful; verify at edge-on specifically).
6. DO-NOT RETRY (genuinely refuted this session — high confidence)
- Camera eye-JITTER / R-A4 stiffness change. Eye is smooth (3/18 reversals) + 1 µm at rest (§2.1, §2.3). acdream's damping already matches retail's stiffness 0.45. Do not "reduce jitter."
- RenderPosition rest-snap (
cd974b2, reverted). The eye isn't the jitter source; at rest it's 1 µm. - "1.3 mm jitter at rest" — it was MOTION (§2.2).
- A robust-MEMBERSHIP scheme retail lacks. Retail's flood is clip-driven too —
PView::add_views(0x5a5210) only pre-pushes view slices onto the stab_list cells viacurr_view_push; it does NOT groundcell_draw_listmembership. So the robustness must live in the clip's edge-on behavior (§3) or the camera position (§4), NOT a stab_list membership-grounding. - Two-pipe inside/outside split; bounded-propagation/churn; byte-stable eye — all refuted earlier (see the 2026-06-08 OPTION-A handoff §7).
7. The fix (R-A2b) — GATED on §5
Do NOT design until §5 disambiguates. Two branches:
- If §5.1 + §5.3 show the clip collapses at edge-on (clip-math): port retail's edge-on clip
robustness into
PortalProjection/PortalVisibilityBuilder; conformance-test "smooth monotonic eye through a doorway ⇒ monotonic vis (no oscillation)"; visual-gate. - If §5.2 shows acdream's eye floats edge-on where retail pulls in (camera-position): the fix is the
camera collision (
PhysicsCameraCollisionProbe.SweepEye/RetailChaseCamera) — make the eye pull in like retail (93% collided at the doorway). This is the camera position, distinct from the ruled-out eye-jitter. - The "going outside" grey (§4, root
0171↔0031swap) is likely a separate, smaller task.
8. Apparatus (reuse — don't rebuild)
- acdream probes (gated in
AcDream.Core.Rendering.RenderingDiagnostics):ACDREAM_PROBE_FLAP=1→[flap](per-portalD/side-testTRV/CULL/clip=vertex count,vis=),[flap-sweep](camera sweep:pulledIn, andin=(desiredEye) /out=(eye) at F6 — addedc7069cf),[flap-cam]. HEAVY (per-frame per-portal) — short captures only.ACDREAM_PROBE_PVINPUT=1→[pv-input](eye/player/rawPlayer F6 + flood count). Lighter.
- cdb on retail:
tools/cdb/flap-cam-measure.cdb(eye origin per framepub+soughtraw float hex +CameraManager/SmartBoxtype dumps). Attach:Get-Process acclient→ pid;cdb.exe -p <pid> -cf tools\cdb\flap-cam-measure.cdb. Exit code 5 is expected (clean detach). PDBrefs/acclient.pdb— verify withpy tools/pdb-extract/check_exe_pdb.py "C:/Turbine/Asheron's Call/acclient.exe"(MATCH). - Logs (UNTRACKED, large — gitignore/delete):
launch-camprobe.log,launch-flap-pin2.log,flap-cam-measure.log,launch-ra2.log. - Launch: CLAUDE.md "Running the client" env block +
$env:ACDREAM_PROBE_FLAP="1". - Build-while-client-running gotcha: the running client locks the DLLs → build fails MSB3027. Close
the client (graceful
CloseMainWindow) before building.
9. Exact pickup (next session)
- Read this doc top-to-bottom, then memory
project_indoor_flap_rootcause(2026-06-08 late CORRECTION). git log --oneline -8(HEAD = the plan-status docs commit).dotnet buildgreen; App~Rendering207 / CorePlayerMovementControllerTests14 green.- Do §5 FIRST (isolate indoor-flood vs camera-position vs root-swap). Do NOT write a fix until §5 tells you which of §3 / §4 is real. This is the whole point of the calibration note.
- Then §5.3 (retail clip oracle) → design the gated fix (§7) → conformance-test PRE-gate → visual-gate.
- Strip the throwaway probes after the visual gate; update memory + the plan + milestones.
10. One-paragraph version (for when you're tired)
Outside-flap and seams are FIXED and confirmed. The indoor flap is a motion-time grey-flash at openings. We MEASURED that it's not eye-jitter (eye is smooth + 1 µm at rest). We did NOT prove it's the clip math: the one "clean" pass had back-and-forth (ratio 4.2×) so the 414 oscillations mix flood-edge-on, back-and-forth, and indoor↔outdoor root-swaps. And we did NOT rule out the camera position (retail's eye is pulled-in/head-on 93% at the doorway; ours floats edge-on). So: isolate a truly one-way single interior-doorway pass, compare acdream's vs retail's eye angle at that doorway, and read retail's edge-on clip code — THEN choose between the clip-math fix and the camera-position fix. Don't pick one until those three are done.