# Slice J5 owner and retail-order inventory **Date:** 2026-07-26 **Scope:** presentation-free selection, interaction, combat/magic intent, movement/outbound cadence, physics, and projectile ownership **Parent plan:** `docs/plans/2026-07-26-modern-runtime-slice-j5.md` ## Purpose Slice J5 moves gameplay simulation and intent out of the graphical App and into `AcDream.Runtime`. This note pins the current production owners and the retail ordering that cannot change while those owners move. This is an ownership refactor, not a new movement, combat, interaction, or projectile implementation. Existing retail ports remain the behavioral oracle. ## Current source ownership | Concern | Current canonical state | Construction/root | Presentation coupling to split | |---|---|---|---| | Selection identity | `AcDream.Core.Selection.SelectionState` | `Program` constructs; `GameWindow` retains | world ray picking, lighting pulse, vivid markers, status/UI projections | | Combat notifications/mode | `AcDream.Core.Combat.CombatState` | `GameWindow` constructs | combat/spell bars, camera target tracking, feedback | | Pointer target mode | `AcDream.App.UI.InteractionState` | optional private construction inside `ItemInteractionController` | cursor image only; state itself is presentation-free | | Item-use/appraisal/pickup intent | `ItemInteractionController`, `SelectionInteractionController`, `InventoryTransactionState` | App retained-UI and live-presentation composition | world picking, retained drag/drop, toasts, pending-slot mesh | | Combat attack intent | `CombatAttackController`, `LiveCombatModeCommandController` | App retained-UI/session composition | input action mapping and combat-bar projection | | Spell-cast intent | `SpellCastingController` inside App `MagicRuntime` | App content/UI composition | DAT catalog loading, component icons/text, spell bar | | Local movement | `PlayerMovementController` plus Core `PhysicsBody`, `MotionInterpreter`, `MovementManager` | App player-mode composition | Silk/input sampling, camera/mouse-look device state, animated pose publication | | Outbound movement cadence | `LocalPlayerOutboundController` | `GameWindow` constructs | App diagnostic sink only | | Per-session collision | Core `PhysicsEngine`, `ShadowObjectRegistry`, transition scratch | `GameWindow` constructs | streaming publishers and debug visualization | | Remote movement/physics | App `RemotePhysicsUpdater`, `RemoteInboundMotionDispatcher`, live sidecars | App composition | `WorldEntity`, render projection, animation pose/effect publication | | Projectile simulation | Core `ProjectilePhysicsStepper` plus App `ProjectileController.Runtime` | App live-presentation composition | `WorldEntity`, effect pose, shadow publication | `RuntimeEntityRecord` already owns canonical accepted identity, timestamps, full cell, raw/final physics state, object clock, `PhysicsBody`, and `IPhysicsObjHost`. The App `LiveEntityRecord` is a projection sidecar. J5 must extend the canonical record rather than add another entity or physics model. `RuntimeInventoryState` already owns the exact inventory transaction/busy/use reservation state. J5 interaction work must borrow that owner and must not recreate a busy counter or pending inventory request. ## Current reset ordering `LiveSessionResetManifest` currently performs the relevant stages in this order: 1. mouse/input capture; 2. player presentation and teleport transit; 3. dialogs/chat/settings; 4. equipped children and external container; 5. interaction plus selection; 6. inventory transactions; 7. selection presentation and object table; 8. spellbook/magic; 9. combat attack and combat state; 10. local-player and remaining session state; 11. live entity teardown; 12. render projection drain and session identity; 13. network effects/presentation tails. Runtime ownership may combine internal stages, but App acknowledgements must retain the same dependency order: presentation releases references before the canonical owner is destroyed, while old session identity remains available until exact-incarnation teardown converges. ## Named-retail ordering matrix ### Selection `ACCWeenieObject::SetSelectedObject @ 0x0058C2E0` 1. If forced or changed, clear the old object's selected flag. 2. Commit the new selected ID. 3. Set the new object's selected flag. 4. If the ID changed, commit previous and previous-valid IDs. 5. Publish the UI selection notice. 6. Publish the shared item-holder selection change. 7. Notify the plugin API. The state commit precedes every observer. Deduplicated selection does not publish the changed notice. ### Session combat initialization `ClientCombatSystem::Begin @ 0x0056A460` 1. Commit NonCombat and clear pending mode. 2. Clear jump, build, response, attack, repeat, and tracking transients. 3. Restore medium attack height and UI requested power `0.5`. 4. Register the global notice handler. Runtime combat reset must clear the complete intent transaction before App projects the peace-mode UI. ### Ordinary use and target mode `ItemHolder::UseObject @ 0x00588A80` 1. Enforce the strict 0.2-second local use gate. 2. Verify inventory-request readiness and vendor restrictions. 3. Resolve automatic wield/use policy and targeted-use policy. 4. For ordinary use, emit `CM_Inventory::Event_UseEvent`. 5. Increment the shared UI busy reference. 6. Invoke `CPlayerSystem::UsingItem` and publish local text. 7. For a targeted item without an acquired target, store the source object and enter `TARGET_MODE_USE_TARGET`; do not emit the use-with-target packet yet. 8. Once a compatible target is acquired, emit `Event_UseWithTargetEvent`, increment busy, then invoke `UsingItem`. `ClientUISystem::Handle_Item__UseDone @ 0x00564900` 1. Decrement exactly one busy reference. 2. Refresh cursor state only when the count reaches zero. 3. Present a nonzero server error afterward. The current production correction remains authoritative for local ACE: ordinary Use is sent immediately and ACE owns spatial approach. Pickup retains the existing ordered local approach transaction and post-arrival send. ### Local movement output `CommandInterpreter::SendMovementEvent @ 0x006B4680` 1. Require player, SmartBox, raw motion state, and nonzero autonomy. 2. Read the player's current raw state, canonical `Position`, contact state, long-jump state, and four retail timestamps. 3. build/send `MoveToStatePack`. 4. Stamp `last_sent_position_time` only after send. `CommandInterpreter::SendPositionEvent @ 0x006B4770` 1. Require SmartBox, player, active/in-world transient state, and valid canonical `Position`. 2. Read current contact and timestamps. 3. build/send `AutonomousPositionPack`. 4. After send, stamp time and copy the complete sent `Position` and contact plane as the next comparison baseline. The existing pre-inbound movement/jump and post-inbound autonomous-position slots remain unchanged. ### Object physics `CPhysicsObj::UpdatePositionInternal @ 0x00512C30`, `CPhysicsObj::transition @ 0x00512DC0`, `CPhysicsObj::SetPositionInternal(CTransition const*) @ 0x00515330`, and the ordered object tail recorded in `docs/research/2026-07-19-r6-update-object-order-pseudocode.md` remain the simulation oracle. Runtime owns the canonical body and simulation. App may publish the final accepted root/part poses only after that simulation result commits. A render callback must never become position, cell, velocity, or collision authority. ### Projectile collision exclusion `OBJECTINFO::missile_ignore @ 0x0050CEB0` The existing Core `ProjectilePhysicsStepper` port remains unchanged: - ignore other missiles; - ignore ethereal weenies unless they are the designated target; - with a nonzero designated target, ignore other creatures; - do not infer a designated target from UI selection. ## Fixed dependency direction ```text Silk / retained UI / camera | v App typed input + presentation adapters | v AcDream.Runtime intent/simulation owners | v Core algorithms + Core.Net transport/content seams ``` Runtime never references App, Silk, OpenGL, OpenAL, ImGui, Arch, or retained UI. App may synchronously acknowledge a committed runtime mutation and project it; it may not keep a second mutable copy. ## Source hazards 1. `ItemInteractionController` can currently create a private `InteractionState`; this is a duplicate-owner seam and must be removed when J5.1 lands. 2. `Program` currently constructs selection while `GameWindow` constructs combat. Both must move under one Runtime owner before higher-level controllers move. 3. `PlayerMovementController` contains environment reads for test-era default skills. A Runtime move must use typed construction options and the existing Runtime character skill projection. 4. `LocalPlayerOutboundController` directly accepts `WorldSession` and an App diagnostic sink. Runtime may use Core.Net, but diagnostics must cross a narrow optional interface. 5. App `LiveEntityRecord` still stores remote/projectile component interfaces. Simulation components must migrate to `RuntimeEntityRecord`; only animation/effect/render projection belongs in the App sidecar. 6. Remote/projectile callbacks can synchronously delete or replace a GUID. Every split-phase commit must retain the existing exact-record, incarnation, authority-version, and object-clock-epoch revalidation. 7. `PhysicsEngine` transition scratch is per engine and same-thread LIFO. Immutable prepared collision content may be shared; the engine and scratch may not be shared by concurrent sessions.