docs(render): V11 closeout — register, architecture, code structure, issues
Retires the GL framing from the documents that described a two-backend,
two-UI-stack client, and files what the deletion left behind.
Divergence register:
* AD-46 (anisotropic tap pattern in dense alpha scenery) is REFRAMED rather
than retired. Its substance survives -- distant foliage may read denser
than retail's -- but it was measured GL-vs-Vulkan, and with GL gone it is
a Vulkan-vs-retail question against the D3D oracle it already cited. The
measurement is kept as the evidence that the residual is a driver tap
pattern; the row now records that it is no longer falsifiable by
self-differential, which is a real loss the deletion causes.
* AD-47 and AD-48 are NEW, and the campaign's own risk register scheduled
them here: MSAA sample positions (measured at 8.83% of the frame at 4x,
which is why every strict gate runs MSAA off -- and therefore why a
regression confined to the multisample path would not be caught) and
present pacing (#235 is the live instance).
* AD-17's justification moves from a GL clip-plane citation to Vulkan's
maxClipDistances floor, which is the same 8, so the divergence is
unchanged and only its authority moves.
* AP-92 keeps IUiViewportRenderer.TextureIsBottomUp rather than folding it
flat, because it is what let the origin question be answered by data.
Architecture and code structure: the layer diagram, the frame order, the
residency vocabulary and the reference table all said OpenGL. The UI section
said two stacks. Rule 3's rationale is rewritten around what actually
happened -- ImGui was deleted and not one panel, ViewModel or command had to
change, because none of them had ever imported ImGuiNET. That is the rule
paying for itself, so it is recorded as evidence rather than removed as
obsolete.
Issues: #258 files the dev-panel host as a decision rather than an accident,
and #255 is REOPENED. Its TaskCreationOptions.LongRunning fix asks the
scheduler for a thread but does not promise two callbacks overlap; under nine
concurrent test assemblies it still failed 2 of 5 whole-suite runs. The
earlier evidence tested a narrower pool, not a contended one. The fix it
needs is a rendezvous inside the read stub -- not a weakened assertion.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5852bdb877
commit
c265b52d4b
5 changed files with 143 additions and 62 deletions
|
|
@ -18,7 +18,7 @@ from WB vs port ourselves).
|
|||
|
||||
## 1. The structural problem we're solving
|
||||
|
||||
The layered architecture works: `AcDream.Core` is GL-free, the network
|
||||
The layered architecture works: `AcDream.Core` is backend-free, the network
|
||||
layer is wire-compatible, the UI has a stable contract, plugins load.
|
||||
The structural debt is concentrated in **one file**:
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ after Slice 8 checkpoint K 1,622 lines / canonical soak shell
|
|||
|
||||
At the campaign baseline, `GameWindow` was the single object that:
|
||||
|
||||
- Owns the GL context, the window, input, and shaders.
|
||||
- Owns the Vulkan device, the window, input, and shaders.
|
||||
- Reads ~40 different environment variables across its lifetime.
|
||||
- Composes the shipped `LiveSessionController`/host/router boundary; it no
|
||||
longer owns a parallel session, command bus, subscription lifetime, connect,
|
||||
|
|
@ -90,34 +90,40 @@ you find yourself adding a 200-line method to `GameWindow`, stop and
|
|||
extract.
|
||||
|
||||
**Exemption:** Trivial wiring that *must* stay in `GameWindow` because
|
||||
it touches GL state during `OnLoad` is acceptable, but should still
|
||||
it touches device state during `OnLoad` is acceptable, but should still
|
||||
delegate to a collaborator for the substance.
|
||||
|
||||
### Rule 2: `AcDream.Core` must not depend on window / GL / backend projects
|
||||
### Rule 2: `AcDream.Core` must not depend on window / backend projects
|
||||
|
||||
**Why:** Core is the GL-free, testable layer. The moment Core imports
|
||||
a GL or windowing namespace, we've lost the ability to test it without
|
||||
a graphics context, and the layer split becomes fiction.
|
||||
**Why:** Core is the backend-free, testable layer. The moment Core imports
|
||||
a graphics or windowing namespace, we've lost the ability to test it without
|
||||
a device, and the layer split becomes fiction.
|
||||
|
||||
**How to apply:** Phase O removed both external WorldBuilder/backend project
|
||||
references. The only currently allowed seams are the GL-free helpers owned in
|
||||
references. The only currently allowed seams are the backend-free helpers owned in
|
||||
our tree under `src/AcDream.Core/Rendering/Wb/`: `TerrainUtils`,
|
||||
`TerrainEntry`, `RegionInfo`, `SceneryHelpers`, and `TextureHelpers`.
|
||||
`ObjectMeshManager` and every GL resource owner remain in App. If Core needs a
|
||||
`ObjectMeshManager` and every GPU resource owner remain in App. If Core needs a
|
||||
new capability, define a narrow Core interface and implement it in App; adding
|
||||
a new project reference requires an inventory-doc update explaining why.
|
||||
|
||||
### Rule 3: UI panels target `AcDream.UI.Abstractions` only
|
||||
|
||||
**Why:** This is the one rule that keeps D.2b (the future retail-look
|
||||
backend) viable. Every panel that imports `ImGuiNET` directly is a panel
|
||||
we'd have to rewrite when the backend swaps.
|
||||
**Why:** The rule was written to keep D.2b (the retail-look backend)
|
||||
viable while ImGui was still the developer stack, and **it paid off**: when
|
||||
Campaign V slice V11 deleted ImGui on 2026-07-29, not one panel contract,
|
||||
ViewModel or command had to change, because none of them had ever imported
|
||||
`ImGuiNET`. `AcDream.UI.Abstractions` survived a backend deletion intact.
|
||||
|
||||
**How to apply:** A panel's `using` block must mention
|
||||
`AcDream.UI.Abstractions.*` and nothing from `AcDream.UI.ImGui`. The
|
||||
panel writes against `IPanelRenderer`. The `ImGuiPanelRenderer`
|
||||
translates those calls to ImGui at runtime. Plugin-facing UI follows the
|
||||
same rule.
|
||||
`AcDream.UI.Abstractions.*` and nothing from any backend assembly. The panel
|
||||
writes against `IPanelRenderer`; a renderer implementation translates those
|
||||
calls at runtime. Plugin-facing UI follows the same rule.
|
||||
|
||||
**Status:** there is currently no `IPanelRenderer` implementation in the tree —
|
||||
the ImGui one went with V11 and the replacement is issue **#258**. The contract
|
||||
is kept rather than deleted precisely because this rule proved its worth; a new
|
||||
host binds to it without touching a single panel.
|
||||
|
||||
### Rule 4: Startup env vars enter through `RuntimeOptions`
|
||||
|
||||
|
|
@ -173,7 +179,7 @@ Today:
|
|||
|
||||
`tests/AcDream.App.Tests/` now exists and owns App-layer controller, streaming,
|
||||
render-resource lifetime, retained-UI, and `RuntimeOptions` tests. New App tests
|
||||
belong there; do not place GL-free Core behavior in that project merely because
|
||||
belong there; do not place backend-free Core behavior in that project merely because
|
||||
App currently wires it.
|
||||
|
||||
---
|
||||
|
|
@ -228,7 +234,7 @@ src/AcDream.App/
|
|||
├── Program.cs # parse args + env → RuntimeOptions, build GameWindow
|
||||
├── RuntimeOptions.cs # typed startup options (Rule 4)
|
||||
├── Rendering/
|
||||
│ ├── GameWindow.cs # thin: GL/window lifecycle + delegates per-frame to RenderFrameOrchestrator
|
||||
│ ├── GameWindow.cs # thin: device/window lifecycle + delegates per-frame to RenderFrameOrchestrator
|
||||
│ ├── RenderFrameOrchestrator.cs # GPU-flight boundary + typed world/private/UI render phases
|
||||
│ ├── LiveEntityAnimationScheduler.cs # shipped: ordinary live-object update workset
|
||||
│ ├── LiveEntityAnimationPresenter.cs # final part-pose/mesh/effect composition after scheduler output
|
||||
|
|
@ -284,10 +290,10 @@ src/AcDream.App/
|
|||
|
||||
What `GameWindow` keeps:
|
||||
|
||||
- `IWindow` / `GL` / `IInputContext` lifecycle (constructor + `OnLoad` +
|
||||
- `IWindow` / device / `IInputContext` lifecycle (constructor + `OnLoad` +
|
||||
`Run` + `OnClosing`).
|
||||
- `RuntimeOptions` reference (the typed startup config).
|
||||
- GL resource construction and top-level collaborator composition. Construction
|
||||
- GPU resource construction and top-level collaborator composition. Construction
|
||||
is allowed here; feature algorithms and mutable subsystem state are not.
|
||||
- One field per top-level collaborator (`_liveSessionController`,
|
||||
`_liveEntityRuntime`, `_selectionInteraction`, `_streamingPresentation`,
|
||||
|
|
@ -480,7 +486,7 @@ useful ordering seam, but its ownership status is **partial**.
|
|||
| Landblock presentation | **Complete** | `LandblockBuildFactory` owns the captured-origin DAT transaction; concrete render/physics/DAT-static publishers and `LandblockPresentationPipeline` own typed-meter publication and exact retryable retirement. `StreamingController` owns stable destination/control/unload/Near/Far queues and destination reservation. CPU mesh-cache restaging requires an exact live owner. `StreamingOriginRecenterCoordinator` serializes old-window retirement with teleport/session origin lifetimes. `GameWindow` retains construction and one pipeline field only (`c79d0a49`, closeout `4a205a3e`; Slice E closeout `91e82c3c`). |
|
||||
| Render-frame orchestration | **Complete** | `RenderFrameOrchestrator` owns the GPU-flight, resource, world/PView/shared-alpha, private-presentation, diagnostics, screenshot, and recovery graph. `GameWindow.OnRender` takes one logical window-size snapshot and performs one immutable handoff (`9d7df1bf`). |
|
||||
| Unified `GameEntity` | **Slice J complete** | Canonical identity, retained-object lifetime, direct views, ordered entity/object deltas, gameplay state, action/combat/magic/movement/physics/remote/projectile simulation, world environment, reveal/transit truth, and host acknowledgement share failure-safe Runtime owners while exact graphical sidecars stay in App. One `GameRuntime` composes the graph. `RuntimeGenerationReset` is the sole retryable canonical-generation reset for graphical and no-window hosts; the deterministic direct host proves lifecycle, commands, portal, reconnect, GUID reuse, fault recovery, isolation, and terminal convergence without presentation assemblies (`a9a822f2`). |
|
||||
| Headless host | **Slice K complete** | `AcDream.Headless` references only Runtime and loads no App/UI/GL/window/audio assembly. Portable paths/config/credentials, deterministic command/event scheduling, shared immutable content, exact per-session identity, failure quarantine, reconnect, resource telemetry, 1/5/10/30-session isolation, two-hour simulated endurance, and the exact two-account native-Linux connected soak pass through `776482da`. |
|
||||
| Headless host | **Slice K complete** | `AcDream.Headless` references only Runtime and loads no App/UI/graphics/window/audio assembly. Portable paths/config/credentials, deterministic command/event scheduling, shared immutable content, exact per-session identity, failure quarantine, reconnect, resource telemetry, 1/5/10/30-session isolation, two-hour simulated endurance, and the exact two-account native-Linux connected soak pass through `776482da`. |
|
||||
|
||||
### 4.3 Revised extraction sequence
|
||||
|
||||
|
|
@ -687,7 +693,7 @@ Detailed execution ledger:
|
|||
(complete).
|
||||
|
||||
Move the complete draw graph and its reusable frame-local scratch state into a
|
||||
GL-owning App collaborator. Preserve the exact modern pipeline order, clip
|
||||
GPU-owning App collaborator. Preserve the exact modern pipeline order, clip
|
||||
routing, PView flood, landscape/opaque/shared-alpha flush boundaries,
|
||||
particles, debug draw, paperdoll, retained UI, and frame fences. Do not pass a
|
||||
hundred individual delegates or let the orchestrator reach back into
|
||||
|
|
@ -715,7 +721,7 @@ residency without weakening leak detection.
|
|||
Detailed execution ledger:
|
||||
[`docs/plans/2026-07-22-gamewindow-slice-8-composition-lifecycle.md`](../plans/2026-07-22-gamewindow-slice-8-composition-lifecycle.md).
|
||||
|
||||
Keep GL/window construction in `GameWindow.OnLoad`, but group creation into
|
||||
Keep device/window construction in `GameWindow.OnLoad`, but group creation into
|
||||
small composition functions and delete feature state left behind by prior
|
||||
slices. `OnClosing` delegates to the existing retryable shutdown transaction.
|
||||
Silk callbacks become narrow calls into the input, update, render, resize,
|
||||
|
|
@ -745,14 +751,14 @@ Gameplay draft fields when combat preferences change. `GameWindow` is now 3,663
|
|||
raw lines / 162 fields / 37 methods at G. H adds sole lifetime roots for the
|
||||
terrain atlas and dedicated sky shader, one retained Host/runtime lease, an
|
||||
atomic update/render frame-root slot, and a prepare-aware portal fallback and
|
||||
transfer slot. GL construction and state mutations now use checked commit
|
||||
transfer slot. GPU construction and state mutations now use checked commit
|
||||
boundaries with exact retry ownership for failed names, bindless residency,
|
||||
and texture-binding restoration. `GameWindow` is 3,689 raw lines / 162 fields /
|
||||
37 methods at H. Checkpoint I.1–I.5 now provide the executable nine-phase
|
||||
oracle, platform/host/content/settings phases, and the production world/render
|
||||
phase. `WorldRenderCompositionPhase` owns Region/environment, the mandatory
|
||||
modern-renderer foundation, immutable terrain-worker inputs, and WB/texture/
|
||||
sampler construction; every Phase-4 GL constructor has retryable prefix
|
||||
sampler construction; every Phase-4 GPU constructor has retryable prefix
|
||||
ownership. `GameWindow` is 3,522 raw lines after I.5. I.6 moves interaction,
|
||||
retained UI, live presentation, and landblock publication into ordered
|
||||
composition phases. Typed exact-owner sources bridge later session,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue