# Slice I4 - differential flat BSP traversal **Date:** 2026-07-25 **Scope:** Modern Runtime Slice I4 only **Behavioral boundary:** the new integer-indexed traversal is a shadow implementation. The parsed-DAT graph remains production-authoritative until the Slice I5 connected shadow gate and Slice I6 cutover. ## Result `FlatBspQuery` now ports every collision entry point used by the current runtime over immutable, integer-indexed nodes and polygon ranges: - point-in-cell; - sphere/cell overlap; - static sphere/polygon overlap; - swept sphere/polygon time-of-impact; - walkable polygon selection; - solid and solid-polygon traversal; - the complete six-path moving-collision dispatcher. The port preserves retail's traversal order, strict comparisons, early returns, and mutable query state. The positive child remains first where retail visits it first; the negative child observes every valid-sphere, contact, path, slide, and candidate mutation made by the positive child. Only `BSPQuery.PolygonHitsSpherePrecise`, which is independent of graph storage, is shared with the existing graph oracle. `CollisionTraversal` is the narrow temporary referee seam. Production starts in `Graph` mode. Tests can run a cloned complete resolver in `Flat` mode, and a missing flat asset fails explicitly instead of falling back to the graph. Slice I6 removes this representation switch after connected acceptance. ## Retail oracle The implementation follows the consolidated pseudocode and boundary table in [`2026-07-25-slice-i-collision-layout-oracle.md`](2026-07-25-slice-i-collision-layout-oracle.md), including: - `BSPTREE::find_collisions` at `0x0053A440`; - `BSPNODE::point_inside_cell_bsp` at `0x0053C1F0`; - `BSPNODE::sphere_intersects_cell_bsp` at `0x0053C260`; - `BSPNODE::sphere_intersects_poly` at `0x0053CA30`; - `BSPNODE::sphere_intersects_solid` at `0x0053CAF0`; - `BSPNODE::find_walkable` at `0x0053CC80`; - `BSPNODE::sphere_intersects_solid_poly` at `0x0053CD50`; - `BSPLEAF::find_walkable` at `0x0053D6F0`. The same oracle records the cross-checks against ACE master `65f092...` and Chorizite DatReaderWriter `c535987...`. Retail remains the authority where those references differ. ## Differential evidence The referee compares scalar results and all stateful outputs by exact float bits. It covers selected polygons, vectors, planes, path state, collision and object flags, contact-plane writes, final `ResolveResult`, persistent body state, and full cell membership. | Gate | Executions | Result | |---|---:|---:| | Null, on-plane, radius-equality, equal-candidate, multi-polygon, and deep-tree fixtures | 4 focused fixtures | 0 mismatches | | Static and swept overlap randomized sweep | 10,000 paired cases | 0 mismatches | | Walkable randomized sweep | 5,000 paired cases | 0 mismatches | | Six dispatcher paths | 6 complete transition fixtures | 0 mismatches | | Installed-DAT sweep across `0x8A02016E`, `0x8A02017A`, and `0xA9B4013F` | 7,500 randomized cases | 0 mismatches | | Complete graph/flat resolver sequences | 1,200 frames | 0 mismatches | | Warmed flat traversal | 10,000 iterations | 0 managed bytes | The installed-DAT gate randomizes points, spheres, movement, insert paths, orientations, scale, and boundary values. No tolerance band is used. ## Verification - focused differential tests: 13 passed; - complete Core suite: 3,276 passed / 2 skipped; - `git diff --check`: no whitespace errors; - full Release build: passed; - complete Release suite: 8,384 passed / 5 skipped. No divergence-register row changes are required. This slice changes the storage representation exercised by the referee, not production gameplay behavior. Slice I5 next publishes the prepared flat assets alongside the current graph under one landblock generation and runs the connected shadow gate.