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,
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
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
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21.
Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and
`SelectionInteractionController` own the domain, exact-incarnation queued work,
and retail's shared inventory-request transaction. Slice 2 finishes live
animation presentation; later slices finish live-session and live-entity App
integration, landblock presentation, update/render orchestration, and
composition cleanup.
and retail's shared inventory-request transaction. Live-animation-presentation
Slice 2 is also complete: `LiveEntityAnimationPresenter` owns final visual and
rigid PartArray composition, effect poses, and MotionDone; scheduler handoffs
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
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
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,
outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
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
behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21.
Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and
`SelectionInteractionController` own the domain, exact-incarnation queued work,
and retail's shared inventory-request transaction. Slice 2 finishes live
animation presentation; later slices finish live-session and live-entity App
integration, landblock presentation, update/render orchestration, and
composition cleanup.
and retail's shared inventory-request transaction. Live-animation-presentation
Slice 2 is also complete: `LiveEntityAnimationPresenter` owns final visual and
rigid PartArray composition, effect poses, and MotionDone; scheduler handoffs
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
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
lifestone/particle alpha visual gate.

View file

@ -1,7 +1,7 @@
# acdream — code structure & extraction sequence
**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.
**Purpose:** Describe the desired structural state of the App layer,
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
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:
@ -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. |
| 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`. |
| 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. |
| 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. |
@ -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
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
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
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,
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
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.
Slice 2 live animation presentation landed 2026-07-21: final visual/rigid
PartArray composition, effect-pose publication, MotionDone binding, and
diagnostics now live in `LiveEntityAnimationPresenter`. Exact incarnation,
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
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
- **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.
- **`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
[`docs/architecture/code-structure.md`](../architecture/code-structure.md).
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.
Selection/interaction Slice 1 and live-animation-presentation Slice 2 are
complete. `GameWindow` is now 14,546 lines, 277 fields, and 190 methods. Slice 3
— complete live-session 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,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
implementation has passed connected lifetime/performance gates and awaits only
its lifestone/particle visual comparison.

View file

@ -1,9 +1,14 @@
# 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.
**Baseline:** `9ad8113c`; `GameWindow.cs` is 14,912 lines, 278 fields, and
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
frame plus one named-retail conformance correction: short AnimFrames retain
the prior/rest pose of trailing CPartArray parts. It must not otherwise change
@ -335,6 +340,12 @@ Additional invariants:
### 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,
fades, ordinary hook drain, effect roots, emitters, lights, particles, and
scripts. A PES-created particle first simulates on the following frame.

View file

@ -1,5 +1,41 @@
# 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
`CreateObject` creates a live entity and a real `DeleteObject` destroys it.