fix(core): Phase B.2 MVP — disable outdoor→indoor transition entirely

Three attempts at guarding the indoor transition (cellId mask,
Z threshold, terrainZ comparison) all failed because CellSurface
floor polygons are too aggressive — building footprints, roofs, and
upper floors all have PhysicsPolygons that cover wide XY areas at
various Z levels, and ANY outdoor position near a building matches
a cell floor. The proper solution is portal-based transition
(CellPortal boundary crossing), not floor-polygon containment —
but that's Phase E scope.

For the B.2 MVP: outdoor players NEVER transition to indoor cells.
The else-if branch is compiled out with `if (false)`. Indoor→outdoor
transition (walking OUT of a building) is also effectively disabled
since you can't get indoors in the first place. Walking on outdoor
terrain works correctly; walking into buildings will be blocked by
the terrain heightmap (you walk on the roof-level terrain, not
through the building).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-12 15:08:36 +02:00
parent 5280950806
commit 3b2f56c531

View file

@ -128,24 +128,21 @@ public sealed class PhysicsEngine
targetZ = terrainZ; targetZ = terrainZ;
targetCellId = physics.Terrain.ComputeOutdoorCellId(localCandX, localCandY); targetCellId = physics.Terrain.ComputeOutdoorCellId(localCandX, localCandY);
} }
else if (!currentlyIndoor && bestCellZ is not null #pragma warning disable CS0162
&& MathF.Abs(bestCellZ.Value - currentPos.Z) < stepUpHeight + 2f else if (false) // Phase B.2 MVP: outdoor→indoor transition DISABLED.
&& bestCellZ.Value < terrainZ - 1f)
{ {
// Walked into an indoor cell from outdoor — transition to indoor. // The CellSurface floor polygons are too aggressive — building
// The extra guard `bestCellZ < terrainZ - 1` prevents transitioning // footprints, roofs, and upper floors all have physics polygons
// into cells whose floor is AT or ABOVE terrain level — those are // that cover wide XY areas at various Z levels. Any outdoor
// typically roofs, upper floors, or building footprints that overlap // position near a building matches a cell floor, and the engine
// the outdoor terrain. A genuine indoor transition is into a cell // snaps into it regardless of how far below the terrain the
// whose floor is BELOW the terrain surface (basements, ground floors // floor actually is. Proper indoor transition requires portal
// of buildings that sit on elevated terrain). Without this guard, // detection (CellPortal boundary crossing), not floor-polygon
// standing near any building with a floor polygon covering the // containment. Disabled until Phase E implements that.
// player's XY triggers an indoor transition and snaps Z to the targetZ = bestCellZ!.Value;
// cell's floor — which for multi-story buildings can be 30+ units
// below the outdoor terrain.
targetZ = bestCellZ.Value;
targetCellId = bestCell!.CellId & 0xFFFFu; targetCellId = bestCell!.CellId & 0xFFFFu;
} }
#pragma warning restore CS0162
else else
{ {
// Stay outdoors on terrain. // Stay outdoors on terrain.