# 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 @ 0x0052C820` - `CObjCell::find_cell_list` - `CEnvCell::find_visible_child_cell` Consolidated pseudocode: [`acclient_indoor_transitions_pseudocode.md`](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].PolygonIndex` retained the direct portal polygon index; - `FlatCellStructureCollisionAsset.PortalPolygons` retained the exact plane; - prepared containment and physics BSPs matched the original DAT graph. `CellTransit.FindTransitCellsSphere`, however, still began with: ```text 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: 1. the parsed dictionary in explicit graph-oracle fixtures; or 2. 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 `0xA9B40029` at 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.