docs(architecture): close GameWindow slice 6
This commit is contained in:
parent
e91f310279
commit
9512404e25
9 changed files with 182 additions and 46 deletions
23
AGENTS.md
23
AGENTS.md
|
|
@ -115,7 +115,7 @@ and the final two-client portal-out/materialization observer flow are
|
||||||
user-gated. Deterministic world-lifecycle automation protects fresh login,
|
user-gated. Deterministic world-lifecycle automation protects fresh login,
|
||||||
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
|
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
|
||||||
disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
|
disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
|
||||||
Release builds; 7,054 tests pass / 5 skip.
|
Release builds; 7,182 tests pass / 5 skip.
|
||||||
|
|
||||||
**Active prerequisite before new M4 subsystem work:** continue the
|
**Active prerequisite before new M4 subsystem work:** continue the
|
||||||
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21.
|
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21.
|
||||||
|
|
@ -123,18 +123,21 @@ Selection/interaction Slice 1, live-animation-presentation Slice 2, complete
|
||||||
live-session ownership Slice 3, and live-entity App integration Slice 4 are
|
live-session ownership Slice 3, and live-entity App integration Slice 4 are
|
||||||
landed. Focused hydration, teardown, inbound-authority, network-update, and
|
landed. Focused hydration, teardown, inbound-authority, network-update, and
|
||||||
motion-runtime owners now sit over canonical `LiveEntityRuntime` without a
|
motion-runtime owners now sit over canonical `LiveEntityRuntime` without a
|
||||||
second GUID dictionary. Slice 5 is complete: the complete DAT
|
second GUID dictionary. Slice 5 landblock presentation and Slice 6 update-frame
|
||||||
build, render/physics/static publication, retryable retirement, and shared-
|
orchestration are complete. Streaming, input, the object/network barrier,
|
||||||
origin lifetime barrier are out of `GameWindow`; it is now 8,811 raw lines /
|
liveness, teleport, player mode, and camera presentation have typed phase
|
||||||
247 fields / 153 methods, down 44% from the 15,723-line campaign baseline.
|
owners; `GameWindow.OnUpdate` is one orchestrator handoff with no substantial
|
||||||
The lifecycle/reconnect and synchronized nine-stop soak gates pass. Slice 6
|
transitive callback facade. `GameWindow` is 7,026 raw lines / 241 fields / 108
|
||||||
update-frame orchestration is active; later slices finish render orchestration
|
methods, down 8,697 lines (55.3%) from the 15,723-line campaign baseline. The
|
||||||
and composition cleanup.
|
7,182-test Release suite, 314-second lifecycle/reconnect gate, and 394-second
|
||||||
|
synchronized nine-stop soak pass. Slice 7 draw-frame orchestration is active;
|
||||||
|
Slice 8 finishes composition and Silk callback cleanup.
|
||||||
See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining
|
See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining
|
||||||
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
|
R6 ownership cleanup, TS-50/TS-51/TS-53, Modern Pipeline MP1b+, and #225's
|
||||||
lifestone/particle alpha visual gate.
|
lifestone/particle alpha visual gate.
|
||||||
|
|
||||||
Start structural work at `docs/architecture/code-structure.md`; start
|
Start structural work at `memory/project_gamewindow_decomposition.md` and
|
||||||
|
`docs/architecture/code-structure.md`; start
|
||||||
magic follow-up at `claude-memory/project_magic_ui_and_casting.md`; start
|
magic follow-up at `claude-memory/project_magic_ui_and_casting.md`; start
|
||||||
render/streaming work at `claude-memory/project_render_pipeline_digest.md`.
|
render/streaming work at `claude-memory/project_render_pipeline_digest.md`.
|
||||||
|
|
||||||
|
|
|
||||||
23
CLAUDE.md
23
CLAUDE.md
|
|
@ -113,7 +113,7 @@ and the final two-client portal-out/materialization observer flow are
|
||||||
user-gated. Deterministic world-lifecycle automation protects fresh login,
|
user-gated. Deterministic world-lifecycle automation protects fresh login,
|
||||||
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
|
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
|
||||||
disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
|
disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
|
||||||
Release builds; 7,054 tests pass / 5 skip.
|
Release builds; 7,182 tests pass / 5 skip.
|
||||||
|
|
||||||
**Active prerequisite before new M4 subsystem work:** continue the
|
**Active prerequisite before new M4 subsystem work:** continue the
|
||||||
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21.
|
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21.
|
||||||
|
|
@ -121,18 +121,21 @@ Selection/interaction Slice 1, live-animation-presentation Slice 2, complete
|
||||||
live-session ownership Slice 3, and live-entity App integration Slice 4 are
|
live-session ownership Slice 3, and live-entity App integration Slice 4 are
|
||||||
landed. Focused hydration, teardown, inbound-authority, network-update, and
|
landed. Focused hydration, teardown, inbound-authority, network-update, and
|
||||||
motion-runtime owners now sit over canonical `LiveEntityRuntime` without a
|
motion-runtime owners now sit over canonical `LiveEntityRuntime` without a
|
||||||
second GUID dictionary. Slice 5 is complete: the complete DAT
|
second GUID dictionary. Slice 5 landblock presentation and Slice 6 update-frame
|
||||||
build, render/physics/static publication, retryable retirement, and shared-
|
orchestration are complete. Streaming, input, the object/network barrier,
|
||||||
origin lifetime barrier are out of `GameWindow`; it is now 8,811 raw lines /
|
liveness, teleport, player mode, and camera presentation have typed phase
|
||||||
247 fields / 153 methods, down 44% from the 15,723-line campaign baseline.
|
owners; `GameWindow.OnUpdate` is one orchestrator handoff with no substantial
|
||||||
The lifecycle/reconnect and synchronized nine-stop soak gates pass. Slice 6
|
transitive callback facade. `GameWindow` is 7,026 raw lines / 241 fields / 108
|
||||||
update-frame orchestration is active; later slices finish render orchestration
|
methods, down 8,697 lines (55.3%) from the 15,723-line campaign baseline. The
|
||||||
and composition cleanup.
|
7,182-test Release suite, 314-second lifecycle/reconnect gate, and 394-second
|
||||||
|
synchronized nine-stop soak pass. Slice 7 draw-frame orchestration is active;
|
||||||
|
Slice 8 finishes composition and Silk callback cleanup.
|
||||||
See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining
|
See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining
|
||||||
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
|
R6 ownership cleanup, TS-50/TS-51/TS-53, Modern Pipeline MP1b+, and #225's
|
||||||
lifestone/particle alpha visual gate.
|
lifestone/particle alpha visual gate.
|
||||||
|
|
||||||
Start structural work at `docs/architecture/code-structure.md`; start
|
Start structural work at `memory/project_gamewindow_decomposition.md` and
|
||||||
|
`docs/architecture/code-structure.md`; start
|
||||||
magic follow-up at `claude-memory/project_magic_ui_and_casting.md`; start
|
magic follow-up at `claude-memory/project_magic_ui_and_casting.md`; start
|
||||||
render/streaming work at `claude-memory/project_render_pipeline_digest.md`.
|
render/streaming work at `claude-memory/project_render_pipeline_digest.md`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,19 @@ What does NOT go here:
|
||||||
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
|
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
|
||||||
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
|
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
|
||||||
|
|
||||||
## Current queue — 2026-07-21
|
## Current queue — 2026-07-22
|
||||||
|
|
||||||
- **Active structural work:** `GameWindow` decomposition. Selection/interaction
|
- **Active structural work:** `GameWindow` decomposition. Slices 1–6 are
|
||||||
ownership, live animation presentation, and complete live-session ownership
|
complete; `GameWindow.OnUpdate` is one typed orchestration handoff and the
|
||||||
are landed; Slice 4 live-entity App integration is next in
|
class is 7,026 lines / 241 fields / 108 methods. Slice 7 draw-frame
|
||||||
|
orchestration is active in
|
||||||
[`docs/architecture/code-structure.md`](architecture/code-structure.md).
|
[`docs/architecture/code-structure.md`](architecture/code-structure.md).
|
||||||
This is the behavior-preserving prerequisite before new M4 feature bodies.
|
This is the behavior-preserving prerequisite before new M4 feature bodies.
|
||||||
- **Separate rendering gate:** `#225`, lifestone/particle alpha ordering. Its
|
- **Separate rendering gate:** `#225`, lifestone/particle alpha ordering. Its
|
||||||
connected performance, lifetime, and unattended portal routes pass.
|
connected performance, lifetime, and unattended portal routes pass.
|
||||||
- **Carried behavior debt:** `#153` far-teleport unstreamed-edge arrival and
|
- **Carried behavior debt:** `#153` far-teleport unstreamed-edge arrival and
|
||||||
`#116` slide response. TS-50/TS-51 are tracked in the divergence register.
|
`#116` slide response. TS-50/TS-51/TS-53 are tracked in the divergence
|
||||||
|
register.
|
||||||
- **Deferred visual fidelity:** `#226` retail landscape detail overlay.
|
- **Deferred visual fidelity:** `#226` retail landscape detail overlay.
|
||||||
- **Build hygiene:** `#228` records 17 clean-Release test-project warnings;
|
- **Build hygiene:** `#228` records 17 clean-Release test-project warnings;
|
||||||
production compilation and all tests pass.
|
production compilation and all tests pass.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
# acdream — code structure & extraction sequence
|
# acdream — code structure & extraction sequence
|
||||||
|
|
||||||
**Status:** Living document. Created 2026-05-16; implementation reconciliation
|
**Status:** Living document. Created 2026-05-16; implementation reconciliation
|
||||||
completed 2026-07-21; Slices 1–5 landed the same day. This is the active
|
completed 2026-07-21; Slices 1–6 landed by 2026-07-22. Slice 7 draw-frame
|
||||||
structural program before new M4 subsystems enter the App layer.
|
orchestration is the active structural program before new M4 subsystems enter
|
||||||
|
the App layer.
|
||||||
**Purpose:** Describe the desired structural state of 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
|
explain the rules we've adopted, and lay out the safe extraction
|
||||||
sequence from today's reality (one 15,723-line `GameWindow.cs` at the
|
sequence from today's reality (one 15,723-line `GameWindow.cs` at the
|
||||||
|
|
@ -28,6 +29,7 @@ after Slice 2 14,546 lines / 277 fields / 190 method
|
||||||
after Slice 3 14,310 lines / 274 fields / 190 methods
|
after Slice 3 14,310 lines / 274 fields / 190 methods
|
||||||
after Slice 4 10,301 lines / 267 fields / 163 methods
|
after Slice 4 10,301 lines / 267 fields / 163 methods
|
||||||
after Slice 5 closeout 8,811 lines / 247 fields / 153 methods
|
after Slice 5 closeout 8,811 lines / 247 fields / 153 methods
|
||||||
|
after Slice 6 closeout 7,026 lines / 241 fields / 108 methods
|
||||||
```
|
```
|
||||||
|
|
||||||
`GameWindow` is the single object that:
|
`GameWindow` is the single object that:
|
||||||
|
|
@ -396,7 +398,7 @@ useful ordering seam, but its ownership status is **partial**.
|
||||||
| Startup options | **Complete** | `RuntimeOptions` owns startup configuration (`eda936dc`). Remaining direct environment reads are legacy runtime diagnostics, not startup configuration. |
|
| Startup options | **Complete** | `RuntimeOptions` owns startup configuration (`eda936dc`). Remaining direct environment reads are legacy runtime diagnostics, not startup configuration. |
|
||||||
| 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`). |
|
| 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 App integration** | `LiveEntityRuntime` owns incarnation identity, accepted snapshots/timestamps, runtime components, and logical/spatial lifetime. `LiveEntityHydrationController`, `LiveEntityRuntimeTeardownController`, and `LiveEntityNetworkUpdateController` own DAT-backed hydration, retryable cleanup, and accepted Position/Vector/State/Movement presentation without a second GUID owner (`aa90c646`). |
|
| Live identity/lifetime | **Complete App integration** | `LiveEntityRuntime` owns incarnation identity, accepted snapshots/timestamps, runtime components, and logical/spatial lifetime. `LiveEntityHydrationController`, `LiveEntityRuntimeTeardownController`, and `LiveEntityNetworkUpdateController` own DAT-backed hydration, retryable cleanup, and accepted Position/Vector/State/Movement presentation without a second GUID owner (`aa90c646`). |
|
||||||
| 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. |
|
| Inbound/object-frame order | **Complete App orchestration** | `UpdateFrameOrchestrator` owns the complete typed host phase graph; `RetailInboundEventDispatcher`, `RetailLiveFrameCoordinator`, `LiveObjectFrameController`, `LiveSpatialPresentationReconciler`, streaming/input/teleport/player-mode/camera owners preserve the accepted order. `GameWindow.OnUpdate` is one profiler-scoped handoff (`e91f3102`). |
|
||||||
| World reveal | **Complete** | `WorldRevealCoordinator` owns login/portal readiness and reveal lifetime (`a4ef5788`). The accepted deterministic lifecycle trace did not change after extraction. |
|
| World reveal | **Complete** | `WorldRevealCoordinator` owns login/portal readiness and reveal lifetime (`a4ef5788`). The accepted deterministic lifecycle trace did not change after extraction. |
|
||||||
| Retained gameplay UI | **Mostly complete feature ownership** | `RetailUiRuntime` and focused panel/controllers own layout and behavior. `GameWindow.OnLoad` still performs substantial service composition, which is allowed until the final composition cleanup. |
|
| Retained gameplay UI | **Mostly complete feature ownership** | `RetailUiRuntime` and focused panel/controllers own layout and behavior. `GameWindow.OnLoad` still performs substantial service composition, which is allowed until the final composition cleanup. |
|
||||||
| Selection/interaction | **Complete** | `WorldSelectionQuery` owns read-only picking/classification/range queries; `SelectionInteractionController` owns selection intent, Use/PickUp transport, exact-incarnation queues, and auto-walk deferral; `ItemInteractionController` owns ItemHolder policy plus the shared retail inventory-request transaction. `GameWindow` retains construction and narrow lifecycle forwarding only. |
|
| Selection/interaction | **Complete** | `WorldSelectionQuery` owns read-only picking/classification/range queries; `SelectionInteractionController` owns selection intent, Use/PickUp transport, exact-incarnation queues, and auto-walk deferral; `ItemInteractionController` owns ItemHolder policy plus the shared retail inventory-request transaction. `GameWindow` retains construction and narrow lifecycle forwarding only. |
|
||||||
|
|
@ -572,11 +574,11 @@ resource pin/release balance, collision footprints across landblock seams, and
|
||||||
first-login bootstrap replacement. The deterministic world-lifecycle gate and
|
first-login bootstrap replacement. The deterministic world-lifecycle gate and
|
||||||
nine-destination resource soak pass.
|
nine-destination resource soak pass.
|
||||||
|
|
||||||
#### Slice 6 — extract update-frame orchestration
|
#### Slice 6 — extract update-frame orchestration — COMPLETE 2026-07-22
|
||||||
|
|
||||||
Detailed execution ledger:
|
Detailed execution ledger:
|
||||||
[`docs/plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md`](../plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md)
|
[`docs/plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md`](../plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md)
|
||||||
(active).
|
(complete).
|
||||||
|
|
||||||
After the stateful bodies above have owners, make the update path a real
|
After the stateful bodies above have owners, make the update path a real
|
||||||
orchestrator instead of delegates back into the window. It preserves the
|
orchestrator instead of delegates back into the window. It preserves the
|
||||||
|
|
@ -590,6 +592,18 @@ graph and registered TS-53 host-order adaptation live in the detailed ledger.
|
||||||
Frame-order tests and the existing R6 gate must produce the same lifecycle and
|
Frame-order tests and the existing R6 gate must produce the same lifecycle and
|
||||||
movement traces before and after extraction.
|
movement traces before and after extraction.
|
||||||
|
|
||||||
|
The production cutover is complete in `e91f3102`. `GameWindow.OnUpdate` now
|
||||||
|
contains the profiler scope and one `UpdateFrameOrchestrator.Tick` handoff;
|
||||||
|
streaming, input, the object/network barrier, liveness, teleport, player-mode,
|
||||||
|
and camera phases have typed owners with no substantial callback facade into
|
||||||
|
the window. The complete Release suite passes 7,182 tests with five intentional
|
||||||
|
skips. The 314-second lifecycle/reconnect gate and 394-second synchronized
|
||||||
|
nine-stop resource soak both pass with graceful exits, stable live-owner
|
||||||
|
counts, and a 0.8 ms update-frame p95 at the final Caul checkpoint.
|
||||||
|
`GameWindow` is 7,026 raw lines / 241 fields / 108 methods: 8,697 lines (55.3%)
|
||||||
|
smaller than the campaign baseline. TS-50, TS-51, and TS-53 remain accurately
|
||||||
|
registered; this behavior-preserving extraction introduced no new divergence.
|
||||||
|
|
||||||
#### Slice 7 — extract `RenderFrameOrchestrator`
|
#### Slice 7 — extract `RenderFrameOrchestrator`
|
||||||
|
|
||||||
Move the complete draw graph and its reusable frame-local scratch state into a
|
Move the complete draw graph and its reusable frame-local scratch state into a
|
||||||
|
|
|
||||||
|
|
@ -257,10 +257,10 @@ AP-94..AP-112 for the confirmed retail-UI completion gaps.
|
||||||
| TS-47 | **NARROWED 2026-07-13** — typed routing now ports the named-retail recall/house/PK travel, age/birth, local display/location, UI persistence, AFK/consent, emote, friends, squelch/filter, and fill-components families. Retail-owned verbs outside the researched family set still fall through to ACE until individually verified. | `src/AcDream.UI.Abstractions/Panels/Chat/RetailClientCommandCatalog.cs`; `src/AcDream.App/UI/ClientCommandController.cs`; `src/AcDream.Core.Net/Messages/ClientCommandRequests.cs` | The high-use researched families have decomp pseudocode, typed actions, and conformance tests; unresearched registry entries must follow the same evidence-first path | An unported retail-owned verb can still produce ACE unknown-command output or server-specific behavior instead of its client action | `ClientCommunicationSystem` command-table construction around `0x00581A40..0x005850A0`; `docs/research/2026-07-13-retail-client-command-routing-pseudocode.md`; `docs/research/2026-07-13-retail-client-command-families-pseudocode.md` |
|
| TS-47 | **NARROWED 2026-07-13** — typed routing now ports the named-retail recall/house/PK travel, age/birth, local display/location, UI persistence, AFK/consent, emote, friends, squelch/filter, and fill-components families. Retail-owned verbs outside the researched family set still fall through to ACE until individually verified. | `src/AcDream.UI.Abstractions/Panels/Chat/RetailClientCommandCatalog.cs`; `src/AcDream.App/UI/ClientCommandController.cs`; `src/AcDream.Core.Net/Messages/ClientCommandRequests.cs` | The high-use researched families have decomp pseudocode, typed actions, and conformance tests; unresearched registry entries must follow the same evidence-first path | An unported retail-owned verb can still produce ACE unknown-command output or server-specific behavior instead of its client action | `ClientCommunicationSystem` command-table construction around `0x00581A40..0x005850A0`; `docs/research/2026-07-13-retail-client-command-routing-pseudocode.md`; `docs/research/2026-07-13-retail-client-command-families-pseudocode.md` |
|
||||||
| TS-48 | Dragging an item onto another player honors the authoritative `DragItemOnPlayerOpensSecureTrade` option, but the option's default-true branch stops at the existing unavailable toast because the secure-trade transaction and UI are not ported. Direct player giving through `GiveObjectRequest 0x00CD` works when the option is disabled; NPC giving is complete. | `src/AcDream.App/UI/ItemInteractionController.cs` (`PlaceIn3D`, `PolicyActionMessage`); `src/AcDream.Core/Items/ItemInteractionPolicy.cs` | The player/NPC distinction and character preference are now faithful; inventing a direct gift while the option requests secure trade would be a worse behavioral divergence. Secure trade is a separate multi-party state machine beyond the starter-dungeon NPC-give slice. | With retail's default character options, an item dragged onto another player cannot be exchanged until the secure-trade subsystem lands. | `ItemHolder::AttemptPlaceIn3D @ 0x00588600`; `PlayerModule::DragItemOnPlayerOpensSecureTrade @ 0x005D31B0`; `ClientTradeSystem`; `docs/research/2026-07-13-retail-give-item-pseudocode.md` |
|
| TS-48 | Dragging an item onto another player honors the authoritative `DragItemOnPlayerOpensSecureTrade` option, but the option's default-true branch stops at the existing unavailable toast because the secure-trade transaction and UI are not ported. Direct player giving through `GiveObjectRequest 0x00CD` works when the option is disabled; NPC giving is complete. | `src/AcDream.App/UI/ItemInteractionController.cs` (`PlaceIn3D`, `PolicyActionMessage`); `src/AcDream.Core/Items/ItemInteractionPolicy.cs` | The player/NPC distinction and character preference are now faithful; inventing a direct gift while the option requests secure trade would be a worse behavioral divergence. Secure trade is a separate multi-party state machine beyond the starter-dungeon NPC-give slice. | With retail's default character options, an item dragged onto another player cannot be exchanged until the secure-trade subsystem lands. | `ItemHolder::AttemptPlaceIn3D @ 0x00588600`; `PlayerModule::DragItemOnPlayerOpensSecureTrade @ 0x005D31B0`; `ClientTradeSystem`; `docs/research/2026-07-13-retail-give-item-pseudocode.md` |
|
||||||
| TS-49 | Hidden-object availability is bridged through `TargetManager.NotifyVoyeurOfEventAndClear(ExitWorld)` because acdream has not ported retail's DetectionManager. Retail `CObjCell::hide_object` sends `LeftDetection` to detection voyeurs; acdream instead withholds Hidden hosts from ordinary `GetObjectA` relationship creation and uses the existing non-Ok target update to tear down MoveTo/Sticky consumers and clear watched-role subscriptions while preserving the hidden object's own watcher role. | `src/AcDream.App/Physics/EntityPhysicsHost.cs` (`NotifyHidden`); `src/AcDream.App/Physics/LiveEntityMotionRuntimeController.cs` (`ResolvePhysicsHost`); `src/AcDream.Core/Physics/Motion/TargetManager.cs` (`NotifyVoyeurOfEventAndClear`) | The current movement consumers already share TargetManager's status fan-out; the bridge prevents pursuit of an unavailable object without inventing a second partial detection database. | Plugins or future systems listening specifically for retail detection enter/leave events receive no `LeftDetection`; only movement/sticky target consumers observe the equivalent availability loss. | `CObjCell::hide_object @ 0x0052BE30`; retire by porting DetectionManager/CObjCell detection-voyeur delivery and routing Hidden through `LeftDetection` |
|
| TS-49 | Hidden-object availability is bridged through `TargetManager.NotifyVoyeurOfEventAndClear(ExitWorld)` because acdream has not ported retail's DetectionManager. Retail `CObjCell::hide_object` sends `LeftDetection` to detection voyeurs; acdream instead withholds Hidden hosts from ordinary `GetObjectA` relationship creation and uses the existing non-Ok target update to tear down MoveTo/Sticky consumers and clear watched-role subscriptions while preserving the hidden object's own watcher role. | `src/AcDream.App/Physics/EntityPhysicsHost.cs` (`NotifyHidden`); `src/AcDream.App/Physics/LiveEntityMotionRuntimeController.cs` (`ResolvePhysicsHost`); `src/AcDream.Core/Physics/Motion/TargetManager.cs` (`NotifyVoyeurOfEventAndClear`) | The current movement consumers already share TargetManager's status fan-out; the bridge prevents pursuit of an unavailable object without inventing a second partial detection database. | Plugins or future systems listening specifically for retail detection enter/leave events receive no `LeftDetection`; only movement/sticky target consumers observe the equivalent availability loss. | `CObjCell::hide_object @ 0x0052BE30`; retire by porting DetectionManager/CObjCell detection-voyeur delivery and routing Hidden through `LeftDetection` |
|
||||||
| TS-50 | `AnimationDone` executes semantically at each owner's retail `CPhysicsObj::process_hooks` boundary, but all other animation hooks are retained in `AnimationHookFrameQueue` until final root/part/equipped-child pose publication. Retail executes the complete hook stream before transition and the Target/Movement/PartArray/Position manager tail because its current CPartArray pose already exists in-place. Static owners correctly reach `process_hooks` only after their root, parts, and children are current. | `src/AcDream.App/Rendering/Vfx/AnimationHookFrameQueue.cs`; `src/AcDream.App/Rendering/RetailStaticAnimatingObjectScheduler.cs`; frame drain in `src/AcDream.App/Rendering/GameWindow.cs` | The modern renderer publishes immutable effect-pose snapshots after all root/child composition; deferred visual sinks avoid attaching particles/lights/audio to the previous pose. Semantic `AnimationDone` is split out and exact, so motion completion and manager behavior are not delayed. Pose-owner lifetime tokens prevent deferred hooks from crossing delete/local-ID reuse. | A non-AnimationDone hook with same-quantum semantic consequences (notably `CallPES`, default-script chaining, audio/particle creation relative to a transition) runs later than retail and can observe post-tail state or start one render frame late. | `CPhysicsObj::process_hooks @ 0x00511550`; `CPhysicsObj::UpdatePositionInternal @ 0x00512C30`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by publishing the current per-object/child pose before hook routing or splitting semantic and presentation sinks without changing authored hook order |
|
| TS-50 | `AnimationDone` executes semantically at each owner's retail `CPhysicsObj::process_hooks` boundary, but all other animation hooks are retained in `AnimationHookFrameQueue` until final root/part/equipped-child pose publication. Retail executes the complete hook stream before transition and the Target/Movement/PartArray/Position manager tail because its current CPartArray pose already exists in-place. Static owners correctly reach `process_hooks` only after their root, parts, and children are current. | `src/AcDream.App/Rendering/Vfx/AnimationHookFrameQueue.cs`; `src/AcDream.App/Rendering/RetailStaticAnimatingObjectScheduler.cs`; shared frame drain in `src/AcDream.App/Update/LiveObjectFrameController.cs` (`LiveEffectFrameController`) | The modern renderer publishes immutable effect-pose snapshots after all root/child composition; deferred visual sinks avoid attaching particles/lights/audio to the previous pose. Semantic `AnimationDone` is split out and exact, so motion completion and manager behavior are not delayed. Pose-owner lifetime tokens prevent deferred hooks from crossing delete/local-ID reuse. | A non-AnimationDone hook with same-quantum semantic consequences (notably `CallPES`, default-script chaining, audio/particle creation relative to a transition) runs later than retail and can observe post-tail state or start one render frame late. | `CPhysicsObj::process_hooks @ 0x00511550`; `CPhysicsObj::UpdatePositionInternal @ 0x00512C30`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by publishing the current per-object/child pose before hook routing or splitting semantic and presentation sinks without changing authored hook order |
|
||||||
| TS-51 | Particle and PhysicsScript tails advance once per render frame after the complete ordinary/static object worksets. Retail advances each ordinary object's ParticleManager then ScriptManager inside every admitted `UpdateObjectInternal` quantum; `animate_static_object` instead advances that static owner's ScriptManager then ParticleManager and only then `process_hooks`, using its whole admitted elapsed interval. acdream's shared tail is Particle → Script after static hook capture. | `src/AcDream.App/Rendering/GameWindow.cs` (`AdvanceLiveObjectRuntime` final `_particleSystem.Tick(dt)` / `_scriptRunner.Tick(...)`); `src/AcDream.App/Rendering/RetailStaticAnimatingObjectScheduler.cs` | The current managers are shared presentation/runtime owners rather than per-object manager instances. R6 makes root motion, animation, object clocks, workset membership, and ordinary manager order faithful without pretending the shared tails have per-owner timing or static-tail order. Splitting ownership safely requires a later effect-lifetime slice. | A render fragment below retail's minimum object quantum can advance an effect while its owner waits; a catch-up frame advances an owner's root through several quanta but its effect tail only once; static hooks can route before their script/particle managers and static default scripts/particles use render elapsed in Particle → Script order rather than `animate_static_object` elapsed/discard and Script → Particle → hooks timing. | `CPhysicsObj::UpdateObjectInternal @ 0x005156B0`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by giving live/static owners incarnation-bound particle/script managers and ticking each manager in the owning object quantum/order |
|
| TS-51 | Particle and PhysicsScript tails advance once per render frame after the complete ordinary/static object worksets. Retail advances each ordinary object's ParticleManager then ScriptManager inside every admitted `UpdateObjectInternal` quantum; `animate_static_object` instead advances that static owner's ScriptManager then ParticleManager and only then `process_hooks`, using its whole admitted elapsed interval. acdream's shared tail is Particle → Script after static hook capture. | `src/AcDream.App/Update/LiveObjectFrameController.cs` (`LiveObjectFrameController` + `LiveEffectFrameController` shared `_particles.Tick` / `_scripts.Tick` tail); `src/AcDream.App/Rendering/RetailStaticAnimatingObjectScheduler.cs` | The current managers are shared presentation/runtime owners rather than per-object manager instances. R6 makes root motion, animation, object clocks, workset membership, and ordinary manager order faithful without pretending the shared tails have per-owner timing or static-tail order. Splitting ownership safely requires a later effect-lifetime slice. | A render fragment below retail's minimum object quantum can advance an effect while its owner waits; a catch-up frame advances an owner's root through several quanta but its effect tail only once; static hooks can route before their script/particle managers and static default scripts/particles use render elapsed in Particle → Script order rather than `animate_static_object` elapsed/discard and Script → Particle → hooks timing. | `CPhysicsObj::UpdateObjectInternal @ 0x005156B0`; `CPhysicsObj::animate_static_object @ 0x00513DF0`; retire by giving live/static owners incarnation-bound particle/script managers and ticking each manager in the owning object quantum/order |
|
||||||
| TS-52 | The terrain shader applies retail-authored base/overlay/road `TerrainTex.TexTiling` but omits the separate Environment Detail Textures pass and its viewer-distance fade (**#226**). | `src/AcDream.App/Rendering/TerrainAtlas.cs`; `src/AcDream.App/Rendering/TerrainModernRenderer.cs`; `src/AcDream.App/Rendering/Shaders/terrain_modern.frag` | `bb5acab9` fixed the user-visible stretched/blurry regression by porting the distinct base-tiling contract. An earlier experimental detail array darkened the whole ground because its source/neutral blend contract was wrong, so it was correctly reverted rather than guessed into production. | With retail's Environment Detail Textures preference enabled, close terrain lacks the extra high-frequency modulation/fade even though authored base texture scale is correct. | `LScape::GenerateDetailSurfaces` / `SetDetailTexturing @ 0x00506B40`; `ACRender::landPolyDraw @ 0x006B6450..0x006B6525`; issue #226 |
|
| TS-52 | The terrain shader applies retail-authored base/overlay/road `TerrainTex.TexTiling` but omits the separate Environment Detail Textures pass and its viewer-distance fade (**#226**). | `src/AcDream.App/Rendering/TerrainAtlas.cs`; `src/AcDream.App/Rendering/TerrainModernRenderer.cs`; `src/AcDream.App/Rendering/Shaders/terrain_modern.frag` | `bb5acab9` fixed the user-visible stretched/blurry regression by porting the distinct base-tiling contract. An earlier experimental detail array darkened the whole ground because its source/neutral blend contract was wrong, so it was correctly reverted rather than guessed into production. | With retail's Environment Detail Textures preference enabled, close terrain lacks the extra high-frequency modulation/fade even though authored base texture scale is correct. | `LScape::GenerateDetailSurfaces` / `SetDetailTexturing @ 0x00506B40`; `ACRender::landPolyDraw @ 0x006B6450..0x006B6525`; issue #226 |
|
||||||
| TS-53 | acdream advances retained UI time on the draw seam and local teleport/UI-camera presentation after its SmartBox-shaped object → inbound network → CommandInterpreter barrier. Retail `Client::UseTime` calls `UIElementManager::UseTime` first, whose global time message reaches `gmSmartBoxUI::UseTime`, and publishes player-camera work from the physics/player callback rather than one post-network camera tail. Slice 6 preserves the accepted host order as an ownership-only extraction. | `src/AcDream.App/Rendering/GameWindow.cs` (`OnUpdate` teleport/camera tails and `_retailUiRuntime.Tick` in `OnRender`); `docs/plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md` | Current retained UI, portal transit, reveal, camera, and connected movement traces are accepted; changing cross-subsystem host order while extracting ownership would combine a behavior change with the structural cutover. | Retained UI, teleport, and camera presentation can observe same-frame object/inbound/player state one host update earlier or later than retail at transition boundaries; a future exact host-order port must prove UI, input, reveal, and camera consequences together. | `Client::UseTime @ 0x00411C40`; `UIElementManager::UseTime`; `gmSmartBoxUI::UseTime @ 0x004D6E30`; `CPhysics::UseTime @ 0x00509950`; retire only with a focused host-order port and connected portal/camera comparison |
|
| TS-53 | acdream advances retained UI time on the draw seam and local teleport/UI-camera presentation after its SmartBox-shaped object → inbound network → CommandInterpreter barrier. Retail `Client::UseTime` calls `UIElementManager::UseTime` first, whose global time message reaches `gmSmartBoxUI::UseTime`, and publishes player-camera work from the physics/player callback rather than one post-network camera tail. Slice 6 preserves the accepted host order as an ownership-only extraction. | `src/AcDream.App/Update/UpdateFrameOrchestrator.cs` (post-live-frame teleport/camera phases); `src/AcDream.App/Rendering/GameWindow.cs` (`_retailUiRuntime.Tick` in `OnRender`); `docs/plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md` | Current retained UI, portal transit, reveal, camera, and connected movement traces are accepted; changing cross-subsystem host order while extracting ownership would combine a behavior change with the structural cutover. | Retained UI, teleport, and camera presentation can observe same-frame object/inbound/player state one host update earlier or later than retail at transition boundaries; a future exact host-order port must prove UI, input, reveal, and camera consequences together. | `Client::UseTime @ 0x00411C40`; `UIElementManager::UseTime`; `gmSmartBoxUI::UseTime @ 0x004D6E30`; `CPhysics::UseTime @ 0x00509950`; retire only with a focused host-order port and connected portal/camera comparison |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# acdream — strategic roadmap
|
# acdream — strategic roadmap
|
||||||
|
|
||||||
**Status:** Living document. Updated 2026-07-21. **M3 landed; M4 is next after the active `GameWindow` structural prerequisite.** M3's retail casting/UI, R6 locomotion/collision/projectile/teleport/radar rebaseline, deterministic fresh-login/portal world lifecycle, and final two-client portal observer flow are user-gated. The current program is the behavior-preserving ownership campaign in [`docs/architecture/code-structure.md`](../architecture/code-structure.md); new M4 quest/emote/character-creation feature bodies wait until that campaign is complete. Issue #225's lifestone/particle alpha comparison remains a separate rendering visual gate.
|
**Status:** Living document. Updated 2026-07-22. **M3 landed; M4 is next after the active `GameWindow` structural prerequisite.** M3's retail casting/UI, R6 locomotion/collision/projectile/teleport/radar rebaseline, deterministic fresh-login/portal world lifecycle, and final two-client portal observer flow are user-gated. The current program is the behavior-preserving ownership campaign in [`docs/architecture/code-structure.md`](../architecture/code-structure.md); Slices 1–6 are complete and Slice 7 draw-frame orchestration is active. New M4 quest/emote/character-creation feature bodies wait until that campaign is complete. Issue #225's lifestone/particle alpha comparison remains a separate rendering visual gate.
|
||||||
**Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file.
|
**Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -56,9 +56,19 @@ session replacement, including failure/retry and fast relogin. Shutdown keeps
|
||||||
the reset graph alive until disposal converges. `GameWindow` is 8,811 raw
|
the reset graph alive until disposal converges. `GameWindow` is 8,811 raw
|
||||||
lines / 247 fields / 153 methods (44% below the campaign baseline); 7,054
|
lines / 247 fields / 153 methods (44% below the campaign baseline); 7,054
|
||||||
Release tests, the capped/reconnect lifecycle gate, and the synchronized
|
Release tests, the capped/reconnect lifecycle gate, and the synchronized
|
||||||
nine-stop resource soak pass. Slice 6 update-frame orchestration is active;
|
nine-stop resource soak pass.
|
||||||
its detailed checkpoint ledger is
|
|
||||||
|
Slice 6 update-frame orchestration is complete. Streaming, input, the retail-
|
||||||
|
shaped object/network barrier, liveness, local teleport, player mode, and
|
||||||
|
camera presentation now have typed phase owners. `GameWindow.OnUpdate` is one
|
||||||
|
orchestrator handoff, with no substantial transitive callback facade back into
|
||||||
|
the window. `GameWindow` is 7,026 raw lines / 241 fields / 108 methods, down
|
||||||
|
8,697 lines (55.3%) from the campaign baseline. The complete Release suite
|
||||||
|
passes 7,182 tests / 5 skips; the 314-second lifecycle/reconnect gate and
|
||||||
|
394-second synchronized nine-stop resource soak pass with graceful exits and
|
||||||
|
stable owner counts. The completed ledger is
|
||||||
[`2026-07-21-gamewindow-slice-6-update-frame-orchestration.md`](2026-07-21-gamewindow-slice-6-update-frame-orchestration.md).
|
[`2026-07-21-gamewindow-slice-6-update-frame-orchestration.md`](2026-07-21-gamewindow-slice-6-update-frame-orchestration.md).
|
||||||
|
Slice 7 `RenderFrameOrchestrator` extraction is now active.
|
||||||
|
|
||||||
This is a behavior-preserving structural program. Severe regressions still get
|
This is a behavior-preserving structural program. Severe regressions still get
|
||||||
root-cause fixes in separate commits; ordinary feature work resumes with M4
|
root-cause fixes in separate commits; ordinary feature work resumes with M4
|
||||||
|
|
|
||||||
|
|
@ -23,16 +23,20 @@ complete. Slice 5 landblock presentation is also complete:
|
||||||
the worker DAT transaction, render/physics/static publishers, and retryable
|
the worker DAT transaction, render/physics/static publishers, and retryable
|
||||||
Near/full retirement now have focused owners. The direct production cutover
|
Near/full retirement now have focused owners. The direct production cutover
|
||||||
also serializes complete old-window retirement with teleport and session
|
also serializes complete old-window retirement with teleport and session
|
||||||
origin lifetimes. `GameWindow` is 8,811 raw lines / 247 fields / 153 methods,
|
origin lifetimes. Slice 6 update-frame orchestration is complete: streaming,
|
||||||
down 1,490 lines from the Slice-5 baseline and 6,912 (44%) from the campaign
|
input, the object/network barrier, liveness, teleport, player mode, and camera
|
||||||
baseline. The full Release suite passes 7,054 tests / 5 skips; the 311-second
|
presentation have typed phase owners, and `GameWindow.OnUpdate` is one
|
||||||
capped/reconnect lifecycle gate and synchronized 394-second nine-destination
|
orchestrator handoff. `GameWindow` is 7,026 raw lines / 241 fields / 108
|
||||||
resource soak both pass. Slice 6 update-frame orchestration is active under
|
methods, down 8,697 lines (55.3%) from the campaign baseline. The full Release
|
||||||
|
suite passes 7,182 tests / 5 skips; the 314-second capped/reconnect lifecycle
|
||||||
|
gate and synchronized 394-second nine-destination resource soak both pass with
|
||||||
|
graceful exits and stable owner counts. The completed Slice 6 ledger is
|
||||||
[`2026-07-21-gamewindow-slice-6-update-frame-orchestration.md`](2026-07-21-gamewindow-slice-6-update-frame-orchestration.md).
|
[`2026-07-21-gamewindow-slice-6-update-frame-orchestration.md`](2026-07-21-gamewindow-slice-6-update-frame-orchestration.md).
|
||||||
|
Slice 7 draw-frame orchestration is active.
|
||||||
|
|
||||||
Carried:
|
Carried:
|
||||||
#153 far-teleport residual, #116 slide-response, the remaining R6 ownership cleanup plus
|
#153 far-teleport residual, #116 slide-response, the remaining R6 ownership cleanup plus
|
||||||
registered TS-50/TS-51 timing residuals (the complete-root-Frame/object-workset
|
registered TS-50/TS-51/TS-53 timing residuals (the complete-root-Frame/object-workset
|
||||||
cutover is automated- and visual-gate complete; Release builds with 17 known
|
cutover is automated- and visual-gate complete; Release builds with 17 known
|
||||||
test-project warnings tracked by #228, and 6,575 tests pass / 5 skip), and
|
test-project warnings tracked by #228, and 6,575 tests pass / 5 skip), and
|
||||||
the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha
|
the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# GameWindow Slice 6 — update-frame orchestration
|
# GameWindow Slice 6 — update-frame orchestration
|
||||||
|
|
||||||
**Status:** Active 2026-07-21.
|
**Status:** Complete 2026-07-22.
|
||||||
**Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 6.
|
**Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 6.
|
||||||
**Baseline:** `d4ecac1d`; `GameWindow.cs` is 8,811 raw lines, 247 fields, and
|
**Baseline:** `d4ecac1d`; `GameWindow.cs` is 8,811 raw lines, 247 fields, and
|
||||||
153 methods. Release baseline: 7,054 passed / 5 skipped. The connected
|
153 methods. Release baseline: 7,054 passed / 5 skipped. The connected
|
||||||
|
|
@ -29,7 +29,7 @@ never hidden behind a retry, delay, suppression flag, or reordered callback.
|
||||||
`UpdateFrameOrchestrator`.
|
`UpdateFrameOrchestrator`.
|
||||||
- [x] G — delete the old `OnUpdate` bodies, callback facades, and obsolete
|
- [x] G — delete the old `OnUpdate` bodies, callback facades, and obsolete
|
||||||
frame state; run focused corrected-diff reviews after each ownership edge.
|
frame state; run focused corrected-diff reviews after each ownership edge.
|
||||||
- [ ] H — full Release suite, connected lifecycle/reconnect gate, synchronized
|
- [x] H — full Release suite, connected lifecycle/reconnect gate, synchronized
|
||||||
resource soak, documentation, durable memory, and line/field/method closeout.
|
resource soak, documentation, durable memory, and line/field/method closeout.
|
||||||
|
|
||||||
Every checked checkpoint is committed as one bisectable architectural unit.
|
Every checked checkpoint is committed as one bisectable architectural unit.
|
||||||
|
|
@ -437,7 +437,7 @@ Focused App/Core tests cover destination readiness, forced holds, same-cell
|
||||||
placement, LoginComplete order, reset/disposal, GUID reuse, reentrancy,
|
placement, LoginComplete order, reset/disposal, GUID reuse, reentrancy,
|
||||||
host rollback, auto-entry idempotence, and completion-mailbox ordering. The
|
host rollback, auto-entry idempotence, and completion-mailbox ordering. The
|
||||||
full App suite is green at 2,814 passed / 3 skipped. `GameWindow.cs` is 7,351
|
full App suite is green at 2,814 passed / 3 skipped. `GameWindow.cs` is 7,351
|
||||||
lines at this checkpoint, down from the slice baseline of 15,723.
|
lines at this checkpoint, down from the 15,723-line campaign baseline.
|
||||||
|
|
||||||
### F/G — camera, cutover, and deletion
|
### F/G — camera, cutover, and deletion
|
||||||
|
|
||||||
|
|
@ -467,7 +467,7 @@ retains no duplicate lifecycle state. Focused Release tests are green at
|
||||||
37/37, the App suite at 2,820 passed / 3 skipped, and the full suite at 7,179
|
37/37, the App suite at 2,820 passed / 3 skipped, and the full suite at 7,179
|
||||||
passed / 5 skipped. All three corrected-diff reviews are clean.
|
passed / 5 skipped. All three corrected-diff reviews are clean.
|
||||||
`GameWindow.cs` is 7,160 lines, down 8,563 lines (54.5%) from the 15,723-line
|
`GameWindow.cs` is 7,160 lines, down 8,563 lines (54.5%) from the 15,723-line
|
||||||
slice baseline.
|
campaign baseline.
|
||||||
|
|
||||||
**Checkpoint G completed 2026-07-22.** `GameWindow.OnUpdate` now owns only the
|
**Checkpoint G completed 2026-07-22.** `GameWindow.OnUpdate` now owns only the
|
||||||
update profiler scope and one `UpdateFrameOrchestrator.Tick` call. Teardown,
|
update profiler scope and one `UpdateFrameOrchestrator.Tick` call. Teardown,
|
||||||
|
|
@ -501,6 +501,22 @@ The slice requires no new visual behavior. If connected screenshots or traces
|
||||||
change, return to the responsible checkpoint; do not defer the difference to
|
change, return to the responsible checkpoint; do not defer the difference to
|
||||||
Slice 7.
|
Slice 7.
|
||||||
|
|
||||||
|
**Completed 2026-07-22.** The complete Release suite is green at 7,182 passed /
|
||||||
|
5 fixture or environment skips. The deterministic lifecycle/reconnect gate
|
||||||
|
passed in 314.195 seconds across capped login/travel checkpoints, graceful close,
|
||||||
|
and a fresh-process reconnect. Its only warning was the expected set of 25
|
||||||
|
world-edge empty landblocks. The synchronized nine-stop resource soak passed in
|
||||||
|
393.581 seconds with movement, turn, jump, combat, teleport waits, fatal-log scan,
|
||||||
|
and graceful exit. The final Caul plateau held the same 21,025 entity and 13
|
||||||
|
animation-owner counts as the earlier Caul return, with update-frame p95 at
|
||||||
|
0.8 ms; working/private memory increased by 112.2/111.0 MiB across that retained
|
||||||
|
route, inside the existing deterministic gate. The soak's only diagnostics were
|
||||||
|
35 known DAT-driven missing VFX table/emitter records and the same 25 expected
|
||||||
|
world-edge misses. The divergence audit keeps TS-50, TS-51, and TS-53 unchanged
|
||||||
|
and found no new behavior adaptation. Final `GameWindow` size is 7,026 raw
|
||||||
|
lines / 241 fields / 108 methods, versus 8,811 / 247 / 153 at Slice 6 entry and
|
||||||
|
15,723 / 278 / 205 at the campaign baseline.
|
||||||
|
|
||||||
## 6. Review gate for every checkpoint
|
## 6. Review gate for every checkpoint
|
||||||
|
|
||||||
After each implementation checkpoint:
|
After each implementation checkpoint:
|
||||||
|
|
|
||||||
84
memory/project_gamewindow_decomposition.md
Normal file
84
memory/project_gamewindow_decomposition.md
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
# 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.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue