acdream/docs/plans/2026-07-26-modern-runtime-slice-j7.md

7.3 KiB
Raw Blame History

Modern runtime Slice J7 — one GameRuntime composition root

Status: ACTIVE Parent: 2026-07-25-modern-runtime-slice-j.md, J7 Authorization: the user approved Slices FL, including the J gameplay-owner gates, on 2026-07-24 Purpose: compose the already-proven Runtime lifetime groups behind one instance-scoped owner without changing retail behavior, update order, command latency, rendering, retained UI, or portal presentation.

1. Baseline problem

The canonical state is already in AcDream.Runtime, but production constructs its owners at separate graphical composition points:

Owner Baseline construction site
entity/object/physics lifetime GameWindow field initializer
inventory, character, communication, actions GameWindow constructor
local movement GameWindow field initializer
world environment GameWindow through WorldEnvironmentController
world transit/reveal LivePresentationComposition
session/transport SessionPlayerComposition
simulation clock inside App's UpdateFrameClock
normalized view/events App CurrentGameRuntime*Adapter objects

These are not duplicate gameplay models, but the split construction and teardown graph makes it possible to assemble incompatible owners or retire them in the wrong order. It also prevents a no-window host from constructing the exact same complete kernel in one operation.

2. Fixed boundary

Add one public, presentation-independent GameRuntime in AcDream.Runtime. It owns exactly:

  • canonical session/transport lifetime;
  • local player server identity;
  • entity/object/physics lifetime;
  • inventory, character, communication, and action lifetime groups;
  • local movement intent/controller lifetime;
  • world environment and world transit/reveal state;
  • the instance simulation clock;
  • normalized borrowed views and the lazy ordered Runtime event source;
  • the terminal ownership ledger and retryable teardown cursor.

GameRuntime may depend only on Runtime's existing operation interfaces, Core/Core.Net/Content/Plugin.Abstractions, and injected clock/log/session operations. It never imports App, UI, Silk.NET, OpenAL, Arch, or ImGui.

App keeps:

  • DAT/GL/audio/UI objects;
  • physical input, camera, selection presentation, and command translation;
  • render-space origin and portal tunnel presentation;
  • synchronous adapters that borrow one GameRuntime;
  • generation-scoped graphical resource receipts.

Input, command execution, UI state reads, simulation, and rendering stay in the same host frame. No queue, snapshot copy, worker hop, or extra frame boundary is introduced.

3. Ownership invariants

  1. A production GameWindow stores exactly one GameRuntime field.
  2. Composition dependency records receive that root, not independently paired Runtime owners.
  3. Runtime children are created once by the root and are never replaced.
  4. Graphical adapters may borrow children but cannot dispose or rebind them.
  5. The session is quiesced by the root before App route/projection teardown.
  6. App projection owners retire before the Runtime root's terminal disposal.
  7. Root disposal is ordered, retryable, and resumes at the exact failed suffix.
  8. Construction failure retires every already-created child in reverse order.
  9. The event source attaches to owner events only while observers exist and is detached before owner disposal.
  10. A disposed graphical adapter is inert without disposing the Runtime root.
  11. Two roots never share identity, clock, event sequence, world, gameplay, physics, or session state.
  12. Root construction and direct views load no graphical/audio/UI backend.

4. Execution

J7.1 — Runtime root, identity, events, and terminal ledger

  • Add GameRuntime, typed construction dependencies, local-player identity, construction fault points, ownership snapshot, and exact teardown stages.
  • Move the normalized view/checkpoint implementation into the root.
  • Move the lazy entity/inventory/chat event fanout into Runtime.
  • Add session ownership accounting.
  • Prove reverse construction rollback, exact retryable disposal, two-instance isolation, lazy subscriptions, and zero presentation dependencies.

Gate: focused Runtime tests pass and dependency/source guards find no App or backend reference.

J7.2 — production composition cutover

  • Construct one root in GameWindow.
  • Make UpdateFrameClock borrow the root clock.
  • Make WorldEnvironmentController and WorldGenerationAvailabilityState graphical adapters over root children.
  • Make live presentation borrow root transit rather than construct it.
  • Make session composition borrow root session rather than construct/transfer it.
  • Change composition dependency records to carry the root instead of independent Runtime owners.
  • Replace App's view/event reconstruction with one inertable graphical command adapter over the root.
  • Delete superseded App view/event adapters and direct production constructors.

Gate: App composition/failure-injection tests prove one exact root and no partial publication or borrowed-owner disposal.

J7.3 — one shutdown transaction

  • Replace individual Runtime roots in GameWindowShutdownRoots with GameRuntime.
  • Quiesce its session at the existing ingress barrier.
  • Retire every graphical borrower before terminal root disposal.
  • Make root disposal preserve the exact suffix through callback failure and re-entrancy.
  • Extend checkpoint/terminal ledgers with root/session/event ownership.

Gate: every shutdown fault point converges on retry; no subscriber, route, entity, physics, gameplay, transit, or session debt remains.

J7.4 — validation and closeout

  • Focused Runtime and App tests.
  • Release solution build.
  • Complete Release suite.
  • Exact-binary connected lifecycle/reconnect route.
  • Canonical nine-stop route and allocation/frame-time comparison against J6.
  • Physical-display visual checks for login, world objects, radar, inventory paperdoll, use/approach, combat facing, portal tunnel, and portal exit.
  • Update architecture, code structure, milestone, roadmap, parent/umbrella plans, AGENTS/CLAUDE, divergence ledger, and durable memory.

5. Adversarial matrix

  • construction failure after every child owner;
  • disposal failure at every root teardown stage;
  • re-entrant session stop/dispose;
  • observer removal and addition during event dispatch;
  • observer failure while another observer remains;
  • App adapter disposal while Runtime remains live;
  • root disposal while an App borrower is still registered;
  • session start/reconnect during disposal;
  • duplicate disposal and retry after partial teardown;
  • two simultaneous roots with different clocks, identities, entities, portals, and event observers;
  • portal host acknowledgement pending at shutdown;
  • graphical composition failure before and after session host creation;
  • same-frame selection/use/combat/magic/UI response before and after cutover;
  • no Runtime load of App/UI/Silk/OpenAL/Arch/ImGui.

6. Commit and rollback discipline

Each production sub-slice lands separately after its focused and complete Release gates. Record its full production SHA and exact git revert <sha> here before beginning the next sub-slice. Documentation-only commits are not behavior rollback points.

No compatibility owner, service locator, asynchronous command queue, timeout, forced-ready path, or alternate headless behavior is permitted.