docs(architecture): reconcile GameWindow extraction program
Close the completed M3 and portal observer gates, make the behavior-preserving GameWindow ownership campaign the explicit M4 prerequisite, and replace the stale extraction sketch with an implementation-audited sequence. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
f4cf802330
commit
cf50ee3d50
8 changed files with 354 additions and 220 deletions
29
AGENTS.md
29
AGENTS.md
|
|
@ -108,23 +108,26 @@ movement queries.
|
|||
|
||||
## Current state
|
||||
|
||||
**M3 — Cast a spell ACTIVE; automated implementation and connected
|
||||
single-client gates complete.** Retail cast intent, component/target gates,
|
||||
live enchantment wire, Magic-scoped input, spell bar, spellbook, component
|
||||
book, effect indicators, shared main-panel switching, and positive/negative
|
||||
effects UI are implemented over the Step-9 projectile/DAT-effect foundation.
|
||||
The R6 complete-root-Frame/object-workset cutover and its unattended
|
||||
seven-destination input/portal/performance rebaseline pass. The 2026-07-20
|
||||
deterministic world-lifecycle gate additionally protects fresh login,
|
||||
**M3 — Cast a spell LANDED 2026-07-21. M4 — Live in the world NEXT.** Retail
|
||||
casting, spellbook/component-book UI, active effects, recall/portal-space
|
||||
presentation, the R6 locomotion/collision/projectile/teleport/radar rebaseline,
|
||||
and the final two-client portal-out/materialization observer flow are
|
||||
user-gated. Deterministic world-lifecycle automation protects fresh login,
|
||||
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
|
||||
disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
|
||||
Release builds; 6,480 tests pass / 5 skip (17 tracked warnings, #228).
|
||||
**Next:** the R6 locomotion/collision/projectile/teleport local visual
|
||||
rebaseline when a local view is available, then the final two-client
|
||||
portal-out/materialization observer gate. **Carried:** #153, #116, remaining
|
||||
Release builds; 6,481 tests pass / 5 skip (17 tracked warnings, #228).
|
||||
|
||||
**Active prerequisite before new M4 subsystem work:** complete the
|
||||
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21. The
|
||||
next slice finishes selection/interaction ownership; later slices finish
|
||||
animation presentation, live-session and live-entity App integration,
|
||||
landblock presentation, update/render orchestration, and composition cleanup.
|
||||
See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining
|
||||
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
|
||||
lifestone/particle alpha visual gate.
|
||||
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; start
|
||||
|
||||
Start structural work at `docs/architecture/code-structure.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`.
|
||||
|
||||
Documentation entry point: [`docs/README.md`](docs/README.md).
|
||||
|
|
|
|||
29
CLAUDE.md
29
CLAUDE.md
|
|
@ -106,23 +106,26 @@ movement queries.
|
|||
|
||||
## Current state
|
||||
|
||||
**M3 — Cast a spell ACTIVE; automated implementation and connected
|
||||
single-client gates complete.** Retail cast intent, component/target gates,
|
||||
live enchantment wire, Magic-scoped input, spell bar, spellbook, component
|
||||
book, effect indicators, shared main-panel switching, and positive/negative
|
||||
effects UI are implemented over the Step-9 projectile/DAT-effect foundation.
|
||||
The R6 complete-root-Frame/object-workset cutover and its unattended
|
||||
seven-destination input/portal/performance rebaseline pass. The 2026-07-20
|
||||
deterministic world-lifecycle gate additionally protects fresh login,
|
||||
**M3 — Cast a spell LANDED 2026-07-21. M4 — Live in the world NEXT.** Retail
|
||||
casting, spellbook/component-book UI, active effects, recall/portal-space
|
||||
presentation, the R6 locomotion/collision/projectile/teleport/radar rebaseline,
|
||||
and the final two-client portal-out/materialization observer flow are
|
||||
user-gated. Deterministic world-lifecycle automation protects fresh login,
|
||||
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
|
||||
disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
|
||||
Release builds; 6,480 tests pass / 5 skip (17 tracked warnings, #228).
|
||||
**Next:** the R6 locomotion/collision/projectile/teleport local visual
|
||||
rebaseline when a local view is available, then the final two-client
|
||||
portal-out/materialization observer gate. **Carried:** #153, #116, remaining
|
||||
Release builds; 6,481 tests pass / 5 skip (17 tracked warnings, #228).
|
||||
|
||||
**Active prerequisite before new M4 subsystem work:** complete the
|
||||
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21. The
|
||||
next slice finishes selection/interaction ownership; later slices finish
|
||||
animation presentation, live-session and live-entity App integration,
|
||||
landblock presentation, update/render orchestration, and composition cleanup.
|
||||
See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining
|
||||
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
|
||||
lifestone/particle alpha visual gate.
|
||||
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; start
|
||||
|
||||
Start structural work at `docs/architecture/code-structure.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`.
|
||||
|
||||
Documentation entry point: [`docs/README.md`](docs/README.md).
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ What does NOT go here:
|
|||
- 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.
|
||||
|
||||
## Current queue — 2026-07-20
|
||||
## Current queue — 2026-07-21
|
||||
|
||||
- **Next visual gate:** R6 locomotion/collision/projectile/teleport comparison
|
||||
after the complete-root-Frame/object-workset cutover.
|
||||
- **M3 closing gate:** `#218`, final two-client portal-out/materialization and
|
||||
indoor observer comparison.
|
||||
- **Active structural work:** `GameWindow` decomposition, beginning with the
|
||||
selection/interaction ownership slice in
|
||||
[`docs/architecture/code-structure.md`](architecture/code-structure.md).
|
||||
This is the behavior-preserving prerequisite before new M4 feature bodies.
|
||||
- **Separate rendering gate:** `#225`, lifestone/particle alpha ordering. Its
|
||||
connected performance, lifetime, and unattended portal routes pass.
|
||||
- **Carried behavior debt:** `#153` far-teleport unstreamed-edge arrival and
|
||||
|
|
@ -98,7 +98,7 @@ production runtime failure.
|
|||
|
||||
**Acceptance:** A non-incremental Release solution build reports zero warnings
|
||||
and zero errors without suppressing analyzers or weakening nullable checking;
|
||||
the full 6,480-pass / 5-skip suite remains green.
|
||||
the full 6,481-pass / 5-skip suite remains green.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -565,7 +565,7 @@ Passed 2026-07-17: “Yes works.”
|
|||
|
||||
## #218 — Portal silhouette pose, destination reveal, and indoor observer snap
|
||||
|
||||
**Status:** IN-PROGRESS — root fixes implemented 2026-07-16; pending connected visual gate
|
||||
**Status:** DONE — 2026-07-21, final two-client observer gate user-confirmed
|
||||
**Severity:** HIGH
|
||||
**Filed:** 2026-07-16
|
||||
**Component:** portal VFX / streaming / physics / outbound movement
|
||||
|
|
@ -635,6 +635,9 @@ pose; outdoor exits reveal only fully rendered terrain/scenery; and a retail
|
|||
observer sees acdream run and stop repeatedly inside a dungeon without any
|
||||
snap back to the entrance.
|
||||
|
||||
**Gate:** Passed 2026-07-21. The user confirmed the final two-client
|
||||
portal-out/materialization and indoor observer comparison on the R6 baseline.
|
||||
|
||||
---
|
||||
|
||||
## #217 — Character windows did not receive live 64-bit experience updates
|
||||
|
|
|
|||
|
|
@ -4,23 +4,26 @@ This page is the entry point for project documentation. It distinguishes
|
|||
current sources of truth from implementation history so an old plan or issue
|
||||
banner cannot silently override the current program state.
|
||||
|
||||
## Current snapshot — 2026-07-20
|
||||
## Current snapshot — 2026-07-21
|
||||
|
||||
- **Active milestone:** M3, “Cast a spell.” The automated implementation and
|
||||
connected single-client magic/portal presentation gates are complete.
|
||||
- **Next visual gates:** the R6 locomotion/collision/projectile/teleport retail
|
||||
comparison, then the final two-client portal-out/materialization observer
|
||||
comparison (`#218`).
|
||||
- **Milestone state:** M3, “Cast a spell,” landed 2026-07-21. M4, “Live in the
|
||||
world,” is next.
|
||||
- **Active program:** behavior-preserving `GameWindow` decomposition before
|
||||
new M4 subsystem work. The reconciled ownership ledger and slice order are
|
||||
in [`architecture/code-structure.md`](architecture/code-structure.md); the
|
||||
next slice finishes selection/interaction ownership.
|
||||
- **Completed gates:** R6 locomotion/collision/projectile/teleport/radar and
|
||||
the final two-client portal-out/materialization observer comparison (`#218`).
|
||||
- **Separate visual verification:** the shared-alpha lifestone/particle result
|
||||
in `#225`; its connected resource-lifetime and performance routes pass.
|
||||
- **Carried behavior debt:** `#153` (far teleport onto an unstreamed edge),
|
||||
`#116` (two narrowed slide-response cases), and divergence rows TS-50/TS-51.
|
||||
- **Deferred engineering tracks:** Modern Pipeline MP1b+ and Linux/headless
|
||||
automation (Track LH). Neither is part of the active M3 gate.
|
||||
automation (Track LH). Neither is part of the active structural campaign.
|
||||
- **Divergence audit:** 178 active rows — IA 17, AD 37, AP 85, TS 34,
|
||||
and UN 5 — plus the retained retired TS-37 history note.
|
||||
- **Latest automated baseline:** Release build succeeds with 17 known
|
||||
test-project warnings (`#228`); 6,457 tests passed and 5 intentionally
|
||||
test-project warnings (`#228`); 6,481 tests passed and 5 intentionally
|
||||
skipped. The unattended connected R6 route
|
||||
completed seven portal materializations, production input exercises, and a
|
||||
graceful close. See
|
||||
|
|
|
|||
|
|
@ -829,12 +829,18 @@ Current movement/collision ownership:
|
|||
- **G.3 is shipped**: dungeon streaming, portal-space presentation, collision,
|
||||
lighting, doors, and the full round-trip gate landed. The separate far-
|
||||
teleport unstreamed-edge residual is issue #153, not unfinished G.3.
|
||||
- **M3** owns current connected magic/portal acceptance; Track LH is the future
|
||||
presentation-independent Linux/headless extraction.
|
||||
- **M3 landed 2026-07-21** with connected magic/portal acceptance and the final
|
||||
two-client observer gate; Track LH is the future presentation-independent
|
||||
Linux/headless extraction.
|
||||
- **The behavior-preserving thin-`GameWindow` ownership campaign is the active
|
||||
prerequisite before new M4 subsystem bodies.** Its reconciled ledger and
|
||||
sequence live in `docs/architecture/code-structure.md`. This decision does
|
||||
not reclassify the remaining L.2 conformance work or Track LH.
|
||||
|
||||
The GameEntity / thin GameWindow refactor remains a valid target architecture,
|
||||
but it is not a prerequisite for L.2. Do not resurrect old R1-R8 phase numbers
|
||||
for new work; add or update roadmap phases instead.
|
||||
Full `GameEntity` type aggregation remains a separate, higher-risk target after
|
||||
the thin-`GameWindow` campaign. The current campaign reuses canonical
|
||||
`LiveEntityRuntime` rather than introducing another entity owner. Do not
|
||||
resurrect old R1-R8 phase numbers for new work; update the roadmap instead.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
# acdream — code structure & extraction sequence
|
||||
|
||||
**Status:** Living document. Created 2026-05-16 as the companion to the
|
||||
"Code Structure Rules" section in `CLAUDE.md`.
|
||||
**Status:** Living document. Created 2026-05-16; implementation reconciliation
|
||||
completed 2026-07-21. 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
|
||||
sequence from today's reality (one 14,557-line `GameWindow.cs` at the
|
||||
2026-07-20 audit) to the
|
||||
sequence from today's reality (one 15,723-line `GameWindow.cs` at the
|
||||
2026-07-21 audit) to the
|
||||
target (thin `GameWindow`, small focused collaborators).
|
||||
**Companion to:** [`acdream-architecture.md`](acdream-architecture.md)
|
||||
(the layered architecture) and
|
||||
|
|
@ -21,30 +22,37 @@ layer is wire-compatible, the UI has a stable contract, plugins load.
|
|||
The structural debt is concentrated in **one file**:
|
||||
|
||||
```
|
||||
src/AcDream.App/Rendering/GameWindow.cs 14,557 lines (2026-07-20)
|
||||
src/AcDream.App/Rendering/GameWindow.cs 15,723 lines (2026-07-21)
|
||||
258 fields / ~259 methods
|
||||
```
|
||||
|
||||
`GameWindow` is the single object that:
|
||||
|
||||
- Owns the GL context, the window, input, and shaders.
|
||||
- Reads ~40 different environment variables across its lifetime.
|
||||
- Hosts the live network session (`WorldSession`) and the offline
|
||||
pre-login state.
|
||||
- Owns parallel dictionaries for entity lookup (`_entitiesByServerGuid`,
|
||||
the per-landblock entity lists in `GpuWorldState`, plus the player
|
||||
controller's own state).
|
||||
- Drives selection / interaction (`WorldPicker`, `SendUse`,
|
||||
`SendPickUp`).
|
||||
- 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.
|
||||
- Owns the adapters that hydrate canonical `LiveEntityRuntime` records into
|
||||
animation, collision, rendering, and DAT-backed appearance resources.
|
||||
- Still drives selection / interaction (`WorldPicker`, target classification,
|
||||
`SendUse`, `SendPickUp`, auto-walk deferral) despite the shipped item and
|
||||
combat controllers.
|
||||
- Drives per-frame render orchestration (sky → terrain → opaque mesh →
|
||||
transparent mesh → particles → debug lines → UI).
|
||||
- Builds and applies streamed landblock presentation (DAT decode, scenery,
|
||||
EnvCells, mesh publication, collision, and retirement) around the shipped
|
||||
`StreamingController` and `GpuWorldState` owners.
|
||||
- Wires up every plugin hook sink, every diagnostic, every panel.
|
||||
|
||||
Almost every M1 / M2 bug touches this file. Every new feature adds a
|
||||
field plus a method plus a wiring call. It is not getting better on its
|
||||
own.
|
||||
The extracted controllers are valuable and tested, but line count alone proves
|
||||
that creating collaborators has not yet made the window thin. A collaborator
|
||||
is a completed extraction only when it owns the state and behavior body;
|
||||
wrapping a `GameWindow` method in a delegate preserves ordering but remains a
|
||||
partial extraction.
|
||||
|
||||
The fix is **not** "rewrite `GameWindow` in one pass" — that's a
|
||||
high-risk change that would block M2. The fix is to **extract one
|
||||
The fix is **not** "rewrite `GameWindow` in one pass" — that is a
|
||||
high-risk change. The fix is to **extract one
|
||||
collaborator at a time**, verify behavior is unchanged, ship, and
|
||||
move on. This document defines that sequence.
|
||||
|
||||
|
|
@ -167,6 +175,7 @@ src/AcDream.App/
|
|||
│ ├── GameWindow.cs # thin: GL/window lifecycle + delegates per-frame to RenderFrameOrchestrator
|
||||
│ ├── RenderFrameOrchestrator.cs # per-frame draw order (sky → terrain → opaque → trans → particles → debug → UI)
|
||||
│ ├── LiveEntityAnimationScheduler.cs # shipped: ordinary live-object update workset
|
||||
│ ├── LiveEntityAnimationPresenter.cs # final part-pose/mesh/effect composition after scheduler output
|
||||
│ ├── RetailStaticAnimatingObjectScheduler.cs # shipped: separate static-animation workset
|
||||
│ ├── StaticLiveRootCommitter.cs # live static root → pose + collision boundary
|
||||
│ ├── TerrainModernRenderer.cs # (already exists)
|
||||
|
|
@ -176,11 +185,13 @@ src/AcDream.App/
|
|||
│ ├── Wb/ # WB seam + EnvCellLandblockBuild transaction
|
||||
│ └── Vfx/ # (already exists)
|
||||
├── Net/
|
||||
│ └── LiveSessionController.cs # owns WorldSession lifecycle, login/handshake, reconnect
|
||||
│ ├── LiveSessionController.cs # owns complete WorldSession connect/enter/logout/reconnect lifecycle
|
||||
│ └── LiveSessionEventRouter.cs # typed subscriptions → focused domain handlers
|
||||
├── Physics/
|
||||
│ ├── ProjectileController.cs # canonical live-record projectile orchestration
|
||||
│ ├── RemotePhysicsUpdater.cs # ordinary/Hidden remote narrow-tick integration
|
||||
│ ├── LiveEntityOrdinaryPhysicsUpdater.cs # manager-less canonical body Transition path
|
||||
│ ├── LiveEntityNetworkUpdateController.cs # Position/Vector/State/Motion App integration
|
||||
│ ├── LiveEntityShadowPublisher.cs # authoritative exact-owner/residency collision gate
|
||||
│ ├── RemoteInboundMotionDispatcher.cs # shared animated/headless UpdateMotion funnel
|
||||
│ ├── RemoteTeleportController.cs # loaded/pending teleport placement ownership
|
||||
|
|
@ -189,13 +200,18 @@ src/AcDream.App/
|
|||
├── World/
|
||||
│ ├── InboundPhysicsStateController.cs # timestamps + accepted spawn snapshots
|
||||
│ ├── LiveEntityRuntime.cs # shipped: logical lifetime + ServerGuid↔entity.Id translation
|
||||
│ ├── LiveEntityHydrationController.cs # spawn/appearance/parent/delete resource integration
|
||||
│ ├── RetailInboundEventDispatcher.cs # update-thread packet/frame FIFO barrier
|
||||
│ ├── RetailLiveFrameCoordinator.cs # shipped: object/network/command/reconcile phase order
|
||||
│ ├── LiveEntityPresentationController.cs # ordered Hidden/NoDraw/effect/collision side effects
|
||||
│ ├── LiveEntityTeardown.cs # failure-isolated multi-owner lifecycle drain
|
||||
│ └── ParentAttachmentState.cs # parent generations + pending ParentEvent relations
|
||||
├── Interaction/
|
||||
│ └── SelectionInteractionController.cs # owns WorldPicker, selection state, Use/PickUp dispatch
|
||||
├── Streaming/ # LandblockStreamer + immutable LandblockBuild completion
|
||||
│ ├── WorldSelectionQuery.cs # read-only picking/classification/description queries
|
||||
│ └── SelectionInteractionController.cs # owns selection intents, Use/PickUp, auto-walk deferral
|
||||
├── Streaming/
|
||||
│ ├── LandblockPresentationPipeline.cs # DAT build/apply/retire transaction and resource publication
|
||||
│ └── ... # shipped streamer/world-state/reveal owners
|
||||
├── Input/ # (already exists)
|
||||
├── Audio/ # (already exists)
|
||||
└── Plugins/ # (already exists)
|
||||
|
|
@ -206,22 +222,27 @@ What `GameWindow` keeps:
|
|||
- `IWindow` / `GL` / `IInputContext` lifecycle (constructor + `OnLoad` +
|
||||
`Run` + `OnClosing`).
|
||||
- `RuntimeOptions` reference (the typed startup config).
|
||||
- One field per collaborator (`_liveSessionController`,
|
||||
`_liveEntityRuntime`, `_selectionInteraction`,
|
||||
`_renderFrameOrchestrator`).
|
||||
- GL 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`,
|
||||
`_liveObjectFrame`, `_renderFrameOrchestrator`).
|
||||
- The Silk.NET event-handler stubs that delegate to collaborators.
|
||||
|
||||
What `GameWindow` loses:
|
||||
|
||||
- The 7 startup-time env var fields → moved into `RuntimeOptions`.
|
||||
- `TryStartLiveSession` + the post-login network drain → moved into
|
||||
`LiveSessionController`.
|
||||
- `_entitiesByServerGuid` + per-entity dictionaries + ServerGuid↔Id
|
||||
translation → moved into `LiveEntityRuntime`.
|
||||
- `WorldPicker` + selection-driven `SendUse` / `SendPickUp` orchestration → moved
|
||||
into `SelectionInteractionController`; Core `SelectionState` remains the
|
||||
already-shipped session owner and is injected into that controller.
|
||||
- Per-frame draw orchestration → moved into `RenderFrameOrchestrator`.
|
||||
- Live connect/enter/logout and event-subscription bodies → completed inside
|
||||
`LiveSessionController` / `LiveSessionEventRouter`.
|
||||
- Live-object hydration adapters and final animated-part presentation → focused
|
||||
world/render owners over canonical `LiveEntityRuntime` records.
|
||||
- `WorldPicker`, target queries, and selection-driven Use/PickUp/auto-walk →
|
||||
`WorldSelectionQuery` + `SelectionInteractionController`. Core
|
||||
`SelectionState` remains the injected session owner.
|
||||
- Landblock DAT build/apply/retirement presentation →
|
||||
`LandblockPresentationPipeline`; `StreamingController` remains the residency
|
||||
scheduler and `GpuWorldState` remains the spatial registry.
|
||||
- Per-frame draw orchestration and its frame-local scratch state →
|
||||
`RenderFrameOrchestrator`.
|
||||
|
||||
The eventual `GameEntity` aggregation (target state described in
|
||||
`acdream-architecture.md` §"GameEntity: The Unified Entity") happens
|
||||
|
|
@ -247,10 +268,14 @@ allocators fail fast instead of wrapping into another landblock's namespace.
|
|||
All other non-Parent packet
|
||||
families still need the future general queue tracked by divergence AD-32.
|
||||
|
||||
The per-frame object body is no longer an animation-dictionary loop inside
|
||||
`GameWindow`. `LiveEntityAnimationScheduler` snapshots canonical spatial root
|
||||
records and advances the incarnation-stable object clock, PartArray, hooks,
|
||||
one selected movement owner, and manager tail in retail order. Manager-less
|
||||
The per-frame object scheduler is extracted, but final animated-part
|
||||
presentation is not. `LiveEntityAnimationScheduler` snapshots canonical spatial
|
||||
root records and advances the incarnation-stable object clock, PartArray,
|
||||
hooks, one selected movement owner, and manager tail in retail order. The
|
||||
remaining `GameWindow.TickAnimations` loop still composes part transforms,
|
||||
drawable `MeshRef`s, and effect poses from the scheduler output; moving that
|
||||
body into `LiveEntityAnimationPresenter` is an explicit pending slice.
|
||||
Manager-less
|
||||
bodies delegate their candidate/Transition/cell/shadow commit to
|
||||
`LiveEntityOrdinaryPhysicsUpdater`; retained projectile bodies and remote
|
||||
MovementManagers remain mutually exclusive movement owners. Static animation
|
||||
|
|
@ -336,145 +361,194 @@ strand teleport, movement, shadow, light, or GUID-scoped state.
|
|||
|
||||
---
|
||||
|
||||
## 4. Extraction sequence — safest first
|
||||
## 4. Reconciled ownership ledger — 2026-07-21
|
||||
|
||||
Each step is **one PR-sized refactor**. Each must build clean, all
|
||||
tests pass, and visual verification at Holtburg looks identical to
|
||||
the previous step. Don't bundle two steps.
|
||||
This section replaces the original six-step sketch. That sketch correctly
|
||||
identified the target but overstated some extractions and omitted large bodies
|
||||
added during M2/M3. The current audit is based on implementation ownership, not
|
||||
whether a class with the planned name exists.
|
||||
|
||||
### Step 1 — `RuntimeOptions` — SHIPPED (`eda936dc`)
|
||||
### 4.1 What counts as extracted
|
||||
|
||||
**Scope:** Replace startup-time env var reads with a typed options
|
||||
object built once in `Program.cs`.
|
||||
An extraction is **complete** only when:
|
||||
|
||||
**Behavior change:** None. Same env vars, same defaults, same effects.
|
||||
1. the collaborator owns the mutable state and behavior body;
|
||||
2. `GameWindow` constructs it and delegates through a narrow method;
|
||||
3. the collaborator does not call back into arbitrary `GameWindow` methods;
|
||||
4. focused tests exercise the collaborator without constructing a Silk window;
|
||||
5. the accepted connected/visual behavior is unchanged.
|
||||
|
||||
**Risk:** Low. Mechanical substitution at ~10-15 call sites in
|
||||
`GameWindow.cs` + one constructor signature change.
|
||||
A class that stores delegates back to substantial `GameWindow` methods is a
|
||||
useful ordering seam, but its ownership status is **partial**.
|
||||
|
||||
**Test:** Unit tests for `RuntimeOptions.FromEnvironment` parsing (the
|
||||
new `tests/AcDream.App.Tests/` project).
|
||||
### 4.2 Current implementation truth
|
||||
|
||||
**Verification:** `dotnet build` + `dotnet test` green. Visual launch
|
||||
verifies live mode + dat dir resolution still work.
|
||||
| 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`. |
|
||||
| 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`, static scheduler, remote/projectile updaters, and teleport owners are shipped. `AdvanceLiveObjectRuntimeCore`, final part/mesh/effect composition, and several integration tails remain in `GameWindow`. |
|
||||
| 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. |
|
||||
| Selection/interaction | **Partial** | `ItemInteractionController`, `CombatTargetController`, and `CombatAttackController` own focused rules. `GameWindow` still owns picking, target queries, selection intent, Use/PickUp sends, range/auto-walk deferral, and related input cases. |
|
||||
| Landblock presentation | **Not extracted** | Residency scheduling is extracted, but DAT build, scenery/EnvCell construction, apply, collision/resource publication, and retirement glue remain a large `GameWindow` body. |
|
||||
| Render-frame orchestration | **Not extracted** | `OnRender` plus its portal/PView/alpha/particle helpers still own the draw graph and frame-local scratch state. There is no `RenderFrameOrchestrator` yet. |
|
||||
| Unified `GameEntity` | **Deferred target** | `LiveEntityRuntime` already supplies the critical canonical owner. Full type aggregation is a separate high-risk migration and is not required to make `GameWindow` thin. |
|
||||
|
||||
### Step 2 — `LiveSessionController` — SHIPPED (`0b25df53`)
|
||||
### 4.3 Revised extraction sequence
|
||||
|
||||
**Scope:** Extract `TryStartLiveSession` + the WorldSession ownership +
|
||||
the post-EnterWorld drain (`OnLiveStateUpdated`, `OnLiveEntityDeleted`,
|
||||
etc.) into a controller class.
|
||||
Every numbered slice is behavior-preserving and independently committed. A
|
||||
slice does not include feature work or opportunistic gameplay fixes.
|
||||
|
||||
**Behavior change:** None. Same wire behavior, same handshake.
|
||||
#### Gate 0 — deterministic baseline — COMPLETE
|
||||
|
||||
**Risk:** Medium. WorldSession lifecycle is load-bearing — every
|
||||
session-state crash would surface here. The change is a class
|
||||
extraction with the same event subscriptions, not a rewrite.
|
||||
The Release suite, connected R6 soak, world-lifecycle screenshots/checkpoints,
|
||||
graceful reconnect, local locomotion/collision/projectile/teleport gate, and
|
||||
two-client portal observer gate form the pre-refactor baseline. Each later
|
||||
slice runs the subset capable of detecting its risk; render/session slices run
|
||||
the complete connected lifecycle gate.
|
||||
|
||||
**Test:** Existing `AcDream.Core.Net.Tests` already cover the wire
|
||||
layer. The controller itself gets a smoke test that verifies it can be
|
||||
constructed without a live socket (offline mode).
|
||||
#### Slice 1 — finish selection/interaction ownership — NEXT
|
||||
|
||||
**Verification:** Visual login + Holtburg traversal + door interaction
|
||||
identical to pre-extraction.
|
||||
Split the old Step 4 into three reviewable commits:
|
||||
|
||||
### Step 3 — `LiveEntityRuntime` — SHIPPED 2026-07-14
|
||||
1. `WorldSelectionQuery` receives camera/scene/live-object read seams and owns
|
||||
picking, target classification, selection bounds, closest-target lookup,
|
||||
names, and descriptions. It cannot mutate selection or send packets.
|
||||
2. `SelectionInteractionController` owns selection intents, double-click Use,
|
||||
Use/PickUp packet requests, range decisions, speculative facing, and the
|
||||
pending auto-walk action. It composes the existing item/combat controllers
|
||||
rather than duplicating their rules.
|
||||
3. Selection/Use/PickUp/combat-target `InputAction` cases delegate to the new
|
||||
controller; the old methods and fields are deleted from `GameWindow`.
|
||||
|
||||
**Shipped scope:** One `LiveEntityRecord` per server-object incarnation now owns
|
||||
ServerGuid↔local-ID translation, accepted state, runtime components, parent
|
||||
relations, logical resource activation, exact teardown, and spatial projection
|
||||
state. `RegisterLiveEntity`, `RebucketLiveEntity`, and `UnregisterLiveEntity`
|
||||
make the lifetime boundary explicit. Landblock unload/reload moves the same
|
||||
`WorldEntity`; it cannot reconstruct from a stale CreateObject or replay setup
|
||||
scripts. Equipped children use an attached projection and never enter the
|
||||
top-level target/radar/status view. Canonical materialized lookup remains
|
||||
available while a projection is pending; the separate visible view is the only
|
||||
surface radar, picking, status, and targeting consume. Pickup/parent leave-world
|
||||
clears cell membership and pauses root movement/animation without destroying the
|
||||
retained owners. Top-level spawn publication is one-shot per incarnation, so
|
||||
leave/re-entry restores presentation without duplicating plugin event replay.
|
||||
Tests cover read-only query classification separately from stateful intents,
|
||||
including direct use, distant auto-walk completion, corpse/container opening,
|
||||
pickup placement, hostile-only targeting, Hidden objects, and same-GUID reuse.
|
||||
The connected gate is select → use door/NPC → distant corpse → loot/pickup →
|
||||
combat target. This is the safest next slice because its outbound boundaries
|
||||
are typed and existing controllers already hold most retail rules.
|
||||
|
||||
**Remaining target:** the player-specific controller is still a separate
|
||||
aggregation. The focused effect queue is shipped; AD-32 now tracks only the
|
||||
future non-effect, non-Parent packet queue.
|
||||
#### Slice 2 — finish live animation presentation
|
||||
|
||||
**Behavior change:** Spatial withdrawal and re-entry now preserve logical
|
||||
identity and active resources instead of replaying create-time effects.
|
||||
Move `TickAnimations`, final rigid/visual part composition, effect-pose
|
||||
publication, and motion-done binding into `LiveEntityAnimationPresenter`.
|
||||
`LiveEntityAnimationScheduler` remains the time/movement owner; the presenter
|
||||
only consumes one scheduler result and publishes the final draw/effect pose.
|
||||
Move the surviving motion diagnostics with this owner instead of adding more
|
||||
environment reads to `GameWindow`.
|
||||
|
||||
**Risk:** Medium-high. Entity lookup is in every hot path. The change
|
||||
is structural (one owner instead of three) but the lookup semantics
|
||||
must be byte-identical.
|
||||
Tests pin legacy and sequencer paths, Hidden/static eligibility, ObjScale versus
|
||||
rigid effect poses, part availability, same-frame hook pose publication, and
|
||||
incarnation replacement. Run the R6 object-frame and projectile/effect suites
|
||||
plus the connected locomotion/projectile gate.
|
||||
|
||||
**Test:** `LiveEntityRuntimeTests` cover duplicate CreateObject, generation
|
||||
replacement, appearance mutation, loaded/pending rebucketing, attached
|
||||
projection, pickup leave/re-entry, canonical-versus-visible lookup, resource
|
||||
rollback, GUID reuse, and idempotent session teardown.
|
||||
#### Slice 3 — complete live-session ownership
|
||||
|
||||
**Verification:** Walk Holtburg, click NPC, open door, pick up item.
|
||||
All four M1 demo targets must still work.
|
||||
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.
|
||||
|
||||
### Step 4 — `SelectionInteractionController`
|
||||
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.
|
||||
|
||||
**Scope:** Extract `WorldPicker`, the Core `SelectionState` consumers, `SendUse`,
|
||||
`SendPickUp`, and the `InputAction.Select*` / `UseSelected` /
|
||||
`SelectionPickUp` switch cases into one controller. Depends on Step 3
|
||||
(uses `LiveEntityRuntime`).
|
||||
#### Slice 4 — extract live-entity App integration
|
||||
|
||||
**Behavior change:** None.
|
||||
This is two owners, not one replacement god object:
|
||||
|
||||
**Risk:** Low-medium. Selection state is local to interactions; the
|
||||
network outbound side is well-defined (`InteractRequests.BuildUse` /
|
||||
`BuildPickUp`).
|
||||
- `LiveEntityHydrationController` owns CreateObject/ObjDesc/Parent/Pickup/Delete
|
||||
integration, DAT-backed appearance hydration, resource registration, and
|
||||
exact teardown callbacks over `LiveEntityRuntime`.
|
||||
- `LiveEntityNetworkUpdateController` owns App routing for accepted
|
||||
Position/Vector/State/Movement updates into the existing remote physics,
|
||||
motion, projectile, presentation, and teleport controllers.
|
||||
|
||||
**Test:** Selection state machine tests in `tests/AcDream.App.Tests/`.
|
||||
Neither may own a GUID dictionary. Both resolve the current incarnation only
|
||||
through `LiveEntityRuntime` and must preserve the inbound FIFO/authority-token
|
||||
rules. Run the complete live-entity stress suite, R6 connected route, inventory
|
||||
equip/parenting, death/corpse, and portal gates.
|
||||
|
||||
**Verification:** Click-to-select, double-click-to-Use, F-key pickup
|
||||
all still work.
|
||||
#### Slice 5 — extract landblock presentation
|
||||
|
||||
### Step 5 — `RenderFrameOrchestrator`
|
||||
Create `LandblockPresentationPipeline` around the existing immutable
|
||||
`LandblockBuild` transaction. It owns DAT build context, scenery/EnvCell
|
||||
construction, mesh/collision/light publication, demotion/full-retirement, and
|
||||
the single-reader DAT lock contract. `StreamingController` continues deciding
|
||||
what is resident; `GpuWorldState` continues owning spatial buckets.
|
||||
|
||||
**Scope:** Extract the per-frame draw sequence (sky → terrain →
|
||||
opaque mesh → translucent mesh → particles → debug → UI) into a
|
||||
dedicated orchestrator that `GameWindow.OnRender` delegates to.
|
||||
Tests pin loaded/pending/demoted/unloaded symmetry, stale build generations,
|
||||
resource pin/release balance, collision footprints across landblock seams, and
|
||||
first-login bootstrap replacement. Run the deterministic world-lifecycle gate
|
||||
and the seven-destination resource soak.
|
||||
|
||||
**Behavior change:** None. Same draw order, same GL state.
|
||||
#### Slice 6 — extract update-frame orchestration
|
||||
|
||||
**Risk:** Medium. GL state management is touchy; the orchestrator
|
||||
must hand the GL context to the same renderers in the same order with
|
||||
the same per-pass state setup.
|
||||
After the stateful bodies above have owners, make the update path a real
|
||||
orchestrator instead of delegates back into the window. It owns the fixed
|
||||
retail phase order: input/local object → ordinary/static objects → hooks/
|
||||
particles/scripts → inbound network → command interpreter → non-advancing
|
||||
spatial reconcile → streaming/UI updates. `GameWindow.OnUpdate` becomes a
|
||||
short time/input handoff.
|
||||
|
||||
**Test:** Visual verification only. Render orchestration is hard to
|
||||
unit-test without a GL context.
|
||||
Frame-order tests and the existing R6 gate must produce the same lifecycle and
|
||||
movement traces before and after extraction.
|
||||
|
||||
**Verification:** Holtburg at radius 4, radius 8, radius 12 looks
|
||||
identical across all four quality presets.
|
||||
#### Slice 7 — extract `RenderFrameOrchestrator`
|
||||
|
||||
### Step 6 — `GameEntity` aggregation (the big one)
|
||||
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
|
||||
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
|
||||
`GameWindow`; inject a small immutable service set plus explicit per-frame
|
||||
input.
|
||||
|
||||
**Scope:** Consolidate `WorldEntity` + `AnimatedEntity` + the per-entity
|
||||
state in `LiveEntityRuntime` into one `GameEntity` class (the target
|
||||
described in `acdream-architecture.md`). Every entity in the world —
|
||||
player, NPC, monster, door, item — becomes a single `GameEntity`.
|
||||
Automated acceptance uses framebuffer artifacts and render/resource
|
||||
checkpoints. Visual acceptance compares outdoor, building, dungeon, portal
|
||||
exit, translucent lifestone/particles, and UI at the same camera positions.
|
||||
|
||||
**Behavior change:** None at the wire / visual level; substantial at
|
||||
the call-site level (everyone moves to the new entity API).
|
||||
#### Slice 8 — composition and shutdown cleanup
|
||||
|
||||
**Risk:** High. Touches every system that reads entity state.
|
||||
Keep GL/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,
|
||||
focus, and shutdown owners.
|
||||
|
||||
**Test:** All existing tests + the new `AcDream.App.Tests` suite. Visual
|
||||
verification at every M1 / M2 scenario.
|
||||
### 4.4 Exit criteria
|
||||
|
||||
**Verification:** Full M2 demo loop (equip sword, kill drudge, pick up
|
||||
loot, open inventory) works identically.
|
||||
The campaign is complete when:
|
||||
|
||||
- `GameWindow` contains no AC gameplay algorithm, entity scan, packet builder,
|
||||
DAT landblock builder, animation-part composer, or draw-graph body;
|
||||
- `OnUpdate`, `OnRender`, `OnInputAction`, and live-session callbacks are short
|
||||
delegation methods;
|
||||
- every extracted owner has App-layer tests and symmetric teardown;
|
||||
- the Release suite and connected lifecycle/resource gates stay green after
|
||||
every slice;
|
||||
- the final local visual matrix passes unchanged.
|
||||
|
||||
Line count is a progress signal, not the acceptance test. The expected result
|
||||
is below roughly 5,000 lines, but ownership and dependency direction decide
|
||||
completion. Full `GameEntity` type aggregation is evaluated only afterwards as
|
||||
a separate migration; it is not folded into this campaign.
|
||||
|
||||
---
|
||||
|
||||
## 5. Rules of the road during the extraction
|
||||
|
||||
1. **One step at a time.** A PR that ships Step 1 ships only Step 1.
|
||||
Bundling steps makes failures hard to isolate.
|
||||
2. **Behavior preservation is the acceptance criterion.** Every step
|
||||
1. **One slice at a time.** Each commit ships one ownership boundary or
|
||||
mechanical call-site cutover. Bundling slices makes failures hard to
|
||||
isolate.
|
||||
2. **Behavior preservation is the acceptance criterion.** Every slice
|
||||
must build clean, all tests pass, and visual verification at the
|
||||
appropriate M1 / M2 scenarios must succeed. We're moving code, not
|
||||
appropriate accepted milestone scenarios must succeed. We're moving code, not
|
||||
changing it.
|
||||
3. **No new features during an extraction step.** If you spot a real
|
||||
bug while extracting, file it in `docs/ISSUES.md` and address it in
|
||||
|
|
@ -484,9 +558,15 @@ loot, open inventory) works identically.
|
|||
moves to a new owner, the diagnostic flag inside it can move to a
|
||||
diagnostic class as part of the same commit. We do not do a bulk
|
||||
diagnostic-cleanup pass.
|
||||
5. **Update this document when the plan changes.** If Step 3 turns out
|
||||
to need a different shape than described above, update §4 in the
|
||||
5. **Update this document when the plan changes.** If a slice turns out
|
||||
to need a different ownership shape than described above, update §4 in the
|
||||
same session you discover the divergence.
|
||||
6. **No façade-only completion claims.** A delegate from a new class back to a
|
||||
substantial `GameWindow` method is a useful intermediate seam, not a
|
||||
completed extraction.
|
||||
7. **No duplicate ownership.** New collaborators query `LiveEntityRuntime`,
|
||||
`GpuWorldState`, `SelectionState`, or the relevant existing owner. They do
|
||||
not create replacement GUID, visibility, session, or resource maps.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -494,8 +574,9 @@ loot, open inventory) works identically.
|
|||
|
||||
- **Not a full rewrite plan.** The point is the *opposite* — small
|
||||
steps, verified at each boundary.
|
||||
- **Not blocking M2.** Step 1 is small enough to ship without
|
||||
disrupting M2 work. Later steps interleave with M2 / M3 phases as
|
||||
the corresponding code paths come into focus.
|
||||
- **Not a feature phase.** Following the 2026-07-21 user decision, this
|
||||
behavior-preserving campaign is the structural prerequisite before new M4
|
||||
subsystem bodies are added. Severe regressions remain fixable in separate
|
||||
commits; ordinary feature work waits.
|
||||
- **Not a substitute for the milestones / roadmap.** Those drive the
|
||||
feature work. This drives the structural work that runs underneath.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,32 @@
|
|||
# acdream — strategic roadmap
|
||||
|
||||
**Status:** Living document. Updated 2026-07-20. **M3 active; automated implementation and connected single-client magic/portal gates complete.** M2's connected demo loop is complete. M3 now has the retail cast-intent/component/target lifecycle, exact live enchantment wire state, scoped Magic input, retained spell bar, spellbook, component book, positive/negative effects panels with authored rows and selected-spell details, the complete seven-control gameplay indicator strip and its Character Information/Link/Vitae detail pages, and shared `gmPanelUI` geometry/switching over the Step 9 projectile/PhysicsScript/particle/portal foundation. Fresh-login and portal world reveal are additionally protected by a deterministic capped/uncapped connected lifecycle gate with screenshots, resource snapshots, exact graceful disconnect, and fresh-process reconnect. The next gate is a local visual rebaseline of the new R6 object-frame path; the final M3 requirement is the two-client portal-out/materialization observer gate. Issue #225's lifestone/particle alpha comparison is a separate rendering visual gate.
|
||||
**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.
|
||||
**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.
|
||||
|
||||
---
|
||||
|
||||
## Current program: M3 — Cast a spell
|
||||
## Current program: `GameWindow` structural stabilization (M4 prerequisite)
|
||||
|
||||
**Outcome:** `GameWindow` becomes a thin Silk.NET composition/lifecycle shell
|
||||
without changing accepted gameplay or rendering behavior. Focused App owners
|
||||
take responsibility for selection, animation presentation, live-session and
|
||||
live-entity integration, landblock presentation, and update/render frame
|
||||
orchestration.
|
||||
|
||||
**Current sequence:** The implementation audit, exact ownership ledger, slice
|
||||
boundaries, tests, connected gates, and exit criteria live in
|
||||
[`docs/architecture/code-structure.md`](../architecture/code-structure.md) §4.
|
||||
The next slice is selection/interaction: extract the read-only world query,
|
||||
move stateful Use/PickUp/auto-walk intent into one controller, then cut the
|
||||
related input cases over and delete the old `GameWindow` bodies.
|
||||
|
||||
This is a behavior-preserving structural program. Severe regressions still get
|
||||
root-cause fixes in separate commits; ordinary feature work resumes with M4
|
||||
after the campaign exit criteria pass.
|
||||
|
||||
---
|
||||
|
||||
## Completed program: M3 — Cast a spell (landed 2026-07-21)
|
||||
|
||||
**Outcome:** Cast a projectile spell at a hostile target, see the complete
|
||||
turn/windup/release/projectile/impact lifecycle, self-cast a buff and see its
|
||||
|
|
@ -39,14 +60,14 @@ active enchantment, then recall through the DAT-driven portal presentation.
|
|||
same-location revisit, graceful logout, and uncapped fresh-process
|
||||
reconnect. The gate records structured readiness/resource checkpoints and
|
||||
full-frame PNGs, and rejects early world visibility or stranded owners.
|
||||
5. **Pending local visual gate:** locomotion, collision, projectile, and
|
||||
teleport comparison after the R6 complete-root-Frame/object-workset cutover.
|
||||
6. **Pending two-client visual gate:** portal-out/materialization observer
|
||||
presentation before M3 closes, including #218's finished Hidden silhouette,
|
||||
fully rendered destination reveal, and no indoor stop-time position snap.
|
||||
5. **Done (connected user gate):** locomotion, collision, projectile, teleport,
|
||||
and radar comparison after the R6 complete-root-Frame/object-workset cutover.
|
||||
6. **Done (two-client user gate):** portal-out/materialization observer
|
||||
presentation, including #218's finished Hidden silhouette, fully rendered
|
||||
destination reveal, and no indoor stop-time position snap.
|
||||
|
||||
Opportunistic UI/physics fixes are no longer the work-order driver. They enter
|
||||
the active slice only when they block this demo or represent a severe regression.
|
||||
M3 is closed. Its detailed ledger remains here as the landing record; the
|
||||
structural program above is the only current work-order driver before M4.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -937,8 +958,7 @@ diagnostic scaffolding, not yet the final collision system.
|
|||
and 0.2 -> 0.3 ms at Sawato. ACE generator population changes are reported
|
||||
rather than treated as client leaks. Absolute FPS/GPU timing remains
|
||||
session/display-path evidence, not an RDP-stable gate. The connected visual
|
||||
locomotion/collision/projectile/teleport comparison remains for the next
|
||||
local viewing session.
|
||||
locomotion/collision/projectile/teleport/radar comparison passed 2026-07-21.
|
||||
- **L.2g — Inbound motion interpretation (remote-entity CMotionInterp funnel).**
|
||||
ACTIVE 2026-07-02. Port retail's inbound motion pipeline verbatim for ALL
|
||||
remote entities (players, NPCs, monsters — one funnel, user-approved):
|
||||
|
|
@ -1453,7 +1473,7 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
|
|||
|
||||
## Cross-cutting work tracked in parallel
|
||||
|
||||
- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,480 passed / 5 intentional skips (2026-07-20).
|
||||
- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,481 passed / 5 intentional skips (2026-07-21).
|
||||
- **Memory files.** Live subsystem state and digests are indexed by `claude-memory/MEMORY.md`; stable engineering references remain under `memory/`. Canonical program status stays in milestones/roadmap/issues.
|
||||
- **`CLAUDE.md` discipline.** Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,28 +2,28 @@
|
|||
|
||||
**Status:** Living document. Created 2026-05-12.
|
||||
**Sits above:** [`docs/plans/2026-04-11-roadmap.md`](2026-04-11-roadmap.md) (the strategic phase index).
|
||||
**Currently working toward:** **M3 — "Cast a spell." M2 — "Kill a drudge"
|
||||
LANDED 2026-07-15.** The complete connected melee/missile, death/loot,
|
||||
inventory, and item-giving demo is user-gated. The shared projectile/effect
|
||||
foundation is hardened through Step 9. Spellbook/component-book filtering,
|
||||
favorite spell bar, connected casting/enchantment effects, and portal-space
|
||||
presentation have passed their single-client visual gates. The corrective bounded
|
||||
render/resource-lifetime integration passed its seven-destination connected
|
||||
stress gate without a crash or cumulative collapse. A second deterministic
|
||||
world-lifecycle gate now protects fresh login, outdoor/world-edge/dungeon
|
||||
travel, same-location revisit, exact graceful disconnect, and an uncapped
|
||||
fresh-process reconnect with canonical readiness snapshots and saved PNG/JSON
|
||||
artifacts. The remaining M3 visual requirement is the final two-client
|
||||
portal-out/materialize observer gate. The new R6 object-update cutover has
|
||||
passed its unattended connected input/portal/performance rebaseline; its
|
||||
locomotion/collision/projectile/teleport visual gate remains for the next local
|
||||
viewing session before that observer gate.
|
||||
**Currently working toward:** **M4 — "Live in the world." M3 — "Cast a
|
||||
spell" LANDED 2026-07-21.** Projectile/self-buff casting, protection effects,
|
||||
spellbook/component-book filtering and deletion, favorite spell bars, active
|
||||
effects, recall, portal-space presentation, and the complete two-client
|
||||
portal-out/materialization observer flow are user-gated. The R6 locomotion,
|
||||
collision, projectile, teleport, and radar rebaseline also passes. Deterministic
|
||||
world-lifecycle automation protects fresh login, outdoor/world-edge/dungeon
|
||||
travel, same-location revisit, exact graceful disconnect, and uncapped
|
||||
fresh-process reconnect with canonical JSON/PNG evidence.
|
||||
|
||||
Before new M4 quest/emote/character-creation subsystem bodies enter the App
|
||||
layer, the active structural prerequisite is the behavior-preserving
|
||||
`GameWindow` decomposition in
|
||||
[`docs/architecture/code-structure.md`](../architecture/code-structure.md).
|
||||
The 2026-07-21 audit found 15,723 lines, 258 fields, and about 259 methods;
|
||||
the next slice finishes selection/interaction ownership.
|
||||
|
||||
Carried:
|
||||
#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
|
||||
cutover is automated-test complete 2026-07-20; three independent re-reviews are
|
||||
clean, Release builds with 17 known test-project warnings tracked by #228, and
|
||||
6,480 tests pass / 5 skip after the world-reveal gate), and
|
||||
cutover is automated- and visual-gate complete; Release builds with 17 known
|
||||
test-project warnings tracked by #228, and 6,481 tests pass / 5 skip), and
|
||||
the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha
|
||||
implementation has passed connected lifetime/performance gates and awaits only
|
||||
its lifestone/particle visual comparison.
|
||||
|
|
@ -662,8 +662,8 @@ include dungeons.
|
|||
publishes outdoor landcells independently of surviving object meshes.
|
||||
Terrain/entity streaming distance is
|
||||
unchanged; the user-requested default Extended setting doubles only particle
|
||||
range, while Retail remains available as the exact cutoff. The
|
||||
final two-client visual gate is still pending.
|
||||
range, while Retail remains available as the exact cutoff. The final
|
||||
two-client visual gate passed 2026-07-21.
|
||||
- **L.1c local attack receive path (implemented and live-gated 2026-07-15)** —
|
||||
local non-autonomous mt-0 UpdateMotion now uses retail's wholesale interpreted
|
||||
funnel and action-stamp gate, so ACE's server-selected melee/missile action
|
||||
|
|
@ -713,7 +713,17 @@ a game.
|
|||
|
||||
---
|
||||
|
||||
### M3 — "Cast a spell" — 🔵 ACTIVE (started 2026-07-15)
|
||||
### M3 — "Cast a spell" — ✅ LANDED 2026-07-21
|
||||
|
||||
**Landing writeup:** Mages now work end to end. A connected player can manage
|
||||
the retail spellbook/component book and favorite bars, cast projectile and
|
||||
self-targeted spells with the correct components/target gates, see traveling
|
||||
missiles and DAT-driven protection/impact effects, inspect live enchantments,
|
||||
and recall or portal through the retail tunnel/reveal lifecycle. The final
|
||||
two-client observer gate confirms departure disappearance, destination
|
||||
materialization, finished pose, rendered destination, and indoor movement
|
||||
without snap-back. The R6 local locomotion/collision/projectile/teleport and
|
||||
radar checks pass on the same Release baseline.
|
||||
|
||||
**Demo scenario:** Cast Flame Bolt at a drudge. Watch the cast animation,
|
||||
the projectile, the impact. Self-cast a buff (Strength Self). See the
|
||||
|
|
@ -740,9 +750,9 @@ The strip now uses retail DAT states for link quality, Helpful/Harmful effects,
|
|||
Vitae, burden, mini-game availability, and end-character-session; live link
|
||||
age, player load, and enchantment registries drive their retail thresholds and
|
||||
the burden/effect/logout actions use the shared panel/dialog owners. Main-panel
|
||||
visibility now flows through retail's one-active `gmPanelUI` owner. M3 remains
|
||||
active only for the connected single-client magic
|
||||
UI/casting visual gate and the final two-client portal observer gate.
|
||||
visibility now flows through retail's one-active `gmPanelUI` owner. The
|
||||
connected single-client magic UI/casting gates and final two-client portal
|
||||
observer gate passed before landing.
|
||||
The 2026-07-17 indicator follow-up also mounts authored Character Information,
|
||||
Link Status, Vitae, and Mini Game detail roots as children of that same
|
||||
main-panel owner. Helpful, Harmful, Character Information, Link, and Vitae
|
||||
|
|
@ -795,7 +805,12 @@ from M3 = retail-equivalent gameplay loop for melee and casters.
|
|||
|
||||
---
|
||||
|
||||
### M4 — "Live in the world" — 🔵 (~6–10 weeks)
|
||||
### M4 — "Live in the world" — 🟡 NEXT (~6–10 weeks)
|
||||
|
||||
**Entry condition:** complete the behavior-preserving `GameWindow`
|
||||
decomposition campaign before adding H.3/H.4/L.1e feature bodies. This protects
|
||||
M4 from deepening the App-layer composition debt; it does not change M4's demo
|
||||
scope.
|
||||
|
||||
**Demo scenario:** Create a fresh character from scratch (no ACE admin).
|
||||
Spawn. Talk to an NPC. Accept a quest. Walk to a dungeon entrance. Portal
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue