docs(runtime): pin J3 entity ownership migration
Reconcile J3 with later gameplay lifetime groups, inventory the current mixed entity/object ownership, and define the staged canonical identity, projection, object-table, delta, teardown, and no-window gates. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
9496c01be1
commit
b0fecc5f65
3 changed files with 365 additions and 0 deletions
|
|
@ -179,6 +179,9 @@ git revert 75930787741db40a83eab8663e4464dce8d687ba
|
|||
|
||||
### J3 — canonical identity, properties, and object-table group
|
||||
|
||||
**Detailed execution plan:**
|
||||
[`2026-07-25-modern-runtime-slice-j3.md`](2026-07-25-modern-runtime-slice-j3.md).
|
||||
|
||||
- Strip renderer, particle, Wb, and streaming components from the canonical
|
||||
record into an App projection store keyed only by local identity/incarnation.
|
||||
- Move `LiveEntityRuntime`, accepted spawn/state/property timestamps,
|
||||
|
|
|
|||
265
docs/plans/2026-07-25-modern-runtime-slice-j3.md
Normal file
265
docs/plans/2026-07-25-modern-runtime-slice-j3.md
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
# Modern runtime Slice J3 — canonical identity, properties, and object table
|
||||
|
||||
**Status:** ACTIVE
|
||||
**Parent:** `2026-07-25-modern-runtime-slice-j.md`, J3
|
||||
**Production base:** `9496c01b`
|
||||
**J2 production commit:** `75930787741db40a83eab8663e4464dce8d687ba`
|
||||
|
||||
## 1. Objective
|
||||
|
||||
Move the one canonical server-object identity/incarnation owner, accepted
|
||||
CreateObject/property/timestamp state, parent relation state, and
|
||||
`ClientObjectTable` lifetime into `AcDream.Runtime`.
|
||||
|
||||
App becomes a projection host. Its world entity, animation, effect, light,
|
||||
selection, paperdoll, spatial bucket, and hydration state is keyed by a
|
||||
Runtime-issued local identity plus exact incarnation. App must not retain a
|
||||
second server-GUID map or decide whether a packet belongs to the current
|
||||
incarnation.
|
||||
|
||||
This is a structural move. Existing named-retail CreateObject, timestamp,
|
||||
parenting, pickup, Hidden, delete, and generation-replacement behavior remains
|
||||
unchanged. No renderer, particle, streaming, GL, or retained-UI type may enter
|
||||
Runtime.
|
||||
|
||||
## 2. Scope reconciliation
|
||||
|
||||
The umbrella J3 text overlaps later lifetime groups. This detailed plan is the
|
||||
authoritative split:
|
||||
|
||||
- J3 moves raw accepted entity identity, immutable spawn/property snapshots,
|
||||
timestamp gates, parent relations, and the canonical client object/container
|
||||
table.
|
||||
- J4 moves higher-level inventory transactions, vitals, enchantments,
|
||||
spell/component state, cooldown services, chat, and their ViewModel-facing
|
||||
revisions.
|
||||
- J5 moves movement/physics/interaction/combat authority.
|
||||
|
||||
J3 may retain existing Core physics references already stored on the entity
|
||||
record while separating presentation, but it does not redesign or relocate
|
||||
their behavior. That coherent move remains J5.
|
||||
|
||||
## 3. Fixed ownership after J3
|
||||
|
||||
`AcDream.Runtime` owns:
|
||||
|
||||
- server GUID to current incarnation;
|
||||
- exact Runtime local identity allocation and reverse lookup;
|
||||
- accepted `INSTANCE_TS` and every retail packet-channel timestamp;
|
||||
- the latest accepted immutable `WorldSession.EntitySpawn`;
|
||||
- logical create, same-incarnation refresh, pickup, parent, Hidden/state,
|
||||
delete, generation replacement, tombstone, and session-clear state;
|
||||
- unresolved/staged/committed parent relations;
|
||||
- `ClientObjectTable`, containers, placement indices, pending authoritative
|
||||
property state, and generation-aware removal;
|
||||
- ordered immutable entity/object deltas;
|
||||
- retryable logical teardown state and the acknowledgement from an attached
|
||||
projection host.
|
||||
|
||||
`AcDream.App` owns:
|
||||
|
||||
- `WorldEntity` and render-scene projection;
|
||||
- loaded/pending spatial buckets and visibility derived from streaming;
|
||||
- animation, remote-motion presentation, projectile presentation, effects,
|
||||
lights, selection geometry, radar presentation, and private paperdolls;
|
||||
- projection hydration/recovery transaction state;
|
||||
- render/resource registration and its exact retryable teardown suffix.
|
||||
|
||||
App projection keys are:
|
||||
|
||||
```text
|
||||
RuntimeLocalEntityId + INSTANCE_TS
|
||||
```
|
||||
|
||||
Server GUID may be carried as immutable metadata for diagnostics and outbound
|
||||
commands, but it is not an App lookup authority.
|
||||
|
||||
## 4. Runtime contracts
|
||||
|
||||
Introduce or finish contracts equivalent to:
|
||||
|
||||
```csharp
|
||||
public readonly record struct RuntimeEntityKey(
|
||||
uint LocalEntityId,
|
||||
ushort Incarnation);
|
||||
|
||||
public readonly record struct RuntimeEntityDelta(
|
||||
ulong Sequence,
|
||||
RuntimeGenerationToken SessionGeneration,
|
||||
RuntimeEntityKey Entity,
|
||||
RuntimeEntityDeltaKind Kind,
|
||||
RuntimeEntitySnapshot Snapshot);
|
||||
|
||||
public interface IRuntimeEntityProjectionHost
|
||||
{
|
||||
RuntimeProjectionAcknowledgement Register(RuntimeEntitySnapshot entity);
|
||||
RuntimeProjectionAcknowledgement Update(RuntimeEntityDelta delta);
|
||||
RuntimeProjectionAcknowledgement Withdraw(RuntimeEntityKey entity);
|
||||
RuntimeProjectionAcknowledgement TearDown(RuntimeEntityKey entity);
|
||||
}
|
||||
```
|
||||
|
||||
The concrete names may follow existing project vocabulary, but these
|
||||
invariants are mandatory:
|
||||
|
||||
- Runtime issues identity before App creates a projection.
|
||||
- Every App callback carries the exact local identity and incarnation.
|
||||
- Callback acknowledgement is exact and retryable.
|
||||
- Completed teardown work never replays.
|
||||
- App cannot query or mutate Runtime by a stale local identity/incarnation.
|
||||
- Runtime emits deltas only after canonical state commits.
|
||||
- Callback reentrancy may supersede the outer operation; the outer operation
|
||||
must revalidate generation/incarnation/operation version before continuing.
|
||||
|
||||
## 5. Execution slices
|
||||
|
||||
### J3.0 — oracle and ownership inventory
|
||||
|
||||
- Pin the current field/method ownership table for `LiveEntityRecord`,
|
||||
`LiveEntityRuntime`, `InboundPhysicsStateController`,
|
||||
`ParentAttachmentState`, `ClientObjectTable`, `GpuWorldState`, hydration,
|
||||
and teardown owners.
|
||||
- Reuse the existing retail pseudocode and citations; no behavior is being
|
||||
invented. Add research only where a current branch lacks a cited oracle.
|
||||
- Capture normalized existing traces for create, same-generation refresh,
|
||||
parent/unparent, pickup, Hidden, delete/recreate, GUID reuse, container
|
||||
placement, and session clear.
|
||||
- Record baseline render-scene identity/digest at deterministic fixtures.
|
||||
|
||||
### J3.1 — move narrow accepted-wire owners
|
||||
|
||||
- Move `InboundPhysicsStateController`, `ParentAttachmentState`, their result
|
||||
types, and their complete tests into Runtime.
|
||||
- Preserve timestamp cursor/order behavior and parent candidate ordering
|
||||
line-for-line.
|
||||
- App's existing `LiveEntityRuntime` temporarily composes those Runtime owners;
|
||||
no second state is introduced.
|
||||
- Add Runtime dependency/load guards around the moved types.
|
||||
|
||||
Gate: all timestamp, malformed, wraparound, parent-generation, and packet-order
|
||||
tests pass in Runtime; App behavior and complete suite remain unchanged.
|
||||
|
||||
### J3.2 — canonical Runtime entity directory
|
||||
|
||||
- Extract current GUID/incarnation maps, accepted snapshot state, session
|
||||
lifetime version, operation versions, tombstones, delete/generation
|
||||
replacement, and local-ID allocation into one Runtime owner.
|
||||
- Split `LiveEntityRecord` into canonical Runtime state and an App projection
|
||||
sidecar. Canonical fields never reference App interfaces or `WorldEntity`.
|
||||
- Preserve current local-ID allocation order during graphical hydration for
|
||||
parity; Runtime owns the allocator and claim, while a no-window host may
|
||||
claim immediately.
|
||||
- Retain exact reentrant supersession and retryable tombstone behavior.
|
||||
- Keep physics/movement fields structurally in place where required for J5,
|
||||
but remove every renderer/effect/hydration reference from the canonical
|
||||
record.
|
||||
|
||||
Gate: the complete existing `LiveEntityRuntimeTests` identity/timestamp/
|
||||
teardown subset moves to Runtime and produces the same normalized trace.
|
||||
|
||||
### J3.3 — App projection store and cutover
|
||||
|
||||
- Add one App projection store keyed only by Runtime local identity plus
|
||||
incarnation.
|
||||
- Move `WorldEntity`, spatial visibility, hydration/recovery flags, animation,
|
||||
remote-motion presentation, projectile presentation, effect profiles,
|
||||
resource flags, and active presentation worksets into that store.
|
||||
- Convert `GpuWorldState`, hydration, equipped children, render journal,
|
||||
animation/effect/light owners, selection/radar queries, and teardown to the
|
||||
exact projection key.
|
||||
- Replace App's mixed `LiveEntityRuntime` facade with focused Runtime directory
|
||||
and App projection-store dependencies; delete its GUID maps and mixed record.
|
||||
- Preserve current register-once, rebucket-only, withdraw-without-destroy,
|
||||
Hidden, and retryable logical teardown order.
|
||||
|
||||
Gate: projection identity/digest and all existing hydration, rebucket,
|
||||
visibility, effect, animation, projectile, selection, and teardown tests match.
|
||||
Source guards reject any App server-GUID authority map.
|
||||
|
||||
### J3.4 — canonical object-table ownership
|
||||
|
||||
- Add a Runtime entity/object lifetime-group root that owns the canonical
|
||||
entity directory and the existing Core `ClientObjectTable`.
|
||||
- Construct it before either graphical UI or live presentation; both borrow
|
||||
the same instances.
|
||||
- Remove the public `ClientObjectTable` owner field from `GameWindow`.
|
||||
- Route J2 inbound object/property/container updates directly to the Runtime
|
||||
group.
|
||||
- Keep UI controllers, item icons, paperdoll, grids, cooldown drawing, and
|
||||
interaction presentation as App borrowers.
|
||||
- Preserve synchronous press-time reads and current event ordering; add no
|
||||
queue or copied inventory model.
|
||||
|
||||
Gate: object add/update/remove, placement, container replacement, optimistic
|
||||
move rollback, stack response, GUID reuse, and session-clear traces match.
|
||||
|
||||
### J3.5 — ordered deltas and borrowed views
|
||||
|
||||
- Publish one monotonic per-session Runtime entity/object delta stream.
|
||||
- Make J1 `IGameRuntimeView.Entities` and inventory snapshots read the Runtime
|
||||
owners directly rather than App adapters.
|
||||
- Feed App projection mutation from the same committed deltas/acknowledgements;
|
||||
do not create a second queue or frame delay.
|
||||
- Remove superseded App entity/object event mirroring and source adapters.
|
||||
- Assert same-thread graphical input and inbound presentation remain
|
||||
synchronous.
|
||||
|
||||
Gate: direct-host and graphical-host normalized traces are identical, including
|
||||
sequence, generation, identity, properties, placement, and teardown edges.
|
||||
|
||||
### J3.6 — hardening and closeout
|
||||
|
||||
- Failure-inject every projection registration/update/withdraw/teardown stage.
|
||||
- Exercise callback reentrancy, duplicate CreateObject, stale/equal/wrapped
|
||||
timestamps, delete/recreate with the same GUID, pending-to-loaded movement,
|
||||
parent events before either object, malformed property packets, and session
|
||||
reset during callbacks.
|
||||
- Prove zero leaked canonical records, tombstones, App projections, resources,
|
||||
container entries, parent candidates, queued deltas, or subscriptions.
|
||||
- Add a Runtime-only entity/object fixture that performs create, property
|
||||
updates, parent/container moves, Hidden, delete/recreate, clear, and teardown
|
||||
without loading presentation/backend assemblies.
|
||||
- Run Release build, focused suites, complete tests, exact-binary connected
|
||||
lifecycle/reconnect, and the canonical world route.
|
||||
- Because J3 changes projection identity plumbing, run the existing automated
|
||||
render digest/referee at every checkpoint. Pause for user visual verification
|
||||
only if the referee or connected client exposes a pixel/interaction symptom.
|
||||
|
||||
## 6. Commit order
|
||||
|
||||
1. `refactor(runtime): move accepted entity wire state`
|
||||
2. `refactor(runtime): own canonical entity identity and incarnations`
|
||||
3. `refactor(app): key live projections by runtime identity`
|
||||
4. `refactor(runtime): own canonical object table`
|
||||
5. `feat(runtime): publish ordered entity and object deltas`
|
||||
6. `test(runtime): close J3 entity ownership parity`
|
||||
|
||||
Each commit is independently buildable and bisectable. The exact rollback for
|
||||
each lands in this document before that commit's connected or visual gate.
|
||||
|
||||
## 7. Acceptance
|
||||
|
||||
J3 is complete only when:
|
||||
|
||||
- Runtime owns the only server-GUID/incarnation map and object table;
|
||||
- App projections are keyed by local identity plus incarnation;
|
||||
- Runtime has no App/UI/backend dependency;
|
||||
- App has no authoritative GUID map or accepted timestamp gate;
|
||||
- no mirrored collection, asynchronous seam, or added input frame exists;
|
||||
- normalized direct/graphical traces match;
|
||||
- deterministic render identity/digests match;
|
||||
- Runtime-only no-window entity/object lifecycle passes;
|
||||
- Release build and complete tests pass;
|
||||
- exact-binary connected login/travel/logout/reconnect passes gracefully;
|
||||
- every teardown owner converges to zero.
|
||||
|
||||
## 8. Current rollback chain
|
||||
|
||||
```text
|
||||
git revert 75930787741db40a83eab8663e4464dce8d687ba
|
||||
git revert 854d9e9cd13092bd5aaa3cf025d73eeb4600e9f8
|
||||
git revert b632672e5ccabfb44c551e08f1c411ab2669c44a
|
||||
```
|
||||
|
||||
These are J2, J1, and J0 respectively. Do not use them for a J3 sub-slice
|
||||
failure; record and revert only the exact failing J3 commit.
|
||||
Loading…
Add table
Add a link
Reference in a new issue