323 lines
15 KiB
Markdown
323 lines
15 KiB
Markdown
# Modern runtime Slice J3 — canonical identity, properties, and object table
|
|
|
|
**Status:** COMPLETE 2026-07-26
|
|
**Parent:** `2026-07-25-modern-runtime-slice-j.md`, J3
|
|
**Production base:** `9496c01b`
|
|
**J2 production commit:** `75930787741db40a83eab8663e4464dce8d687ba`
|
|
|
|
## 0. Current checkpoint
|
|
|
|
| Slice | Status | Commit / evidence |
|
|
|---|---|---|
|
|
| J3.0 ownership inventory | complete | `b0fecc5f65ed26042c61a1651fb134aeb432c141`; `docs/research/2026-07-25-slice-j3-entity-ownership-inventory.md` |
|
|
| J3.1 accepted-wire owners | complete | `f7442d13e9ae7d5b077ffecb1f8a10899ad46edd`; 110 Runtime tests and complete Release parity remain green after J3.2 |
|
|
| J3.2 canonical Runtime entity directory | complete | `f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`; 8,441 Release tests / 5 skips and `logs/connected-world-gate-20260725-200749/report.json` pass |
|
|
| J3.3 App projection store | complete | `420e5eea70fd2c29cf9c8614e6298a1f84d64045` + `e937cc36df39cf6ea1eaba2f9c0243d1929da702`; 8,444 Release tests / 5 skips and `logs/connected-world-gate-20260725-221008/report.json` pass |
|
|
| J3.4 canonical object-table ownership | complete | `5ef8b5371d8990f0380acd939e71cd711289d429`; 118 Runtime tests, 3,762 App tests / 3 skips, 8,453 complete Release tests / 5 skips, and `logs/connected-world-gate-20260726-055713/report.json` pass |
|
|
| J3.5 ordered deltas and borrowed views | complete | `ce3ac310d92722ffb637e81cb1957458874dd220`; 134 Runtime tests, 3,765 App tests / 3 skips, 8,472 complete Release tests / 5 skips, and `logs/connected-world-gate-20260726-064324/report.json` pass |
|
|
| J3.6 adversarial hardening and closeout | complete | `119b7c115107245546180b2f5cb3cb44c7d5476a`; 146 Runtime tests, 3,765 App tests / 3 skips, 8,484 complete Release tests / 5 skips, exact lifecycle/reconnect gate, and canonical nine-stop route pass |
|
|
|
|
J3.5 passes the Release solution build, 134 Runtime tests, 3,765 App tests with
|
|
three skips, and 8,472 complete tests with five expected skips. Its exact-
|
|
binary seven-checkpoint connected lifecycle/reconnect route also passes with
|
|
graceful exits, zero render-shadow mismatches, and zero pending deltas. Runtime
|
|
now issues canonical identity before graphical hydration, publishes entity and
|
|
inventory commits through one per-generation sequence, and exposes the same
|
|
direct borrowed views to graphical and no-window hosts. App no longer
|
|
reconstructs those views or events. No frame queue, backend dependency, or
|
|
gameplay behavior change was added. The exact rollback for J3.5 is:
|
|
|
|
```text
|
|
git revert ce3ac310d92722ffb637e81cb1957458874dd220
|
|
```
|
|
|
|
J3.6 closes the group under callback failure, re-entrancy, retained teardown,
|
|
reset, GUID reuse, and direct disposal. Its complete owner ledger converges to
|
|
zero and both exact-binary connected routes pass. Evidence:
|
|
[`../research/2026-07-26-slice-j3-6-lifetime-closeout.md`](../research/2026-07-26-slice-j3-6-lifetime-closeout.md).
|
|
The exact rollback for J3.6 is:
|
|
|
|
```text
|
|
git revert 119b7c115107245546180b2f5cb3cb44c7d5476a
|
|
```
|
|
|
|
## 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
|
|
|
|
**Detailed execution plan:**
|
|
[`2026-07-25-modern-runtime-slice-j3-object-table.md`](2026-07-25-modern-runtime-slice-j3-object-table.md).
|
|
|
|
- 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
|
|
|
|
**Detailed execution plan:**
|
|
[`2026-07-26-modern-runtime-slice-j3-delta-stream.md`](2026-07-26-modern-runtime-slice-j3-delta-stream.md).
|
|
|
|
- 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.
|
|
|
|
J3 sub-slices are independently reversible:
|
|
|
|
```text
|
|
git revert ce3ac310d92722ffb637e81cb1957458874dd220
|
|
git revert 5ef8b5371d8990f0380acd939e71cd711289d429
|
|
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
|
|
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
|
|
git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
|
|
git revert f7442d13e9ae7d5b077ffecb1f8a10899ad46edd
|
|
```
|
|
|
|
Revert J3.6 before J3.5. Revert J3.5 before J3.4. Revert J3.4 before J3.3.
|
|
Revert J3.3's exact-spatial
|
|
correction before its main projection-store commit. Revert J3.3 before J3.2,
|
|
and J3.2 before J3.1, when rolling back more than one sub-slice.
|