acdream/memory/project_gamewindow_decomposition.md

84 lines
4.1 KiB
Markdown

# GameWindow decomposition — current truth
## Current state
The behavior-preserving App ownership campaign is complete through Slice 6.
`GameWindow.cs` moved from the 2026-07-21 baseline of 15,723 lines / 278 fields /
205 methods to 7,026 lines / 241 fields / 108 methods: 8,697 lines (55.3%) were
removed without changing accepted gameplay or rendering behavior.
| Slice | Ownership moved out | Closeout size |
|---|---|---:|
| 1 | world selection and interaction intent | 14,912 / 278 / 191 |
| 2 | live animation presentation | 14,546 / 277 / 190 |
| 3 | complete live-session lifecycle and routing | 14,310 / 274 / 190 |
| 4 | live-entity hydration, teardown, and network presentation | 10,301 / 267 / 163 |
| 5 | landblock build, publication, retirement, and shared-origin lifetime | 8,811 / 247 / 153 |
| 6 | complete update-frame orchestration | 7,026 / 241 / 108 |
Slice 6 implementation commits are `99a3e819`, `4e4aac2c`, `0bc9fda9`,
`c5570383`, `eeb0f6b4`, `947c61d2`, and production cutover `e91f3102`.
The detailed ledgers and earlier commit sets live under `docs/plans/2026-07-21-
gamewindow-slice-*.md` and `docs/architecture/code-structure.md`.
## Frozen update graph
`GameWindow.OnUpdate` starts the profiler scope and calls one
`UpdateFrameOrchestrator.Tick`. The accepted production graph is:
1. retry retained live-entity teardown;
2. normalize/publish the update and PhysicsScript clocks;
3. converge streaming origin, residence, readiness, and rescued projections;
4. sample semantic input, raw mouse, and combat intent;
5. advance live objects and deferred presentation hooks;
6. drain inbound network traffic inside one world mutation batch;
7. run the local post-network position tail;
8. reconcile root/child/emitter/light presentation without advancing time;
9. expire liveness;
10. advance local teleport/reveal/tunnel presentation;
11. evaluate one-shot player-mode entry;
12. publish fly/chase/player camera presentation.
`LiveEntityRuntime` remains the canonical identity/incarnation owner.
`GpuWorldState` remains the spatial bucket owner. `LiveSessionController` owns
the session generation. Extracted phase owners query these typed runtimes and
must not create replacement dictionaries, service locators, or callback
facades into substantial `GameWindow` methods.
## Accepted verification
- Release suite: 7,182 passed / 5 fixture or environment skips.
- Connected lifecycle/reconnect: 314.195 seconds, graceful close and fresh
process reconnect passed; only 25 expected world-edge empty landblocks.
- Synchronized nine-stop resource soak: 393.581 seconds, graceful exit; stable
21,025 entity and 13 animation-owner counts at the Caul return and Caul
plateau; update p95 0.8 ms. Working/private memory delta was +112.2/+111.0
MiB, inside the gate.
- The 35 missing VFX table/emitter diagnostics are known DAT-driven records,
not a Slice 6 regression.
- TS-50, TS-51, and TS-53 remain registered; Slice 6 introduced no new retail
divergence.
## Next work
Slice 7 extracts `RenderFrameOrchestrator`: the modern draw graph, portal/PView
visibility routing, landscape/opaque/shared-alpha flushes, particles, debug
draw, paperdoll, retained UI, frame fences, and reusable frame-local scratch.
It must keep the exact accepted order and use a small immutable service set plus
explicit per-frame input. It may not become a GL service locator or call
substantial draw bodies back on `GameWindow`.
Slice 8 then groups composition and shutdown wiring and reduces Silk callbacks
to narrow calls into input, update, render, resize, focus, and shutdown owners.
## Do not retry
- Do not reintroduce delegate facades into `GameWindow`; an ordering wrapper is
not an extraction until the state and behavior body move.
- Do not reorder the frozen update graph during structural work. TS-53 records
the known retail host-order difference for a separate evidence-backed port.
- Do not add a second GUID, session, spatial, or resource owner.
- Do not fold full `GameEntity` aggregation into this campaign; evaluate it
after Slice 8.
- Small value/policy callbacks and diagnostics are acceptable only when they do
not call a substantial window body or hide mutable ownership.