docs(architecture): close live animation slice

Record the shipped presentation owner, exact frame-handoff lifetime, retail short-frame behavior, current GameWindow metrics, and Slice 3 as the next structural boundary.
This commit is contained in:
Erik 2026-07-21 10:03:20 +02:00
parent 833520253a
commit 9a150e2421
7 changed files with 94 additions and 23 deletions

View file

@ -115,16 +115,19 @@ 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; 6,558 tests pass / 5 skip (17 tracked warnings, #228). Release builds; 6,575 tests pass / 5 skip (17 tracked warnings, #228).
**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.
Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and
`SelectionInteractionController` own the domain, exact-incarnation queued work, `SelectionInteractionController` own the domain, exact-incarnation queued work,
and retail's shared inventory-request transaction. Slice 2 finishes live and retail's shared inventory-request transaction. Live-animation-presentation
animation presentation; later slices finish live-session and live-entity App Slice 2 is also complete: `LiveEntityAnimationPresenter` owns final visual and
integration, landblock presentation, update/render orchestration, and rigid PartArray composition, effect poses, and MotionDone; scheduler handoffs
composition cleanup. are incarnation-, clock-, projection-, and appearance-bound. `GameWindow` is
14,546 lines, 277 fields, and 190 methods. Slice 3 completes live-session
ownership next; later slices finish live-entity App integration, landblock
presentation, update/render orchestration, and composition 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, Modern Pipeline MP1b+, and #225's
lifestone/particle alpha visual gate. lifestone/particle alpha visual gate.

View file

@ -113,16 +113,19 @@ 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; 6,558 tests pass / 5 skip (17 tracked warnings, #228). Release builds; 6,575 tests pass / 5 skip (17 tracked warnings, #228).
**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.
Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and
`SelectionInteractionController` own the domain, exact-incarnation queued work, `SelectionInteractionController` own the domain, exact-incarnation queued work,
and retail's shared inventory-request transaction. Slice 2 finishes live and retail's shared inventory-request transaction. Live-animation-presentation
animation presentation; later slices finish live-session and live-entity App Slice 2 is also complete: `LiveEntityAnimationPresenter` owns final visual and
integration, landblock presentation, update/render orchestration, and rigid PartArray composition, effect poses, and MotionDone; scheduler handoffs
composition cleanup. are incarnation-, clock-, projection-, and appearance-bound. `GameWindow` is
14,546 lines, 277 fields, and 190 methods. Slice 3 completes live-session
ownership next; later slices finish live-entity App integration, landblock
presentation, update/render orchestration, and composition 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, Modern Pipeline MP1b+, and #225's
lifestone/particle alpha visual gate. lifestone/particle alpha visual gate.

View file

@ -1,7 +1,7 @@
# 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; Slice 1 landed the same day. This is the active completed 2026-07-21; Slices 1 and 2 landed the same day. This is the active
structural program before new M4 subsystems enter the App layer. 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
@ -24,6 +24,7 @@ The structural debt is concentrated in **one file**:
``` ```
baseline cf50ee3d 15,723 lines / 278 fields / 205 methods baseline cf50ee3d 15,723 lines / 278 fields / 205 methods
after Slice 1 14,912 lines / 278 fields / 191 methods after Slice 1 14,912 lines / 278 fields / 191 methods
after Slice 2 14,546 lines / 277 fields / 190 methods
``` ```
`GameWindow` is the single object that: `GameWindow` is the single object that:
@ -388,7 +389,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 | **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`. | | 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. | | 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`. | | 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. |
| 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. |
@ -443,7 +444,7 @@ legacy state for composed owners. Three independent retail, architecture, and
adversarial review loops finished clean. Release build passed; 6,558 tests adversarial review loops finished clean. Release build passed; 6,558 tests
passed and five fixture/conformance tests skipped intentionally. passed and five fixture/conformance tests skipped intentionally.
#### Slice 2 — finish live animation presentation — NEXT #### Slice 2 — finish live animation presentation — COMPLETE 2026-07-21
Move `TickAnimations`, final rigid/visual part composition, effect-pose Move `TickAnimations`, final rigid/visual part composition, effect-pose
publication, and motion-done binding into `LiveEntityAnimationPresenter`. publication, and motion-done binding into `LiveEntityAnimationPresenter`.
@ -457,7 +458,17 @@ rigid effect poses, part availability, same-frame hook pose publication, and
incarnation replacement. Run the R6 object-frame and projectile/effect suites incarnation replacement. Run the R6 object-frame and projectile/effect suites
plus the connected locomotion/projectile gate. plus the connected locomotion/projectile gate.
#### Slice 3 — complete live-session ownership Result: `LiveEntityAnimationPresenter` owns final visual/rigid part
composition, effect-pose publication, MotionDone binding, and typed diagnostics.
Schedules carry exact record/entity/component/epoch/projection/presentation
identity and own their authored frame prefix until the next scheduler tick.
Appearance and static-owner rebinding invalidate stale work. Named-retail
`CPartArray::UpdateParts` short-frame retention now preserves both visual and
rigid trailing poses. `GameWindow` lost 366 lines, two methods, and one net
field. Three independent retail, architecture, and adversarial review loops
finished clean; focused App/Core tests and the complete App suite pass.
#### Slice 3 — complete live-session ownership — NEXT
Expand `LiveSessionController` to own connect, character-list validation, Expand `LiveSessionController` to own connect, character-list validation,
character selection, EnterWorld, graceful character logout, reconnect, and character selection, EnterWorld, graceful character logout, reconnect, and

View file

@ -21,10 +21,16 @@ stateful intent owner are extracted, exact-incarnation lifetime is enforced,
and retail's global inventory-request transaction is shared across every UI and retail's global inventory-request transaction is shared across every UI
mutation surface. `GameWindow` is 811 lines and 14 methods smaller. mutation surface. `GameWindow` is 811 lines and 14 methods smaller.
**Next:** Slice 2 finishes live animation presentation by moving final Slice 2 live animation presentation landed 2026-07-21: final visual/rigid
part/mesh/effect-pose composition and motion-done binding behind PartArray composition, effect-pose publication, MotionDone binding, and
`LiveEntityAnimationPresenter`, while preserving the shipped scheduler and diagnostics now live in `LiveEntityAnimationPresenter`. Exact incarnation,
retail object-frame order. projection, object-clock, and appearance-revision tokens reject stale work;
ordinary/static frame handoffs own their buffers; retail short AnimFrames
retain trailing visible and rigid poses. `GameWindow` is now 14,546 lines.
**Next:** Slice 3 completes live-session ownership by moving connection,
character entry, typed event subscriptions, graceful logout, reconnect, and
session-scoped cleanup behind `LiveSessionController`/`LiveSessionEventRouter`.
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
@ -1479,7 +1485,7 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
## Cross-cutting work tracked in parallel ## Cross-cutting work tracked in parallel
- **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). - **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,575 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. - **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. - **`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

@ -17,14 +17,15 @@ layer, the active structural prerequisite is the behavior-preserving
`GameWindow` decomposition in `GameWindow` decomposition in
[`docs/architecture/code-structure.md`](../architecture/code-structure.md). [`docs/architecture/code-structure.md`](../architecture/code-structure.md).
The 2026-07-21 audit baseline was 15,723 lines, 278 fields, and 205 methods. 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 Selection/interaction Slice 1 and live-animation-presentation Slice 2 are
methods. Slice 2 — final live animation presentation ownership — is next. complete. `GameWindow` is now 14,546 lines, 277 fields, and 190 methods. Slice 3
— complete live-session ownership — is next.
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 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,558 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
implementation has passed connected lifetime/performance gates and awaits only implementation has passed connected lifetime/performance gates and awaits only
its lifestone/particle visual comparison. its lifestone/particle visual comparison.

View file

@ -1,9 +1,14 @@
# GameWindow Slice 2 — live animation presentation ownership # GameWindow Slice 2 — live animation presentation ownership
**Status:** Approved for execution 2026-07-21. **Status:** Complete 2026-07-21. Automated and three-agent review gates pass;
connected visual regression gate is carried to the final campaign gate.
**Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 2. **Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 2.
**Baseline:** `9ad8113c`; `GameWindow.cs` is 14,912 lines, 278 fields, and **Baseline:** `9ad8113c`; `GameWindow.cs` is 14,912 lines, 278 fields, and
191 methods before this slice. 191 methods before this slice.
**Result:** `GameWindow.cs` is 14,546 lines, 277 fields, and 190 methods.
The slice also closed stale-schedule ABA across replacement, appearance
rebinding, static rebind, and borrowed sequencer buffers. Forty-one focused
Release tests and the full 6,575-pass / 5-skip Release suite are green.
**Behavior rule:** This is an ownership extraction over the accepted R6 object **Behavior rule:** This is an ownership extraction over the accepted R6 object
frame plus one named-retail conformance correction: short AnimFrames retain frame plus one named-retail conformance correction: short AnimFrames retain
the prior/rest pose of trailing CPartArray parts. It must not otherwise change the prior/rest pose of trailing CPartArray parts. It must not otherwise change
@ -335,6 +340,12 @@ Additional invariants:
### Cross-owner order and reconciliation ### Cross-owner order and reconciliation
The presenter-level portions below are covered by Slice 2. The full
instrumented owner-order trace and non-advancing spatial-reconcile assertion
remain assigned to Slice 6, where the update sequence becomes one testable
orchestrator instead of a `GameWindow` method. Slice 2 preserves that order but
does not claim an end-to-end orchestrator test prematurely.
- One instrumented object-frame test pins presenter, children, static hooks, - One instrumented object-frame test pins presenter, children, static hooks,
fades, ordinary hook drain, effect roots, emitters, lights, particles, and fades, ordinary hook drain, effect roots, emitters, lights, particles, and
scripts. A PES-created particle first simulates on the following frame. scripts. A PES-created particle first simulates on the following frame.

View file

@ -1,5 +1,41 @@
# Animation Runtime Crib # Animation Runtime Crib
## Current live presentation ownership (2026-07-21)
`LiveEntityAnimationScheduler` owns ordinary-object time, PartArray advance,
root motion, and the retail manager tail. `RetailStaticAnimatingObjectScheduler`
owns the separate retail static-object workset. `LiveEntityAnimationPresenter`
is the sole consumer that composes final drawable part transforms, publishes
rigid part/effect poses, and binds `MotionDone`. `GameWindow` wires these owners
but no longer contains the presentation body.
The frame handoff is identity- and lifetime-bound. A schedule carries the exact
`LiveEntityRecord`, `WorldEntity`, animation state, sequencer, object-clock
epoch, projection mutation version, and presentation revision. Both ordinary
and static schedulers copy the sequencer's borrowed PartArray view into their
own buffers before invoking callbacks. Presentation is non-reentrant because
it consumes legacy elapsed time and static prepared frames exactly once.
Appearance rebinding increments `PresentationRevision`. That rejects a pose
prepared against the old part template without replacing the live animation
component. For a static owner, rejecting only that stale visual pose must retain
the same sequencer's pending `process_hooks` tail so `MotionDone` is not lost;
owner, sequencer, residency, projection, or clock mismatches still invalidate
the entire handoff.
Retail `CPartArray::UpdateParts` updates only the authored AnimFrame prefix.
When a frame contains fewer parts than the Setup, trailing parts keep their
previous pose (or their rest pose on first presentation) in both channels:
- visual: `DefaultScale * rotation * translation(origin) * ObjScale`;
- rigid/effect: `rotation * translation(origin * ObjScale)`.
Canonical per-frame order remains scheduler tick, static tick, live presenter,
equipped-child update, static `process_hooks`, deferred hook drain, attached
effects/lights, particles, and draw. The end-to-end order assertion belongs to
Slice 6's extracted update orchestrator; do not reintroduce local ordering into
the presenter.
## Live entity lifecycle invariant ## Live entity lifecycle invariant
`CreateObject` creates a live entity and a real `DeleteObject` destroys it. `CreateObject` creates a live entity and a real `DeleteObject` destroys it.