acdream/docs/plans/2026-07-26-modern-runtime-slice-j5.md
Erik fce8e7b18e docs(runtime): close per-session physics ownership
Record J5.5 production SHA, complete Release baseline, exact-binary lifecycle/reconnect and nine-stop collision/movement evidence, and rollback. Synchronize architecture, roadmap, milestones, AGENTS/CLAUDE, and advance the active program to J5.6 projectile runtime.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 13:59:06 +02:00

22 KiB
Raw Blame History

Modern runtime Slice J5 — movement, physics, interaction, and combat

Status: ACTIVE — J5.1J5.5 complete; J5.6 next Parent: 2026-07-25-modern-runtime-slice-j.md, J5 Production base: 2c67a2c3 Authorization: the user approved Slices FL, 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 complete aa3f4a60f87f2cbebc3d8ecd5e33d779b7fb13c1; one Runtime movement/controller/cadence owner; 303 Runtime tests, 3,716 App tests / 3 skips, 8,575 complete Release tests / 5 skips, exact-binary lifecycle/reconnect and nine-stop movement gates pass
J5.5 per-session physics and remote simulation complete 7e6033d0adcd0b572c20e89dd275746fb442d52f; one Runtime engine/cache/scratch/shadow/body/host/remote/workset owner; 314 Runtime tests, 3,718 App tests / 3 skips, 8,588 complete Release tests / 5 skips, exact-binary lifecycle/reconnect and nine-stop collision/movement gates pass
J5.6 projectile runtime active 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.

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.

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.

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.

Completed 2026-07-26 at aa3f4a60f87f2cbebc3d8ecd5e33d779b7fb13c1. RuntimeLocalPlayerMovementState constructs and owns the exact PlayerMovementController, construction-time motion seam, autorun latch, typed movement view, and terminal ledger. The movement controller and LocalPlayerOutboundController now live in AcDream.Runtime.Gameplay. Graphical input samples physical state and borrows that owner; direct Runtime commands mutate the same state without an App/input detour. Character run/jump skill projections enter through typed construction options rather than process environment reads. Runtime tests pass 303/303, App tests pass 3,716/3 skips, and the complete Release suite passes 8,575/5 skips. The exact-binary connected lifecycle/reconnect report logs/connected-world-gate-20260726-123425/report.json passes both sessions, 7/7 readiness checkpoints, graceful code-zero exits, and zero failures. The canonical route logs/connected-r6-soak-20260726-124049.report.json passes all nine destinations; forward, jump, combat, and authoritative movement-truth exercises pass at Caul, Holtburg, and the Caul return before graceful shutdown. Evidence: ../research/2026-07-26-slice-j5-4-local-movement-ownership.md.

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.

Completed 2026-07-26 at 7e6033d0adcd0b572c20e89dd275746fb442d52f. RuntimeEntityObjectLifetime now constructs one RuntimePhysicsState, which owns the sole production PhysicsEngine, data cache/cell graph, transition scratch, shadow registry, collision admissions, canonical bodies and hosts, remote components, ordinary/remote worksets, simulation, and full-cell commits. App publishes prepared collision through generation-scoped receipts, supplies DAT/animation inputs, and projects immutable committed snapshots; it does not construct or run a parallel solver. Runtime tests pass 314/314, App tests pass 3,718/3 skips, and the complete Release suite passes 8,588/5 skips. The exact-binary lifecycle/reconnect report logs/connected-world-gate-20260726-134107/report.json passes both sessions, 7/7 readiness checkpoints, graceful code-zero exits, and zero failures. The canonical route logs/connected-r6-soak-20260726-134638.report.json matches source/binary, passes all nine render/collision-ready destinations and movement exercises, and exits gracefully with code zero and zero failures. Evidence: ../research/2026-07-26-slice-j5-5-physics-remote-ownership.md.

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 <sha> 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:

git revert b298f99f913249d299796e6a71f7a9b6b283ac1a

J5.2 rollback:

git revert f5f7b4177f449ebcad9724bfea263ef73ab60255

J5.3 rollback:

git revert 20df9d155db50706a42420d60a9b15861cf4bfe7

J5.4 rollback:

git revert aa3f4a60f87f2cbebc3d8ecd5e33d779b7fb13c1

J5.5 rollback:

git revert 7e6033d0adcd0b572c20e89dd275746fb442d52f

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.