3.6 KiB
Prepared indoor transit regression
Date: 2026-07-26 Scope: Slice-I prepared collision consumer correction Behavioral boundary: No collision formula, portal rule, or renderer behavior changed. This restores the existing retail traversal over the production flat representation.
Symptom and connected evidence
After the Slice-I parsed-graph removal, entering houses or dungeons could:
- collide with empty space at a doorway or room boundary;
- retain the wrong indoor cell on stairs or upper floors;
- expose the world background through the interior portal view.
The connected capture at
.test-out/indoor-visibility-20260726-220007/stdout.log placed the player in
Holtburg cottage vestibule 0xA9B40150, with the chase-camera eye outside the
doorway in outdoor landcell 0xA9B40029. The original DAT graph advanced the
camera transition from 0xA9B40150 to 0xA9B40029. The prepared production
path retained 0xA9B40150, causing collision and portal rendering to share
the same wrong viewer-cell root.
Retail oracle
Named retail:
CEnvCell::find_transit_cells @ 0x0052C820CObjCell::find_cell_listCEnvCell::find_visible_child_cell
Consolidated pseudocode:
acclient_indoor_transitions_pseudocode.md.
For each CCellPortal, retail reads that portal's polygon plane from the
owning CCellStruct. An exterior portal admits outdoor cells when any path
sphere straddles the plane. An interior portal tests the loaded neighbor's
cell-containment BSP, using the plane only as an unloaded-cell hint.
Root cause
The prepared package was complete:
FlatEnvCellTopology.Portals[i].PolygonIndexretained the direct portal polygon index;FlatCellStructureCollisionAsset.PortalPolygonsretained the exact plane;- prepared containment and physics BSPs matched the original DAT graph.
CellTransit.FindTransitCellsSphere, however, still began with:
if currentCell.PortalPolygons is null: return
PortalPolygons is the old parsed-DAT dictionary and is intentionally null in
production after Slice I7. Therefore every prepared indoor cell skipped its
entire portal loop. The I4/I5 differential referee covered BSP queries and
complete resolver results, but did not exercise portal-plane lookup after the
parsed graph had been removed, allowing the representation-boundary defect to
escape.
Correction
CellTransit now resolves the exact same portal plane from:
- the parsed dictionary in explicit graph-oracle fixtures; or
- the prepared topology's direct polygon index and flat polygon table in production.
Prepared topology/list mismatches and invalid polygon indices fail loudly as corrupt publication rather than silently disabling indoor traversal. Portal iteration order, comparisons, sphere transforms, neighbor containment, and outside admission remain unchanged.
Automated evidence
- Synthetic prepared exterior-portal test with no parsed polygon dictionary.
- Synthetic prepared loaded-neighbor test with no parsed containment tree.
- Exact connected Holtburg cottage camera path:
graph and prepared paths both end in
0xA9B40029at identical position. - Installed-DAT graph/flat coverage expanded across the Holtburg cottage and inn vestibules, connectors, stairwell, upper floor, and inn shell.
- Physics-focused Release tests: 1,778 passed / 1 skipped.
- Interaction/projection focused App tests: 127 passed.
- Client-object ordering tests: 82 passed.
- Complete Release build: passed with zero warnings.
No divergence-register row is required: the correction removes an accidental production divergence and introduces no replacement behavior.