From 6a2c432e5ad16aa7f84913f1baae859021e3fb11 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 24 May 2026 20:52:53 +0200 Subject: [PATCH] =?UTF-8?q?docs(handoff):=20door=20collision=20session=20e?= =?UTF-8?q?nd=20=E2=80=94=20honest=20accounting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the puffed-up framing in the prior task7-shipped handoff. Honest summary: no user-visible bug fixed this session. Off-center and inside-out door walk-through still 100% reproducible. The 4 commits shipped real infrastructure (multi-part registration + the GetNearbyObjects dedup fix that would have silently broken any future multi-part feature) but no observed behavioral change. Also explicitly retracts the "step-up is the bug" hypothesis from the prior handoff doc — ACDREAM_DUMP_STEPUP=1 in the apparatus produced no stepup: ENTER lines, so DoStepUp wasn't even being called. That hypothesis was over-reach from an inference I should not have inflated to a conclusion. Recommends the apparatus-replay pattern (same one that closed issue #98 after 6+ speculation rounds): live capture via ACDREAM_CAPTURE_RESOLVE → harness replay test → first per-field divergence names the broken assumption. DO-NOT list for the next session: do not redo the multi-part work, do not speculate-and-fix, do not relaunch with more probes hoping for an obvious signal. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...5-24-door-collision-session-end-handoff.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 docs/research/2026-05-24-door-collision-session-end-handoff.md diff --git a/docs/research/2026-05-24-door-collision-session-end-handoff.md b/docs/research/2026-05-24-door-collision-session-end-handoff.md new file mode 100644 index 0000000..f14cfd4 --- /dev/null +++ b/docs/research/2026-05-24-door-collision-session-end-handoff.md @@ -0,0 +1,188 @@ +# Door collision — end-of-session handoff (2026-05-24, late) + +**Branch:** `claude/strange-albattani-3fc83c` +**Worktree:** `C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c` + +## TL;DR — what was actually accomplished + +**No user-visible bug was fixed this session.** The door bug the user +reported at the start (center blocks, off-center walks through, +inside-out walks through) is **identically reproducible after the +4 commits** as it was before them. + +What changed: infrastructure. Server-spawned doors now register +multi-part shadow shapes (cylinder + BSP slab) instead of one +cylinder approximation. The BSP slab is queried 135 times per door +near approach but produces **zero collision hits**, so observed +behavior is unchanged. + +**Don't re-do the infrastructure.** It's correctly built and necessary +for any future fix. The remaining work is downstream of it. + +## Commits landed (4) + +``` +163a1f0 diag(phys): [bsp-test] probe + grounded apparatus test + handoff +ca9341c feat(phys): A6.P4 Task 7 — RegisterLiveEntityCollision uses ShadowShapeBuilder + RegisterMultiPart +3b7dc46 fix(phys): GetNearbyObjects dedup-by-entityId silently drops multi-part shadows +e1d94d7 test(phys): door setup + GfxObj dat-inspection — Hypothesis A falsified +``` + +**Real-but-latent value from these:** +- The dedup-by-entityId issue (3b7dc46) was a latent footgun: any + future attempt at multi-part shadows (NPCs with hit-region capsules, + multi-part creatures, props with separated collision) would have + silently dropped all but the first shape. Now safe. +- The dat-inspection (e1d94d7) proved part 0 (`0x010044B5`) has a + real 1.9×0.26×2.5 m BSP slab in the dat. A future fix doesn't have + to question whether the data exists. +- The Task 7 wiring (ca9341c) puts the right architecture in place — + doors now register the shapes retail expects (cyl per CylSphere + + cyl per Sphere + BSP per Part-with-BSP). +- The `[bsp-test]` probe (163a1f0) fires before the cache lookup, + distinguishing "cache miss → silent skip" from "queried but no + hit" — neither of which `[resolve-bldg]` ever showed. + +**Brutally clear: zero of these commits change observed door behavior.** + +## What we now know vs. what we don't + +### Known (from this session's probes) + +- `0x010044B5` PhysicsBSP has 6 collision-bearing polygons forming a + 1.925 × 0.261 × 2.490 m door slab. All `SidesType=Landblock` + (two-sided). Bounding sphere radius 1.975 m. Verified by direct + dat read. +- `0x010044B6` (the two leaf parts) have `HasPhysics=false`, + `PhysicsBSP=null`, `PhysicsPolygons.Count=0`. Visual-only by retail + design — our skip matches retail's + `CPhysicsPart::find_obj_collisions:275051`. +- Live Holtburg doors register with `shapes=cyl1+bsp1`. Cache is + populated. BSP entries are visited (135x for one door at player + approaches as close as 0.42 m). +- The BSP traversal produces ZERO attributed hits during live walking + (all 19 `[resolve-bldg]` lines show `gfxObj=0x00000000`, which is + the Cylinder shape). Whatever is happening inside + `SphereIntersectsPolyInternal` or the dispatch around it is + swallowing the hit silently. + +### NOT known (don't speculate further) + +- **Whether `DoStepUp` is involved.** The prior handoff doc + (`2026-05-24-door-collision-task7-shipped-but-bug-remains.md`) + asserted "step-up incorrectly succeeds" as the leading hypothesis. + That was over-reach. In the apparatus, `ACDREAM_DUMP_STEPUP=1` + produced no `stepup: ENTER` lines — `DoStepUp` was never called. + So the apparatus shows `hit=yes n=(0,0,1)` from some OTHER path + (terrain step-down? walkable poly preservation?). It does not + confirm step-up is the production bug. +- **Whether the production hit happens at the BSP polygon edge test, + the BSP node traversal, or some other layer.** +- **Whether the production code path is the same as the apparatus + path 5 in the first place.** + +The earlier framing of "step-up is the bug" was a guess I inflated +into a conclusion. Treat it as a candidate, not a finding. + +## Proper next move + +**Same pattern that closed issue #98 after 6+ failed speculation rounds: +live capture + apparatus replay.** + +The infrastructure for this already exists in the codebase: + +1. `ACDREAM_CAPTURE_RESOLVE=` env var (see + `src/AcDream.Core/Physics/PhysicsResolveCapture.cs`) captures every + player-side `PhysicsEngine.ResolveWithTransition` call as a JSON + Lines record with full `PhysicsBody` before-and-after snapshots. +2. `CellarUpTrajectoryReplayTests.LoadCapturedRecord` + + `AssertCallMatchesCapture` replay a captured record through a + harness engine and emit the first per-field divergence between + live and harness outputs. + +The plan: + +1. Launch with `ACDREAM_CAPTURE_RESOLVE=door-walkthrough.jsonl` + (no other probes — capture is independent). +2. Walk into a closed Holtburg cottage door 50 cm off-center. +3. Close gracefully. Save the JSONL. +4. Write a new test `LiveCompare_DoorOffCenterWalkthrough` that loads + the failing-tick record and replays it through a harness with the + real `0x010044B5` BSP hydrated + registered via + `RegisterMultiPart`. Compare per-field. +5. The first divergent field names the broken assumption. Fix that. + +This is concrete, deterministic, and doesn't ask you to relaunch +multiple times for each fix attempt. The harness round-trip is <500 +ms; a fix iteration is ~3 seconds. + +## What NOT to do + +1. **Do NOT re-do the multi-part registration.** It's correct. The + dedup fix is correct. Task 7 is correct. Verified by 53/53 tests + in the targeted scope. +2. **Do NOT speculate-and-fix.** This session burned cycles on a + "step-up is the bug" hypothesis that wasn't supported by the + evidence. The apparatus-first rule (`feedback_apparatus_for_physics_bugs.md`) + exists for exactly this. Build the apparatus before the fix. +3. **Do NOT re-investigate whether the door has BSP polygons.** + It does. 6 of them. Forming a full door slab. Cached. Visited. +4. **Do NOT relaunch with more probes hoping for an obvious signal.** + The probes we have already say "BSP visited 135 times, no hits." + More log lines won't tell us WHY it doesn't hit. The apparatus + replay will. + +## Files to read first + +- This doc (you're in it). +- `docs/research/2026-05-24-door-dat-inspection-findings.md` — the + dat data, polygon layout, bounding sphere center vs frame offset. +- `docs/research/2026-05-24-door-collision-task7-shipped-but-bug-remains.md` + — the prior end-of-session handoff. **Read with skepticism** — its + "leading hypothesis" section overstates confidence in the step-up + theory (corrected here). +- `tests/AcDream.Core.Tests/Physics/CellarUpTrajectoryReplayTests.cs` + — the capture+replay pattern to mirror for the door bug. See + `LiveCompare_*` tests. + +## State of the M1.5 milestone + +Doors at Holtburg cottages: center blocks, off-center walks through, +inside-out walks through. Same as it was 24 hours ago. The walking- +through case is the actual user pain point. Until the apparatus +replay names the divergence, treat M1.5 indoor-world as still +incomplete on the door front. + +The infrastructure is in place for the eventual fix. The fix itself +remains future work. + +## Pickup prompt for the next session + +``` +Door collision investigation. Previous session shipped infrastructure +(multi-part registration + GetNearbyObjects dedup fix) but did NOT fix +the user-visible bug: off-center / inside-out approaches still walk +through closed Holtburg cottage doors. + + Read docs/research/2026-05-24-door-collision-session-end-handoff.md + + State both altitudes: + Currently working toward: M1.5 — Indoor world feels right + Current phase: A6.P4 door bug — apparatus replay phase. + Multi-part registration shipped; need live capture + + per-field divergence comparison to identify why + the door's BSP slab fires zero attributed hits + despite being visited 135x per approach. + + First move: launch the client with ACDREAM_CAPTURE_RESOLVE=, + walk into a closed Holtburg cottage door 50 cm off-center, close + gracefully. Then write a LiveCompare_* test in CellarUpTrajectoryReplayTests + that loads the captured failing tick + replays through a harness + with the door BSP hydrated via the existing 0x010044B5 dat read + pattern and registered via RegisterMultiPart. + + DO NOT redo the multi-part registration. DO NOT speculate about + step-up without evidence — the apparatus tested DoStepUp and it + didn't fire. The bug is upstream of step-up. The replay will name + the actual divergence. +```