docs(architecture): close selection extraction slice

Record the measured GameWindow reduction, final review and test gates, durable selection/inventory ownership rules, and live animation presentation as Slice 2.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-21 09:04:31 +02:00
parent 5acc3f01cf
commit 9ad8113c79
10 changed files with 141 additions and 52 deletions

View file

@ -26,8 +26,8 @@ What does NOT go here:
## Current queue — 2026-07-21
- **Active structural work:** `GameWindow` decomposition, beginning with the
selection/interaction ownership slice in
- **Active structural work:** `GameWindow` decomposition. Selection/interaction
ownership is complete; Slice 2 live animation presentation is next 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
@ -69,7 +69,7 @@ Copy this block when adding a new issue:
## #231 — F-key pickup omits retail pending destination-slot presentation
**Status:** FIXED (2026-07-21) — keyboard pickup uses the shared ItemHolder path
**Status:** DONE (2026-07-21, `52dbb574` + `5acc3f01`)
**Severity:** MEDIUM
**Filed:** 2026-07-21
**Component:** selection / inventory / retained UI
@ -86,9 +86,9 @@ always sends `CM_Item::SendNotice_ShowPendingInPlayer` before
`ItemInteractionController` and raises `PendingBackpackPlacementRequested`;
the F-key switch case bypasses that owner.
**Files:** `src/AcDream.App/Rendering/GameWindow.cs`;
`src/AcDream.App/UI/ItemInteractionController.cs`;
future `src/AcDream.App/Interaction/SelectionInteractionController.cs`.
**Files:** `src/AcDream.App/UI/ItemInteractionController.cs`;
`src/AcDream.App/Interaction/SelectionInteractionController.cs`;
`src/AcDream.App/UI/Layout/InventoryController.cs`.
**Research:**
[`docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md`](plans/2026-07-21-gamewindow-slice-1-selection-interaction.md).
@ -99,15 +99,20 @@ Server confirmation settles it; server failure removes it without speculative
ownership mutation.
**Resolution:** `ItemInteractionController.PlaceWorldItemInBackpack` now owns
the shared pending-placement notification and request dispatch. Both
double-click activation and the F-key route enter that method, so they publish
the same destination container and placement before the server request.
the exact-token pending destination projection. The F-key route reserves it
before immediate or deferred MoveTo transport, promotes that same reservation
only when the packet is actually sent, and withdraws it on cancel/lifetime
loss. The review correction also ported the single global
`ACCWeenieObject::prevRequest` owner across inventory, external-container,
toolbar, paperdoll, give, merge, split, and drop routes. Optimistic placement,
server rollback, and authoritative response notifications are distinct; a
response clears global and local state atomically before reentrant observers.
---
## #230 — Selection hits and deferred actions can cross live GUID incarnations
**Status:** FIXED (2026-07-21) — incarnation identity is carried and revalidated
**Status:** DONE (2026-07-21, `047a4c83` + `5acc3f01`)
**Severity:** HIGH
**Filed:** 2026-07-21
**Component:** selection / live entity lifetime / interaction
@ -127,9 +132,9 @@ pending action. `CombatTargetController` also treats SessionReset like an
ordinary clear and can re-acquire before live records drain.
**Files:** `src/AcDream.Core/Selection/RetailSelectionMesh.cs`;
`src/AcDream.App/Rendering/Selection/`;
`src/AcDream.App/Rendering/GameWindow.cs`;
`src/AcDream.App/Combat/CombatTargetController.cs`.
`src/AcDream.App/Interaction/WorldSelectionQuery.cs`;
`src/AcDream.App/Interaction/SelectionInteractionController.cs`;
`src/AcDream.App/Input/OutboundInteractionQueue.cs`.
**Research:**
[`docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md`](plans/2026-07-21-gamewindow-slice-1-selection-interaction.md).
@ -144,7 +149,10 @@ complete interaction lifetime and never auto-targets.
current interaction-visible record. Deferred actions capture the same identity
and teardown clears the captured action even after GUID replacement. Session
reset now clears published selection geometry, lighting, ItemHolder target and
throttle state, and cannot trigger combat auto-target acquisition.
throttle state, and cannot trigger combat auto-target acquisition. Queued
input also captures the exact `ClientObject` reference, deferred movement is a
cancel-before-arm transaction, and session queue epochs prevent pre-reset work
from crossing into a new world.
---
@ -179,7 +187,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,481-pass / 5-skip suite remains green.
the full 6,558-pass / 5-skip suite remains green.
---

View file

@ -10,8 +10,9 @@ banner cannot silently override the current program state.
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.
in [`architecture/code-structure.md`](architecture/code-structure.md).
Selection/interaction Slice 1 is complete; live animation presentation is
next.
- **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
@ -23,7 +24,7 @@ banner cannot silently override the current program state.
- **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,481 tests passed and 5 intentionally
test-project warnings (`#228`); 6,558 tests passed and 5 intentionally
skipped. The unattended connected R6 route
completed seven portal materializations, production input exercises, and a
graceful close. See

View file

@ -833,7 +833,10 @@ Current movement/collision ownership:
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
prerequisite before new M4 subsystem bodies.** Selection/interaction Slice 1
landed 2026-07-21 with `WorldSelectionQuery`,
`SelectionInteractionController`, and the shared retail inventory-request
owner; live animation presentation is next. The 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.

View file

