Record the canonical Runtime session/transport cutover, exact rollback, full Release evidence, and exact-binary lifecycle acceptance. Advance the active execution pointer and durable memory to J3 identity and object ownership. Validated by the existing 79 Runtime tests, 3,776 App tests with three skips, 8,428 complete Release tests with five skips, and logs/connected-world-gate-20260725-193936/report.json. Co-authored-by: Codex <codex@openai.com>
279 lines
13 KiB
Markdown
279 lines
13 KiB
Markdown
# Modern runtime Slice J — presentation-independent runtime
|
||
|
||
**Status:** J0–J2 COMPLETE — boundary, borrowed contracts, and canonical
|
||
session/transport lifetime; J3 is ACTIVE
|
||
**Parent:** `2026-07-24-modern-runtime-architecture.md`, Slice J
|
||
**Authorization:** the user approved Slices F–L, including the otherwise-frozen
|
||
Slice J gameplay-owner moves, on 2026-07-24
|
||
**Purpose:** move the existing authoritative client kernel into a
|
||
presentation-independent assembly without creating a second world, changing
|
||
retail behavior, or making the graphical host a special case.
|
||
|
||
Slice J is a lifetime-group campaign, not one large move. Each sub-slice keeps
|
||
the graphical client on the same owner instance, establishes host parity, and
|
||
deletes the replaced App production path before the next group moves.
|
||
|
||
## 1. Fixed invariants
|
||
|
||
1. `LiveEntityRuntime` remains the sole server-GUID/incarnation owner. There is
|
||
never a second GUID map or synchronized gameplay world.
|
||
2. Runtime types do not reference `AcDream.App`, either UI assembly, Silk.NET,
|
||
OpenAL, Arch, ImGui, a native window, or an OpenGL resource.
|
||
3. App projection state is keyed by runtime-issued local entity identity plus
|
||
incarnation. It may not recover or mirror server GUID ownership.
|
||
4. The accepted update order, packet ordering, timestamp gates, outbound
|
||
cadence, and retail-shaped gameplay algorithms do not change during the
|
||
extraction.
|
||
5. Contracts expose borrowed/immutable views, typed commands, and ordered
|
||
deltas. They do not expose App render components or deep per-frame object
|
||
graphs.
|
||
6. All clocks, queues, random sources, diagnostics identity, plugin behavior,
|
||
and mutable caches that can differ between sessions are instance-scoped.
|
||
7. Immutable prepared content may be shared. Session state and mutable query
|
||
scratch may not.
|
||
8. Every new owner participates in the structural teardown protocol in parent
|
||
plan §9.2.1 through acquisition leases and exact acknowledgements.
|
||
9. A headless construction path is proved after every coherent move. “No
|
||
window” means no App, Silk, OpenAL, retained UI, particle, or render assembly
|
||
is loaded—not a hidden graphical process.
|
||
10. Slice I is closed: production collision is flat-authoritative and retains
|
||
no parsed collision graph. J1 contracts adapt that final canonical owner
|
||
shape; they may not reintroduce a graph fallback or mirrored collision
|
||
authority.
|
||
|
||
## 2. Target dependency direction
|
||
|
||
```text
|
||
AcDream.App ───────────────► AcDream.Runtime
|
||
AcDream.Headless (Slice K) ─► AcDream.Runtime
|
||
├──► AcDream.Core.Net
|
||
├──► AcDream.Core
|
||
├──► AcDream.Content
|
||
└──► AcDream.Plugin.Abstractions
|
||
|
||
AcDream.Runtime -X► AcDream.App / AcDream.UI.* / Silk.NET / OpenAL / Arch
|
||
```
|
||
|
||
Runtime-emitted entity events contain incarnation, transform, flags, and
|
||
property deltas only. An App-side projection adapter translates them into
|
||
`IRenderScene` journal operations. Render vocabulary never enters Runtime.
|
||
|
||
## 3. Teardown transaction
|
||
|
||
The exact order is:
|
||
|
||
1. cancel scheduler/session generations and make commands inert;
|
||
2. detach producers, drain accepted ordered events, and poison queues;
|
||
3. withdraw and acknowledge graphical presentation;
|
||
4. retire session residence and GPU-backed owners through existing fences;
|
||
5. dispose the process-owned immutable `ContentStore` only after every runtime
|
||
and host has completed.
|
||
|
||
Completed stages never replay. Failure retains the exact remaining suffix.
|
||
Logout, reset, mid-portal disconnect, reconnect replacement, construction
|
||
rollback, and native close all traverse the same transaction.
|
||
|
||
## 4. Execution slices
|
||
|
||
### J0 — boundary, plan, and dependency enforcement
|
||
|
||
**Completed 2026-07-25.**
|
||
|
||
- Add `AcDream.Runtime` and `AcDream.Runtime.Tests`.
|
||
- Permit references only to Core, Core.Net, Content, and Plugin.Abstractions.
|
||
- Add App → Runtime as the future host dependency; Runtime never references
|
||
App.
|
||
- Add direct-reference, dependency-closure, source-project, and assembly-load
|
||
guards that fail if a presentation/backend dependency enters Runtime.
|
||
- Add only an assembly boundary marker; do not introduce a facade
|
||
`GameRuntime`, mirror state, or move behavior in J0.
|
||
- Pin this lifetime-group plan and parent-plan teardown protocol.
|
||
|
||
Gate: Release build and full tests pass; the Runtime test process loads no App,
|
||
UI, Silk, OpenAL, Arch, or ImGui assembly; graphical behavior is byte-for-byte
|
||
unchanged because no runtime path changed.
|
||
|
||
Evidence: four focused dependency tests pass, the Release solution builds with
|
||
zero errors, and the complete Release suite passes 8,406 tests with five
|
||
pre-existing skips. Exact rollback:
|
||
|
||
```text
|
||
git revert b632672e5ccabfb44c551e08f1c411ab2669c44a
|
||
```
|
||
|
||
### J1 — read, command, event, clock, and lifecycle contracts
|
||
|
||
**Completed 2026-07-25 at `854d9e9c`.**
|
||
|
||
- Define `IGameRuntimeView`, typed command interfaces, ordered event/delta
|
||
records, instance clock, lifecycle states, generation tokens, and teardown
|
||
acknowledgements.
|
||
- Build App adapters over the current owners first. Adapters borrow; they do
|
||
not copy mutable collections or own lifetime.
|
||
- Add a normalized parity trace of accepted inbound events, runtime commands,
|
||
state revisions, and lifecycle edges.
|
||
- Prove press-time graphical input reaches the same current owners through the
|
||
command contract with no extra frame of latency.
|
||
|
||
Gate: adapter and direct-host traces are identical over deterministic session,
|
||
entity, inventory, chat, movement, and portal fixtures; no canonical owner has
|
||
moved yet.
|
||
|
||
Result:
|
||
|
||
- `AcDream.Runtime` owns immutable borrowed-view contracts, typed commands,
|
||
ordered deltas, an instance clock, generation tokens, lifecycle snapshots,
|
||
and retryable teardown acknowledgements.
|
||
- Focused App adapters borrow the current canonical owners. They create no
|
||
second GUID map, state store, command queue, or frame boundary.
|
||
- Startup plus press-time selection, movement, and combat input now traverse
|
||
the typed command seam synchronously and still mutate the exact same owners.
|
||
- Runtime tests pass 13/13, App tests pass 3,838 with three skips, and the
|
||
complete Release solution passes 8,424 tests with five skips.
|
||
- The exact-binary connected gate at
|
||
`logs/connected-world-gate-20260725-190953/report.json` passed six capped
|
||
world checkpoints plus a fresh uncapped reconnect. Both processes exited
|
||
gracefully with no failures.
|
||
|
||
Exact rollback:
|
||
|
||
```text
|
||
git revert 854d9e9cd13092bd5aaa3cf025d73eeb4600e9f8
|
||
```
|
||
|
||
### J2 — session lifetime and ordered transport group
|
||
|
||
**Completed 2026-07-25 at `75930787`.**
|
||
|
||
**Detailed execution plan:**
|
||
[`2026-07-25-modern-runtime-slice-j2.md`](2026-07-25-modern-runtime-slice-j2.md).
|
||
|
||
- Remove App presentation dependencies from `LiveSessionController`,
|
||
`LiveSessionHost`, lifecycle host, event router, and command router.
|
||
- Move the same owner instances into Runtime with Core.Net transport and
|
||
instance-scoped clocks/queues.
|
||
- Preserve bind-before-connect, publish-after-EnterWorld, exact generation
|
||
rechecks, receive ordering, ack placement, graceful F653/disconnect, and
|
||
retryable replacement.
|
||
- Let App provide only endpoint credentials, presentation bindings, and
|
||
graphical lifecycle acknowledgements.
|
||
|
||
Gate: connected login/logout/reconnect and malformed/reentrant lifecycle suites
|
||
produce the same packet/order trace; no-window construction can connect and
|
||
disconnect without loading App or a backend.
|
||
|
||
Result: Runtime now owns the one `WorldSession` generation, ordered inbound
|
||
route, connect/enter/tick/replace transaction, and exact retryable teardown
|
||
acknowledgement. App keeps only connection-option conversion, graphical
|
||
callbacks, and one borrowed inertable UI command projection. The Release build,
|
||
79 Runtime tests, 3,776 App tests / 3 skips, 8,428 complete tests / 5 skips,
|
||
and the exact-binary seven-checkpoint connected gate pass with graceful exits.
|
||
Evidence:
|
||
[`../research/2026-07-25-slice-j2-session-lifetime-closeout.md`](../research/2026-07-25-slice-j2-session-lifetime-closeout.md).
|
||
|
||
Exact rollback:
|
||
|
||
```text
|
||
git revert 75930787741db40a83eab8663e4464dce8d687ba
|
||
```
|
||
|
||
### J3 — canonical identity, properties, and object-table group
|
||
|
||
- Strip renderer, particle, Wb, and streaming components from the canonical
|
||
record into an App projection store keyed only by local identity/incarnation.
|
||
- Move `LiveEntityRuntime`, accepted spawn/state/property timestamps,
|
||
`ClientObjectTable`, container/inventory indices, vitals, enchantments,
|
||
spell state, target/combat state, and their exact teardown into Runtime.
|
||
- Emit ordered create/update/rebucket/hidden/withdraw/delete deltas.
|
||
- Keep DAT-backed visual hydration, render registrations, effects, lights,
|
||
paperdoll, selection markers, and radar projections in App.
|
||
|
||
Gate: GUID reuse, equal-generation updates, parent/child identity,
|
||
inventory/container mutations, Hidden, delete/recreate, and portal teardown
|
||
match current traces; App has no server-GUID ownership.
|
||
|
||
### J4 — chat, inventory, magic, and gameplay-state services
|
||
|
||
- Move canonical chat history/channel state, inventory transactions, spell and
|
||
component state, enchantments, vitals, skills/attributes, and gameplay
|
||
cooldown state by coherent owner groups.
|
||
- Keep retained panel layout, text shaping, icons, paperdoll rendering, and
|
||
status-bar presentation in App.
|
||
- Route plugins and future bots through the same typed command/event surface
|
||
as graphical UI.
|
||
|
||
Gate: deterministic command/response traces and graphical ViewModel revisions
|
||
match; no Runtime type references UI abstractions.
|
||
|
||
### J5 — movement, physics, interaction, and combat group
|
||
|
||
- Move presentation-free movement interpretation, authoritative/predicted
|
||
physics state, selection identity, approach/use transactions, combat intent,
|
||
projectiles, and outbound movement cadence.
|
||
- Replace input and camera dependencies with typed commands and runtime views.
|
||
- Keep camera, mouse look, selection markers/highlight, combat/spell bars,
|
||
animated pose composition, sounds, and particles in App.
|
||
- Share immutable flat collision content while retaining per-session transition
|
||
scratch.
|
||
|
||
Gate: bit-identical collision/trajectory fixtures, target-facing and
|
||
auto-approach traces, outbound packet timing, combat/magic commands, and
|
||
graphical feel gates remain unchanged.
|
||
|
||
### J6 — world, portal, environment, and projection handshake
|
||
|
||
- Move authoritative teleport/session cell identity, world clock, weather
|
||
state, and reveal-generation state required by gameplay.
|
||
- Keep streaming publication, terrain/EnvCell rendering, portal tunnel,
|
||
materialization VFX, sky drawing, audio, and UI in App.
|
||
- Define the destination-ready/withdrawal acknowledgements between Runtime and
|
||
the graphical or headless host without making visual readiness gameplay
|
||
authority.
|
||
|
||
Gate: fresh login, repeated recall/portal, world edge, dungeon, reconnect, and
|
||
mid-portal disconnect traces match; the graphical screenshots remain accepted.
|
||
|
||
### J7 — one `GameRuntime` composition root
|
||
|
||
- Compose all moved lifetime groups into one instance-scoped `GameRuntime`.
|
||
- Make `GameWindow`/App own exactly one Runtime instance plus presentation
|
||
adapters.
|
||
- Delete temporary direct-owner adapters and every superseded App production
|
||
path.
|
||
- Register all Runtime and App projection owners with structural acquisition
|
||
leases and the exact teardown transaction.
|
||
|
||
Gate: graphical connected lifecycle/resource routes pass with no mirrored
|
||
state, no extra update latency, and no performance regression.
|
||
|
||
### J8 — no-window integration and Slice J closeout
|
||
|
||
- Build a transport/content test host that constructs Runtime directly.
|
||
- Connect, enter world, receive chat/inventory/world updates, move, use,
|
||
fight/cast through deterministic fixtures, portal, log out, reconnect, and
|
||
tear down without loading App/Silk/OpenAL/UI.
|
||
- Add cancellation, failure injection, same-process multiple-instance
|
||
isolation, credential-safe diagnostics, and zero-presentation-allocation
|
||
gates.
|
||
- Update architecture, milestone, roadmap, issue/divergence ledgers, and
|
||
durable memory.
|
||
|
||
Final gate: Release build/full tests, connected graphical route, no-window
|
||
integration, resource teardown, packet/order/timing parity, and the user visual
|
||
matrix all pass. Slice K may then build the Linux multi-session host without
|
||
another gameplay extraction.
|
||
|
||
## 5. Commit order
|
||
|
||
1. `arch(runtime): establish presentation-independent boundary`
|
||
2. `feat(runtime): define borrowed views commands and ordered events`
|
||
3. `refactor(runtime): move session lifetime and ordered transport`
|
||
4. `refactor(runtime): move canonical entity and property ownership`
|
||
5. `refactor(runtime): move gameplay state services`
|
||
6. `refactor(runtime): move movement physics interaction and combat`
|
||
7. `refactor(runtime): separate world authority from presentation`
|
||
8. `refactor(runtime): compose one graphical game runtime`
|
||
9. `test(runtime): close no-window parity and teardown`
|
||
|
||
Each commit is independently buildable and retains an exact rollback command
|
||
in this plan before its connected gate.
|