Session 2026-04-14 summary: rendering rebuild complete, movement speed+jump+facing working, collision partially working but needs full retail port. Memory updated with explicit user feedback: no more patching collision, must port from decompiled code faithfully per CLAUDE.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.5 KiB
Collision System Port — Status and Plan
Current State (2026-04-14)
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.
What Went Wrong
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
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.
What Must Happen Next
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#:
Files to port from ACE (in order):
-
Sphere.cs —
IntersectsSphere(FUN_005387c0),SlideSphere(both variants),StepSphereUp,StepSphereDown,LandOnSphere,CollideWithPoint,CollidesWithSphere -
BSPTree.cs —
find_collisions(6-path dispatcher) -
BSPNode.cs —
sphere_intersects_poly(tree traversal with movement),find_walkable,hits_walkable,sphere_intersects_solid -
BSPLeaf.cs — leaf-level polygon tests
-
Polygon.cs —
pos_hits_sphere,adjust_sphere_to_plane,check_walkable -
Transition.cs —
FindTransitionalPosition,TransitionalInsert,StepUp,StepDown,ValidateTransition,AdjustOffset -
SpherePath.cs —
SetCheckPos,AddOffsetToCheckPos,CacheLocalSpaceSphere,SetCollide,SetWalkable,SetNegPolyHit -
CollisionInfo.cs —
SetContactPlane,SetSlidingNormal,SetCollisionNormal -
ObjectInfo.cs —
ValidateWalkable -
LandCell.cs —
FindEnvCollisions(outdoor terrain) -
EnvCell.cs —
FindEnvCollisions(indoor BSP) -
ObjCell.cs —
FindObjCollisions,find_cell_list
ACE source locations:
references/ACE/Source/ACE.Server/Physics/Sphere.csreferences/ACE/Source/ACE.Server/Physics/BSP/BSPTree.csreferences/ACE/Source/ACE.Server/Physics/BSP/BSPNode.csreferences/ACE/Source/ACE.Server/Physics/BSP/BSPLeaf.csreferences/ACE/Source/ACE.Server/Physics/Polygon.csreferences/ACE/Source/ACE.Server/Physics/Transition.csreferences/ACE/Source/ACE.Server/Physics/SpherePath.csreferences/ACE/Source/ACE.Server/Physics/Collision/CollisionInfo.csreferences/ACE/Source/ACE.Server/Physics/Collision/ObjectInfo.cs
Decompiled ground truth:
docs/research/decompiled/chunk_00530000.c— BSP, Polygon, Sphere collisiondocs/research/decompiled/chunk_00500000.c— PhysicsObj, transition callersdocs/research/acclient_function_map.md— mapped functions
Pseudocode (already written):
docs/research/transition_pseudocode.md— full system documented
What to Keep
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.csdata 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.
What to Replace
BSPQuery.cs— replace with faithful port of BSPTree/BSPNode/BSPLeafTransitionTypes.csTransition methods — replace FindTransitionalPosition, TransitionalInsert, FindEnvCollisions, FindObjCollisions, SlideSphere, AdjustOffset with faithful portsPhysicsEngine.ResolveWithTransition— may need restructuring
Approach (MANDATORY — per CLAUDE.md)
For EVERY function:
-
DECOMPILE FIRST. Find the matching function in the decompiled client (
docs/research/decompiled/). Use the function map atdocs/research/acclient_function_map.md. If not mapped, search by characteristic constants or struct offsets. -
CROSS-REFERENCE ACE. Read ACE's C# port of the same function. ACE provides naming and structure. Note any differences.
-
WRITE PSEUDOCODE. Translate the decompiled C into readable pseudocode BEFORE porting to C#. Add to
docs/research/collision_port_pseudocode.md. -
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.
-
VERIFY. When ACE and the decompiled code disagree, the decompiled code wins. Document the difference.
Execution order:
- Sphere collision (Sphere.cs) — FUN_005387c0 and sub-functions
- BSP tree (BSPTree/Node/Leaf) — find_collisions dispatcher
- Polygon tests (Polygon.cs) — pos_hits_sphere, adjust_sphere_to_plane
- Transition orchestrator (Transition.cs) — FindTransitionalPosition
- Cell collision (LandCell/EnvCell/ObjCell) — FindEnvCollisions, FindObjCollisions
- Wire into PhysicsEngine.ResolveWithTransition
- Test: terrain → indoor walls → objects → step-up → every object type