@ -1,8 +1,8 @@
# acdream — code structure & extraction sequence
**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.
completed 2026-07-21; Slice 1 landed the same day. 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 15,723-line `GameWindow.cs` at the
@ -22,8 +22,8 @@ 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 15,723 lines (2026-07-21)
258 fields / ~259 methods
baseline cf50ee3d 15,723 lines / 278 fields / 205 methods
after Slice 1 14,912 lines / 278 fields / 191 methods
```
`GameWindow` is the single object that:
@ -35,9 +35,9 @@ src/AcDream.App/Rendering/GameWindow.cs 15,723 lines (2026-07-21)
`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.
- Composes the shipped `WorldSelectionQuery` and
`SelectionInteractionController`; it no longer owns world-picking,
selection intent, Use/PickUp, or auto-walk deferral algorithms.
- Drives per-frame render orchestration (sky → terrain → opaque mesh →
transparent mesh → particles → debug lines → UI).
- Builds and applies streamed landblock presentation (DAT decode, scenery,
@ -391,7 +391,7 @@ useful ordering seam, but its ownership status is **partial**.
| 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. |
| 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. |
| 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. |
@ -409,7 +409,7 @@ 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.
#### Slice 1 — finish selection/interaction ownership — NEXT
#### Slice 1 — finish selection/interaction ownership — COMPLETE 2026-07-21
Detailed execution plan:
[`docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md`](../plans/2026-07-21-gamewindow-slice-1-selection-interaction.md).
@ -429,11 +429,21 @@ Split the old Step 4 into three reviewable commits:
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.
The cutover landed in `047a4c83`, `52dbb574`, `e74f2ca9`, `fa8d5232`,
`d2bb5af4`, and review-correction commit `5acc3f01`. The final review also
ported the shared `ACCWeenieObject::prevRequest` transaction shape across
inventory, toolbar, paperdoll, external-container, give, split, merge, and
drop routes. Queued actions, pending placements, and responses are bound to
exact object incarnations/tokens; optimistic projection, rollback projection,
and authoritative response notices are distinct.
#### Slice 2 — finish live animation presentation
Measured against `cf50ee3d`, `GameWindow` fell from 15,723 to 14,912 lines and
from 205 to 191 methods; field count stayed at 278 because the slice exchanged
legacy state for composed owners. Three independent retail, architecture, and
adversarial review loops finished clean. Release build passed; 6,558 tests
passed and five fixture/conformance tests skipped intentionally.
#### Slice 2 — finish live animation presentation — NEXT
Move `TickAnimations`, final rigid/visual part composition, effect-pose
publication, and motion-done binding into `LiveEntityAnimationPresenter`.

View file

@ -16,9 +16,15 @@ 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.
Slice 1 selection/interaction landed 2026-07-21: the read-only world query and
stateful intent owner are extracted, exact-incarnation lifetime is enforced,
and retail's global inventory-request transaction is shared across every UI
mutation surface. `GameWindow` is 811 lines and 14 methods smaller.
**Next:** Slice 2 finishes live animation presentation by moving final
part/mesh/effect-pose composition and motion-done binding behind
`LiveEntityAnimationPresenter`, while preserving the shipped scheduler and
retail object-frame order.
This is a behavior-preserving structural program. Severe regressions still get
root-cause fixes in separate commits; ordinary feature work resumes with M4
@ -1473,7 +1479,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,481 passed / 5 intentional skips (2026-07-21).
- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,558 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.

View file

@ -16,14 +16,15 @@ 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.
The 2026-07-21 audit baseline was 15,723 lines, 278 fields, and 205 methods.
Selection/interaction Slice 1 is complete at 14,912 lines, 278 fields, and 191
methods. Slice 2 — final live animation presentation ownership — is next.
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- and visual-gate complete; Release builds with 17 known
test-project warnings tracked by #228, and 6,481 tests pass / 5 skip), and
test-project warnings tracked by #228, and 6,558 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.

View file

@ -1,12 +1,33 @@
# GameWindow Slice 1 — selection and interaction ownership
**Status:** Approved for execution 2026-07-21.
**Status:** COMPLETE — landed 2026-07-21.
**Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 1.
**Baseline:** `cf50ee3d`; `GameWindow.cs` is 15,723 lines before this slice.
**Behavior rule:** Existing retail behavior moves unchanged. Any defect found by
the extraction audit is fixed in a separately identified commit before the
mechanical cutover.
## Landing record
- Plan/oracle: `c2713837`.
- Exact-incarnation lifetime hardening: `047a4c83`.
- Retail pending keyboard-pickup presentation: `52dbb574`.
- Read-only query extraction: `e74f2ca9`.
- Stateful interaction owner: `fa8d5232`.
- `GameWindow` cutover: `d2bb5af4`.
- Three-review correction pass: `5acc3f01`.
The correction pass unified retail's one-inventory-request-at-a-time owner
across every mutation surface, separated optimistic/rollback/authoritative
placement notices, made response completion atomic and reentrancy-safe, and
bound pending work to exact object identities and placement tokens.
Final metrics: `GameWindow.cs` 15,723 → 14,912 lines and 205 → 191 methods;
fields remained 278. Release build passed, the focused selection/inventory
gate passed, the full suite passed 6,558 tests with five intentional skips,
and the retail-conformance, architecture/integration, and adversarial reviews
all finished with no actionable findings.
## 1. Outcome
`GameWindow` stops owning world selection and selection-driven interaction.