acdream/tests/AcDream.Core.Tests/Fixtures/door-bug/live-capture.jsonl
Erik 28cd97be62 fix(phys): A6.P4 door bug — AddAllOutsideCells coord convention + replay apparatus
CellTransit.AddAllOutsideCells assumed sphere coords were absolute world
coords (subtracting lbXf = 0xA9 * 192 = 32448 from the sphere position).
Production has used landblock-local coords since Phase A.1
(streaming-center landblock at world origin), so the subtraction
produced localX = -32316, gridX = -1346 → out-of-range → early return
→ ZERO outdoor cells added.

For outdoor primary cells the bug was masked by GetNearbyObjects's
radial sweep. For indoor primary cells (where #98 gates the outdoor
sweep), the door's outdoor cell 0xA9B40029 never reached
portalReachableCells, the door's BSP was never queried, and the player
walked through Holtburg cottage doors unimpeded.

Fix: AddAllOutsideCells treats worldSphereCenter as landblock-local
directly. Matches retail CLandCell::add_all_outside_cells which uses
the per-cell 6-byte landblock-relative position struct.

Existing CellTransitAddAllOutsideCellsTests + CellTransitFindCellSetTests
updated to use landblock-local sphere coords (they were the only callers
using the world-coord convention; production never did).

Apparatus shipped:
- DoorBugTrajectoryReplayTests — live-capture-driven replay harness
  that pinpointed the bug per-field at unit-test speed (<500ms iteration)
- AddAllOutsideCells_LandblockLocalSphere_AddsDoorOutdoorCell — direct
  unit test that demonstrates the fix
- FindTransitCellsSphere_IndoorExitPortal_AddsOutsideForCapturedSpherePos
  — verifies cell-portal traversal at the captured sphere position
- DoorSetupGfxObjInspectionTests.HoltburgCottage_CellPortals_DatInspection
  — dat-direct EnvCell + Environment.Cells + portal-poly inspector
- Fixture: tests/AcDream.Core.Tests/Fixtures/door-bug/live-capture.jsonl
  (tick 13558 walkthrough + tick 22760 outdoor block)

Visual verification (user-driven at Holtburg cottage door, ~50cm off-center):
- outside→inside RUN: now BLOCKS (was: walks through)
- outside→inside WALK: presumed blocks (not retested)
- inside→outside RUN: PARTIAL — body intersects door, sphere slides through
- inside→outside WALK: same partial behavior

The remaining inside→outside asymmetry is a SEPARATE bug in BSP
collision response for two-sided polygons. The [bsp-test] probe now
fires 245 times for the door entity from indoor (was 0 pre-fix) —
door IS being queried; the BSP polygon-level collision response is
the new bug. Handoff at
docs/research/2026-05-25-door-bug-partial-fix-shipped.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 07:53:34 +02:00

2 lines
4 KiB
JSON

{"tick":13558,"timestampMs":54680488,"input":{"currentPos":{"x":132.36032,"y":16.811314,"z":94},"targetPos":{"x":132.4347,"y":17.204084,"z":94},"cellId":2847146320,"sphereRadius":0.48,"sphereHeight":1.2,"stepUpHeight":0.6,"stepDownHeight":1.5,"isOnGround":true,"moverFlags":768,"movingEntityId":1000000},"bodyBefore":{"position":{"x":132.4347,"y":17.204084,"z":94},"orientation":{"isIdentity":false,"x":-0,"y":-0,"z":-0.09343648,"w":0.99562526},"velocity":{"x":2.2044106,"y":11.641261,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":0,"z":1},"d":-94},"contactPlaneCellId":2847146320,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":0,"z":1},"d":-94},"walkableVertices":[{"x":131.6,"y":17.1,"z":94},{"x":131.6,"y":16.5,"z":94},{"x":133.5,"y":16.5,"z":94},{"x":133.5,"y":17.1,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0},"result":{"position":{"x":132.4347,"y":17.204084,"z":94},"cellId":2847146320,"isOnGround":true,"collisionNormalValid":false,"collisionNormal":{"x":0,"y":0,"z":0}},"bodyAfter":{"position":{"x":132.4347,"y":17.204084,"z":94},"orientation":{"isIdentity":false,"x":-0,"y":-0,"z":-0.09343648,"w":0.99562526},"velocity":{"x":2.2044106,"y":11.641261,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":0,"z":1},"d":-94},"contactPlaneCellId":2847146320,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":0,"z":1},"d":-94},"walkableVertices":[{"x":131.6,"y":17.1,"z":94},{"x":131.6,"y":16.5,"z":94},{"x":133.5,"y":16.5,"z":94},{"x":133.5,"y":17.1,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0}}
{"tick":22760,"timestampMs":54721581,"input":{"currentPos":{"x":133.13905,"y":18.018276,"z":94},"targetPos":{"x":133.1034,"y":17.600323,"z":94},"cellId":2847146025,"sphereRadius":0.48,"sphereHeight":1.2,"stepUpHeight":0.6,"stepDownHeight":1.5,"isOnGround":true,"moverFlags":768,"movingEntityId":1000000},"bodyBefore":{"position":{"x":133.1034,"y":17.600323,"z":94},"orientation":{"isIdentity":false,"x":-0,"y":-0,"z":-0.9990943,"w":-0.042551227},"velocity":{"x":-1.0073924,"y":-11.805234,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":0,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":131,"lastUpdateTime":0},"result":{"position":{"x":133.1034,"y":18.018276,"z":94},"cellId":2847146025,"isOnGround":true,"collisionNormalValid":true,"collisionNormal":{"x":0,"y":1,"z":0}},"bodyAfter":{"position":{"x":133.1034,"y":17.600323,"z":94},"orientation":{"isIdentity":false,"x":-0,"y":-0,"z":-0.9990943,"w":-0.042551227},"velocity":{"x":-1.0073924,"y":-11.805234,"z":0},"acceleration":{"x":0,"y":0,"z":0},"omega":{"x":0,"y":0,"z":0},"groundNormal":{"x":0,"y":0,"z":1},"slidingNormal":{"x":0,"y":1,"z":0},"contactPlaneValid":true,"contactPlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"contactPlaneCellId":2847146025,"contactPlaneIsWater":false,"walkablePolygonValid":true,"walkablePlane":{"normal":{"x":0,"y":-0,"z":1},"d":-94},"walkableVertices":[{"x":144,"y":0,"z":94},{"x":144,"y":24,"z":94},{"x":120,"y":24,"z":94}],"walkableUp":{"x":0,"y":0,"z":1},"elasticity":0.05,"friction":0.95,"state":1040,"transientState":135,"lastUpdateTime":0}}