# GameWindow Slice 8 — Checkpoint G Runtime Settings Plan ## Objective Replace `GameWindow`'s duplicated pre-window and `OnLoad` settings paths with one two-phase `RuntimeSettingsController`. The controller owns persistence and live settings state; render, window, audio, UI, and streaming objects remain borrowed targets. This is a structural cutover, not a redesign of the settings format or retail option behavior. Two carried behaviors are now explicit rather than accidental. Saved FOV is applied during startup even when developer tools are disabled; previously it was incorrectly gated on construction of `SettingsVM`. The named-retail `/framerate` live toggle and notice remain intact, while acdream's already shipped cross-launch ShowFps persistence is documented as AP-121 rather than being attributed to the retail command body. ## Frozen behavior and ordering 1. Construct the controller before `Window.Create` and load Display, Audio, Gameplay, Chat, and the `default` Character bag exactly once. 2. Resolve the preset plus environment overrides once for the immutable startup snapshot. `WindowOptions.VSync` comes from the pacing policy initialized with that snapshot; `WindowOptions.Samples` comes from the same resolved quality. 3. After window/GL input, camera, DAT effects, and optional audio exist, but before devtools or world/render factories, apply startup settings in this order: monitor-aware pacing, resolution/fullscreen, field of view, then audio. 4. Downstream terrain, dispatcher, render-range, and streaming factories read the same startup quality snapshot. The legacy startup stream-radius override remains at its current composition boundary. 5. Bind one complete `RuntimeSettingsTargets` only after window, UI (when enabled), terrain atlas, dispatcher, render-range, and streaming exist. Binding performs no display, quality, UI-lock, or audio replay. 6. Settings-panel Save preserves its callback order: keybindings, Display, Audio, Gameplay, Chat, Character. Each section retains its existing persistence/error boundary. 7. Display Save persists first, applies resolution/fullscreen, publishes the new display snapshot, then reapplies quality. A changed MSAA sample count is logged as restart-required and is not applied to the live GL context. 8. Runtime quality reapply preserves the existing order: alpha-to-coverage, terrain anisotropy, render-range publication, streaming reconciliation, completion budget. 9. `/framerate`, UI lock, loot permits, and combat preferences mutate the controller's canonical state, synchronize the optional Settings draft using the existing draft-preservation rules, and retain their existing save-error behavior. 10. Enter-world changes the active toon key, loads that character bag even when devtools are disabled, and publishes it to the optional Settings view model. Session reset restores the startup/default character context before the later identity-reset operation restores the key to `default`. 11. Per-frame display/audio preview reads the optional Settings draft through a typed source. Particle range and FPS visibility read the same source so an unsaved draft still previews exactly as it does today. 12. Shutdown first withdraws the Settings view-model and runtime-target loans; the controller never disposes the window, renderer, UI, streaming, audio, or input objects it borrows. ## Types and ownership - `IRuntimeSettingsStorage` is the test seam for the five settings bags. `JsonRuntimeSettingsStorage` is the production owner of the one concrete `SettingsStore` and exposes that store only for retained-window layout persistence. - `RuntimeSettingsSnapshot` is the immutable startup value. - `IRuntimeSettingsStartupTarget` receives the one startup Display/Audio apply. - `IRuntimeSettingsTargets` receives future display-window, quality, and UI-lock changes. `BindRuntimeTargets` stores it without invoking it. - `IRuntimeSettingsPreviewSource` exposes current Display/Audio preview values and whether a live draft exists. - `RuntimeSettingsController` owns persistence, current values, active toon, resolved quality, and the optional `SettingsVM` binding. It also implements the combat settings source; no second gameplay-state mirror remains. - `SilkRuntimeDisplayWindowTarget`, `RuntimeSettingsStartupTargets`, and `RuntimeSettingsTargets` are App-layer adapters over borrowed runtime objects. ## Automated gates - Construction loads every bag once and populates one immutable snapshot. - Startup apply is ordered, exactly once, and independent of GL in controller tests. - Runtime target binding produces zero calls; unbinding prevents future target calls while state and persistence still advance. - Display Save ordering, quality transition, and restart-required MSAA logging. - Quality target receives one complete resolved value per reapply. - Draft preview/cancel, external FPS mutation, UI lock, loot permits, and combat option synchronization. - Toon activate/load/reset/save behavior with and without a Settings view model. - Save failures preserve each established state/target boundary. - Source-boundary test proves `GameWindow` no longer constructs or loads a `SettingsStore`, owns persisted settings fields, or contains quality/display feature bodies. - Focused App tests, full App tests, Release solution build, and full Release suite. ## Review and commit gate After the focused tests pass, the existing retail-conformance, architecture/integration, and adversarial reviewers inspect the complete diff in parallel. Confirmed findings are corrected and the same reviewers repeat until clean. Documentation, roadmap, issues, memory, `CLAUDE.md`, and `AGENTS.md` are reconciled in the same bisectable Checkpoint G commit. ## Implementation result - `RuntimeSettingsController` is constructed before `Window.Create`; all five bags load once and `WindowOptions` consumes its immutable startup snapshot. - Startup substeps commit independently, so an audio failure retries audio without replaying already successful pacing/display/FOV work. - Late target binding is inert and reversible; expected-instance SettingsVM withdrawal cannot detach a replacement binding. - The concrete quality adapter preserves all five application steps and the unchanged MSAA restart boundary. - Combat changes merge their three fields into a live Gameplay draft rather than overwriting unrelated unsaved fields; successful external changes also advance the SettingsVM persisted baseline so Cancel cannot resurrect stale command state. - UI-lock target, persistence, and baseline publication form one explicit convergence state. A transient failure leaves the same requested value retryable instead of letting the equality fast-path strand unfinished work. - Enter/reset/toon changes load and publish Character state independently of developer-tool availability. - `GameWindow` no longer constructs or loads `SettingsStore`, owns persisted settings mirrors, or contains display/quality/settings feature bodies. - Candidate metrics: 3,663 raw lines / 162 fields / 37 methods, down 394 lines / 36 fields / 17 methods from Checkpoint F and 12,060 lines (76.7%) from the campaign baseline. - Thirty-five focused App settings/boundary tests, all 43 `SettingsVMTests`, the UI Abstractions Release suite (534 pass), and the App Release suite (3,183 pass / 3 intentional skips) pass. All three independent corrected-diff reviews are clean. The production App Release build has zero warnings/errors; the solution Release build retains the 17 existing #228 test-project warnings; and the complete Release suite passes 7,553 tests / 5 intentional skips.