docs(handoff): door collision session end — honest accounting
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) <noreply@anthropic.com>
This commit is contained in:
parent
163a1f0d35
commit
6a2c432e5a
1 changed files with 188 additions and 0 deletions
188
docs/research/2026-05-24-door-collision-session-end-handoff.md
Normal file
188
docs/research/2026-05-24-door-collision-session-end-handoff.md
Normal file
|
|
@ -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=<path>` 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=<path>,
|
||||||
|
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.
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue