docs(handoff): ContactPlane retention investigation pickup prompt

Self-contained fresh-session prompt that points at the BSP-port
shipped-handoff, summarizes the foundation work to keep vs delete,
notes the retail decomp anchors for CTransition::transitional_insert /
last_known_contact_plane, and includes the session-lesson reminder:
probe-first, design-second.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-20 07:06:11 +02:00
parent c6b3fd6ebf
commit 7034be9294

View file

@ -0,0 +1,149 @@
# Indoor ContactPlane retention — fresh-session pickup prompt
**Status:** Indoor walkable-plane BSP port foundation shipped to main 2026-05-19 at `c6b3fd6` (8 commits between `165f67a` spec and `c6b3fd6` handoff). Visual verification FAILED — cellar descent, 2nd-floor walking, single-floor cottage regression. Root cause diagnosed deeper than originally thought: the per-frame `TryFindIndoorWalkablePlane` synthesis is a Phase 2 stop-gap retail never had; retail RETAINS `ContactPlane` across frames.
This doc is the start-of-session brief for whoever picks up the next phase.
---
## What's on main
**Foundation (kept, useful):**
- `BSPQuery.FindWalkableInternal` exposes `ref ushort hitPolyId`.
- New public `BSPQuery.FindWalkableSphere` wrapper over the retail-faithful walkable finder.
- `Transition.TryFindIndoorWalkablePlane` routes through the BSP walker with `WalkableAllowance` save/restore.
- `[indoor-walkable]` runtime-toggleable diagnostic probe at the `FindEnvCollisions` callsite.
- 5 new unit tests + 9 updated existing tests + 1 wall-poly integration test, all green.
- `dotnet build -c Debug` clean; 8 pre-existing test baseline unchanged.
**Behavioral result:** ISSUES #83 remains OPEN. Cellar descent fails ("ground blocking" — outdoor terrain backstop returns wrong Z). 2nd-floor walking gets intermittent falling-stuck. Single-floor cottage REGRESSED from stable (Phase 2) to intermittent falling-stuck. Phantom collisions persist. Probe captured 1443 MISS / 2 HIT — the foot-sphere-tangent-to-floor case is rejected by `PolygonHitsSpherePrecise`'s `|dist| > radius - epsilon` check (~0.0002 margin), which is correct retail behavior but wrong for this caller.
**Comprehensive handoff:** [`docs/research/2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md`](2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md). Read this FIRST.
---
## How to start a fresh session
Copy the block below into a fresh Claude Code session in this repo.
---
```
Pick up the acdream project. The Indoor walkable-plane BSP port shipped
to main 2026-05-19 at c6b3fd6 — 8 commits of foundation work — but
visual verification by the user FAILED to fix the indoor walking bugs
(cellars, 2nd floors, phantom collisions). Foundation is good and
stays on main; the root cause was deeper than I diagnosed.
1. Read docs/research/2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md
FIRST. Long but complete: what shipped, what failed, the probe
evidence (1443 MISS / 2 HIT), the deeper diagnosis, the recommended
next phase target, session lessons. The "Session lessons" section
at the bottom is important — I made specific mistakes that you
should not repeat.
2. The recommended next phase: port retail's ContactPlane retention.
Retail RETAINS the previous frame's ContactPlane when the BSP
reports "no collision" — it doesn't re-synthesize per frame the way
our Phase 2 commit eb0f772 introduced. The proper fix likely
eliminates Transition.TryFindIndoorWalkablePlane entirely from the
FindEnvCollisions per-frame path. Retail decomp anchors are in the
handoff doc; key starting points:
- acclient_2013_pseudo_c.txt:273137 — CTransition::transitional_insert
- Search the decomp for "last_known_contact_plane" and
"contact_plane_valid" to map the full ContactPlane lifecycle.
- Grep our acdream code for ContactPlane writers/readers to map
who currently sets it and when.
3. Use the brainstorming skill FIRST. But before designing a spec,
SPIKE: add a small diagnostic probe that logs every ContactPlane
write site with caller, old plane, new plane. Capture a log of the
user walking around indoors. Look at the data BEFORE designing the
fix. That's the lesson from the previous session — I designed a
spec on a wrong hypothesis and shipped 6 commits before the
diagnostic probe surfaced the truth. Probe-first, design-second.
4. CLAUDE.md rules apply:
- No workarounds; fix root causes. (Specifically: do NOT add a
sphere-offset hack to make PolygonHitsSpherePrecise accept
tangent contact. The right answer is to stop calling find_walkable
as a standing-still query.)
- Use superpowers skills (brainstorming → writing-plans →
subagent-driven-development → finishing-a-development-branch).
- Drive autonomously — Claude picks the next step, user reviews.
- Visual verification by the user is the acceptance test for any
physics/collision change.
5. Foundation work to KEEP (the previous session's commits):
- BSPQuery.FindWalkableSphere wrapper — useful for legitimate
"find a walkable indoors" queries (spawn-placement, teleport-
target verification), just not per-frame from FindEnvCollisions.
- FindWalkableInternal's hitPolyId ref param.
- The [indoor-walkable] probe (will fire less often once retention
is in place — that's expected).
- All 14 tests (5 new BSPQuery + 9 updated IndoorWalkablePlane).
Foundation work to LIKELY DELETE or refactor:
- Transition.TryFindIndoorWalkablePlane — likely deleted entirely,
OR kept as an out-of-band synthesis path for edge cases (initial
spawn, cell-id promotion mid-frame) but NOT called per-frame.
- The per-frame call from FindEnvCollisions:1380.
6. The user has limited tolerance for repeated failed visual
verifications. Be especially disciplined this time: capture
diagnostic evidence early, validate the hypothesis against the
probe data BEFORE designing the fix, present the smallest
possible change that addresses the root cause.
State the milestone and your chosen phase in the first action you
take. Then begin.
```
---
## Quick reference for the user
To start the new session: open a fresh Claude Code in the acdream repo and paste the boxed prompt above. Or just say:
> "Read `docs/research/2026-05-19-contactplane-retention-pickup-prompt.md` and start on the next phase."
## Quick reference for the helper
Key files / anchors for the investigation:
- **Handoff:** `docs/research/2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md` — the canonical record of what just shipped and the deeper diagnosis.
- **ISSUES #83:** Updated 2026-05-19 with the deeper diagnosis. Still OPEN.
- **Foundation spec (for context, do not re-execute):** `docs/superpowers/specs/2026-05-19-indoor-walkable-plane-bsp-port-design.md`.
- **Foundation plan (for context, do not re-execute):** `docs/superpowers/plans/2026-05-19-indoor-walkable-plane-bsp-port.md`.
- **Retail decomp anchors:**
- `acclient_2013_pseudo_c.txt:273137``CTransition::transitional_insert`
- `acclient_2013_pseudo_c.txt:273099``CTransition::step_up`
- `acclient_2013_pseudo_c.txt:323565``BSPTREE::step_sphere_up`
- Search for `last_known_contact_plane` and `contact_plane_valid` for the retention machinery.
- **acdream code:**
- `src/AcDream.Core/Physics/TransitionTypes.cs:1192``TryFindIndoorWalkablePlane` (likely to delete in the next phase).
- `src/AcDream.Core/Physics/TransitionTypes.cs:1262``FindEnvCollisions` indoor branch (where the per-frame `TryFindIndoorWalkablePlane` call happens at line ~1380).
- `src/AcDream.Core/Physics/PhysicsDiagnostics.cs``ProbeIndoorBspEnabled` flag (reuse for any new diagnostic probe).
- Grep `ContactPlane` across `src/AcDream.Core/Physics/` to find all write sites.
## Visual verification scenarios (re-use for the next phase)
1. **Cellar descent** — the primary failing scenario. Walk into any building with a cellar entry, descend the stairs. Acceptance: smooth descent onto cellar floor.
2. **2nd-floor walking** — climb stairs to 2nd floor, walk around. Acceptance: no intermittent falling-stuck.
3. **Single-floor cottage regression check** — walk into a Holtburg cottage. Acceptance: stable walking, no intermittent falling-stuck (Phase 2 baseline restored).
4. **Phantom collisions** — observational. If root cause is fixed, these should improve.
## Launch command (for the user, with probes enabled)
```powershell
$env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call"
$env:ACDREAM_LIVE = "1"
$env:ACDREAM_TEST_HOST = "127.0.0.1"
$env:ACDREAM_TEST_PORT = "9000"
$env:ACDREAM_TEST_USER = "testaccount"
$env:ACDREAM_TEST_PASS = "testpassword"
$env:ACDREAM_DEVTOOLS = "1"
$env:ACDREAM_PROBE_INDOOR_BSP = "1"
dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug 2>&1 | Tee-Object -FilePath "launch-contactplane.log"
```