feat(physics): add differential flat BSP traversal
Port every current containment, overlap, walkable, and six-path moving-collision query to immutable integer-indexed assets behind a graph-authoritative referee. Exact synthetic, installed-DAT, complete-resolver, and zero-allocation gates prove bit-identical behavior before connected dual publication. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
9cd42417a8
commit
f7ff9f4eea
13 changed files with 3907 additions and 46 deletions
87
docs/research/2026-07-25-slice-i4-flat-bsp-differential.md
Normal file
87
docs/research/2026-07-25-slice-i4-flat-bsp-differential.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue