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