Move the complete update/render construction graph into a typed Phase-8 owner, explicitly carry the content dependencies it consumes, and publish both roots through one exact lease. Extract lifecycle resource sampling and frame-owned late bindings so partial startup and shutdown withdraw the same generation without window callbacks. Co-authored-by: Codex <codex@openai.com>
244 lines
10 KiB
Markdown
244 lines
10 KiB
Markdown
# GameWindow Slice 8 — Checkpoint I.8 Frame Roots and Session Start
|
||
|
||
**Status:** Active — I.8a–I.8b complete; I.8c terminal start next
|
||
|
||
**Parent:** `2026-07-22-gamewindow-slice-8-checkpoint-i-ordered-composition.md`
|
||
|
||
**Scope:** Complete Phase 7's session-facing owners, then implement ordered
|
||
composition Phases 8 and 9.
|
||
|
||
## 1. Outcome
|
||
|
||
Finish the production startup graph without changing accepted input, update,
|
||
render, network, portal, or UI behavior:
|
||
|
||
1. complete Phase 7 before any frame root is visible;
|
||
2. construct update and render roots locally and publish the pair atomically;
|
||
3. start the optional live session as the absolute final startup operation.
|
||
|
||
The current ordering defect is structural: `GameWindow.OnLoad` publishes the
|
||
frame pair before the combat/diagnostic command targets and sole gameplay input
|
||
subscriber are attached. I.8 moves those pre-frame owners into the Phase-7
|
||
result, so native callbacks can never observe an incomplete input/command
|
||
graph.
|
||
|
||
This is an ownership move. Retail algorithms and wire behavior remain
|
||
unchanged, so no divergence-register row is added.
|
||
|
||
## 2. I.8a — complete session/player composition
|
||
|
||
**Completed 2026-07-22.** `LiveSessionRuntimeFactory` now owns the exact
|
||
reset/router/command graph without a window reference. Phase 7 publishes the
|
||
session host, exact-owner combat and diagnostic command bindings, and the sole
|
||
gameplay input subscriber before Phase 8 can expose a frame root. Desired
|
||
components have a focused canonical snapshot owner. The component-lifecycle
|
||
handoff into the earlier live-presentation phase is an exact, retryable
|
||
adoption lease, so any later Phase-7 fault rolls it back without stranding or
|
||
replaying teardown.
|
||
|
||
### 2.1 Focused session runtime factory
|
||
|
||
Add `LiveSessionRuntimeFactory` under `AcDream.App/Net`. It owns the existing
|
||
domain-specific construction of:
|
||
|
||
- `LiveSessionHostBindings`;
|
||
- reset manifest bindings;
|
||
- selection and entered-world callbacks;
|
||
- event and command routers;
|
||
- inventory, character, and social session bindings.
|
||
|
||
The factory receives focused owners and state slots, never `GameWindow` and
|
||
never a callback to a substantial window method. Move the existing reset and
|
||
router bodies verbatim. Preserve the exact reset order and the existing
|
||
retail citations around player-module identity/shortcut/component cleanup.
|
||
|
||
Add `DesiredComponentSnapshotState` beside `ShortcutSnapshotState` so session
|
||
routers mutate one focused state owner. `GameWindow.DesiredComponents` remains
|
||
an ABI-compatible read-only projection over that owner. Existing
|
||
`LocalPlayerIdentityState`, `LocalPlayerControllerSlot`, and
|
||
`ShortcutSnapshotState` remain canonical; no mirrored values are introduced.
|
||
|
||
### 2.2 Commands and sole gameplay subscriber
|
||
|
||
At the tail of `SessionPlayerCompositionPhase`, after player mode and teleport
|
||
exist but before result publication:
|
||
|
||
1. create `LiveSessionHost` through the focused factory;
|
||
2. create and bind `LiveCombatModeCommandController`;
|
||
3. create and bind `RuntimeDiagnosticCommandController`;
|
||
4. create `GameplayInputCommandController` and priority targets;
|
||
5. create and attach the sole `GameplayInputActionRouter`.
|
||
|
||
Add exact-owner `BindOwned` tokens to the combat and diagnostic command slots.
|
||
The existing gameplay router already owns both subscriptions transactionally;
|
||
Phase 7 scope-owns it immediately after construction and before `Attach`.
|
||
|
||
Extend `SessionPlayerResult` and its publication seam with the exact
|
||
`LiveSessionHost`, command owners, and optional gameplay router. Publication
|
||
rejects replacement before changing any field. Failure before publication
|
||
disposes the router, detaches command targets, and rolls back the existing
|
||
Phase-7 suffix in reverse order.
|
||
|
||
## 3. I.8b — atomic frame-root composition
|
||
|
||
**Completed 2026-07-22.** `FrameRootCompositionPhase` now constructs the
|
||
unchanged render and update graphs from explicit prior-phase results and
|
||
focused runtime owners. `GameFrameGraphSlot.PublishOwned` publishes and
|
||
withdraws one exact pair. Optional lifecycle automation has a Phase-8 binding
|
||
owner, and `WorldLifecycleResourceSnapshotSource` samples the same canonical
|
||
owners without window callbacks or mirrored counters. The Phase-8 contract now
|
||
receives the Phase-2 content result explicitly because scripts and particles
|
||
are real frame dependencies; this removes a hidden reach-back through the
|
||
window shell.
|
||
|
||
Add `FrameRootCompositionPhase` implementing the existing
|
||
`IFrameRootCompositionPhase` contract. Its dependencies are focused App owners;
|
||
prior phase results supply all resources created during startup.
|
||
|
||
Preserve the exact current construction order:
|
||
|
||
1. teleport/login/GL-state and render-live preparation;
|
||
2. render resource begin/clear/live phases;
|
||
3. weather, sky-PES, world environment, camera, visibility, settings preview,
|
||
root, animated-object, and building sources;
|
||
4. terrain, PView, scene-pass, and world-scene diagnostics;
|
||
5. optional lifecycle automation;
|
||
6. retained/devtools/private presentation;
|
||
7. render orchestrator;
|
||
8. live-frame coordinator, camera frame, and update orchestrator;
|
||
9. atomic update/render pair publication as the final Phase-8 action.
|
||
|
||
Add `GameFrameGraphSlot.PublishOwned`. Its lease withdraws only the exact pair
|
||
it published, is idempotent, and cannot withdraw a later replacement. Scope-own
|
||
the lease immediately. A failure before publication leaves the slot empty; a
|
||
failure after publication withdraws the exact pair unless result publication
|
||
has transferred lifetime to the window shutdown owner.
|
||
|
||
### 3.1 Automation and resource snapshots
|
||
|
||
Add `WorldLifecycleResourceSnapshotSource` now rather than retaining
|
||
`CaptureWorldLifecycleResourceSnapshot` on the window. It samples the same
|
||
canonical world, live-runtime, effect, particle, light, script, mesh, texture,
|
||
GPU-memory, managed-memory, render-diagnostic, and frame-profiler owners.
|
||
|
||
This advances the owner-extraction portion of Checkpoint K; K still changes
|
||
checkpoint timing, acknowledgement barriers, JSONL validation, and soak
|
||
comparison. No checkpoint semantics change in I.8.
|
||
|
||
`FrameRootRuntimeBindings` owns the optional automation late binding and any
|
||
other Phase-8 external edge. It uses reverse, retryable, no-replay cleanup.
|
||
Shutdown withdraws the frame graph first, then detaches these frame-owned
|
||
bindings before borrowed session/presentation owners retire.
|
||
|
||
### 3.2 Publication
|
||
|
||
`FrameRootResult` contains:
|
||
|
||
- exact update and render roots;
|
||
- optional lifecycle automation owner;
|
||
- Phase-8 runtime bindings;
|
||
- the `LiveSessionHost` borrowed from Phase 7 for terminal start.
|
||
|
||
`IGameWindowFrameRootPublication` stores only owners needed by steady-state or
|
||
shutdown. Replacement is rejected atomically.
|
||
|
||
## 4. I.8c — terminal start and window cutover
|
||
|
||
Add `SessionStartCompositionPhase` implementing
|
||
`ISessionStartCompositionPhase<FrameRootResult>`. It invokes only
|
||
`LiveSessionHost.Start(RuntimeOptions)` and preserves the existing diagnostics
|
||
for missing credentials and failed startup.
|
||
|
||
`GameWindow.OnLoad` ends with:
|
||
|
||
```text
|
||
Phase 7 Compose
|
||
Phase 8 Compose and atomic pair publication
|
||
Phase 9 Start
|
||
return
|
||
```
|
||
|
||
There is no callback attachment, binding, publication, diagnostics setup, or
|
||
other work after Phase 9. Delete the old inline frame construction, session
|
||
factory/reset/router methods, snapshot method, and terminal status switch.
|
||
|
||
The existing typed nine-phase `GameWindowCompositionPipeline` remains the
|
||
executable order/failure oracle. Production `OnLoad` uses the same phase
|
||
interfaces and result chain explicitly because later-phase dependency records
|
||
are assembled from earlier concrete results; it must not introduce a retained
|
||
mega-context, service locator, or delegate façade around `GameWindow`.
|
||
|
||
## 5. Ownership and rollback order
|
||
|
||
Before frame publication, Phase-7 rollback is:
|
||
|
||
1. gameplay router detach;
|
||
2. diagnostic and combat command unbind;
|
||
3. remaining session/player bindings;
|
||
4. teleport, live session, and streamer teardown.
|
||
|
||
After frame publication, Phase-8 rollback is:
|
||
|
||
1. exact frame-pair withdrawal;
|
||
2. automation/other frame binding detach;
|
||
3. no disposal of resources borrowed from earlier successful phases.
|
||
|
||
Normal shutdown retains the frozen barrier order:
|
||
|
||
1. logical input/command quiescence;
|
||
2. live-session convergence;
|
||
3. physical input callback detach;
|
||
4. frame-pair withdrawal;
|
||
5. frame then session/player late-binding detach;
|
||
6. remaining session, live-entity, effect, render, content, GL, and native
|
||
owners.
|
||
|
||
## 6. Automated gates
|
||
|
||
### Session/runtime
|
||
|
||
- exact live-session host construction and reset trace;
|
||
- no `GameWindow` field or delegate capture in the focused factory;
|
||
- exact-owner combat/diagnostic bind, competing-owner rejection, idempotent
|
||
release, and rebind;
|
||
- gameplay router attaches before frame publication and rolls back from either
|
||
partial subscription;
|
||
- failed Phase-7 publication leaves no command/input/session target behind.
|
||
|
||
### Frame roots
|
||
|
||
- exact render/update leaf construction order;
|
||
- frame slot is empty at every pre-publication fault;
|
||
- exact pair publishes once and both native callbacks see the same generation;
|
||
- rollback withdraws only the published pair and never a later replacement;
|
||
- automation disabled path acquires nothing;
|
||
- automation enabled path binds once, detaches exactly, and samples the same
|
||
resource values as the former window method;
|
||
- frame result publication rejects replacement atomically.
|
||
|
||
### Terminal start and structure
|
||
|
||
- terminal start runs only after frame publication and every input/command
|
||
attachment;
|
||
- missing credentials and failed starts preserve current diagnostics;
|
||
- no operation follows `Start`;
|
||
- `GameWindow` contains no live-session binding factory, frame-root
|
||
construction body, resource-snapshot algorithm, or direct frame-pair
|
||
publication;
|
||
- no backend dependency enters Core and panels remain on UI abstractions;
|
||
- App Release tests, clean solution Release build, and complete Release suite
|
||
pass;
|
||
- behavior/order, architecture/ownership, and adversarial failure reviews are
|
||
clean.
|
||
|
||
## 7. Commit sequence
|
||
|
||
1. `docs(architecture): plan frame roots and terminal session start`
|
||
2. `refactor(app): complete session startup composition`
|
||
3. `refactor(app): compose atomic frame roots`
|
||
4. `refactor(app): make session start terminal`
|
||
|
||
Each implementation commit is independently buildable and preserves the
|
||
protected pre-existing `TransitionTypes.cs`, `.test-out/`, and `logs/` changes.
|
||
I.9 performs the complete Checkpoint-I corrected-diff review and documentation
|
||
closeout after these cuts land.
|