refactor(runtime): compose canonical game runtime root
This commit is contained in:
parent
75f9510e10
commit
96ddd16539
6 changed files with 1585 additions and 0 deletions
165
docs/plans/2026-07-26-modern-runtime-slice-j7.md
Normal file
165
docs/plans/2026-07-26-modern-runtime-slice-j7.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# 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 F–L, 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue