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