Move the canonical local movement controller, body/motion managers, object clock, movement wire data, and MTS/jump/AP sender into AcDream.Runtime. Replace process skill defaults with typed Runtime character options, make graphical and direct commands borrow one autorun owner, retain the construction-time PartArray seam, and include movement in terminal ownership convergence. Preserve the accepted pre-inbound movement/jump and post-inbound autonomous-position order while moving the exact packet/cadence fixtures into Runtime tests. Add graphical/direct parity, two-instance isolation, teardown, allocation, architecture, and divergence-path coverage. Co-authored-by: Codex <noreply@openai.com>
6.2 KiB
Slice J5.4 — canonical local movement ownership
Date: 2026-07-26
Parent: docs/plans/2026-07-26-modern-runtime-slice-j5.md
Scope: ownership relocation only; no movement, collision, animation, or
wire behavior changes
Retail oracle
The named September 2013 client remains the oracle:
| Mechanism | Named symbol | Address / named pseudo-C |
|---|---|---|
| take local control | CommandInterpreter::TakeControlFromServer |
0x006B32D0, lines 699046–699145 |
| apply current raw movement | CommandInterpreter::ApplyCurrentMovement |
0x006B3430, lines 699146–699530 |
| stop decision | CommandInterpreter::MaybeStopCompletely |
0x006B3B90, lines 699531–699563 |
| post-inbound position slot | CommandInterpreter::UseTime |
0x006B3BF0, lines 699564–699645 |
| input command boundary | CommandInterpreter::MovePlayer |
0x006B3F40, lines 699803–700232 |
| AP predicate | CommandInterpreter::ShouldSendPositionEvent |
0x006B45E0, lines 700233–700273 |
| MTS serialization | CommandInterpreter::SendMovementEvent |
0x006B4680, lines 700274–700315 |
| AP serialization | CommandInterpreter::SendPositionEvent |
0x006B4770, lines 700316 onward |
| object/root-motion step | CPhysicsObj::UpdatePositionInternal |
0x00512C30, lines 280817 onward |
| object update envelope | CPhysicsObj::update_object |
0x00515D10, lines 283950 onward |
The detailed wire unpack/pack interpretation and prior ACE/Holtburger cross-checks are retained in:
docs/research/2026-05-04-l3-port/02-um-handling.md;docs/research/2026-05-04-l3-port/14-local-player-audit.md;docs/research/2026-05-01-retail-motion-trace/findings.md;docs/research/2026-07-26-slice-j5-owner-and-retail-order-inventory.md.
The reference source trees are not present in this worktree, so J5.4 reuses those already-recorded cross-checks rather than inventing a new interpretation. No behavioral algorithm is changed by this slice.
Consolidated retail pseudocode
Input / object phase
MovePlayer(command, speed, hold, ...)
if server currently controls movement
TakeControlFromServer()
mutate the player's one RawMotionState / MotionInterpreter
apply the current movement to the same CPhysicsObj
if the movement boundary requires a report
SendMovementEvent()
SendMovementEvent()
require player + SmartBox + raw motion state + autonomous movement
snapshot complete raw motion state
snapshot the player's canonical cell-local Position and contact
snapshot instance/server-control/teleport/force-position sequences
serialize and send MoveToState
stamp only last_sent_position_time after successful send
Jump uses the same pre-inbound input/object phase. The charged extent and body-local launch velocity are read from the canonical local controller and serialized exactly once on release.
Object simulation
UpdatePositionInternal(dt, rootFrame)
apply the animation-authored root frame to the canonical physics body
integrate/transition through the existing retail physics pipeline
commit complete Position, velocity, contact, and cell membership
update_object()
advance the retail object clock in fixed quanta
update movement and physics in retail order
leave one committed canonical body for every later borrower
App animation may supply the authored root frame and consume the committed pose. It does not own a second body, movement state, or object clock.
Post-inbound autonomous position phase
UseTime()
after inbound messages may have corrected the canonical body:
if ShouldSendPositionEvent()
SendPositionEvent()
ShouldSendPositionEvent()
compare current cell/contact against the last AP baseline
after the retail interval, compare the complete current Frame
SendPositionEvent()
snapshot canonical cell-local Position, orientation, contact, timestamps
serialize and send AutonomousPosition
after successful send:
stamp last_sent_position_time
copy complete Position and contact plane into the AP baseline
This preserves the accepted acdream frame order:
- graphical or no-window input becomes a typed
MovementInput; - Runtime mutates the canonical controller/body;
- Runtime emits MTS/jump before inbound dispatch;
- inbound corrections mutate that same body;
- Runtime evaluates/emits AP after inbound dispatch;
- App projects the final committed body to animation, camera, and UI.
Ownership result
PlayerMovementController, its movement data types, andLocalPlayerOutboundControllernow live inAcDream.Runtime.Gameplay.RuntimeLocalPlayerMovementStateis the sole controller, construction motion seam, autorun latch, typed view, and terminal ownership ledger.DispatcherMovementInputSourcesamples physical held state only and maps configured edges onto the Runtime owner.- direct Runtime movement commands and graphical input mutate that same autorun state.
PlayerMovementConstructionOptionsreplaces process environment reads and is populated fromRuntimeMovementSkillState.- the App diagnostic implementation crosses only
IMovementTruthDiagnosticSink. - shutdown retires graphical/session borrowers before disposing the Runtime movement owner.
Preserved boundaries
- Silk input, mouse filtering, camera, CSequence/PartArray presentation, retained jump bar, sounds, and effects remain in App.
PhysicsEngineremains App-owned until J5.5.- remote movement and projectiles remain App-owned until J5.5/J5.6.
- TS-33's already-recorded possible same-update MTS/AP ordering difference is preserved; this ownership move neither widens nor hides it.
Automated evidence required before closeout
- Runtime state/view identity, two-instance isolation, construction lease, terminal convergence, typed movement skills, and zero-allocation snapshots;
- graphical/direct autorun parity and one-production-owner source guards;
- existing bit-exact RawMotionState, MTS, jump, AP, quaternion, contact, and strict cadence tests;
- existing run/walk/back/strafe/turn/mouse-look/jump/land, short-tap, portal/reset, target-facing, and repeat-abort tests;
- Release build, complete solution tests, exact-binary connected lifecycle, and canonical movement route.