Replace the outdoor root's single unified reverse-portal flood (whose root-level
portal-side test oscillated as the chase eye grazed a doorway — the measured
flood 2<->6) with retail's per-building floods.
- OutdoorCellNode.Build(uint): portal-less land root; floods only itself ->
full-screen OutsideView -> terrain (PortalVisibilityBuilder IsOutdoorNode seed).
- PortalVisibilityBuilder.ConstructViewBuilding: per-building flood seeded at a
building's own finite entrance (retail ConstructView(CBldPortal) 0x5a59a0 via
DrawPortal 0x5a5ab0 / portal_draw_portals_only 0x53d870). Entrance-bounded ->
consistent ~2-cell depth (measured retail cell_draw_num, handoff OPTION-A 3.4).
- RetailPViewRenderer.DrawInside: when the root is the outdoor node, group nearby
cells by BuildingId and merge each per-building flood into the frame before
assembly; existing shells/object-list draw path unchanged. 48 m seed cutoff.
- GameWindow: pass flat NearbyBuildingCells only on outdoor-node frames.
Tests: +3 PortalVisibilityRobustnessTests (per-building touches ~2 cells, membership
stable under the measured 36 um eye jitter). UnifiedFloodTests retired (its subject,
the unified flood from the outdoor node, is removed); surviving full-screen-OutsideView
coverage moved to OutdoorCellNodeTests. App Rendering 207/207, Core movement 14/14.
Conformance-verified sound; the grazing-doorway flap is the visual acceptance test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace ReferenceEquals(clipRoot, _outdoorNode) object-identity checks with the
documented LoadedCell.IsOutdoorNode flag (4 sites) so they survive R-A2 changing
the outdoor root's portals. Behavior-preserving (build + targeted suites green:
App PortalVisibilityBuilderTests 24/24, Core PlayerMovementControllerTests 14/14).
Right-sized from the planned 'collapse to one root': reading the live dispatch,
the viewerRoot ?? outdoorRoot split is already correct (viewerRoot feeds
cameraInsideCell/lighting via the older CellVisibility BFS; clipRoot is the render
root), and the 2026-06-07 cutover flip already made in-world frames single-path
DrawInside. The real flap fix is R-A2 (per-building floods). Dead exterior
DrawPortal look-in deletion deferred to R-A3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>