docs(architecture): close live-session ownership slice

This commit is contained in:
Erik 2026-07-21 12:44:48 +02:00
parent 485b3fb6ed
commit ed9dc36643
8 changed files with 80 additions and 50 deletions

View file

@ -1,7 +1,7 @@
# acdream — code structure & extraction sequence
**Status:** Living document. Created 2026-05-16; implementation reconciliation
completed 2026-07-21; Slices 1 and 2 landed the same day. This is the active
completed 2026-07-21; Slices 13 landed the same day. This is the active
structural program before new M4 subsystems enter the App layer.
**Purpose:** Describe the desired structural state of the App layer,
explain the rules we've adopted, and lay out the safe extraction
@ -25,15 +25,16 @@ The structural debt is concentrated in **one file**:
baseline cf50ee3d 15,723 lines / 278 fields / 205 methods
after Slice 1 14,912 lines / 278 fields / 191 methods
after Slice 2 14,546 lines / 277 fields / 190 methods
after Slice 3 14,310 lines / 274 fields / 190 methods
```
`GameWindow` is the single object that:
- Owns the GL context, the window, input, and shaders.
- Reads ~40 different environment variables across its lifetime.
- Still owns live-session bootstrap, character entry, roughly 440 lines of
event subscription, and most App-side packet handlers even though
`LiveSessionController` owns the socket/session shell.
- Composes the shipped `LiveSessionController`/host/router boundary; it no
longer owns a parallel session, command bus, subscription lifetime, connect,
character-entry, reconnect, or graceful-close body.
- Owns the adapters that hydrate canonical `LiveEntityRuntime` records into
animation, collision, rendering, and DAT-backed appearance resources.
- Composes the shipped `WorldSelectionQuery` and
@ -187,6 +188,7 @@ src/AcDream.App/
│ └── Vfx/ # (already exists)
├── Net/
│ ├── LiveSessionController.cs # owns complete WorldSession connect/enter/logout/reconnect lifecycle
│ ├── LiveSessionLifecycleHost.cs # narrow App composition + exact borrowed-session attachment
│ └── LiveSessionEventRouter.cs # typed subscriptions → focused domain handlers
├── Physics/
│ ├── ProjectileController.cs # canonical live-record projectile orchestration
@ -387,7 +389,7 @@ useful ordering seam, but its ownership status is **partial**.
| Area | Status | Current truth |
|---|---|---|
| Startup options | **Complete** | `RuntimeOptions` owns startup configuration (`eda936dc`). Remaining direct environment reads are legacy runtime diagnostics, not startup configuration. |
| Network session | **Partial** | `LiveSessionController` owns endpoint resolution, `WorldSession` construction, ticking, and disposal (`0b25df53`). `TryStartLiveSession`, character choice/entry, session clearing, about 440 lines of subscriptions, and most App packet handlers remain in `GameWindow`. |
| Network session | **Complete** | `LiveSessionController` owns resolve/create/bind/Connect/selection/EnterWorld/Tick/stop/reconnect/disposal; `LiveSessionLifecycleHost` is the narrow App composition boundary; `LiveSessionEventRouter` and `LiveSessionCommandRouter` own exact inbound/outbound lifetimes. `GameWindow` retains one controller field and focused domain sink factories only (`d9ccf8a6`, `6a5d9e2e`). |
| Live identity/lifetime | **Complete core owner** | `LiveEntityRuntime` owns incarnation identity, accepted snapshots/timestamps, runtime components, logical/spatial lifetime, and teardown. `GameWindow` still owns large hydration and wire-to-presentation adapter bodies. |
| Inbound/object-frame order | **Partial** | `RetailInboundEventDispatcher`, `RetailLiveFrameCoordinator`, `LiveEntityAnimationScheduler`, `LiveEntityAnimationPresenter`, static scheduler, remote/projectile updaters, and teleport owners are shipped. `AdvanceLiveObjectRuntimeCore` retains the visible cross-owner order until Slice 6. |
| World reveal | **Complete** | `WorldRevealCoordinator` owns login/portal readiness and reveal lifetime (`a4ef5788`). The accepted deterministic lifecycle trace did not change after extraction. |
@ -468,19 +470,32 @@ rigid trailing poses. `GameWindow` lost 366 lines, two methods, and one net
field. Three independent retail, architecture, and adversarial review loops
finished clean; focused App/Core tests and the complete App suite pass.
#### Slice 3 — complete live-session ownership — NEXT
#### Slice 3 — complete live-session ownership — COMPLETE 2026-07-21
Expand `LiveSessionController` to own connect, character-list validation,
character selection, EnterWorld, graceful character logout, reconnect, and
session-scoped disposal. Add `LiveSessionEventRouter` for typed subscriptions;
it routes events to focused domain handlers and owns unsubscription, but owns
no entity or UI state.
Detailed execution plan:
[`docs/plans/2026-07-21-gamewindow-slice-3-live-session.md`](../plans/2026-07-21-gamewindow-slice-3-live-session.md).
Move `TryStartLiveSession`, `ClearInboundEntityState`, and
`WireLiveSessionEvents` out of `GameWindow`. Do not create a giant context bag
or a second world-state owner. The connected gate must prove login, fresh world
reveal, command/chat, portal, exact `0xF653` logout, ACE endpoint disconnect,
and fresh-process reconnect.
`LiveSessionController` now owns the complete resolve/create/bind/Connect/
CharacterList/select/EnterWorld/Tick/stop/reconnect/dispose transaction. Exact
generation and operation-depth gates prevent synchronous lifecycle callbacks
from resurrecting a superseded session. Staged teardown makes commands inert,
detaches events, gracefully disposes the exact `WorldSession`, detaches the
host, and runs the full reset manifest to convergence before reuse.
`LiveSessionLifecycleHost` is the narrow App adapter; the router and command
owners are transactional and session-bound. `GameWindow` lost `_liveSession`,
the router/command fields, and the old startup/reset/wiring/disposal methods.
Both UI stacks resolve `controller.Commands`; direct feature sends borrow
`CurrentSession` at call time. Forty-seven controller cases plus host,
transport-allocation, and structural gates cover failure/reentrancy/reuse.
Three independent retail, architecture, and adversarial reviews finished
clean. The Release suite passes 6,714 tests with five intentional skips. The
306-second connected lifecycle gate passed capped login, five travel/revisit
checkpoints, exact graceful close, and uncapped fresh-process reconnect; both
client processes exited normally.
`GameWindow` fell another 236 lines and three fields to 14,310 lines / 274
fields / 190 methods. Slice 4 is next.
#### Slice 4 — extract live-entity App integration