110 lines
5.7 KiB
Markdown
110 lines
5.7 KiB
Markdown
# 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
|
|
|
|
```text
|
|
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`.
|
|
- 2026-07-31: #272 burden invalidation. Retail `InqLoad @ 0x0058F130`
|
|
obtains Strength through `InqAttribute @ 0x00591A00`, so carry capacity
|
|
always uses the enchantment-adjusted value. Runtime movement, the indicator
|
|
bar, and the inventory meter must all consume
|
|
`LocalPlayerState.GetEffectiveAttribute(Strength)` and react to the same
|
|
`Spellbook.EnchantmentsChanged` event. That one event covers spell add,
|
|
remove, expiration, dispel, and death purge. Never refresh this through a
|
|
UI-only workaround or wait for a base-attribute packet. The connected
|
|
buff/death gate was user-accepted on 2026-07-31.
|