test(phys): A6.P4 door — corner-slide hypothesis falsified, bug is state-related

CornerSlide_AlcoveEastToCottageNorth_ShouldBlock test:
- Registers cottage GfxObj 0x01000A2B (contains north exterior walls)
- Registers cell 0xA9B40150 BSP via dat-direct load (alcove walls)
- Places sphere at (132.95, 16.8, 94) inside alcove near east wall
- Walks sphere +Y 50 times at walk speed (0.05 m/tick)

Result: sphere STAYS at (132.95, 16.8) for all 50 ticks with collision
normal cn=(0.71, -0.71, 0) — the average of alcove east wall normal
and cottage north wall normal at their meeting corner. The corner
handling works correctly in the harness.

So production's inside-out walkthrough is NOT a geometric or BSP
collision-detection bug. The geometry exists, the collision detection
fires symmetrically at corners. The discrepancy must be a STATE
difference between harness and production:
- Real walkable polygons with edges (harness uses big quad)
- Real terrain (harness uses Z=-1000 stub)
- Accumulated body state across many prior ticks (harness uses fresh)
- Possibly cell ping-pong between 0x0150 and 0x0029 in production

Cottage GfxObj wall polygons at the doorway area confirmed:
- North exterior wall east of doorway: polys 0x0032, 0x0033
  X=[133.5, 136.3], Y=17.10, Z=[94, 97], normal +Y
- North exterior wall west of doorway: polys 0x0030, 0x0031, 0x0034,
  0x0035 (X<131.6 various ranges)
- Lintel polys above doorway: 0x0037, 0x0038, 0x003A, 0x003B at Z>96.5

Next-session moves (per handoff):
1. Replay captured tick 2586 (where sphere went from cell 0x0150 to
   0x0029 at X=134.022, way past alcove east wall). Inspect engine
   behavior at exactly that tick's body state.
2. cdb attach to retail at Holtburg cottage doorway — verify whether
   retail also lets sphere walk through at off-center, OR blocks
   cleanly. If retail also allows walkthrough, this might be
   retail-faithful behavior we should accept.

Updated handoff: docs/research/2026-05-25-door-bug-inside-out-geometry-gap.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-25 08:37:31 +02:00
parent fe29db5691
commit a657ca946c
2 changed files with 179 additions and 17 deletions

View file

@ -142,27 +142,50 @@ the corner at (133.5, 17.10) — should encounter the cottage wall
and be stopped. If our engine handles the corner transition
incorrectly, sphere slides past.
## What's next (revised)
## What's next (revised AGAIN — corner test PASSED, bug is state-related)
**Investigate sphere-vs-corner collision behavior** at the alcove
east wall → cottage north wall meeting point at world (133.5, 17.10).
**Corner-slide hypothesis: FALSIFIED.** `CornerSlide_AlcoveEastToCottageNorth_ShouldBlock`
test runs cottage GfxObj + cell 0x0150 BSP both registered. Places
sphere at (132.95, 16.8, 94) inside alcove near east wall. Walks +Y
50 times at 0.05 m/tick. **Sphere stays put at (132.95, 16.8) for all
50 ticks with cn=(0.71, -0.71, 0)** — the corner normal between
alcove east wall and cottage north wall. **The corner handling works
correctly in the harness.**
Apparatus to write:
- Load cottage GfxObj + cell 0x0150 BSP into harness
- Place sphere at (133.0, 16.8, 94) (inside alcove, near east wall)
- Walk sphere +Y in small increments
- Expected: sphere stops at Y=17.10-0.48 = 16.62 if east wall blocks
OR: sphere slides along corner staying in alcove
- Captured: sphere ends up at (133.655, 17.59) — sliding past corner
So production's walkthrough is **a STATE difference**, not a geometric
or collision-detection bug. The harness's sphere can't reach
X=133.655 inside the cottage geometry. Production's sphere does
reach it somehow.
If harness reproduces "sphere slides past corner", the bug is in
the engine's corner-handling. Read BSPQuery for the sphere-vs-edge
case. Retail oracle: CTransition::find_obj_collisions corner
handling at acclient_2013_pseudo_c.txt.
Differences between harness and production:
- Harness uses identity walkable polygon (big quad). Production uses
real cell walkable polys (small, with edges).
- Harness has stub landblock terrain at Z=-1000. Production has real
terrain.
- Harness uses fresh body each tick. Production has accumulated state
from many prior ticks (velocity, contact plane history, etc.).
- Harness uses sphereRadius=0.48 + sphereHeight=1.20 exactly. Production
matches but might have different stepUp / stepDown.
If harness BLOCKS at corner (no sliding past), the bug is something
else — maybe cell 0x0150 BSP isn't being queried in production from
some sphere position.
**Next-session apparatus**: replay the EXACT captured tick 2586's body
state through the corner-blocking test setup. Tick 2586 was where
sphere went from indoor cell 0x0150 to outdoor cell 0x0029 at
PrevPy=17.586, Py=17.586 (no Y motion) with X=134.022 (way past alcove
east wall). That tick is the smoking-gun "how did sphere get to X=134
inside alcove" event. Load its body state into the harness, replay
the call, see what the engine reports about getting to that position.
If the harness blocks (sphere can't reach X=134), then production has
state we're not capturing — probably accumulated push/depenetration
across many earlier ticks. If the harness reproduces sphere at X=134,
the bug is in the specific body state at that moment.
The cleanest path forward is **cdb attach to retail** as the original
handoff recommended. Inspect what retail does FRAME-BY-FRAME at the
same doorway approach. If retail walks the user inside cottage at
off-center approach EXACTLY like we do — the bug isn't a bug, and
we should accept the behavior. If retail blocks cleanly — diff
retail's body state evolution vs ours to find the divergence.
## OLD (superseded) "what's next" candidates