perf(physics): reuse reset-complete transition scratch
Mirror retail's ten-deep LIFO transition lifetime, retain all query scratch with complete reset contracts, and remove Tier-0 enum boxing without changing collision decisions. Fresh and retained engines are bit-identical across the expanded oracle, while measured transition profiles now allocate 0 bytes per resolve.
This commit is contained in:
parent
2effba5127
commit
16d182c2f0
19 changed files with 3037 additions and 1228 deletions
108
docs/research/2026-07-25-slice-i1-transition-scratch.md
Normal file
108
docs/research/2026-07-25-slice-i1-transition-scratch.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Slice I1 — reset-complete transition and query scratch
|
||||
|
||||
**Status:** COMPLETE
|
||||
**Parent:** `docs/plans/2026-07-25-modern-runtime-slice-i.md`
|
||||
**Scope:** storage lifetime and allocation only; retail collision math,
|
||||
comparisons, branch order, traversal order, and returned behavior are
|
||||
unchanged.
|
||||
|
||||
## Retail lifetime carried forward
|
||||
|
||||
Named retail establishes a retained, stack-disciplined transition lifetime:
|
||||
|
||||
- `CTransition::makeTransition` `0x0050B150`
|
||||
- `CTransition::cleanupTransition` `0x00509DC0`
|
||||
- `CTransition::init` `0x00509DD0`
|
||||
- `COLLISIONINFO::init` `0x00509D60`
|
||||
- `SPHEREPATH::init` `0x0050C330`
|
||||
|
||||
Retail owns ten pre-existing `CTransition` records, selects one by nesting
|
||||
depth, resets it before use, and releases it in LIFO order. The acdream port
|
||||
now gives each `PhysicsEngine` the same ten-deep, same-thread lease contract.
|
||||
`ResolveWithTransition` and `ResolvePlacement` always return their lease in a
|
||||
`finally` block.
|
||||
|
||||
## Storage changes
|
||||
|
||||
- `ObjectInfo`, `CollisionInfo`, `SpherePath`, and `Transition` have complete
|
||||
`ResetForReuse` contracts.
|
||||
- Fixed sphere objects, collision GUID storage, exact-length walkable buffers,
|
||||
candidate-cell storage, and reentrant ordered-cell lists retain identity.
|
||||
Every logical value and retained buffer content is reset before reuse.
|
||||
- Neighboring-cell scans use a retained LIFO list arena. This is required
|
||||
because a cell collision may recursively enter step-up/step-down and another
|
||||
`CheckOtherCells` before the outer scan resumes.
|
||||
- `BSPQuery.CollisionSphere` is value/ref scratch instead of a short-lived
|
||||
reference object.
|
||||
- Terrain's always-three-vertex surface sample is stored inline. Production
|
||||
BSP entry points take center/radius values directly instead of constructing
|
||||
temporary DAT `Sphere` objects.
|
||||
- `CellTransit` reuses the transition-owned ordered/deduplicated candidate
|
||||
collection.
|
||||
- Walkable publication to `PhysicsBody` reuses only an exact-length backing
|
||||
array; a real polygon-size change replaces it.
|
||||
- Hot enum predicates use equivalent bit masks. This removes Tier-0
|
||||
`Enum.HasFlag` boxing while preserving the exact branch condition.
|
||||
|
||||
The wider collision oracle exposed the reentrant-cell-list hazard before
|
||||
landing: three Facility Hub corridor seam replays initially threw
|
||||
`Collection was modified`. The final LIFO query arena keeps every nested
|
||||
scan independent; all three exact seam replays pass.
|
||||
|
||||
## Differential and structural evidence
|
||||
|
||||
`TransitionScratchResetTests`:
|
||||
|
||||
- reflection-poisons every stored member;
|
||||
- resets and compares the complete logical graph with a fresh transition;
|
||||
- proves sphere, child, list, candidate, and walkable-buffer identities are
|
||||
retained while their values are cleared;
|
||||
- proves exact-length walkable reuse and replacement on a true size change;
|
||||
- proves ten distinct nested leases, capacity rejection, LIFO enforcement,
|
||||
same-thread enforcement, and clean reuse.
|
||||
|
||||
`TransitionScratchDifferentialTests` runs a fresh-transition engine beside the
|
||||
production retained engine and compares every `ResolveResult` float by bits
|
||||
plus every public `PhysicsBody` side effect. The hostile alternating sequence
|
||||
covers:
|
||||
|
||||
- successful and failed transitions;
|
||||
- grounded and airborne movement;
|
||||
- wall collision and carried sliding state;
|
||||
- step-up and step-down inputs;
|
||||
- two-sphere characters;
|
||||
- one-sphere projectiles;
|
||||
- viewer/camera sweeps;
|
||||
- placement overlap search;
|
||||
- different mover and designated-target identities.
|
||||
|
||||
The fixed graph oracle, including corridor seams, cellar, doors, projectiles,
|
||||
camera, stairs, cylinder/sphere families, and the new I1 gates, is
|
||||
**118 passed / 0 skipped / 0 failed**.
|
||||
|
||||
## Allocation result
|
||||
|
||||
Release, one thread, 256 warmups and 4,096 measured resolves per profile:
|
||||
|
||||
| Profile | I0 graph baseline | I1 retained scratch |
|
||||
|---|---:|---:|
|
||||
| player, two spheres | 4,448 B/resolve | **0 B/resolve** |
|
||||
| remote, two spheres | 4,448 B/resolve | **0 B/resolve** |
|
||||
| projectile, one 5 cm sphere | 6,848 B/resolve | **0 B/resolve** |
|
||||
| camera/viewer, one 30 cm sphere | 2,512 B/resolve | **0 B/resolve** |
|
||||
| grounded walkable publication | not isolated | **0 B/resolve** |
|
||||
|
||||
This is an isolated transition/query-scratch gate. Optional diagnostics and
|
||||
capture remain intentionally allocating, and the ordinary connected
|
||||
frame-allocation profile is repeated at Slice I7 after flat-asset cutover.
|
||||
|
||||
## Release gates
|
||||
|
||||
- focused collision oracle: **118 passed**
|
||||
- complete Core tests: **3,250 passed / 2 skipped**
|
||||
- `dotnet build AcDream.slnx -c Release --no-restore`: **passed**
|
||||
- complete solution tests: **8,342 passed / 5 skipped**
|
||||
|
||||
Issue #237 is closed. Slice I2 begins with immutable Core-only flat collision
|
||||
records and deterministic source-graph flattening; the current graph traversal
|
||||
remains the executable behavior oracle.
|
||||
Loading…
Add table
Add a link
Reference in a new issue