acdream/memory/project_movement_collision_conformance.md

5.1 KiB

Movement & Collision Conformance Crib

Phase

Active phase: Campaign P — Physics Retail-Feel Parity (the L.2/R6 foundation is shipped).

Plan: docs/plans/2026-07-29-physics-parity-campaign.md.

Roadmap: docs/plans/2026-04-11-roadmap.md.

One-Sentence Framing

B.3 shipped the MVP resolver foundation; L.2 is the holistic conformance program for physics, collision, buildings, edge/wall sliding, cell ownership, movement packets, and server correction.

Active Movement Spine

InputDispatcher / PlayerMovementController
  -> MotionInterpreter + local body prediction
  -> PhysicsEngine.ResolveWithTransition
  -> TransitionTypes + BSPQuery + ShadowObjectRegistry
  -> ResolveResult contact/cell state
  -> MoveToState / AutonomousPosition outbound messages
  -> WorldSession server echo or correction diagnostics

Lane Ownership

  • L.2a: truth probes, diagnostics, fixture capture.
  • L.2b: movement wire/contact truth, cell id on packets, correction handling.
  • L.2c: transition parity, edge-slide, cliff-slide, precipice-slide, NegPolyHit.
  • L.2d: CSphere / CCylSphere, live entity shapes, building object identity.
  • L.2e: outdoor seams, CELLARRAY, find_cell_list, adjacent-cell checks, cell_bsp, building entry/exit boundaries.
  • L.2f: real-DAT fixtures and live retail-observer conformance.

Non-Negotiables

  • Grep named retail before changing AC-specific physics or movement behavior.
  • Do not treat ACE accepting a position as proof of retail collision parity.
  • Do not reintroduce rewrite-from-zero collision guidance. Continue the partial retail port by L.2 lanes.
  • G.3 dungeon/portal delivery waits on L.2e for trustworthy cell/building ownership.
  • L.1 animation work must coordinate with L.2 when root motion or observer movement changes the predicted body path.

Shipped Slices

  • 2026-04-29: L.2a/L.2b first diagnostic slice. ACDREAM_DUMP_MOVE_TRUTH=1 logs move-truth OUT for outbound MoveToState / AutonomousPosition and move-truth ECHO for player UpdatePosition echoes, including local/server delta. GameWindow now passes explicit grounded/airborne contact bytes from MovementResult.IsOnGround to both movement packet builders.
  • 2026-04-29: L.2e first cell-ownership fix. ResolveWithTransition refreshes outdoor cell ownership from world position during the sphere sweep, so 24m outdoor seams update low cell ids and full-cell callers crossing landblock seams get the destination landblock prefix plus the correct outdoor low cell.
  • 2026-04-30: L.2c edge-slide plumbing. User live-tested wall-adjacent slide as acceptable. Local player and remote dead-reckoning now pass retail-default ObjectInfoState.EdgeSlide; ACDREAM_DUMP_EDGE_SLIDE=1 logs failed step-down edge cases and now reports whether walkable polygon context is present before cliff/precipice handling.
  • 2026-04-30: L.2c precipice-slide context. Named retail SPHEREPATH::precipice_slide and ACE Polygon.find_crossed_edge are now captured in docs/research/2026-04-30-precipice-slide-pseudocode.md. Terrain supplies exact walkable triangle vertices, BSP step-down/find-walkable stores world-space walkable vertices for static object tops, and failed step-down edge cases run the retail back-probe before precipice slide. cliff_slide has a first port, but NegPolyHit, CELLARRAY, full cell_bsp, and real-DAT building portal conformance remain open L.2 work.
  • 2026-04-30: Edge-slide retry-loop lesson. SPHEREPATH::precipice_slide usually returns Slid after applying the tangent offset. That result must be handled inside TransitionalInsert like wall slide (continue and re-test the adjusted CheckPos), not returned to ValidateTransition; the outer validator treats non-OK as a collision and restores CurPos, making edges feel like hard stops even when the tangent was computed.
  • 2026-07-31: Campaign P #269 slope-stop parity. A 2,184-quantum live capture proved the 5% landing reflect and calc_friction were correct, but ValidateTransition restored LastKnownContactPlane without retail's preceding OBJECTINFO::kill_velocity. Retail consumes that plane only on a non-OK recovery and overwrites last-known validity from the final contact plane. Both rules are now ported; focused/full tests and the user's repeated slope-jump gate pass. See docs/research/2026-07-31-269-slope-stop-capture.md.
  • 2026-07-31: #271 stair-side uphill reversal. Never promote ACDream's retained LastWalkable history into retail's current SPHEREPATH::walkable slot inside edge_slide. When current walkable is null, retail CTransition::edge_slide @ 0x0050B3D0 must back-probe at the current sphere center and either use that newly discovered polygon or collide. The stale substitution selected a preceding stair tread, reversed the uphill tangent, and dropped the player rapidly down the stairs. The exact live frame is pinned in Issue185OutdoorStairsSeamReplayTests; Core passes 4,108 / 2 skips and the complete Release solution passes 10,062 / 5 skips. The user accepted repeated uphill stair-side runs on 2026-07-31. See docs/research/2026-07-31-271-stair-side-slide-capture.md.