# Modern runtime Slice J5 — movement, physics, interaction, and combat **Status:** ACTIVE — J5.1–J5.3 complete; J5.4 next **Parent:** `2026-07-25-modern-runtime-slice-j.md`, J5 **Production base:** `2c67a2c3` **Authorization:** the user approved Slices F–L, including the Slice J gameplay-owner gates, on 2026-07-24 ## Objective Move the complete presentation-independent action and simulation graph into `AcDream.Runtime` while preserving retail behavior and the accepted graphical feel. At completion: - Runtime owns selection, interaction mode/transactions, combat and spell-cast intent, local/remote movement, outbound cadence, per-session physics, and projectile simulation; - App converts physical input into typed commands and projects committed state into cameras, retained UI, animation, sound, particles, markers, and meshes; - graphical and future no-window hosts borrow the same owners and observe the same ordered state; - no render callback, UI element, or camera object is gameplay authority. ## Presentation boundary ### Moves to Runtime - selected/previous object identity; - temporary use/examine/use-item-on-target mode; - appraisal/use/pickup/approach transaction identity; - combat mode, attack build/request/repeat intent, target identity; - spell-cast request intent; - `PlayerMovementController` state, movement interpretation, canonical local body, object clock, movement managers, and outbound cadence; - per-session `PhysicsEngine`, transition scratch, shadow/collision gameplay state; - remote canonical body/movement state; - projectile component state and simulation; - typed views, commands, ordered events, reset, disposal, and ownership ledgers for all of the above. ### Remains in App - Silk input sources and configurable key/chord mapping; - camera orbit, mouse cursor capture, and device-delta filtering; - world ray construction/picking; - selection lighting pulse, vivid markers, and selected-object HUD; - combat/spell bars and retained target-mode cursor images; - animated part/root pose composition; - meshes, terrain/EnvCell streaming publication, sounds, particles, lights, translucency, and debug drawing; - UI text, toasts, drag/drop visuals, pending-slot mesh, and appraisals' retained window. The camera's instant mouse-look mode still emits typed retail turn/sidestep commands to Runtime. The camera may not write the player heading directly. ## Fixed invariants 1. Retail algorithms and branch/order semantics do not change during the move. 2. One mutable owner exists for every state class. 3. Runtime has no App/UI/backend dependency. 4. `RuntimeEntityRecord` remains canonical entity identity and physics authority; App `LiveEntityRecord` remains a projection sidecar. 5. `RuntimeInventoryState` remains the only busy/inventory-transaction owner. 6. Core flat collision data is immutable/shareable. Each runtime/session owns its `PhysicsEngine`, transition scratch, bodies, shadows, interpolation, and projectile state. 7. All mutation stays on the existing update thread. Network workers enqueue immutable messages only. 8. App input-to-Runtime commands are synchronous; no extra frame, polling mirror, or background queue is introduced. 9. App presentation callbacks may re-enter/delete/replace entities. Every continuation revalidates exact record, incarnation, authority version, and object-clock epoch before commit. 10. Reset/disposal executes every suffix after an observer failure and refuses a new session until the complete ownership ledger converges. 11. Every sub-slice is independently buildable, tested, connected-gated where behavior can change, documented, committed, and given an exact rollback. ## Execution ledger | Sub-slice | Status | Result/evidence | |---|---|---| | J5.0 owner/retail inventory | complete | `docs/research/2026-07-26-slice-j5-owner-and-retail-order-inventory.md` | | J5.1 canonical action state | complete | `b298f99f913249d299796e6a71f7a9b6b283ac1a`; one Runtime selection/combat/target-mode owner; 182 Runtime tests, 3,779 App tests / 3 skips, 8,550 complete Release tests / 5 skips, exact-binary connected lifecycle/reconnect pass | | J5.2 interaction transactions | complete | `f5f7b4177f449ebcad9724bfea263ef73ab60255`; one Runtime transaction owner; 197 Runtime tests, 3,775 App tests / 3 skips, 8,561 complete Release tests / 5 skips, exact-binary connected lifecycle/reconnect pass | | J5.3 combat and magic intent | complete | `20df9d155db50706a42420d60a9b15861cf4bfe7`; exact Runtime attack/mode/target/cast owners; 223 Runtime tests, 3,754 App tests / 3 skips, 8,566 complete Release tests / 5 skips, exact-binary connected lifecycle/reconnect pass | | J5.4 local movement and outbound cadence | active | controller, body, movement managers, MTS/AP/jump cadence | | J5.5 per-session physics and remote simulation | pending | engine/scratch/shadows/remote canonical body | | J5.6 projectile runtime | pending | canonical component/simulation plus App projection acknowledgements | | J5.7 combined cleanup and closeout | pending | no mirrors, no-window parity, teardown, connected and visual gates | ## J5.1 — canonical action state Create one Runtime owner for: - `SelectionState`; - `CombatState`; - presentation-free interaction/target-mode state. Actions: 1. Move interaction-mode types/state from App UI into Runtime gameplay. 2. Make Runtime construct all three exact owners. 3. Remove Program's selection construction and GameWindow's direct combat construction. 4. Make App composition, session routing, retained UI, plugins, and current Runtime commands/views borrow the exact Runtime instances. 5. Remove `ItemInteractionController`'s optional private `InteractionState` fallback; production and tests must pass the exact owner. 6. Add a combined ownership/revision snapshot and failure-safe reset/disposal. 7. Add Runtime views for selection, combat mode/known health, and interaction mode without exposing mutable collections. Gate: - named-retail selection order and deduplication; - combat Begin/reset defaults; - target-mode enter/acquire/cancel/reset; - UI/plugin observer failure isolation; - two Runtime instances in one process; - exact graphical/direct owner identity; - source guard proving App cannot construct a production owner; - Runtime dependency and assembly-load closure; - focused Runtime/App tests, Release build, full Release suite, connected lifecycle/reconnect route. Completed 2026-07-26 at `b298f99f913249d299796e6a71f7a9b6b283ac1a`. `RuntimeActionState` now constructs the exact selection, combat, and temporary interaction-mode children. Program, plugins, retained UI, session routing, typed commands/views, and terminal shutdown borrow those exact instances. The App-owned `InteractionState` and `ItemInteractionController` fallback are deleted. Failure-safe reset/disposal, two-instance isolation, normalized checkpoints, dependency closure, and production source guards pass. The exact-binary connected report is `logs/connected-world-gate-20260726-104445/report.json`: 7/7 ready checkpoints, two graceful code-zero exits, zero failures, and only the 25 expected world-edge landblock misses. Evidence: [`../research/2026-07-26-slice-j5-1-canonical-action-state.md`](../research/2026-07-26-slice-j5-1-canonical-action-state.md). ## J5.2 — interaction transactions Split App orchestration into: - App `WorldSelectionQuery`/picker/lighting/drag presentation; - Runtime interaction transaction owner; - typed query, movement, inventory-policy, transport, and presentation acknowledgement seams. Runtime owns: - use throttle and source/target identity; - appraisal request/current identity; - ordinary use reservation transfer to authoritative UseDone; - pickup request and exact post-arrival identity/token; - ordered outbound interaction queue; - entity-hidden/deleted cancellation; - reset/disposal convergence. App retains: - cursor position and world ray; - lighting pulse; - toasts/text rendering; - retained drag/drop and pending-slot drawing. Ordering: - ordinary Use sends immediately, then transfers its busy reservation to UseDone; - targeted Use enters mode until a compatible target is acquired; - pickup's same-frame send drains after local movement output and before inbound dispatch; - post-arrival pickup sends once only on natural completion; - stale/replaced object identities never execute queued work. Gate: - current connected near/far door/NPC/corpse use; - item-on-target, appraisal, pickup, pending-slot accept/failure; - same-frame W-release plus R; - delete/GUID reuse, hidden target, cancellation, transport failure, callback reentrancy, reset/disposal; - normalized graphical/direct ordered traces and no duplicate busy owner. Completed 2026-07-26 at `f5f7b4177f449ebcad9724bfea263ef73ab60255`. `RuntimeInteractionTransactionState`, owned beneath `RuntimeActionState`, now owns the retail 200-ms use gate, exact use source/target identity, pending and current appraisal identity, typed ordered interactions, and the exact post-arrival pickup token. It borrows—not duplicates—J4's `InventoryTransactionState`, so ordinary Use transfers one busy reference to authoritative UseDone and pickup retains the same one-request-at-a-time gate. App retains world rays, lighting, movement installation, transport, toasts, drag/drop, and pending-slot presentation. The old App delegate queue and App transaction fields are deleted. Identity-bound work is cancelled by exact local incarnation on delete and by server GUID on Hidden. Re-entrant reset, disposal, transport failure, stale approach completion, and GUID reuse cannot resurrect a transaction or strand the busy gate. Focused near/far use, carried-use, appraisal, item-on-target, pickup, pending-slot, hidden/delete, reset, and callback-order tests pass. The exact-binary connected report is `logs/connected-world-gate-20260726-111330/report.json`: 7/7 ready checkpoints, two graceful code-zero exits, zero failures or invariant violations, and only the 25 expected world-edge landblock misses. Evidence: [`../research/2026-07-26-slice-j5-2-interaction-transactions.md`](../research/2026-07-26-slice-j5-2-interaction-transactions.md). ## J5.3 — combat and magic intent Move: - `CombatAttackController`'s presentation-free build/request/repeat state; - combat-mode selection/default policy; - target death/auto-target identity transitions; - `SpellCastingController` intent and last-request state. Replace `InputAction` dependencies with Runtime-specific typed commands. App maps configured actions and bar/button presses onto those commands and projects Runtime snapshots. Keep App-only: - combat/spell bar widgets; - camera target tracking; - animation, sound, particles, and response text layout; - DAT catalog/icon/formula presentation. Ordering: - movement aborts repeat attack at the existing retail input boundary; - targeted attack/cast turns through the shared movement owner before release; - cast stops movement, emits exactly one targeted/untargeted request, then increments the shared busy reference; - server attack/cast completion remains authoritative. Gate: - power-bar cadence and height selection; - repeat start/abort/movement cancellation; - combat-mode equipment defaults; - 180-degree bow/spell target facing; - hostile-only auto-target after death; - self/untargeted/targeted spell requests, component failure, busy completion; - graphical bar parity and direct typed-command parity. **Completed 2026-07-26 at `20df9d155db50706a42420d60a9b15861cf4bfe7`.** `RuntimeActionState` constructs and owns the exact combat-attack, combat-target, combat-mode, and spell-cast intent children. Retained attack/spell bars and graphical input borrow those owners; direct Runtime combat/magic commands drive the same operations and snapshots without a retained UI. App retains world/content queries, transport, bars, animation, sound, particles, and response text. Runtime tests pass 223/223, App tests pass 3,754/3 skips, and the complete Release suite passes 8,566/5 skips. The exact-binary connected report `logs/connected-world-gate-20260726-115752/report.json` passes two sessions, 7/7 checkpoints, graceful code-zero exits, and zero failures. Evidence: [`../research/2026-07-26-slice-j5-3-combat-magic-intent.md`](../research/2026-07-26-slice-j5-3-combat-magic-intent.md). ## J5.4 — local movement and outbound cadence Move `PlayerMovementController`, its data types, and `LocalPlayerOutboundController` into Runtime. Replace test-era environment reads with typed construction options and the Runtime character movement-skill projection. App provides: - current typed movement snapshot from the input dispatcher; - filtered mouse-look turn adjustment; - animation root-motion frame and completion acknowledgements; - optional diagnostic sink. Runtime owns: - canonical local `PhysicsBody`, `MotionInterpreter`, `MovementManager`, `MoveToManager`, `PositionManager`, and object clock; - local input edge interpretation; - run lock, jump charge/launch, movement/contact state; - target-facing movement; - pre-inbound MTS/jump and post-inbound autonomous-position send cadence; - complete canonical `Position`, contact-plane, timestamps, and sent baselines. Gate: - bit-exact `RawMotionState`, MTS, jump, and autonomous-position fixtures; - strict cadence/equality boundaries; - complete quaternion/cell-local frame; - short-tap animation-owned start; - run/walk/back/strafe/turn/mouse-look/jump/land; - portal/focus/reset teardown; - target-facing and movement-aborts-repeat ordering; - zero added per-frame allocations after warmup. ## J5.5 — per-session physics and remote simulation Add a Runtime physics owner that constructs one `PhysicsEngine` per runtime instance. App streaming publishes immutable prepared collision assets through typed admission/withdrawal acknowledgements. Move canonical remote simulation state and component indexes from App sidecars to `RuntimeEntityRecord`/Runtime owners: - remote body/interpolation/movement-manager state; - canonical cell/rebucket writes; - physics-host lookup; - shadow/collision gameplay membership; - ordinary-object update workset. App consumes committed snapshots/events to: - update `WorldEntity`; - rebucket render projections; - publish current root/part/equipped-child poses; - refresh graphical collision/debug views. Gate: - complete flat collision conformance corpus remains bit-identical; - fresh/reused engine parity and zero-allocation resolve profiles; - player and remote position/cell/orientation parity; - crowd de-overlap, doors, stairs, dungeon/cell seams, login placement; - hidden/pending/rehydration, teleport correction, delete/GUID reuse; - two concurrent Runtime instances prove scratch/shadow isolation. ## J5.6 — projectile runtime Move projectile component identity, prediction versions, and simulation into Runtime. Store the canonical component on `RuntimeEntityRecord`, not the App sidecar. Runtime uses: - existing Core `ProjectilePhysicsStepper`; - canonical body/cell/state/timestamp authority; - strict prepared collision shapes; - existing split Begin/Complete prediction with exact-version revalidation. App acknowledges successful commits by: - updating/rebucketing the render projection; - synchronizing graphical shadow representation; - publishing effect root/pose. App does not decide collision outcome, impact, damage, effect, or deletion. Gate: - existing clamp/gravity/AlignPath/angular/collision/thin-wall fixtures; - designated-target exclusion semantics; - loaded/pending/cross-landblock/correction/delete/GUID-reuse; - 96-owner lifetime/effect stress; - no duplicated mesh, effect, shadow, body, or script owner; - arrow, bolt, and representative spell projectile connected route. ## J5.7 — combined cleanup and closeout Delete: - temporary App owner fields and construction fallbacks; - App simulation component dictionaries; - current-runtime adapters that reconstruct moved snapshots; - reset/disposal branches replaced by Runtime; - compatibility aliases after all consumers borrow Runtime. Add: - one J5 ownership ledger; - failure injection at every construction, subscription, command, projection acknowledgement, reset, and disposal boundary; - graphical/direct normalized traces; - Runtime-only movement/use/combat/cast/projectile fixture host; - source/dependency guards against App/backend leakage and duplicate owners. Run: 1. focused Core physics/selection/combat tests; 2. Runtime state/command/event/teardown tests; 3. App input/interaction/combat/magic/physics/projectile tests; 4. Release build and complete Release suite; 5. exact-binary lifecycle/reconnect route; 6. canonical nine-stop movement/combat/jump route; 7. connected interaction, casting, projectile, portal, and reconnect route; 8. user graphical feel gate for movement, facing, use, combat/cast bars, and visible missiles; 9. architecture, divergence, issue, roadmap, AGENTS/CLAUDE, and durable-memory reconciliation. ## Commit and rollback discipline Each sub-slice lands as one independently reversible production commit followed by a documentation/evidence checkpoint where needed. Planned production commit sequence: 1. `refactor(runtime): own canonical action state` (`b298f99f913249d299796e6a71f7a9b6b283ac1a`) 2. `refactor(runtime): own interaction transactions` 3. `refactor(runtime): own combat and magic intent` 4. `refactor(runtime): own local movement and outbound cadence` 5. `refactor(runtime): own per-session physics simulation` 6. `refactor(runtime): own projectile simulation` 7. `refactor(runtime): close simulation ownership` Record each full SHA and exact `git revert ` command in this file before running its connected gate. Revert J5 groups in reverse order. Do not revert J4 or the flat-collision Slice I cutover to mask a J5 ownership failure. J5.1 rollback: ```text git revert b298f99f913249d299796e6a71f7a9b6b283ac1a ``` J5.2 rollback: ```text git revert f5f7b4177f449ebcad9724bfea263ef73ab60255 ``` J5.3 rollback: ```text git revert 20df9d155db50706a42420d60a9b15861cf4bfe7 ``` ## Acceptance J5 is complete only when: - every listed presentation-free owner is constructed by Runtime; - App owns presentation only and borrows exact Runtime state; - graphical and no-window commands produce the same ordered state and packets; - collision and trajectory fixtures remain bit-identical; - reset, reconnect, same-process multiple-instance, GUID reuse, and failure injection converge every owner; - no extra frame or per-frame allocation regression exists; - complete Release and connected gates pass; - the user accepts graphical movement, facing, interaction, combat/casting, and projectile behavior; - architecture, roadmap, milestones, issues/divergences, AGENTS/CLAUDE, evidence, memory, and rollback instructions are synchronized.