235 lines
11 KiB
Markdown
235 lines
11 KiB
Markdown
# Collision System Port - Status and Plan
|
||
|
||
## 2026-08-03 production cutover stabilization checkpoint
|
||
|
||
Production initial Create placement is cut over through the Runtime residence
|
||
and continuation-executor path. The O(changed) collision-publication
|
||
checkpoint is live, followed by five root-cause fixes:
|
||
|
||
- `01f4791e`: pending-only live projections no longer create/replay a second
|
||
origin-recenter retirement receipt;
|
||
- `670f307c`: remote Create placement, local-player hosting, targeting, chase,
|
||
and attack share the same world-coordinate frame;
|
||
- `1fc529cd`: distant Use materializes the canonical minimal static host before
|
||
MoveTo;
|
||
- `f24532ad`: effects, projectiles, and static animation bind after canonical
|
||
placement and follow the committed cell;
|
||
- `175ad6b0`: LoginComplete waits for the local first-placement terminal edge.
|
||
|
||
The user accepted those connected behaviors. The campaign remains open for
|
||
six fixture reconciliations, C4 placement routes 2–7, #276/#277, destination
|
||
prefetch #280, C5's final-binary suite/soak/two-client matrix, AP-22, and
|
||
AD-10. Canonical continuation prompt:
|
||
`docs/research/2026-08-02-collision-throughput-handoff/NEXT-AGENT-PROMPT.md`.
|
||
|
||
**Do not use the 2026-04-29 whole-world staging-root description below as a
|
||
production blueprint.** It is retained as historical context. O1/O2/O3 at
|
||
`71604331` replaced that clone/journal/rebase design with the per-landblock
|
||
O(changed) publication mechanism; `01f4791e` then repaired its recenter
|
||
receipt lifetime.
|
||
|
||
## 2026-08-01 initial Create residence checkpoint
|
||
|
||
> Historical checkpoint; superseded by the 2026-08-03 production cutover
|
||
> status above.
|
||
|
||
The dormant Runtime SetPosition path is now complete through activation,
|
||
graphical/no-window placement receipts, collision-prefix quiescence, exact
|
||
authoritative route classification, pre-placement App staging, and initial
|
||
Create residence. Commit `38fd4b8d` owns the accepted initial Create frame,
|
||
cell-less pending lifetime, fresher Position FIFO, exact completion/adoption
|
||
revision, and reentrant teardown. Its retail and continuation handoff is:
|
||
|
||
- `docs/research/2026-08-01-runtime-initial-create-residence-handoff.md`
|
||
|
||
Production Create registration has not yet been cut over. Next, implement the
|
||
synchronous Runtime continuation executor and exact Create tail order
|
||
(visual, Parent/Position/Pickup, Movement, State, Vector, WeenieDesc, cleanup),
|
||
then cut graphical and no-window hosts over together. AP-1/AD-1 remain open
|
||
until that cutover. AP-22 and AD-10 follow as separate behavior slices.
|
||
|
||
## 2026-07-31 placement checkpoint 2
|
||
|
||
Runtime now owns the retail collision-report state required by canonical
|
||
SetPosition: exact-incarnation object-contact tables, the environment latch,
|
||
ordinary/ethereal expiry, force-end ordering, asymmetric object/environment
|
||
report eligibility, missile-state clearing, reentrant ordered reports, and the
|
||
report-result boolean which distinguishes failed-placement `Collided` from
|
||
`NoValidPosition`. Successful dormant SetPosition commits reporting after
|
||
contact/ground state and before its one response plus shadow reflood. The
|
||
named-retail oracle and next-agent instructions are in:
|
||
|
||
- `docs/research/2026-07-31-runtime-set-position-collision-reporting.md`
|
||
- `docs/research/2026-07-31-runtime-set-position-collision-reporting-handoff.md`
|
||
|
||
This checkpoint deliberately does not activate production placement. Next,
|
||
4B2 must prepare exact authored movers and land one atomic Runtime body/local-
|
||
controller transaction, followed by presentation-only host projection,
|
||
collision-prefix quiescence, and an all-route cutover. AP-1 and AD-1 remain
|
||
open until that cutover; AP-22 and AD-10 remain later campaign slices.
|
||
|
||
## Current State (2026-04-29)
|
||
|
||
The collision system is no longer a pure placeholder and should not be treated
|
||
as "delete everything and start over." A partial retail transition port exists:
|
||
|
||
- `PhysicsEngine.ResolveWithTransition` is the active player movement resolver.
|
||
- `BSPQuery` contains a partial retail-style BSP dispatcher.
|
||
- `TransitionTypes` carries the active `SpherePath`, `CollisionInfo`,
|
||
transition, step, contact, and partial slide logic.
|
||
- `PhysicsDataCache` loads GfxObj, Setup, and CellStruct physics data.
|
||
- Landblock streaming never edits the live collision world incrementally.
|
||
`PreparedLandblockCollisionGeneration` owns an off-side cache, CellGraph,
|
||
engine snapshot, buildings, statics, and versioned retained-owner refloods.
|
||
Retained means every non-suspended dynamic or adjacent-root static touching
|
||
(or withdrawn from) the target prefix; only authored target-root statics are
|
||
superseded. Stable per-prefix owner slots bound capture independently of
|
||
unrelated movement. One Runtime-scoped versioned journal records a live
|
||
mutation once, coalesces repeated changes by owner, and lets every draft
|
||
reconcile only that owner's latest exact state one owner per seal step.
|
||
Relevant owners subscribe only after discovery, preserving exact continuous
|
||
updates without the former preparations-by-mutations global fanout or a quiet
|
||
frame. A changed prefix routes first target entry/departure to the one
|
||
matching draft after its journal cursor has passed. During topology build,
|
||
visited unrelated owners receive only coalesced dirty notifications; one
|
||
later seal unit performs the exact mirror. After the topology seal exists,
|
||
observed owners temporarily write through exactly until same-call activation,
|
||
guaranteeing that the finite dirty queue drains under multi-owner motion.
|
||
Old slots are superseded at the tail rather than reused behind
|
||
live cursors, new drafts start at their captured suffix, and obsolete slots
|
||
plus empty prefix containers are reclaimed under churn.
|
||
Admission captures the active aggregate
|
||
root reference in O(1), then stable landblock/owner suffixes materialize the
|
||
non-target cache, CellGraph, engine, and shadow leaves one work unit per host
|
||
step. All scans and replacement construction run
|
||
through bounded preparation/capture/seal cursors. Cache, CellGraph, engine, and shadow
|
||
topology share one complete off-side `CollisionWorldState`; final activation
|
||
is a single zero-allocation volatile root transfer that preserves borrowed
|
||
facade identities and revokes staging. Deterministically ordered concurrent
|
||
preparations queue their deltas into later drafts only after commit; each
|
||
seal call rebases at most one cache/graph/landblock/owner leaf. Demotion or
|
||
withdrawal cancels matching queued/active rebases, suppresses stale source-
|
||
clone leaves, and retires one owner/cache/graph/outdoor leaf per seal step
|
||
from growable storage; commit rechecks pending retirement after sealing.
|
||
The host performs the zero-work root transfer in the same update-thread call
|
||
that completes final reconciliation, avoiding a quiet-frame requirement.
|
||
Cancellation tears down
|
||
only the named staging generation. The old generation remains queryable until
|
||
commit. See
|
||
`docs/research/2026-07-31-atomic-collision-generation.md`.
|
||
- `ShadowObjectRegistry` gives the resolver a broadphase over nearby objects.
|
||
- `TerrainSurface` uses triangle-aware terrain contact.
|
||
|
||
This foundation is useful, but it is not complete retail collision parity.
|
||
The project now tracks the remaining work as Phase L.2 - Movement & Collision
|
||
Conformance:
|
||
|
||
- Plan: `docs/plans/2026-04-29-movement-collision-conformance.md`
|
||
- Roadmap owner: `docs/plans/2026-04-11-roadmap.md`
|
||
- Tactical follow-ups: `docs/ISSUES.md` #30-#34
|
||
|
||
## Durable Lesson
|
||
|
||
Do not guess at AC physics, movement packets, terrain/cell ownership, or
|
||
collision constants. The previous patchwork failures came from simplified
|
||
approximations:
|
||
|
||
- static overlap instead of swept-sphere transition behavior
|
||
- custom object collision instead of retail `CSphere` / `CCylSphere`
|
||
- incomplete BSP dispatch
|
||
- ad-hoc push-out instead of retail slide / edge / precipice handling
|
||
- server "no rubber-band" treated as proof of local collision correctness
|
||
|
||
The named retail decomp is now the primary source. Search
|
||
`docs/research/named-retail/acclient_2013_pseudo_c.txt` by `class::method`
|
||
before using older decompiled chunks or reference repos.
|
||
|
||
## Active Approach
|
||
|
||
Continue by conformance lanes rather than rewriting blindly:
|
||
|
||
1. **Truth & diagnostics (L.2a).** Add local placement/contact/cell,
|
||
object-hit, outbound-packet, server echo, and correction-delta probes.
|
||
2. **Movement wire/contact authority (L.2b).** Fix contact byte and full-cell
|
||
truth before using ACE acceptance as evidence.
|
||
3. **Transition parity (L.2c).** Port edge-slide, cliff-slide,
|
||
precipice-slide, step-up/down slide, and `NegPolyHit` dispatch.
|
||
4. **Shape fidelity (L.2d).** Finish `CSphere` / `CCylSphere` semantics,
|
||
live-entity shapes, and building object identity.
|
||
5. **Cell ownership (L.2e).** Port `CELLARRAY`, `find_cell_list`,
|
||
`check_other_cells`, `adjust_check_pos`, low-cell updates, and `cell_bsp`.
|
||
6. **Real-DAT and live observer conformance (L.2f).** Promote every synthetic
|
||
case to real-world fixtures and retail-observer checks.
|
||
|
||
## What To Preserve
|
||
|
||
- `CollisionPrimitives.cs` low-level helpers, while auditing remaining shape
|
||
gaps against named retail.
|
||
- `PhysicsDataCache.cs` DAT-backed collision data loading.
|
||
- `ShadowObjectRegistry.cs` broadphase concept.
|
||
- `TransitionTypes.cs` data structures and partial transition port.
|
||
- `BSPQuery.cs` partial dispatcher as the current porting surface.
|
||
- `PhysicsBody.cs`, `MotionInterpreter.cs`, and `PlayerWeenie.cs` foundations.
|
||
|
||
## Known Gaps
|
||
|
||
- Full `CELLARRAY` and adjacent-cell ownership are missing.
|
||
- `cell_bsp` is not yet a first-class runtime owner.
|
||
- Building portal transit and building entry/exit collision are incomplete.
|
||
- `edge_slide`, `cliff_slide`, `precipice_slide`, and `NegPolyHit` behavior are
|
||
incomplete.
|
||
- Live entity shape fidelity is simplified.
|
||
- Outbound movement contact/cell fields can be overconfident.
|
||
- Routine local/server correction diagnostics are missing.
|
||
|
||
## Retail Anchors
|
||
|
||
Primary:
|
||
|
||
- `docs/research/named-retail/acclient_2013_pseudo_c.txt`
|
||
- `docs/research/named-retail/acclient.h`
|
||
- `docs/research/named-retail/symbols.json`
|
||
|
||
Key names:
|
||
|
||
- `CTransition::find_transitional_position`
|
||
- `CTransition::transitional_insert`
|
||
- `CTransition::step_up`
|
||
- `CTransition::step_down`
|
||
- `CTransition::edge_slide`
|
||
- `CTransition::cliff_slide`
|
||
- `SPHEREPATH::step_up_slide`
|
||
- `SPHEREPATH::precipice_slide`
|
||
- `SPHEREPATH::adjust_check_pos`
|
||
- `CTransition::check_other_cells`
|
||
- `CObjCell::find_cell_list`
|
||
- `CPhysicsObj::is_valid_walkable`
|
||
- `CBuildingObj::find_building_collisions`
|
||
- `CCellStruct::sphere_intersects_cell`
|
||
- `CCylSphere::intersects_sphere`
|
||
- `CSphere::intersects_sphere`
|
||
- `CSphere::slide_sphere`
|
||
|
||
Older fallback:
|
||
|
||
- `docs/research/decompiled/chunk_00530000.c`
|
||
- `docs/research/decompiled/chunk_00500000.c`
|
||
- `docs/research/acclient_function_map.md`
|
||
|
||
Reference aids:
|
||
|
||
- `references/ACE/Source/ACE.Server/Physics/`
|
||
- `references/holtburger/` for movement wire behavior
|
||
- `references/AC2D/` for the older client-side movement packet reference
|
||
|
||
## Mandatory Workflow
|
||
|
||
For every AC-specific function:
|
||
|
||
1. Grep named retail first.
|
||
2. Cross-reference ACE / holtburger / AC2D where relevant.
|
||
3. Write readable pseudocode before porting.
|
||
4. Port faithfully; do not simplify.
|
||
5. Add conformance tests.
|
||
6. Integrate surgically into the active L.2 lane.
|
||
7. Verify with synthetic tests, real-DAT fixtures, and live observer evidence.
|