Inventory the present selection, interaction, combat, movement, physics, and projectile owners; pin named-retail ordering; and define independently reversible J5.1-J5.7 gates without moving presentation into Runtime. Co-authored-by: Codex <noreply@openai.com>
9.4 KiB
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:
- mouse/input capture;
- player presentation and teleport transit;
- dialogs/chat/settings;
- equipped children and external container;
- interaction plus selection;
- inventory transactions;
- selection presentation and object table;
- spellbook/magic;
- combat attack and combat state;
- local-player and remaining session state;
- live entity teardown;
- render projection drain and session identity;
- 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
- If forced or changed, clear the old object's selected flag.
- Commit the new selected ID.
- Set the new object's selected flag.
- If the ID changed, commit previous and previous-valid IDs.
- Publish the UI selection notice.
- Publish the shared item-holder selection change.
- Notify the plugin API.
The state commit precedes every observer. Deduplicated selection does not publish the changed notice.
Session combat initialization
ClientCombatSystem::Begin @ 0x0056A460
- Commit NonCombat and clear pending mode.
- Clear jump, build, response, attack, repeat, and tracking transients.
- Restore medium attack height and UI requested power
0.5. - 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
- Enforce the strict 0.2-second local use gate.
- Verify inventory-request readiness and vendor restrictions.
- Resolve automatic wield/use policy and targeted-use policy.
- For ordinary use, emit
CM_Inventory::Event_UseEvent. - Increment the shared UI busy reference.
- Invoke
CPlayerSystem::UsingItemand publish local text. - 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. - Once a compatible target is acquired, emit
Event_UseWithTargetEvent, increment busy, then invokeUsingItem.
ClientUISystem::Handle_Item__UseDone @ 0x00564900
- Decrement exactly one busy reference.
- Refresh cursor state only when the count reaches zero.
- 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
- Require player, SmartBox, raw motion state, and nonzero autonomy.
- Read the player's current raw state, canonical
Position, contact state, long-jump state, and four retail timestamps. - build/send
MoveToStatePack. - Stamp
last_sent_position_timeonly after send.
CommandInterpreter::SendPositionEvent @ 0x006B4770
- Require SmartBox, player, active/in-world transient state, and valid
canonical
Position. - Read current contact and timestamps.
- build/send
AutonomousPositionPack. - After send, stamp time and copy the complete sent
Positionand 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
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
ItemInteractionControllercan currently create a privateInteractionState; this is a duplicate-owner seam and must be removed when J5.1 lands.Programcurrently constructs selection whileGameWindowconstructs combat. Both must move under one Runtime owner before higher-level controllers move.PlayerMovementControllercontains environment reads for test-era default skills. A Runtime move must use typed construction options and the existing Runtime character skill projection.LocalPlayerOutboundControllerdirectly acceptsWorldSessionand an App diagnostic sink. Runtime may use Core.Net, but diagnostics must cross a narrow optional interface.- App
LiveEntityRecordstill stores remote/projectile component interfaces. Simulation components must migrate toRuntimeEntityRecord; only animation/effect/render projection belongs in the App sidecar. - 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.
PhysicsEnginetransition 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.