test(phys): A6.P4 door inside-out — collision-geometry gap diagnosis
Added diagnostic apparatus that pinpoints the inside-out walkthrough as a collision-geometry GAP, not a collision-detection bug. New tests in DoorBugTrajectoryReplayTests: - InsideOut_Tick3254_WithCottageWalls_ShouldBlock: hypothesis test that registered cottage GfxObj 0x01000A2B and replayed the captured tick. Cottage blocked sphere but with cn=(0,0,1) floor-cap normal, not a wall normal — first signal that cottage geometry near the sphere isn't a wall. - Diagnostic_CottagePolys_NearWalkthroughPosition: dumps cottage polys near sphere XY=(133.655, 17.59) at any Z. Result: ZERO cottage polygons in that area. The cottage GfxObj has no geometry where the sphere walks through. DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection extended to dump cell 0xA9B40150's 4 physics polygons in world frame: - floor (Z=94), ceiling (Z=96.5), west wall (X=131.6), east wall (X=133.5) - All walls only span Y=[16.5, 17.1] — the small doorway alcove volume - North of Y=17.1, no wall Captured sphere at (133.655, 17.59) is 0.155 m east of cell east wall AND 0.49 m north of the wall's Y range. No collision geometry exists at that XY past Y=17.1. The collision representation has a gap that the visual cottage covers with a wall. Production capture confirms the diagnosis: cottage GfxObj fires [bsp-test] 425 times during inside-out walking — visibility IS correct post-AddAllOutsideCells fix. Door slab fires 245 times. But the BSP queries find no polygon at (133.655, 17.6+, 94-95.20). The slab's east face blocks WEST motion (cn=(+1,0,0) as captured), sphere free to move +Y past it because no wall is there to block. Three candidates for next-session investigation: 1. Different cottage GfxObj (Holtburg cottages may be multi-piece) 2. Landblock-baked stab static at the cottage exterior wall location 3. Cottage GfxObj's visual polygons wider than physics polygons (dat fact) Cheapest next step: add LandblockStatics_DatInspection test that loads LandBlockInfo 0xA9B4FFFE + iterates StaticObjects + prints every entity at world XY in [131,135] x [16,19]. Reveals what other entities live at the cottage doorway. Full 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:
parent
85a164f4a8
commit
da798b2071
3 changed files with 333 additions and 0 deletions
157
docs/research/2026-05-25-door-bug-inside-out-geometry-gap.md
Normal file
157
docs/research/2026-05-25-door-bug-inside-out-geometry-gap.md
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# Door bug — inside-out walkthrough: missing cottage exterior wall (geometry gap)
|
||||
2026-05-25, continuation of door-collision investigation
|
||||
|
||||
## TL;DR
|
||||
|
||||
The inside-out walkthrough that persisted after the
|
||||
`AddAllOutsideCells` fix is **NOT a collision-detection bug**. It's a
|
||||
**collision-geometry GAP**: the cottage's north exterior wall east
|
||||
(and presumably west) of the doorway opening doesn't exist in any
|
||||
registered entity our engine knows about. The sphere walks past the
|
||||
door slab on its east side, clears the doorway alcove cell's small
|
||||
east wall (Y range [16.5, 17.1]), and then has nothing in front of it
|
||||
in the collision representation — even though the VISUAL cottage has
|
||||
a wall there.
|
||||
|
||||
## Apparatus diagnostics
|
||||
|
||||
Three new tests landed (in `DoorBugTrajectoryReplayTests`):
|
||||
|
||||
1. `Directional_OutsideIn_SouthApproach_BlocksAtSlabSouthFace` — sphere
|
||||
south moving north blocks. PASSES.
|
||||
2. `Directional_InsideOut_NorthApproach_BlocksAtSlabNorthFace` — sphere
|
||||
north moving south blocks. PASSES.
|
||||
3. `Geometric_DoorSlabAtSphereHeight_OverlapsInZ` — pins slab world Z
|
||||
range = [94.139, 96.630]; sphere top at Z=95.20 IS within slab.
|
||||
The slab is at sphere height — BSP collision is geometrically active.
|
||||
4. `InsideOut_Tick3254_WithCottageWalls_ShouldBlock` — hypothesis test
|
||||
adds cottage GfxObj 0x01000A2B. Result: cottage DID block but with
|
||||
cn=(0,0,1) — a floor-cap response, NOT a wall response.
|
||||
5. `Diagnostic_CottagePolys_NearWalkthroughPosition` — dumps cottage
|
||||
polygons near sphere XY=(133.655, 17.59), any Z. **Result: ZERO
|
||||
cottage polygons in that area.** The cottage GfxObj has no
|
||||
geometry where the sphere walks through.
|
||||
|
||||
`DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection`
|
||||
extended to dump cell 0xA9B40150's 4 physics polys in world frame:
|
||||
|
||||
```
|
||||
[0] sides=Landblock X=[131.600, 133.500] Y=[16.500, 17.100] Z=[94.000, 94.000] FLOOR
|
||||
[1] sides=Landblock X=[131.600, 131.600] Y=[16.500, 17.100] Z=[94.000, 96.500] WEST WALL
|
||||
[2] sides=Landblock X=[131.600, 133.500] Y=[16.500, 17.100] Z=[96.500, 96.500] CEILING
|
||||
[3] sides=Landblock X=[133.500, 133.500] Y=[16.500, 17.100] Z=[94.000, 96.500] EAST WALL
|
||||
```
|
||||
|
||||
Cell 0xA9B40150 is the **doorway alcove** — a small ~1.9m × 0.6m × 2.5m
|
||||
volume between the cottage interior and the outdoor area. Its east wall
|
||||
only extends Y=[16.5, 17.1]. **North of Y=17.1, no wall** in this cell.
|
||||
|
||||
The captured failing sphere at (133.655, 17.59) is 0.155m east of the
|
||||
east wall AND 0.49m NORTH of the wall's Y range. The wall doesn't
|
||||
reach the sphere.
|
||||
|
||||
## The collision-geometry gap
|
||||
|
||||
Visual representation (in-client):
|
||||
- Cottage has a north exterior wall east and west of the doorway opening
|
||||
- The wall extends Y > 17.1 (north of the alcove)
|
||||
- User sees their character partially clipping into this wall
|
||||
|
||||
Collision representation (what we register):
|
||||
- Cottage GfxObj 0x01000A2B: **0 polygons** in the area (133.655, 17.59, 94-95.20)
|
||||
- Cell 0xA9B40150 (alcove): walls only at Y=[16.5, 17.1]
|
||||
- Door slab: only spans X=[131.635, 133.560] — too narrow to cover the cottage opening
|
||||
- Outdoor cell 0xA9B40029: outdoor cell, no walls
|
||||
|
||||
**Net: no entity has wall polygons at (133.655, Y > 17.1).** Sphere can
|
||||
walk there freely.
|
||||
|
||||
## Verification in production capture
|
||||
|
||||
`door-fix-inout2.launch.log` shows:
|
||||
- Cottage GfxObj `[bsp-test]` fires 425 times during inside-out walking
|
||||
(so visibility is correct post-fix)
|
||||
- Door slab `[bsp-test]` fires 245 times
|
||||
- Captured tick 3254: sphere at (133.655, 17.590), target (133.549,
|
||||
17.599). Result: position X=133.655 unchanged (blocked westward),
|
||||
position Y=17.599 (moved north freely). cn=(+1, 0, 0) = slab east
|
||||
face normal.
|
||||
- The slab east face blocks WEST motion correctly. The sphere is FREE
|
||||
to move north because no geometry covers (133.655, Y > 17.1).
|
||||
|
||||
## What's next
|
||||
|
||||
**Identify which entity SHOULD own the cottage's north exterior wall
|
||||
east of the doorway.** Three candidates:
|
||||
|
||||
1. **A different cottage GfxObj.** Holtburg cottages might be
|
||||
multi-piece (separate GfxObjs for wall sections, doorway frame, roof).
|
||||
The cottage we have (0x01000A2B) might be one of multiple. Check
|
||||
the landblock's static-entity list for other GfxObjs at the cottage
|
||||
position via `[entity-source]` log + Setup file.
|
||||
|
||||
2. **A landblock-baked "stab"** (separate static entity registered at
|
||||
spawn time). LandblockLoader produces these. Check `LandBlockInfo`
|
||||
dat record for landblock 0xA9B4 — what other entities are at world
|
||||
(~133, ~18)?
|
||||
|
||||
3. **The cottage GfxObj's drawing geometry is wider than its physics.**
|
||||
If 0x01000A2B has `Polygons` (visual) at the wall location but no
|
||||
`PhysicsPolygons` (collision), the visual is wider than the
|
||||
collision. This is a dat-data fact — not fixable without retail
|
||||
re-engineering of the dat.
|
||||
|
||||
For candidates 1-2, the fix is "register the missing entity." For 3,
|
||||
the bug is dat-side (or retail accepts the same walkthrough we do).
|
||||
|
||||
**Cheapest next-step test:** add a method to
|
||||
`DoorSetupGfxObjInspectionTests` that loads `LandBlockInfo` 0xA9B4FFFE
|
||||
(landblock-baked statics) and prints every static at world XY in
|
||||
[131, 135] × [16, 19]. The output will name what other GfxObjs/Setups
|
||||
are registered at the cottage doorway — if any include the missing
|
||||
wall, we know what to register additionally.
|
||||
|
||||
## Apparatus committed
|
||||
|
||||
- `tests/AcDream.Core.Tests/Physics/DoorBugTrajectoryReplayTests.cs`:
|
||||
faithful door registration, directional collision tests, geometric
|
||||
pin test, cottage GfxObj hypothesis test, cottage polygon dump.
|
||||
- `tests/AcDream.Core.Tests/Physics/DoorSetupGfxObjInspectionTests.cs`:
|
||||
HoltburgCottage_CellPortals_DatInspection extended with cell-poly
|
||||
world-frame dump.
|
||||
|
||||
All tests under `DoorBugTrajectoryReplayTests` and the extended
|
||||
`DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection`
|
||||
PASS (skip on CI when dat dir absent).
|
||||
|
||||
## Pickup prompt for next session
|
||||
|
||||
```
|
||||
A6.P4 door inside-out walkthrough: identified as collision-geometry
|
||||
gap, NOT collision-detection bug. The cottage's north exterior wall
|
||||
east+west of the doorway opening isn't represented in any registered
|
||||
entity. Sphere walks freely at (133.655, 17.59) — no wall to block.
|
||||
|
||||
Read docs/research/2026-05-25-door-bug-inside-out-geometry-gap.md
|
||||
+ Diagnostic_CottagePolys_NearWalkthroughPosition test output
|
||||
+ HoltburgCottage_CellPortals_DatInspection dump for cell 0x0150
|
||||
|
||||
State both altitudes:
|
||||
Currently working toward: M1.5 — Indoor world feels right
|
||||
Current phase: A6.P4 door bug — find missing cottage wall entity.
|
||||
The fix isn't in BSP, cells, or AddAllOutsideCells
|
||||
— those are correct. The collision geometry has a
|
||||
gap. Need to identify which entity SHOULD own the
|
||||
wall and register it.
|
||||
|
||||
First move: add a LandblockStatics_DatInspection test to
|
||||
DoorSetupGfxObjInspectionTests that loads LandBlockInfo 0xA9B4FFFE
|
||||
+ iterates StaticObjects. Print every entity at world XY in
|
||||
[131, 135] x [16, 19] — name + setup id + position. Will reveal
|
||||
what other entities (if any) live at the cottage doorway.
|
||||
|
||||
If a wall-bearing entity exists but we're not registering it: fix
|
||||
the registration path. If nothing exists: the dat doesn't have the
|
||||
wall, and this might be retail-faithful behavior we have to accept
|
||||
(or compensate for by widening the door slab via gameplay layer).
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue