docs(physics): Phase L.2 movement collision conformance plan
Formalize Phase L.2 as the active holistic movement/collision program, align the roadmap and architecture docs, file tactical physics follow-ups, and refresh collision memory away from rewrite-from-zero guidance. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
e44d24cec6
commit
d4c3f947d2
6 changed files with 689 additions and 242 deletions
|
|
@ -1,131 +1,128 @@
|
|||
# Collision System Port — Status and Plan
|
||||
# Collision System Port - Status and Plan
|
||||
|
||||
## Current State (2026-04-14)
|
||||
## Current State (2026-04-29)
|
||||
|
||||
The collision system has been patched multiple times but does NOT match
|
||||
retail. The user has explicitly requested a **full faithful port** of
|
||||
the retail collision system — no shortcuts, no simplifications.
|
||||
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:
|
||||
|
||||
## What Went Wrong
|
||||
- `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.
|
||||
- `ShadowObjectRegistry` gives the resolver a broadphase over nearby objects.
|
||||
- `TerrainSurface` uses triangle-aware terrain contact.
|
||||
|
||||
Instead of porting the decompiled code line-by-line (as CLAUDE.md
|
||||
mandates), I wrote simplified approximations:
|
||||
- Static overlap instead of swept-sphere FindTimeOfCollision
|
||||
- Custom FindObjCollisions instead of porting Sphere.IntersectsSphere
|
||||
- Custom BSP query instead of porting BSPTree.find_collisions dispatcher
|
||||
- Ad-hoc push-out instead of proper SlideSphere crease-projection
|
||||
- Incremental patches that don't address root architectural issues
|
||||
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:
|
||||
|
||||
Each patch fixed one symptom but introduced new edge cases. The result
|
||||
is a patchwork that handles ~60-70% of cases but fails on the rest.
|
||||
- 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
|
||||
|
||||
## What Must Happen Next
|
||||
## Durable Lesson
|
||||
|
||||
**Delete the existing collision code and start fresh.** Port from ACE's
|
||||
complete C# implementation, cross-referencing the decompiled code for
|
||||
ground truth. ACE has the ENTIRE system already in C#:
|
||||
Do not guess at AC physics, movement packets, terrain/cell ownership, or
|
||||
collision constants. The previous patchwork failures came from simplified
|
||||
approximations:
|
||||
|
||||
### Files to port from ACE (in order):
|
||||
- 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
|
||||
|
||||
1. **Sphere.cs** — `IntersectsSphere` (FUN_005387c0), `SlideSphere` (both variants), `StepSphereUp`, `StepSphereDown`, `LandOnSphere`, `CollideWithPoint`, `CollidesWithSphere`
|
||||
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.
|
||||
|
||||
2. **BSPTree.cs** — `find_collisions` (6-path dispatcher)
|
||||
## Active Approach
|
||||
|
||||
3. **BSPNode.cs** — `sphere_intersects_poly` (tree traversal with movement), `find_walkable`, `hits_walkable`, `sphere_intersects_solid`
|
||||
Continue by conformance lanes rather than rewriting blindly:
|
||||
|
||||
4. **BSPLeaf.cs** — leaf-level polygon tests
|
||||
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.
|
||||
|
||||
5. **Polygon.cs** — `pos_hits_sphere`, `adjust_sphere_to_plane`, `check_walkable`
|
||||
## What To Preserve
|
||||
|
||||
6. **Transition.cs** — `FindTransitionalPosition`, `TransitionalInsert`, `StepUp`, `StepDown`, `ValidateTransition`, `AdjustOffset`
|
||||
- `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.
|
||||
|
||||
7. **SpherePath.cs** — `SetCheckPos`, `AddOffsetToCheckPos`, `CacheLocalSpaceSphere`, `SetCollide`, `SetWalkable`, `SetNegPolyHit`
|
||||
## Known Gaps
|
||||
|
||||
8. **CollisionInfo.cs** — `SetContactPlane`, `SetSlidingNormal`, `SetCollisionNormal`
|
||||
- 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.
|
||||
|
||||
9. **ObjectInfo.cs** — `ValidateWalkable`
|
||||
## Retail Anchors
|
||||
|
||||
10. **LandCell.cs** — `FindEnvCollisions` (outdoor terrain)
|
||||
Primary:
|
||||
|
||||
11. **EnvCell.cs** — `FindEnvCollisions` (indoor BSP)
|
||||
- `docs/research/named-retail/acclient_2013_pseudo_c.txt`
|
||||
- `docs/research/named-retail/acclient.h`
|
||||
- `docs/research/named-retail/symbols.json`
|
||||
|
||||
12. **ObjCell.cs** — `FindObjCollisions`, `find_cell_list`
|
||||
Key names:
|
||||
|
||||
### ACE source locations:
|
||||
- `references/ACE/Source/ACE.Server/Physics/Sphere.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/BSP/BSPTree.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/BSP/BSPNode.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/BSP/BSPLeaf.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/Polygon.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/Transition.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/SpherePath.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/Collision/CollisionInfo.cs`
|
||||
- `references/ACE/Source/ACE.Server/Physics/Collision/ObjectInfo.cs`
|
||||
- `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`
|
||||
|
||||
### Decompiled ground truth (named-retail is now primary, 2026-04-25):
|
||||
- **`docs/research/named-retail/acclient_2013_pseudo_c.txt`** — grep for
|
||||
`BSPTree::`, `BSPNode::`, `BSPLeaf::`, `CPolygon::`, `CCylSphere::`,
|
||||
`Transition::`, `CPhysicsObj::`, `SpherePath::` to find named bodies.
|
||||
- **`docs/research/named-retail/acclient.h`** — verbatim retail struct
|
||||
layouts for the BSP / Sphere / Transition types.
|
||||
- **`docs/research/named-retail/symbols.json`** — name↔address lookup.
|
||||
- `docs/research/decompiled/chunk_00530000.c` — older Ghidra fallback for
|
||||
BSP / Polygon / Sphere collision (FUN_xxx names).
|
||||
- `docs/research/decompiled/chunk_00500000.c` — older Ghidra fallback for
|
||||
PhysicsObj / transition callers.
|
||||
- `docs/research/acclient_function_map.md` — hand-curated cross-port index
|
||||
(ACE / ACME mappings + struct-offset notes).
|
||||
Older fallback:
|
||||
|
||||
### Pseudocode (already written):
|
||||
- `docs/research/transition_pseudocode.md` — full system documented
|
||||
- `docs/research/decompiled/chunk_00530000.c`
|
||||
- `docs/research/decompiled/chunk_00500000.c`
|
||||
- `docs/research/acclient_function_map.md`
|
||||
|
||||
## What to Keep
|
||||
Reference aids:
|
||||
|
||||
- `CollisionPrimitives.cs` — 9 low-level functions already faithfully ported from decompiled code. These are CORRECT and match retail.
|
||||
- `PhysicsDataCache.cs` — GfxObj/Setup/CellStruct physics data loading from dats. Correct.
|
||||
- `ShadowObjectRegistry.cs` — cell-based spatial index. Correct concept, may need refinement.
|
||||
- `TransitionTypes.cs` data structures — SpherePath, CollisionInfo, ObjectInfo, PhysicsGlobals. Mostly correct, may need field additions.
|
||||
- `PhysicsBody.cs` — Euler integration. Correct.
|
||||
- `MotionInterpreter.cs` — Motion state machine. Correct.
|
||||
- `PlayerWeenie.cs` — Run/Jump formulas. Correct.
|
||||
- `references/ACE/Source/ACE.Server/Physics/`
|
||||
- `references/holtburger/` for movement wire behavior
|
||||
- `references/AC2D/` for the older client-side movement packet reference
|
||||
|
||||
## What to Replace
|
||||
## Mandatory Workflow
|
||||
|
||||
- `BSPQuery.cs` — replace with faithful port of BSPTree/BSPNode/BSPLeaf
|
||||
- `TransitionTypes.cs` Transition methods — replace FindTransitionalPosition, TransitionalInsert, FindEnvCollisions, FindObjCollisions, SlideSphere, AdjustOffset with faithful ports
|
||||
- `PhysicsEngine.ResolveWithTransition` — may need restructuring
|
||||
For every AC-specific function:
|
||||
|
||||
## Approach (MANDATORY — per CLAUDE.md)
|
||||
|
||||
For EVERY function:
|
||||
|
||||
1. **GREP NAMED FIRST, then DECOMPILE FALLBACK.** Search the named
|
||||
retail decomp first: `grep -n "ClassName::Method" docs/research/named-retail/acclient_2013_pseudo_c.txt`.
|
||||
For struct layouts: `grep -n "^struct ClassName" docs/research/named-retail/acclient.h`.
|
||||
Only if the named pseudo-C lacks a function (rare), fall back to the
|
||||
older `docs/research/decompiled/` chunks via the function map at
|
||||
`docs/research/acclient_function_map.md`.
|
||||
|
||||
2. **CROSS-REFERENCE ACE.** Read ACE's C# port of the same function.
|
||||
ACE provides naming and structure. Note any differences.
|
||||
|
||||
3. **WRITE PSEUDOCODE.** Translate the decompiled C into readable
|
||||
pseudocode BEFORE porting to C#. Add to
|
||||
`docs/research/collision_port_pseudocode.md`.
|
||||
|
||||
4. **PORT FAITHFULLY.** Translate pseudocode to C# line-by-line.
|
||||
Same variable names, same control flow, same boundary conditions.
|
||||
Do NOT "improve" or "simplify" the algorithm.
|
||||
|
||||
5. **VERIFY.** When ACE and the decompiled code disagree, the
|
||||
decompiled code wins. Document the difference.
|
||||
|
||||
### Execution order:
|
||||
|
||||
1. Sphere collision (Sphere.cs) — FUN_005387c0 and sub-functions
|
||||
2. BSP tree (BSPTree/Node/Leaf) — find_collisions dispatcher
|
||||
3. Polygon tests (Polygon.cs) — pos_hits_sphere, adjust_sphere_to_plane
|
||||
4. Transition orchestrator (Transition.cs) — FindTransitionalPosition
|
||||
5. Cell collision (LandCell/EnvCell/ObjCell) — FindEnvCollisions, FindObjCollisions
|
||||
6. Wire into PhysicsEngine.ResolveWithTransition
|
||||
7. Test: terrain → indoor walls → objects → step-up → every object type
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue