diff --git a/AGENTS.md b/AGENTS.md index 0fc6cea5..860ba21d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -261,7 +261,8 @@ work is complete; the exact seven-checkpoint connected lifecycle/reconnect gate passes. Slice I is closed in `docs/plans/2026-07-25-modern-runtime-slice-i.md`; the coherent Slice J campaign executes from `docs/plans/2026-07-25-modern-runtime-slice-j.md`; J3.6 closeout -is `docs/research/2026-07-26-slice-j3-6-lifetime-closeout.md`. The exact G4 +is `docs/research/2026-07-26-slice-j3-6-lifetime-closeout.md`; J4 executes from +`docs/plans/2026-07-26-modern-runtime-slice-j4.md`. The exact G4 visual rollback is `git revert ef1d263337997bb030eadb7b8e71d73dc659907a`; do not revert G3 or the portal-warmup corrections. Evidence: diff --git a/CLAUDE.md b/CLAUDE.md index b03d5239..ca2e4df3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -259,7 +259,8 @@ work is complete; the exact seven-checkpoint connected lifecycle/reconnect gate passes. Slice I is closed in `docs/plans/2026-07-25-modern-runtime-slice-i.md`; the coherent Slice J campaign executes from `docs/plans/2026-07-25-modern-runtime-slice-j.md`; J3.6 closeout -is `docs/research/2026-07-26-slice-j3-6-lifetime-closeout.md`. The exact G4 +is `docs/research/2026-07-26-slice-j3-6-lifetime-closeout.md`; J4 executes from +`docs/plans/2026-07-26-modern-runtime-slice-j4.md`. The exact G4 visual rollback is `git revert ef1d263337997bb030eadb7b8e71d73dc659907a`; do not revert G3 or the portal-warmup corrections. Evidence: diff --git a/docs/plans/2026-07-25-modern-runtime-slice-j.md b/docs/plans/2026-07-25-modern-runtime-slice-j.md index 7c78f302..bd245c3c 100644 --- a/docs/plans/2026-07-25-modern-runtime-slice-j.md +++ b/docs/plans/2026-07-25-modern-runtime-slice-j.md @@ -215,6 +215,9 @@ match current traces; App has no server-GUID ownership. **Active 2026-07-26.** +**Detailed execution plan:** +[`2026-07-26-modern-runtime-slice-j4.md`](2026-07-26-modern-runtime-slice-j4.md). + - Move canonical chat history/channel state, inventory transactions, spell and component state, enchantments, vitals, skills/attributes, and gameplay cooldown state by coherent owner groups. @@ -233,7 +236,7 @@ lifetime group at a time in this order: 2. inventory transaction and gameplay item-use state that is not already canonical in `RuntimeEntityObjectLifetime`; 3. learned spells, formulas/components, enchantments, and cast/cooldown state; -4. vitals, skills, attributes, advancement, and target/combat gameplay state; +4. vitals, skills, attributes, advancement, and character-option state; 5. plugin/bot borrowed views and typed commands over those same owners; 6. delete every replaced App owner/adapter, then run the combined no-window, graphical parity, teardown, Release, lifecycle/reconnect, and nine-stop diff --git a/docs/plans/2026-07-26-modern-runtime-slice-j4.md b/docs/plans/2026-07-26-modern-runtime-slice-j4.md new file mode 100644 index 00000000..3d342cc4 --- /dev/null +++ b/docs/plans/2026-07-26-modern-runtime-slice-j4.md @@ -0,0 +1,160 @@ +# Modern runtime Slice J4 — gameplay-state lifetime groups + +**Status:** ACTIVE +**Parent:** `2026-07-25-modern-runtime-slice-j.md`, J4 +**Production base:** `77c013998b902724d66e487589a4ea18538e1ea6` +**Authorization:** the user approved Slices F–L, including Slice J gameplay +owner moves, on 2026-07-24 + +## Objective + +Move the remaining presentation-independent player/gameplay state into +`AcDream.Runtime` without creating a second model, changing retail behavior, +or making the graphical host authoritative. + +Runtime must construct and own each mutable Core state object. App, retained +UI, devtools, plugins, and the live-session router borrow those exact +instances. Every moved group retains current synchronous packet/command +ordering and its existing retail-derived algorithms. + +## Current ownership inventory + +The App `GameWindow` currently constructs or roots these +presentation-independent owners: + +| Group | Current canonical objects | Current App roots | +|---|---|---| +| Communication/social | `ChatLog`, `TurbineChatState`, `FriendsState`, `SquelchState`; reply/retell targets currently live in `ChatVM` | public `GameWindow` fields plus `ChatVM` subscription | +| Inventory/session transactions | J3's Runtime-owned `ClientObjectTable`; `ExternalContainerState`, `ItemManaState`, shortcut snapshot, desired-component snapshot | `GameWindow`, App snapshot wrappers, and `LiveSessionRuntimeFactory` | +| Magic/effects/player sheet | coupled `Spellbook` + `LocalPlayerState`; learned spells, favorites, filters, desired components, active enchantments, cooldown bucket, attributes, skills, vitals, properties, positions | `GameWindow` fields; App `MagicRuntime` and retained controllers borrow them | +| Character settings/skill motion projection | character options and run/jump controller inputs | App input/composition state | +| Presentation-only state | formatted/layout chat rows, retained panels, text/icons, selected rows, scroll offsets, paperdoll/viewport, effects rendering, cooldown overlays | App/UI; these do **not** move | + +`RuntimeEntityObjectLifetime` already owns the inventory object collection and +ordered object deltas. J4 must reuse that owner. It may not introduce a second +inventory list or replay object-table events into another collection. + +Selection, approach/use input, movement, combat intent, target state, +projectiles, and outbound motion/cast cadence remain J5. World reveal, +environment, and portal presentation remain J6. + +## Fixed invariants + +1. One mutable owner instance per state class; adapters and panels borrow. +2. Runtime has no App, UI, Silk, OpenAL, Arch, ImGui, or GL dependency. +3. No asynchronous App seam, extra frame, polling copy, or reconstructed + ViewModel collection. +4. Existing `WorldSession`/`GameEventWiring` registration order and + generation acceptance gates remain unchanged. +5. Session reset preserves the current semantic order. Visible chat history + survives character teardown while reply targets, local identity, negotiated + rooms, friends, and squelch state reset. +6. Immutable DAT-derived catalog data may be installed once. Mutable learned + spells, enchantments, filters, favorites, desired components, vitals, + skills, and cooldown state are session-owned. +7. Every group has a Runtime-only construction/reset/disposal test that loads + no presentation/backend assembly. +8. The replaced App ownership path is deleted in the same sub-slice. + +## Execution + +### J4.1 — communication and social state + +- Add a Runtime owner for `ChatLog`, `TurbineChatState`, `FriendsState`, + `SquelchState`, and reply/retell command targets. +- Move reply/retell target tracking out of `ChatVM`; the VM borrows the same + presentation-independent target state. +- Make `LiveSessionRuntimeFactory`, command routing, current-runtime views, + retained UI, devtools, and plugins borrow the Runtime owner. +- Replace `GameWindow` object fields with read-only aliases to that owner. +- Preserve transcript lifetime and exact per-session reset semantics. + +Gate: incoming/outgoing tell tracking, room negotiation/cookie wrap, friend and +squelch updates, command routing, clear, reset/reconnect, graphical/direct +event traces, disposal, and Runtime dependency closure. + +### J4.2 — inventory transaction state + +- Move `ExternalContainerState`, `ItemManaState`, shortcuts, and desired + component snapshots into one Runtime owner. +- Keep the J3 object table as the only item collection and borrow it directly. +- Split presentation/input-only portions from item-use reservations only where + the existing class mixes them; do not move retained drag/drop or panel state. +- Route inbound object/use/mana/shortcut/component updates and bot/plugin views + through the same owner. + +Gate: optimistic move/rollback, external-container open/replace/close, +use-completion, mana query, shortcut/component replacement, clear/reconnect, +and zero duplicate collection. + +### J4.3 — spell, enchantment, vital, attribute, and skill state + +- Move construction/lifetime of the coupled `Spellbook` and + `LocalPlayerState` into Runtime. +- Preserve one-time immutable `SpellTable` installation from App content. +- Keep learned spells, favorites, filters, desired components, + enchantments/cooldowns, vitals, attributes, skills, properties, and positions + on those exact owners. +- Retained magic/effects/character panels and App `MagicCatalog` borrow; no + DAT/UI type enters Runtime. + +Gate: complete PlayerDescription, incremental updates, spell/enchantment +add/remove, favorite/filter/component changes, cooldowns, vital modifiers, +clear/reconnect, ViewModel revisions, and graphical/direct trace parity. + +### J4.4 — character settings and player-state projections + +- Move remaining presentation-independent character options and skill-derived + state needed by commands/bots. +- Keep controller/body/camera/input application in App/J5. +- Expose borrowed immutable views and synchronous typed commands for all J4 + groups. + +Gate: character replacement, settings isolation, two Runtime instances in one +process, no static mutable session state, and no backend load. + +### J4.5 — combined cleanup and closeout + +- Delete temporary App owner fields, reset branches, reconstructed runtime + views/events, and compatibility adapters replaced by J4. +- Prove graphical UI and no-window hosts observe the same owner instances, + revisions, command effects, and ordered deltas. +- Failure-inject construction, subscription, callback, reset, and disposal for + every group; require complete owner-ledger convergence. + +Run: + +1. focused Core and Runtime state tests; +2. UI ViewModel/controller tests; +3. App composition/session/reset/runtime-adapter tests; +4. Runtime dependency/source/assembly-load guards; +5. full Runtime and App suites; +6. Release build and complete Release suite; +7. exact-binary lifecycle/reconnect gate; +8. canonical nine-stop route; +9. documentation, divergence, dependency, and source-ownership audit. + +## Acceptance + +J4 is complete only when: + +- Runtime constructs and owns every listed presentation-independent object; +- App/UI/plugin/bot consumers borrow exact instances; +- no App mirror, reconstructed collection, or command target remains; +- reset, reconnect, direct disposal, and two-instance isolation pass; +- graphical and Runtime-only normalized traces match; +- Runtime's assembly closure remains backend-free; +- full Release and both exact-binary connected routes pass; +- architecture, roadmap, milestones, AGENTS/CLAUDE, durable memory, evidence, + and exact rollback are synchronized. + +## Rollback + +Record each J4 production commit before its connected gate. Revert J4 groups in +reverse order only. J3.6 remains independently reversible with: + +```text +git revert 119b7c115107245546180b2f5cb3cb44c7d5476a +``` + +Do not revert J3 to mask a J4 owner/reset failure.