docs(runtime): close J3.3 and hand off J3.4
Record exact projection-store ownership, automated and connected evidence, rollback chain, and the executor-ready canonical object-table plan. Reconcile milestones, roadmap, architecture, divergence pointers, AGENTS/CLAUDE, and durable handoff state. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
e937cc36df
commit
d9bf4c4960
15 changed files with 757 additions and 114 deletions
21
AGENTS.md
21
AGENTS.md
|
|
@ -213,8 +213,14 @@ operation maps; `RuntimeEntityRecord` is presentation-free and App records are
|
|||
graphical sidecars. Runtime tests pass 110/110, App tests pass 3,758/3 skips,
|
||||
the complete Release suite passes 8,441/5 skips, and the exact-binary seven-
|
||||
checkpoint lifecycle/reconnect gate passes with graceful exits, zero render-
|
||||
shadow mismatches, and zero pending deltas. J3.3 exact-key App projection-store
|
||||
cutover is next. J0's rollback is
|
||||
shadow mismatches, and zero pending deltas. J3.3 is complete at `420e5eea`
|
||||
plus exact-spatial correction `e937cc36`: `LiveEntityProjectionStore` and every
|
||||
materialized presentation/spatial owner now use exact `RuntimeEntityKey`; the
|
||||
temporary GUID-shaped compatibility view is deleted. App tests pass 3,761/3
|
||||
skips, the complete Release suite passes 8,444/5 skips, and the final exact-
|
||||
binary seven-checkpoint gate passes with two graceful exits, zero failures,
|
||||
zero render-shadow mismatches, and zero pending deltas. J3.4 canonical
|
||||
`ClientObjectTable` ownership is next. J0's rollback is
|
||||
`git revert b632672e5ccabfb44c551e08f1c411ab2669c44a`.
|
||||
J1's rollback is
|
||||
`git revert 854d9e9cd13092bd5aaa3cf025d73eeb4600e9f8`.
|
||||
|
|
@ -222,11 +228,15 @@ J2's rollback is
|
|||
`git revert 75930787741db40a83eab8663e4464dce8d687ba`.
|
||||
J3.2's rollback is
|
||||
`git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`.
|
||||
J3.3's rollback is, newest first,
|
||||
`git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702` then
|
||||
`git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045`.
|
||||
Slice H's retained UI/frame, bounded-light, and pooled/borrowed/direct network
|
||||
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`. The exact G4 visual rollback
|
||||
executes from `docs/plans/2026-07-25-modern-runtime-slice-j.md`; J3.4 starts at
|
||||
`docs/plans/2026-07-25-modern-runtime-slice-j3-object-table.md`. The exact G4 visual rollback
|
||||
is `git revert ef1d263337997bb030eadb7b8e71d73dc659907a`; do not revert G3 or
|
||||
the portal-warmup corrections. Evidence:
|
||||
`docs/research/2026-07-25-slice-h-closeout.md` and
|
||||
|
|
@ -239,7 +249,10 @@ the portal-warmup corrections. Evidence:
|
|||
`docs/research/2026-07-25-slice-i6-flat-production-cutover.md` and
|
||||
`docs/research/2026-07-25-slice-i7-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j1-runtime-contract-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j2-session-lifetime-closeout.md`.
|
||||
`docs/research/2026-07-25-slice-j2-session-lifetime-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j3-2-canonical-entity-directory-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j3-3-exact-projection-store.md`. Agent handoff:
|
||||
`docs/research/2026-07-25-slice-j3-3-complete-j3-4-handoff.md`.
|
||||
|
||||
**Structural prerequisite before new M4 subsystem work:** all eight
|
||||
behavior-preserving `GameWindow` decomposition slices and the automated
|
||||
|
|
|
|||
21
CLAUDE.md
21
CLAUDE.md
|
|
@ -211,8 +211,14 @@ operation maps; `RuntimeEntityRecord` is presentation-free and App records are
|
|||
graphical sidecars. Runtime tests pass 110/110, App tests pass 3,758/3 skips,
|
||||
the complete Release suite passes 8,441/5 skips, and the exact-binary seven-
|
||||
checkpoint lifecycle/reconnect gate passes with graceful exits, zero render-
|
||||
shadow mismatches, and zero pending deltas. J3.3 exact-key App projection-store
|
||||
cutover is next. J0's rollback is
|
||||
shadow mismatches, and zero pending deltas. J3.3 is complete at `420e5eea`
|
||||
plus exact-spatial correction `e937cc36`: `LiveEntityProjectionStore` and every
|
||||
materialized presentation/spatial owner now use exact `RuntimeEntityKey`; the
|
||||
temporary GUID-shaped compatibility view is deleted. App tests pass 3,761/3
|
||||
skips, the complete Release suite passes 8,444/5 skips, and the final exact-
|
||||
binary seven-checkpoint gate passes with two graceful exits, zero failures,
|
||||
zero render-shadow mismatches, and zero pending deltas. J3.4 canonical
|
||||
`ClientObjectTable` ownership is next. J0's rollback is
|
||||
`git revert b632672e5ccabfb44c551e08f1c411ab2669c44a`.
|
||||
J1's rollback is
|
||||
`git revert 854d9e9cd13092bd5aaa3cf025d73eeb4600e9f8`.
|
||||
|
|
@ -220,11 +226,15 @@ J2's rollback is
|
|||
`git revert 75930787741db40a83eab8663e4464dce8d687ba`.
|
||||
J3.2's rollback is
|
||||
`git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`.
|
||||
J3.3's rollback is, newest first,
|
||||
`git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702` then
|
||||
`git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045`.
|
||||
Slice H's retained UI/frame, bounded-light, and pooled/borrowed/direct network
|
||||
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`. The exact G4 visual rollback
|
||||
executes from `docs/plans/2026-07-25-modern-runtime-slice-j.md`; J3.4 starts at
|
||||
`docs/plans/2026-07-25-modern-runtime-slice-j3-object-table.md`. The exact G4 visual rollback
|
||||
is `git revert ef1d263337997bb030eadb7b8e71d73dc659907a`; do not revert G3 or
|
||||
the portal-warmup corrections. Evidence:
|
||||
`docs/research/2026-07-25-slice-h-closeout.md` and
|
||||
|
|
@ -237,7 +247,10 @@ the portal-warmup corrections. Evidence:
|
|||
`docs/research/2026-07-25-slice-i6-flat-production-cutover.md` and
|
||||
`docs/research/2026-07-25-slice-i7-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j1-runtime-contract-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j2-session-lifetime-closeout.md`.
|
||||
`docs/research/2026-07-25-slice-j2-session-lifetime-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j3-2-canonical-entity-directory-closeout.md` and
|
||||
`docs/research/2026-07-25-slice-j3-3-exact-projection-store.md`. Agent handoff:
|
||||
`docs/research/2026-07-25-slice-j3-3-complete-j3-4-handoff.md`.
|
||||
|
||||
**Structural prerequisite before new M4 subsystem work:** all eight
|
||||
behavior-preserving `GameWindow` decomposition slices and the automated
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ This page is the entry point for project documentation. It distinguishes
|
|||
current sources of truth from implementation history so an old plan or issue
|
||||
banner cannot silently override the current program state.
|
||||
|
||||
## Current snapshot — 2026-07-24
|
||||
## Current snapshot — 2026-07-25
|
||||
|
||||
- **Milestone state:** M3, “Cast a spell,” landed 2026-07-21. M4, “Live in the
|
||||
world,” is active.
|
||||
|
|
@ -14,38 +14,32 @@ banner cannot silently override the current program state.
|
|||
[`plans/2026-07-23-world-interaction-completion.md`](plans/2026-07-23-world-interaction-completion.md).
|
||||
The eight-slice `GameWindow` decomposition and its connected visual matrix
|
||||
are complete.
|
||||
- **Current active engineering program:** Slices A–E of
|
||||
- **Current active engineering program:** Slices A–I and J0–J3.3 of
|
||||
[`plans/2026-07-24-modern-runtime-architecture.md`](plans/2026-07-24-modern-runtime-architecture.md)
|
||||
are complete. Production world-mesh streaming consumes the validated
|
||||
prepared package, typed residency is bounded/accounted, and streaming now
|
||||
has typed admission plus immediate old-generation quiescence, metered
|
||||
retirement, and retained cursor-budgeted publication across render, physics,
|
||||
statics, building registries, collision/reflood, and EnvCells. The canonical
|
||||
reveal generation now owns an exact destination reservation across every
|
||||
typed budget dimension; incomplete destinations remain in portal space and
|
||||
receive retail's centered wait cue instead of forced early reveal. E6's
|
||||
deterministic/resource gates and capped, uncapped, and dense-Arwic
|
||||
physical-local routes pass. Slices F–L, including the F/G and J approval
|
||||
gates, were explicitly authorized 2026-07-24; Slice F is active.
|
||||
Their post-E evidence, ownership map, shadow-comparison design, cutover
|
||||
sequence, and acceptance matrix are implementation-ready in the
|
||||
[F/G render-scene plan](plans/2026-07-24-modern-runtime-slices-f-g-render-scene.md).
|
||||
See also the [Slice E streaming report](research/2026-07-24-slice-e-cost-budgeted-streaming-report.md).
|
||||
are complete. Production uses prepared world/collision packages, typed
|
||||
residence, retained render-scene/delta submission, bounded frame owners, and
|
||||
flat-authoritative collision without parsed-graph production residency.
|
||||
Runtime owns canonical session/transport and the sole live-entity
|
||||
GUID/incarnation/local-ID directory. App materialized projections,
|
||||
presentation worksets, and spatial visibility carry exact
|
||||
`RuntimeEntityKey`. J3.4 canonical object-table ownership is next in
|
||||
[`plans/2026-07-25-modern-runtime-slice-j3-object-table.md`](plans/2026-07-25-modern-runtime-slice-j3-object-table.md).
|
||||
- **Completed gates:** R6 locomotion/collision/projectile/teleport/radar and
|
||||
the final two-client portal-out/materialization observer comparison (`#218`).
|
||||
- **Separate visual verification:** the shared-alpha lifestone/particle result
|
||||
in `#225`; its connected resource-lifetime and performance routes pass.
|
||||
- **Carried behavior debt:** `#153` (far teleport onto an unstreamed edge),
|
||||
`#116` (two narrowed slide-response cases), and divergence rows TS-50/TS-51.
|
||||
- **Active engineering track:** render ECS/MP3 is executing from the
|
||||
implementation-ready F/G plan, followed by the approved Linux/headless
|
||||
automation slices. The pre-F/G runtime rollback anchor is `e7d9d6fa`.
|
||||
- **Active engineering track:** complete Slice J's coherent Runtime lifetime
|
||||
groups, then build the approved Linux/headless multi-session host in Slice K.
|
||||
J3.3's exact rollback is `git revert e937cc36` followed by
|
||||
`git revert 420e5eea`.
|
||||
- **Divergence audit:** 178 active rows — IA 17, AD 37, AP 85, TS 34,
|
||||
and UN 5 — plus the retained retired TS-37 history note.
|
||||
- **Latest automated baseline:** Release build succeeds; 8,164 tests pass and
|
||||
five are intentionally skipped. The capped, uncapped, and dense-Arwic
|
||||
physical prepared-asset routes all completed their portal/input/lifetime
|
||||
assertions and disconnected gracefully.
|
||||
- **Latest automated baseline:** Release build succeeds; 8,444 tests pass and
|
||||
five are intentionally skipped. The exact J3.3 connected lifecycle/reconnect
|
||||
gate completed two sessions and seven checkpoints with graceful zero-code
|
||||
exits, zero failures, zero render-shadow mismatches, and zero pending deltas.
|
||||
|
||||
## Sources of truth
|
||||
|
||||
|
|
|
|||
|
|
@ -209,7 +209,12 @@ src/
|
|||
ordered deltas, clock, generation + teardown
|
||||
Session/ -> J2 canonical session lifetime, ordered
|
||||
inbound routing + retryable teardown
|
||||
-> J3 identity, properties, and object-table extraction active
|
||||
Entities/
|
||||
RuntimeEntityDirectory.cs -> sole GUID/incarnation/local-ID authority
|
||||
RuntimeEntityRecord.cs -> presentation-free accepted entity state
|
||||
InboundPhysicsStateController.cs -> retail timestamp/snapshot authority
|
||||
ParentAttachmentState.cs -> generation-exact parent relations
|
||||
-> J3.1-J3.3 complete; J3.4 canonical object-table ownership next
|
||||
-> may reference Core, Core.Net, Content, and Plugin.Abstractions only
|
||||
-> must never reference App, UI, Silk.NET, OpenAL, Arch, or ImGui
|
||||
|
||||
|
|
@ -230,7 +235,8 @@ src/
|
|||
RemoteTeleportHook.cs -> ordered retail teleport teardown seam
|
||||
RemoteTeleportPlacement.cs -> collision-seated SetPosition transition commit
|
||||
World/
|
||||
LiveEntityRuntime.cs -> canonical identity/state/body/projectile/spatial ownership
|
||||
LiveEntityRuntime.cs -> exact-key App projection/lifecycle host
|
||||
LiveEntityProjectionStore.cs -> materialized sidecars by RuntimeEntityKey
|
||||
RetailInboundEventDispatcher.cs -> update-thread packet/frame FIFO barrier
|
||||
LiveEntityPresentationController.cs -> Hidden/NoDraw/effect/collision presentation
|
||||
LiveEntityTeardown.cs -> failure-isolated multi-owner lifecycle drain
|
||||
|
|
@ -447,26 +453,38 @@ Ownership by phase:
|
|||
|
||||
## GameEntity: The Unified Entity (target refactor)
|
||||
|
||||
`LiveEntityRuntime` is now the shipped bridge to this target. It owns one
|
||||
`LiveEntityRecord` per accepted server-object incarnation, ServerGuid-to-local-id
|
||||
translation, accepted snapshots/timestamp gates, the canonical `PhysicsBody`,
|
||||
animation/remote-motion/projectile components, parent-event state,
|
||||
effect-profile defaults, and exact logical
|
||||
teardown. Live `PhysicsDesc` effect fields replace Setup defaults on that same
|
||||
record; rebucketing never recreates them. `GpuWorldState`
|
||||
owns spatial buckets only: register/rebucket/unregister are separate operations,
|
||||
logical teardown removes the exact `WorldEntity` incarnation rather than every
|
||||
projection sharing its server GUID, and per-GUID/session mutation epochs prevent
|
||||
a callback from resurrecting an outer CreateObject after delete/reset. Per-GUID
|
||||
epoch tombstones remain until session clear, so delete-then-create cannot repeat
|
||||
an outer operation's epoch (the ABA problem). Resource registration is an atomic
|
||||
boundary, superseded cleanup failures surface at the runtime boundary, and
|
||||
visibility observers are failure-isolated without interrupting canonical commits.
|
||||
Landblock reloads reuse the same `WorldEntity` without replaying renderer or
|
||||
script creation. Its canonical materialized view remains stable across pending
|
||||
landblocks, while a separate visible-only view feeds radar, picking, status, and
|
||||
targeting. Raw server PhysicsState and the final state produced by retail's
|
||||
ordered Lighting/NoDraw/Hidden side effects are stored separately.
|
||||
The shipped bridge is now split at the Runtime/App boundary.
|
||||
`AcDream.Runtime.Entities.RuntimeEntityDirectory` owns the only current
|
||||
server-GUID/incarnation map, Runtime local-ID allocation/reverse lookup,
|
||||
accepted snapshots and timestamp gates, parent state, session/operation
|
||||
versions, and exact tombstones. `RuntimeEntityRecord` is presentation-free.
|
||||
|
||||
`LiveEntityRuntime` is the App projection/lifecycle host.
|
||||
`RegisterLiveEntity` first creates or refreshes canonical Runtime state without
|
||||
an App record. `MaterializeLiveEntity` claims the Runtime local ID and creates
|
||||
one graphical `LiveEntityRecord` sidecar in `LiveEntityProjectionStore`, keyed
|
||||
by exact `RuntimeEntityKey` (local ID plus `INSTANCE_TS`). The sidecar owns the
|
||||
App animation, remote-motion, projectile, hydration, and effect presentation
|
||||
state. `RuntimeEntityRecord` deliberately still carries the canonical
|
||||
`PhysicsBody`/physics-host facts until their coherent J5 move.
|
||||
Live `PhysicsDesc` effect fields replace Setup defaults on that same exact
|
||||
sidecar; rebucketing never recreates it.
|
||||
|
||||
`GpuWorldState` owns spatial buckets only and retains the exact projection key
|
||||
through loaded/pending movement, landblock retirement/reload, origin recenter,
|
||||
quiescence, and visibility transition delivery. Register, rebucket, withdraw,
|
||||
and unregister remain separate operations. Logical teardown removes the exact
|
||||
`WorldEntity` incarnation rather than every projection sharing its server GUID.
|
||||
Runtime per-GUID/session operation versions prevent a callback from
|
||||
resurrecting an outer CreateObject after delete/reset, and exact tombstones
|
||||
prevent ABA reuse. Resource registration is an atomic boundary, superseded
|
||||
cleanup failures surface at the runtime boundary, and visibility observers are
|
||||
failure-isolated without interrupting canonical commits. Landblock reloads
|
||||
reuse the same `WorldEntity` without replaying renderer or script creation.
|
||||
Focused exact-key materialized queries remain stable across pending landblocks;
|
||||
focused visible queries feed radar, picking, status, and targeting. Raw server
|
||||
PhysicsState and the final state produced by retail's ordered
|
||||
Lighting/NoDraw/Hidden side effects are stored separately.
|
||||
When retail's 25-second leave-visibility deadline expires, active ownership
|
||||
still ends completely. The ACE adapter retains only the accepted
|
||||
`EntitySpawn` in `DormantLiveEntityStore`, because ACE can keep that GUID in
|
||||
|
|
@ -494,10 +512,11 @@ does not depend on Content or a database implementation.
|
|||
|
||||
Runtime effect delivery is owned by App-layer `EntityEffectController`. It
|
||||
retains pre-materialization F754/F755 packets in one mixed FIFO per server GUID,
|
||||
resolves the canonical local ID through `LiveEntityRuntime` only after
|
||||
renderer/resources/profile are ready, and resolves typed/default/part-default
|
||||
hooks through the live owner's current `EntityEffectProfile`. It does not own a
|
||||
second GUID map. The same profile publishes Setup/static or network/live
|
||||
asks Runtime for the current canonical incarnation, then resolves the exact
|
||||
App projection only after renderer/resources/profile are ready. It resolves
|
||||
typed/default/part-default hooks through that projection's current
|
||||
`EntityEffectProfile`; it does not own a second GUID map. The same profile
|
||||
publishes Setup/static or network/live
|
||||
SoundTable ownership at readiness and on every same-generation PhysicsDesc
|
||||
replacement, including present-zero clearing. Core `PhysicsScriptRunner` mirrors retail's one
|
||||
serial FIFO per owner: duplicate plays append, owners progress independently,
|
||||
|
|
@ -920,7 +939,8 @@ Current movement/collision ownership:
|
|||
|
||||
- **B.3** is shipped MVP history: first collision resolver foundation.
|
||||
- **L.1/R6** own animation/motion parity and the complete retail object-frame
|
||||
update order over canonical `LiveEntityRuntime` records.
|
||||
update order over canonical Runtime records plus exact-key App projection
|
||||
sidecars.
|
||||
- **L.2** owns the remaining movement and collision conformance:
|
||||
`docs/plans/2026-04-29-movement-collision-conformance.md`.
|
||||
- **G.3 is shipped**: dungeon streaming, portal-space presentation, collision,
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ At the campaign baseline, `GameWindow` was the single object that:
|
|||
- Composes the shipped `LiveSessionController`/host/router boundary; it no
|
||||
longer owns a parallel session, command bus, subscription lifetime, connect,
|
||||
character-entry, reconnect, or graceful-close body.
|
||||
- Owns the adapters that hydrate canonical `LiveEntityRuntime` records into
|
||||
animation, collision, rendering, and DAT-backed appearance resources.
|
||||
- Owns the adapters that hydrate canonical Runtime entity records into
|
||||
exact-key App projection sidecars and their animation, collision, rendering,
|
||||
and DAT-backed appearance resources.
|
||||
- Composes the shipped `WorldSelectionQuery` and
|
||||
`SelectionInteractionController`; it no longer owns world-picking,
|
||||
selection intent, Use/PickUp, or auto-walk deferral algorithms.
|
||||
|
|
@ -298,7 +299,8 @@ What `GameWindow` loses:
|
|||
- Live connect/enter/logout and event-subscription bodies → completed inside
|
||||
`LiveSessionController` / `LiveSessionEventRouter`.
|
||||
- Live-object hydration adapters and final animated-part presentation → focused
|
||||
world/render owners over canonical `LiveEntityRuntime` records.
|
||||
world/render owners over exact-key App projection sidecars backed by
|
||||
canonical Runtime records.
|
||||
- `WorldPicker`, target queries, and selection-driven Use/PickUp/auto-walk →
|
||||
`WorldSelectionQuery` + `SelectionInteractionController`. Core
|
||||
`SelectionState` remains the injected session owner.
|
||||
|
|
@ -310,27 +312,33 @@ What `GameWindow` loses:
|
|||
|
||||
The eventual `GameEntity` aggregation (target state described in
|
||||
`acdream-architecture.md` §"GameEntity: The Unified Entity") happens
|
||||
**after** `LiveEntityRuntime` is the single owner of entity state.
|
||||
Until then, the parallel-dicts problem is bounded inside one class
|
||||
instead of spread across `GameWindow`.
|
||||
**after** `RuntimeEntityDirectory` is the single owner of canonical entity
|
||||
state. That boundary is now shipped. App's former parallel presentation
|
||||
dictionaries are bounded by one exact-key projection store rather than spread
|
||||
across `GameWindow`.
|
||||
|
||||
`LiveEntityRuntime` is now that single boundary. It composes
|
||||
`InboundPhysicsStateController` for the nine-channel retail timestamp gates and
|
||||
latest accepted immutable CreateObject snapshot, owns the canonical local ID
|
||||
and optional runtime components, and separates logical registration from
|
||||
spatial projection. It also retains raw PhysicsState separately from the final
|
||||
state produced by retail's ordered side effects;
|
||||
`LiveEntityPresentationController` projects those transitions into draw,
|
||||
collision, effect, child-NoDraw, and target visibility without becoming a
|
||||
second lifetime or GUID owner. `ParentAttachmentState` is runtime-owned and keys unresolved
|
||||
relations by child and parent generation. `Rendering/Vfx/EntityEffectController`
|
||||
owns the focused mixed F754/F755 pending FIFO, effect profiles, typed-table
|
||||
resolution, and a readiness set; canonical ServerGuid-to-local-ID translation
|
||||
always stays in `LiveEntityRuntime`. `EntityScriptActivator` uses the same
|
||||
canonical `WorldEntity.Id` as rendering and physics; the disjoint static ID
|
||||
allocators fail fast instead of wrapping into another landblock's namespace.
|
||||
All other non-Parent packet
|
||||
families still need the future general queue tracked by divergence AD-32.
|
||||
`RuntimeEntityDirectory` owns the only active server-GUID/incarnation map,
|
||||
Runtime local-ID allocation/reverse lookup, accepted immutable CreateObject
|
||||
snapshot and nine-channel timestamp gates, parent relations, operation
|
||||
versions, and exact teardown tombstones. `RuntimeEntityRecord` is
|
||||
presentation-free. `LiveEntityRuntime` is the App projection/lifecycle host:
|
||||
it creates a `LiveEntityRecord` sidecar only after Runtime local-ID claim and
|
||||
stores it in `LiveEntityProjectionStore` by exact `RuntimeEntityKey`.
|
||||
Hydration, animation, effects, lights, equipped children, render identity,
|
||||
movement observations, liveness, teardown, and spatial worksets borrow that
|
||||
same exact identity. `LiveEntityPresentationController` projects Runtime state
|
||||
transitions into draw, collision, effects, child-NoDraw, and target visibility
|
||||
without becoming a second canonical owner.
|
||||
|
||||
`Rendering/Vfx/EntityEffectController` owns the focused mixed F754/F755 pending
|
||||
FIFO, effect profiles, typed-table resolution, and readiness markers. A GUID
|
||||
is retained there only as pending wire-delivery metadata; current-incarnation
|
||||
resolution always asks `RuntimeEntityDirectory` and then the exact projection
|
||||
store. `EntityScriptActivator` uses the same Runtime-issued `WorldEntity.Id` as
|
||||
rendering and physics; disjoint static ID allocators fail fast instead of
|
||||
wrapping into another landblock's namespace. All other non-Parent pre-create
|
||||
packet families still need the future general queue tracked by divergence
|
||||
AD-32.
|
||||
|
||||
The per-frame object scheduler is extracted, but final animated-part
|
||||
presentation is not. `LiveEntityAnimationScheduler` snapshots canonical spatial
|
||||
|
|
@ -348,8 +356,8 @@ is deliberately separate: `RetailStaticAnimatingObjectScheduler` owns the
|
|||
Static owners with Setup DefaultAnimation. Both schedulers are wired by
|
||||
`GameWindow`, but neither owns GUID identity or logical resources.
|
||||
The typed animation view fills its reusable snapshot and render-ID set from
|
||||
`LiveEntityRuntime`'s concrete spatial dictionary, avoiding interface-enumerator
|
||||
boxing on both update and render hot paths.
|
||||
the exact-key projection workset, avoiding interface-enumerator boxing on both
|
||||
update and render hot paths.
|
||||
`RemoteInboundMotionDispatcher` similarly keeps UpdateMotion protocol behavior
|
||||
outside `GameWindow`: GameWindow resolves the canonical record/body and the
|
||||
optional PartArray sink, while one dispatcher owns retail's interrupt, style,
|
||||
|
|
@ -408,7 +416,8 @@ not `GameWindow`: it retains at most one pending request per materialized
|
|||
incarnation, scopes it by the live generation and accepted PositionSequence,
|
||||
and asks `RemoteTeleportPlacement` to collision-seat the current body when the
|
||||
destination projection is available. `GameWindow` supplies lifecycle and
|
||||
shadow-sync callbacks only; canonical identity remains in `LiveEntityRuntime`.
|
||||
shadow-sync callbacks only; canonical identity remains in
|
||||
`RuntimeEntityDirectory`, and App placement retains the exact projection key.
|
||||
Failed hydration restores the captured source and delegates an
|
||||
incarnation-scoped shadow restore to `LiveEntityPresentationController` while
|
||||
that source is unloaded, so Hidden/UnHide and teleport never become competing
|
||||
|
|
@ -459,16 +468,16 @@ useful ordering seam, but its ownership status is **partial**.
|
|||
| Area | Status | Current truth |
|
||||
|---|---|---|
|
||||
| Startup options | **Complete** | `RuntimeOptions` owns startup configuration (`eda936dc`). Remaining direct environment reads are legacy runtime diagnostics, not startup configuration. |
|
||||
| Network session | **Complete** | `LiveSessionController` remains the sole resolve/create/Connect/selection/EnterWorld/Tick/stop/reconnect/disposal and current-session owner. `LiveSessionHost` owns App reset/selection/entry ordering plus create→attach route factories; `LiveSessionLifecycleHost` guards exact borrowed-session attachment. `LiveSessionEventRouter` and `LiveSessionCommandRouter` own exact inbound/outbound lifetimes, with retryable per-edge teardown before reset or replacement. `GameWindow` retains the controller, focused host, and typed domain binding factories—no mirrored session or reset plan. |
|
||||
| Network session | **Complete Runtime ownership** | `RuntimeLiveSessionController` owns the sole `WorldSession` generation and resolve/create/Connect/selection/EnterWorld/Tick/stop/reconnect/disposal transaction. Runtime route owners preserve exact inbound/outbound ordering and retryable teardown. App supplies immutable options, graphical/domain callbacks, and one borrowed inertable UI command projection—no mirrored session or reset plan (`75930787`). |
|
||||
| World environment | **Complete ownership** | `WorldEnvironmentController` solely owns WorldTime, the loaded DAT sky, current day group, Weather, server synchronization, AdminEnvirons bridging, and debug time/weather cycles. `GameWindow` keeps ABI-compatible readonly aliases to the same clock/weather instances and composes one render source plus the two live-session callbacks. TS-54/TS-55 register the remaining centered UI sound and full fog/ambient/radar behavior gaps. |
|
||||
| Live identity/lifetime | **Complete App integration** | `LiveEntityRuntime` owns incarnation identity, accepted snapshots/timestamps, runtime components, and logical/spatial lifetime. `LiveEntityHydrationController`, `LiveEntityRuntimeTeardownController`, and `LiveEntityNetworkUpdateController` own DAT-backed hydration, retryable cleanup, and accepted Position/Vector/State/Movement presentation without a second GUID owner (`aa90c646`). |
|
||||
| Live identity/lifetime | **J3.3 complete** | `RuntimeEntityDirectory` owns the sole GUID/incarnation/local-ID identity, accepted snapshots/timestamps, parent state, operation versions, and tombstones. `LiveEntityProjectionStore` owns App graphical sidecars by exact `RuntimeEntityKey`; hydration, presentation components, `GpuWorldState` residence/visibility, and retryable teardown preserve that key without another GUID authority (`f46ddb5c`, `420e5eea`, `e937cc36`). |
|
||||
| Inbound/object-frame order | **Complete App orchestration** | `UpdateFrameOrchestrator` owns the complete typed host phase graph; `RetailInboundEventDispatcher`, `RetailLiveFrameCoordinator`, `LiveObjectFrameController`, `LiveSpatialPresentationReconciler`, streaming/input/teleport/player-mode/camera owners preserve the accepted order. `GameWindow.OnUpdate` is one profiler-scoped handoff (`e91f3102`). |
|
||||
| World reveal | **Complete** | `WorldRevealCoordinator` owns login/portal readiness, generation quiescence, and the exact streaming destination reservation. Login auto-entry and portal completion close only their active generation; stale completion cannot clear its replacement. Delayed portals retain the authored tunnel and centered retail wait notice rather than force-revealing incomplete content. Quiesced destination projections may become spatially resident for renderer preparation while all availability-gated gameplay consumers stay closed. |
|
||||
| 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. |
|
||||
| Landblock presentation | **Complete** | `LandblockBuildFactory` owns the captured-origin DAT transaction; concrete render/physics/DAT-static publishers and `LandblockPresentationPipeline` own typed-meter publication and exact retryable retirement. `StreamingController` owns stable destination/control/unload/Near/Far queues and destination reservation. CPU mesh-cache restaging requires an exact live owner. `StreamingOriginRecenterCoordinator` serializes old-window retirement with teleport/session origin lifetimes. `GameWindow` retains construction and one pipeline field only (`c79d0a49`, closeout `4a205a3e`; Slice E closeout `91e82c3c`). |
|
||||
| Render-frame orchestration | **Complete** | `RenderFrameOrchestrator` owns the GPU-flight, resource, world/PView/shared-alpha, private-presentation, diagnostics, screenshot, and recovery graph. `GameWindow.OnRender` takes one logical window-size snapshot and performs one immutable handoff (`9d7df1bf`). |
|
||||
| Unified `GameEntity` | **Deferred target** | `LiveEntityRuntime` already supplies the critical canonical owner. Full type aggregation is a separate high-risk migration and is not required to make `GameWindow` thin. |
|
||||
| Unified `GameEntity` | **Slice J active** | Canonical identity is now in Runtime and exact graphical sidecars are in App. J3.4 next moves `ClientObjectTable`; later J4–J7 move coherent gameplay lifetime groups before one Runtime composition root. |
|
||||
|
||||
### 4.3 Revised extraction sequence
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ accepted-divergence entries (#96, #49, #50).
|
|||
| AD-28 | Chat transcript (`UiText`) and input (`UiChatInput`) are two separate widget classes placed inside their dat-authored container panels; retail's `ChatInterface` uses a single mode-flagged `UIElement_Text` (Type-12) that switches between read and edit mode | `src/AcDream.App/UI/Layout/ChatWindowController.cs:135` (transcript) + `:150` (input) | `UIElement_Text` is inside keystone.dll with no PDB/decomp; a two-widget split is functionally equivalent (read-only scroll, editable input) and is the structural adaptation required by our UiElement architecture | A future consumer expecting a single widget for both read/write (e.g. a plugin calling the chat API and getting one widget back) must be written to the two-widget contract | `UIElement_Text` (Type-12) @ keystone.dll; `gmMainChatUI::PostInit` @0x4ce130 |
|
||||
| AD-29 | `ClientObjectTable` fires global `ObjectAdded`/`ObjectUpdated`/`ObjectRemoved` events; consumers filter by guid on their end. Retail dispatches per-object via `NoticeRegistrar` observer dispatch — each UI cell observes only its specific object guid | `src/AcDream.Core/Items/ClientObjectTable.cs:48` (events); `src/AcDream.App/UI/Layout/ToolbarController.cs:115` (guid filter) | `NoticeRegistrar` is inside keystone.dll with no PDB/decomp; global broadcast + consumer-side filter is functionally equivalent for the current panel count and object volumes seen in practice | At high object counts (>1 000 objects), every `ObjectUpdated` wakes every subscribed consumer — O(n·m) notification cost instead of retail's O(1) per-observer dispatch; a consumer that forgets the guid filter processes all objects (a latent correctness bug) | `NoticeRegistrar` (keystone.dll, no PDB); retail per-object observer registration in `CObjectMaint` |
|
||||
| AD-30 | Cell-march preserves seed landblock id when `TryGetTerrainOrigin` returns false for an outdoor seed (#145 D, 2026-06-22): `BuildCellSetAndPickContaining` returns `currentCellId` verbatim rather than marching via `blockOrigin=(0,0,0)`; retail never encounters this state (cells stored block-local, no streaming-gap concept) | `src/AcDream.Core/Physics/CellTransit.cs:765` | Equivalence argument: "preserve-verbatim when unregistered" is the same contract as `PhysicsEngine.Resolve`'s NO-LANDBLOCK branch; the player's cell stays the last known-correct cell until the landblock's terrain registers — no march, no lbX=0 wire | A body whose seed landblock is genuinely absent for >1 physics tick holds its last-known cell rather than discovering the true containing cell; transient only — corrects the instant terrain registers; an indoor seed is explicitly excluded from the guard (outdoor low < 0x100 gate) | `CObjCell::find_cell_list` + block-local storage (retail has no streaming gap); `TryGetTerrainOrigin` pc path |
|
||||
| AD-32 | Movement, Position, State, Vector, Pickup, Delete, and ObjDesc packets for a FUTURE object incarnation are dropped until its CreateObject arrives; retail queues each blob for the not-yet-created object (`SmartBox::QueueBlobForObject`, dispatch return 4) and replays it after construction. F754/F755 and ParentEvent are no longer part of this divergence: `EntityEffectController` preserves one mixed effect FIFO per server GUID until the canonical local owner is ready, while runtime-owned `ParentAttachmentState` retains parent relations by generation. Older-incarnation state packets drop in both clients. | `src/AcDream.Core/Physics/PhysicsTimestampGate.cs` (`TryAcceptInstance`); `src/AcDream.App/World/InboundPhysicsStateController.cs`; `src/AcDream.App/World/LiveEntityRuntime.cs`; effect exception `src/AcDream.App/Rendering/Vfx/EntityEffectController.cs`; Parent exception `src/AcDream.App/World/ParentAttachmentState.cs` | acdream has no general per-object mixed queue for non-effect state packets yet. Dropping those state families is generation-safe: a future packet cannot mutate the old body or advance its stamps, and the newer CreateObject wholesale-seeds all nine channels. The canonical runtime remains the seam for widening the queue later. | The first queued non-effect state can be absent until a later authoritative update; effect and Parent packets retain retail order and ownership | `SmartBox::HandleSetState` 0x004533E0; `HandleVectorUpdate` 0x00453480; `HandleParentEvent` 0x004535D0; `HandlePickupEvent` 0x00453530; `HandleDeleteObject` 0x00451EA0; `HandleObjDescEvent` 0x00453340; `UnpackPositionEvent` 0x004542C0; F754/F755 dispatch and pending replay pc:357214-357239 |
|
||||
| AD-32 | Movement, Position, State, Vector, Pickup, Delete, and ObjDesc packets for a FUTURE object incarnation are dropped until its CreateObject arrives; retail queues each blob for the not-yet-created object (`SmartBox::QueueBlobForObject`, dispatch return 4) and replays it after construction. F754/F755 and ParentEvent are no longer part of this divergence: `EntityEffectController` preserves one mixed effect FIFO per server GUID until the canonical local owner is ready, while runtime-owned `ParentAttachmentState` retains parent relations by generation. Older-incarnation state packets drop in both clients. | `src/AcDream.Core/Physics/PhysicsTimestampGate.cs` (`TryAcceptInstance`); `src/AcDream.Runtime/Entities/InboundPhysicsStateController.cs`; `src/AcDream.App/World/LiveEntityRuntime.cs`; effect exception `src/AcDream.App/Rendering/Vfx/EntityEffectController.cs`; Parent exception `src/AcDream.Runtime/Entities/ParentAttachmentState.cs` | acdream has no general per-object mixed queue for non-effect state packets yet. Dropping those state families is generation-safe: a future packet cannot mutate the old body or advance its stamps, and the newer CreateObject wholesale-seeds all nine channels. The canonical runtime remains the seam for widening the queue later. | The first queued non-effect state can be absent until a later authoritative update; effect and Parent packets retain retail order and ownership | `SmartBox::HandleSetState` 0x004533E0; `HandleVectorUpdate` 0x00453480; `HandleParentEvent` 0x004535D0; `HandlePickupEvent` 0x00453530; `HandleDeleteObject` 0x00451EA0; `HandleObjDescEvent` 0x00453340; `UnpackPositionEvent` 0x004542C0; F754/F755 dispatch and pending replay pc:357214-357239 |
|
||||
| AD-33 | `CSequence.frame_number` at C# `double` (64-bit); retail is x87 `long double` (80-bit extended) — every frame-boundary comparison ran at extended precision on retail (Phase R1, 2026-07-02) | `src/AcDream.Core/Physics/Motion/CSequence.cs` (`FrameNumber`) | `double` is the widest C# float type; the R1 port removes ACE-style boundary epsilons so comparisons are exact-int against bare boundaries, minimizing ULP sensitivity (ACE's `float` is far worse) | A frame landing within 1 double-ULP of an integer boundary could classify differently than retail's 80-bit compare — sub-frame timing skew at pathological framerate×dt combinations | `acclient.h:30747` (`long double frame_number`) |
|
||||
| AD-34 | Retail's intrusive `DLListBase`/`DLListData` lists are managed `LinkedList<T>`s; node identity via `LinkedListNode<>` references (Phase R1 anim list, 2026-07-02; extended R2-Q3 to `MotionTableManager.pending_animations`; extended R4-V2 to `MoveToManager.pending_actions` — whose node type, retail `MoveToManager::MovementNode`, is RENAMED `MoveToNode` to avoid colliding with R2's `Motion/MotionNode.cs` pending_motions node) | `src/AcDream.Core/Physics/Motion/CSequence.cs` (`_animList`); `src/AcDream.Core/Physics/Motion/MotionTableManager.cs` (`_pendingAnimations`); `src/AcDream.Core/Physics/Motion/MoveToManager.cs` (`_pendingActions`) + `MoveToNode.cs` | Same topology + cursor semantics (curr_anim/first_cyclic/tail-anchored scans are node references); unlink/delete becomes `Remove(node)`; conformance tests pin the surgery state tables | Any retail behavior depending on the −4 pointer adjustment or node memory reuse (none observed in the decomp) would diverge; a reader grepping for retail's `MovementNode` name must find it via this row | `acclient.h` DLListBase; `r1-csequence-decomp.md` §0; `r2-motiontable-decomp.md` §11; `r4-moveto-decomp.md` node factories §4a |
|
||||
| AD-35 | `MotionTableManager.PerformMovement`'s unhandled-type default case returns the named sentinel `0xFFFFFFFF` (`MotionTableManagerError.NotHandled`); retail's compiled code leaks the `CSequence*` pointer reinterpreted as the return code (BN-confirmed artifact, dead/unreachable — callers gate on type first) (R2-Q3, 2026-07-02) | `src/AcDream.Core/Physics/Motion/MotionTableManager.cs` (`PerformMovement` default case) | No retail caller consults the return value for unhandled types (RawCommand/StopRawCommand/MoveTo\*/TurnTo\* route elsewhere); returning a stable non-zero sentinel preserves the only observable contract (non-zero = not success) without fabricating a pointer-shaped number | If a future port wires a caller that passes unhandled types AND branches on the exact return value, it would see `0xFFFFFFFF` where retail saw an arbitrary pointer — flag at that port | `PerformMovement` 0x0051c0b0 (`r2-motiontable-decomp.md` §11 default-case note) |
|
||||
|
|
|
|||
|
|
@ -1687,8 +1687,14 @@ port in any phase — no separate listing here.
|
|||
> tombstone, local-ID/reverse, accepted-wire, parent, and operation-version
|
||||
> maps. Its 110 Runtime tests, 3,758 App tests / 3 skips, 8,441-test / 5-skip
|
||||
> complete Release suite, and exact-binary seven-checkpoint connected gate pass
|
||||
> with graceful exits and zero render-shadow mismatch. J3.3 exact-key App
|
||||
> projection storage is next.
|
||||
> with graceful exits and zero render-shadow mismatch. J3.3 is complete at
|
||||
> `420e5eea` plus `e937cc36`: App's materialized sidecars, presentation
|
||||
> worksets, spatial residence, quiescence, and visibility edges now carry the
|
||||
> exact `RuntimeEntityKey`; the compatibility GUID view is deleted. Its 3,761
|
||||
> App tests / 3 skips, 8,444-test / 5-skip complete Release suite, and exact-
|
||||
> binary seven-checkpoint gate pass with two graceful exits, zero failures,
|
||||
> zero render-shadow mismatches, and zero pending deltas. J3.4 canonical object-
|
||||
> table ownership is next.
|
||||
> The historical exact cutover
|
||||
> rollback remains
|
||||
> `git revert ef1d263337997bb030eadb7b8e71d73dc659907a`. Slice H is complete:
|
||||
|
|
|
|||
|
|
@ -162,8 +162,14 @@ residency is `0/0/0` at every stable checkpoint and teardown converges. Slice I
|
|||
local-ID/reverse, accepted-wire, parent, and operation-version maps in
|
||||
Runtime. Its 110 Runtime tests, 3,758 App tests / 3 skips, 8,441 full Release
|
||||
tests / 5 skips, and exact-binary seven-checkpoint connected gate pass with
|
||||
graceful exits and zero render-shadow mismatch. J3.3 exact-key App projection
|
||||
storage is next under
|
||||
graceful exits and zero render-shadow mismatch. J3.3 is complete at
|
||||
`420e5eea` plus exact-spatial correction `e937cc36`:
|
||||
`LiveEntityProjectionStore` and every materialized presentation/spatial
|
||||
workset now use exact `RuntimeEntityKey`; the GUID-shaped compatibility view
|
||||
is deleted. Its 3,761 App tests / 3 skips, 8,444 full Release tests / 5 skips,
|
||||
and exact-binary seven-checkpoint connected gate pass with two graceful
|
||||
exits, zero failures, zero render-shadow mismatches, and zero pending deltas.
|
||||
J3.4 canonical `ClientObjectTable` ownership is next under
|
||||
[`2026-07-25-modern-runtime-slice-j.md`](2026-07-25-modern-runtime-slice-j.md).
|
||||
Slice-I closeout evidence is
|
||||
[`../research/2026-07-25-slice-i7-closeout.md`](../research/2026-07-25-slice-i7-closeout.md).
|
||||
|
|
@ -171,6 +177,8 @@ Slice-J2 closeout evidence is
|
|||
[`../research/2026-07-25-slice-j2-session-lifetime-closeout.md`](../research/2026-07-25-slice-j2-session-lifetime-closeout.md).
|
||||
Slice-J3.2 closeout evidence is
|
||||
[`../research/2026-07-25-slice-j3-2-canonical-entity-directory-closeout.md`](../research/2026-07-25-slice-j3-2-canonical-entity-directory-closeout.md).
|
||||
Slice-J3.3 closeout evidence is
|
||||
[`../research/2026-07-25-slice-j3-3-exact-projection-store.md`](../research/2026-07-25-slice-j3-3-exact-projection-store.md).
|
||||
The historical exact G4 visual rollback remains
|
||||
`git revert ef1d263337997bb030eadb7b8e71d73dc659907a`.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
**Date:** 2026-07-24
|
||||
|
||||
**Status:** Slices A–I and J0–J2 are complete. Flat-authoritative collision, zero-
|
||||
**Status:** Slices A–I and J0–J3.3 are complete. Flat-authoritative collision, zero-
|
||||
allocation resolve scratch, parsed-graph removal, connected correctness/
|
||||
lifetime acceptance, and Slice-I closeout landed 2026-07-25. Slices F–L were
|
||||
explicitly approved 2026-07-24. Slice J0–J1 established the enforced Runtime
|
||||
boundary and borrowed contract seam; J2 moved canonical session/transport
|
||||
lifetime and ordered inbound routing. J3 is the active execution point.
|
||||
lifetime and ordered inbound routing; J3.1–J3.3 moved canonical entity identity
|
||||
to Runtime and exact graphical projection identity to App. J3.4 is the active
|
||||
execution point.
|
||||
|
||||
**Scope:** Reconcile and sequence the existing Modern Pipeline (`MP`) and
|
||||
Linux/headless (`LH`) tracks using the 2026-07-24 connected performance audit.
|
||||
|
|
@ -19,8 +21,9 @@ world detail, or retail behavior.
|
|||
This plan refines rather than replaces
|
||||
[`docs/superpowers/specs/2026-07-05-modern-pipeline-design.md`](../superpowers/specs/2026-07-05-modern-pipeline-design.md).
|
||||
It preserves the shipped N.5 bindless/MDI renderer, the completed `GameWindow`
|
||||
decomposition, canonical `LiveEntityRuntime` ownership, the retail PView/cell
|
||||
visibility ports, and all behavior already accepted by the user.
|
||||
decomposition, canonical Runtime entity ownership with exact-key App
|
||||
projections, the retail PView/cell visibility ports, and all behavior already
|
||||
accepted by the user.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -1246,9 +1249,12 @@ proved exact flat traversal, strict dual publication, and flat-authoritative
|
|||
gameplay before removing every production parsed collision graph. Slice I7
|
||||
passes 8,413 Release tests / 5 skips plus both exact-binary connected routes;
|
||||
every stable checkpoint reports zero retained parsed collision graphs. J1 is
|
||||
complete with borrowed contracts, and J2 now owns canonical session/transport
|
||||
lifetime plus ordered inbound routing in Runtime. J3 is the current execution
|
||||
point.
|
||||
complete with borrowed contracts, and J2 owns canonical session/transport
|
||||
lifetime plus ordered inbound routing in Runtime. J3.1–J3.3 are complete:
|
||||
Runtime owns the only entity GUID/incarnation/local-ID directory, and App's
|
||||
materialized sidecars plus spatial/presentation worksets carry exact
|
||||
`RuntimeEntityKey`. J3.4 canonical `ClientObjectTable` ownership is the current
|
||||
execution point.
|
||||
Evidence:
|
||||
[`../research/2026-07-25-slice-g5-production-profile.md`](../research/2026-07-25-slice-g5-production-profile.md)
|
||||
and
|
||||
|
|
@ -1262,6 +1268,8 @@ and
|
|||
and
|
||||
[`../research/2026-07-25-slice-j2-session-lifetime-closeout.md`](../research/2026-07-25-slice-j2-session-lifetime-closeout.md)
|
||||
and
|
||||
[`../research/2026-07-25-slice-j3-3-exact-projection-store.md`](../research/2026-07-25-slice-j3-3-exact-projection-store.md)
|
||||
and
|
||||
[`2026-07-25-modern-runtime-slice-j.md`](2026-07-25-modern-runtime-slice-j.md).
|
||||
|
||||
The intended order is therefore:
|
||||
|
|
@ -1276,7 +1284,7 @@ honest metrics + committed baselines (A — exit criteria block C)
|
|||
-> delta GPU submission (G)
|
||||
-> residual frame cleanup (H-a, H-b, H-c)
|
||||
-> flat collision assets (I — COMPLETE)
|
||||
-> presentation-independent runtime (J — CURRENT at J3)
|
||||
-> presentation-independent runtime (J — CURRENT at J3.4)
|
||||
-> Linux/headless/multi-session (K)
|
||||
-> evidence-gated GPU jobs (L)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Modern runtime Slice J — presentation-independent runtime
|
||||
|
||||
**Status:** J0–J2 COMPLETE — boundary, borrowed contracts, and canonical
|
||||
session/transport lifetime; J3 is ACTIVE
|
||||
**Status:** J0–J2 COMPLETE; J3.1–J3.3 COMPLETE; J3.4 canonical object-table
|
||||
ownership is next
|
||||
**Parent:** `2026-07-24-modern-runtime-architecture.md`, Slice J
|
||||
**Authorization:** the user approved Slices F–L, including the otherwise-frozen
|
||||
Slice J gameplay-owner moves, on 2026-07-24
|
||||
|
|
@ -15,8 +15,9 @@ deletes the replaced App production path before the next group moves.
|
|||
|
||||
## 1. Fixed invariants
|
||||
|
||||
1. `LiveEntityRuntime` remains the sole server-GUID/incarnation owner. There is
|
||||
never a second GUID map or synchronized gameplay world.
|
||||
1. `RuntimeEntityDirectory` is the sole server-GUID/incarnation/local-ID owner.
|
||||
`LiveEntityRuntime` is the exact-key App projection host. There is never a
|
||||
second GUID map or synchronized gameplay world.
|
||||
2. Runtime types do not reference `AcDream.App`, either UI assembly, Silk.NET,
|
||||
OpenAL, Arch, ImGui, a native window, or an OpenGL resource.
|
||||
3. App projection state is keyed by runtime-issued local entity identity plus
|
||||
|
|
@ -182,6 +183,15 @@ git revert 75930787741db40a83eab8663e4464dce8d687ba
|
|||
**Detailed execution plan:**
|
||||
[`2026-07-25-modern-runtime-slice-j3.md`](2026-07-25-modern-runtime-slice-j3.md).
|
||||
|
||||
**Current checkpoint:** J3.1–J3.3 are complete. Runtime owns accepted entity
|
||||
wire state and the only canonical identity/incarnation/local-ID directory.
|
||||
App's `LiveEntityProjectionStore` and every materialized presentation/spatial
|
||||
workset are keyed by exact `RuntimeEntityKey`; the temporary GUID-shaped
|
||||
compatibility view is deleted. The final J3.3 binary `e937cc36` passes 8,444
|
||||
Release tests / 5 skips and the exact seven-checkpoint connected gate at
|
||||
`logs/connected-world-gate-20260725-221008/report.json`. J3.4 now moves the
|
||||
existing `ClientObjectTable` under the Runtime entity/object lifetime root.
|
||||
|
||||
- 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,
|
||||
|
|
|
|||
237
docs/plans/2026-07-25-modern-runtime-slice-j3-object-table.md
Normal file
237
docs/plans/2026-07-25-modern-runtime-slice-j3-object-table.md
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
# Modern runtime J3.4 — canonical object-table ownership
|
||||
|
||||
**Status:** READY
|
||||
**Parent:** `2026-07-25-modern-runtime-slice-j3.md`
|
||||
**Required production base:** `e937cc36df39cf6ea1eaba2f9c0243d1929da702`
|
||||
**Prior closeout:** `docs/research/2026-07-25-slice-j3-3-exact-projection-store.md`
|
||||
|
||||
## Objective
|
||||
|
||||
Make one presentation-independent Runtime lifetime-group root own both:
|
||||
|
||||
- the canonical `RuntimeEntityDirectory`; and
|
||||
- the existing canonical `ClientObjectTable`.
|
||||
|
||||
App, retained UI, interaction controllers, and the graphical projection host
|
||||
must borrow those exact same instances. There must be no copied inventory
|
||||
model, second object table, asynchronous delivery seam, extra input frame, or
|
||||
change to retail event order.
|
||||
|
||||
This slice moves ownership and transaction boundaries, not the
|
||||
`ClientObjectTable` implementation out of `AcDream.Core`. The type is already
|
||||
presentation-free and has extensive Core conformance coverage.
|
||||
|
||||
## Current ownership inventory
|
||||
|
||||
At the required base:
|
||||
|
||||
- `LiveEntityRuntime` constructs its own `RuntimeEntityDirectory`.
|
||||
- `GameWindow` constructs a public readonly `ClientObjectTable Objects`.
|
||||
- App composition records pass that table to retained UI, selection,
|
||||
interaction, magic, combat, paperdoll, appraisal, cooldown, and diagnostics.
|
||||
- Runtime `LiveSessionEventRouter` already applies property, stack, inventory,
|
||||
player-description, container, and appraisal traffic directly to the
|
||||
borrowed table through `ObjectTableWiring`.
|
||||
- App `LiveEntityHydrationController` applies CreateObject to the table only
|
||||
after canonical Runtime create acceptance and revalidates
|
||||
`CreateIntegrationVersion`.
|
||||
- App `LiveEntityDeletionController` applies logical DeleteObject before the
|
||||
exact App projection teardown suffix.
|
||||
- App `LiveSessionResetManifest` clears the object table before clearing live
|
||||
graphical projections.
|
||||
- Optimistic moves, confirmations, rollback, stack updates, container
|
||||
replacement, and every table event are synchronous on the current thread.
|
||||
|
||||
Retail behavior and citations already live in:
|
||||
|
||||
- `src/AcDream.Core/Items/ClientObjectTable.cs`;
|
||||
- `src/AcDream.Core.Net/ObjectTableWiring.cs`;
|
||||
- `docs/research/2026-07-13-retail-give-item-pseudocode.md`;
|
||||
- the named-retail symbols cited beside `ACCObjectMaint::CreateObject`,
|
||||
`ACCObjectMaint::DeleteObject`, and
|
||||
`ACCWeenieObject::ServerSaysMoveItem`.
|
||||
|
||||
J3.4 does not reinterpret those algorithms.
|
||||
|
||||
## Fixed target
|
||||
|
||||
Add a presentation-free Runtime owner equivalent to:
|
||||
|
||||
```csharp
|
||||
public sealed class RuntimeEntityObjectLifetime
|
||||
{
|
||||
public RuntimeEntityDirectory Entities { get; }
|
||||
public ClientObjectTable Objects { get; }
|
||||
}
|
||||
```
|
||||
|
||||
The concrete name may change, but these invariants do not:
|
||||
|
||||
1. The owner constructs each canonical instance exactly once.
|
||||
2. `LiveEntityRuntime` receives `Entities`; it may not construct a directory.
|
||||
3. Runtime session routing receives `Objects` from the same owner.
|
||||
4. App projection, UI, and interaction composition receive borrowed references
|
||||
only.
|
||||
5. Accepted CreateObject/DeleteObject object-table mutation is implemented by
|
||||
the Runtime group and revalidates the exact canonical record/version.
|
||||
6. Reset preserves the current order: object-table clear before graphical live
|
||||
projection teardown, with completed stages never replayed.
|
||||
7. Studio/sample-data object tables remain independent fixture owners and are
|
||||
not part of the live session.
|
||||
|
||||
## Execution
|
||||
|
||||
### 1. Pin parity traces and construction identity
|
||||
|
||||
- Capture normalized traces for:
|
||||
- initial player description and equipment manifest;
|
||||
- item CreateObject add/update;
|
||||
- same-incarnation refresh;
|
||||
- new-generation replacement;
|
||||
- property Int/Int64/String/Float/DataID updates;
|
||||
- stack-size update;
|
||||
- optimistic move, authoritative confirm, and rejection rollback;
|
||||
- wield/unwield;
|
||||
- ViewContents replacement and close;
|
||||
- logical delete, GUID reuse, and session clear.
|
||||
- Add a construction-identity test proving the router, App projection host,
|
||||
retained UI source, and interaction source all receive one table instance.
|
||||
- Preserve current synchronous event order in the golden trace.
|
||||
|
||||
### 2. Introduce the Runtime lifetime-group root
|
||||
|
||||
- Add the owner under `src/AcDream.Runtime/Entities/`.
|
||||
- Construct `RuntimeEntityDirectory` and `ClientObjectTable` there.
|
||||
- Expose borrowed properties only; no collection mirror or event repeater.
|
||||
- Add Runtime-only tests that instantiate it without loading App, UI, Silk,
|
||||
OpenAL, Arch, or ImGui assemblies.
|
||||
- Keep mutable state instance-scoped so two roots can hold conflicting GUIDs
|
||||
and inventory contents without interference.
|
||||
|
||||
### 3. Inject canonical identity into the App projection host
|
||||
|
||||
- Change `LiveEntityRuntime` to require the exact
|
||||
`RuntimeEntityDirectory` instance from the group.
|
||||
- Remove its internal `new RuntimeEntityDirectory(...)`.
|
||||
- Preserve the existing local-ID start override for focused wraparound tests
|
||||
through an explicit fixture/group construction seam, not a second production
|
||||
allocator.
|
||||
- Assert that App cannot replace the directory after projection construction.
|
||||
- Preserve J3.3 `RuntimeEntityKey` identity and teardown behavior unchanged.
|
||||
|
||||
### 4. Replace the `GameWindow` object-table owner
|
||||
|
||||
- Construct the Runtime group before retained UI and live presentation
|
||||
composition.
|
||||
- Delete `GameWindow`'s public readonly `ClientObjectTable Objects` field.
|
||||
- Pass `runtimeGroup.Objects` through the existing typed composition records.
|
||||
- Keep App controllers as direct synchronous borrowers; do not wrap every read
|
||||
in a copied DTO or event bus.
|
||||
- Add source guards rejecting a production App `new ClientObjectTable()` and a
|
||||
second Runtime entity directory. Exempt Studio/sample-data and tests.
|
||||
|
||||
### 5. Move accepted object mutation to the Runtime group
|
||||
|
||||
- Move the generation/version-sensitive
|
||||
`ObjectTableWiring.ApplyEntitySpawn/Delete` transaction boundary out of App.
|
||||
- Runtime must apply a CreateObject only after the canonical directory accepts
|
||||
that exact incarnation and while its create-integration version remains
|
||||
current.
|
||||
- New-generation replacement must remove the old object generation and publish
|
||||
the same add/update/removal sequence as today.
|
||||
- Logical delete must mutate the table before App graphical teardown, exactly
|
||||
as the current `beforeTeardown` callback does.
|
||||
- Pickup/parent leave-world must not delete the object-table entry.
|
||||
- Dormant liveness pruning must retain the existing object-table semantics;
|
||||
only an authoritative logical delete removes the retained object generation.
|
||||
- Keep all callbacks synchronous and revalidate after every callback that can
|
||||
replace, delete, or clear the incarnation.
|
||||
|
||||
### 6. Route session and reset ownership
|
||||
|
||||
- Bind J2 `LiveSessionEventRouter` directly from the Runtime group rather than
|
||||
an App-owned table field.
|
||||
- Keep the current pre-Connect subscription order.
|
||||
- Keep local-player property projection to `LocalPlayerState` and the same
|
||||
table instance until J4 moves the coherent player/gameplay state group.
|
||||
- Replace the App reset field with a Runtime-group object-table reset
|
||||
acknowledgement at the same manifest position.
|
||||
- Failure injection must retain the unfinished reset suffix and never clear a
|
||||
replacement session's table.
|
||||
|
||||
### 7. Delete superseded ownership seams
|
||||
|
||||
- Remove public ownership comments and aliases that describe the table as a
|
||||
GameWindow state owner.
|
||||
- Remove any App construction helper whose only purpose was to allocate the
|
||||
live table.
|
||||
- Keep direct table parameters on UI/controllers for now: they are explicit
|
||||
borrowed dependencies and J4 will move higher-level inventory transactions.
|
||||
- Update architecture, plans, durable memory, and exact rollback in the same
|
||||
closeout commit.
|
||||
|
||||
## Adversarial cases
|
||||
|
||||
- Reentrant `ObjectAdded` deletes or replaces the same GUID.
|
||||
- Reentrant `ObjectMoved` starts another optimistic move.
|
||||
- Delete arrives during CreateObject callbacks.
|
||||
- Same GUID with a new `INSTANCE_TS` while old projection teardown is pending.
|
||||
- Unknown-object authoritative move publishes the same nullable item event.
|
||||
- Equal, stale, and wrapped object/physics generations.
|
||||
- Multiple in-flight optimistic moves followed by confirm/reject in either
|
||||
order.
|
||||
- Container replacement while item events mutate the same container.
|
||||
- Reset during object-table event dispatch.
|
||||
- Failed graphical teardown after canonical object removal.
|
||||
- Two Runtime roots use identical GUIDs with different contents.
|
||||
- No-window root executes the full entity/object lifecycle without loading App
|
||||
or backend assemblies.
|
||||
|
||||
## Mandatory gates
|
||||
|
||||
Run in this order:
|
||||
|
||||
1. Runtime entity/object lifetime tests.
|
||||
2. Core `ClientObjectTable*` and `ObjectTableWiring*` tests.
|
||||
3. Focused App hydration, deletion, reset, inventory, interaction, paperdoll,
|
||||
magic, cooldown, and runtime-adapter tests.
|
||||
4. All Runtime tests.
|
||||
5. All App tests.
|
||||
6. `dotnet build AcDream.slnx -c Release`.
|
||||
7. `dotnet test AcDream.slnx -c Release --no-build`.
|
||||
8. Exact-binary connected lifecycle/reconnect gate.
|
||||
9. At every connected checkpoint: zero render-shadow mismatches, zero pending
|
||||
deltas, graceful process exit, and object/projection teardown convergence.
|
||||
|
||||
A user visual pause is not required unless an automated or connected gate
|
||||
exposes an inventory, paperdoll, selection, or interaction symptom.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- One Runtime lifetime-group root owns the exact entity directory and object
|
||||
table.
|
||||
- `GameWindow` owns neither instance directly.
|
||||
- App and Runtime routing borrow the same object table.
|
||||
- Runtime remains the only GUID/incarnation/local-ID authority.
|
||||
- Create/delete/property/container ordering matches the pinned trace.
|
||||
- Optimistic move/rollback and press-time UI remain synchronous.
|
||||
- No App/UI/backend dependency enters Runtime.
|
||||
- No mirror, queue, frame delay, or steady-state traversal allocation is added.
|
||||
- Runtime-only entity/object lifecycle and multiple-instance isolation pass.
|
||||
- Complete Release and exact connected gates pass on one committed binary.
|
||||
|
||||
## Rollback
|
||||
|
||||
Record the exact J3.4 production commit here before its connected gate. J3.3
|
||||
remains independently reversible; do not use its rollback for a J3.4 failure.
|
||||
|
||||
## Final J3 goal
|
||||
|
||||
J3.4 is not the end of J3. J3.5 must publish one ordered per-session
|
||||
entity/object delta stream and make graphical/direct hosts consume the same
|
||||
committed facts without a second queue. J3.6 then failure-injects and proves
|
||||
the complete no-window entity/object lifecycle, zero leaked records,
|
||||
tombstones, projections, container entries, queued deltas, or subscriptions,
|
||||
plus Release and connected parity. That J3.6 proof is the clean boundary before
|
||||
J4 moves inventory transactions, vitals, enchantments, magic, and other
|
||||
gameplay-state services.
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
# Modern runtime J3.3 — exact-key App projection store
|
||||
|
||||
**Status:** READY AFTER J3.2 CONNECTED GATE
|
||||
**Status:** COMPLETE 2026-07-25
|
||||
**Parent:** `2026-07-25-modern-runtime-slice-j3.md`
|
||||
**Required base:** `f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`
|
||||
**Production commits:** `420e5eea70fd2c29cf9c8614e6298a1f84d64045`,
|
||||
then exact-spatial correction
|
||||
`e937cc36df39cf6ea1eaba2f9c0243d1929da702`
|
||||
**Closeout:** `docs/research/2026-07-25-slice-j3-3-exact-projection-store.md`
|
||||
|
||||
## Objective
|
||||
|
||||
|
|
@ -131,3 +135,46 @@ Run:
|
|||
- No new allocation appears in steady-state live-object traversal.
|
||||
- No callback is delayed to another frame.
|
||||
- All automated and connected gates pass on the exact commit.
|
||||
|
||||
## Completion result
|
||||
|
||||
All acceptance conditions pass on final exact binary `e937cc36`.
|
||||
|
||||
- `LiveEntityProjectionStore` is the only materialized App sidecar store and is
|
||||
keyed by exact `RuntimeEntityKey`.
|
||||
- The temporary `ActiveRecordView`, `_activeRecords`, detached App record
|
||||
constructor, and broad materialized/visible `WorldEntity` collection
|
||||
surfaces are deleted. Borrowed exact-key record views remain for hot
|
||||
traversal and tests.
|
||||
- Hydration, animation, effects, lights, equipped children, remote teleport,
|
||||
render journal, liveness, movement observations, teardown, spatial
|
||||
residence, and visibility transitions carry the exact key.
|
||||
- `GpuWorldState` retains the exact key through loaded/pending rebucketing,
|
||||
landblock retirement, origin recentering, quiescence, and reentrant
|
||||
visibility delivery. DAT-static entities remain outside live Runtime
|
||||
identity.
|
||||
- Runtime remains the only current-GUID/incarnation/local-ID authority. App
|
||||
resolves GUID through Runtime and never decides which incarnation is current.
|
||||
- Synchronous callbacks, allocation order, render ordering, and frame timing
|
||||
are unchanged.
|
||||
|
||||
Evidence:
|
||||
|
||||
- 104 focused App ownership/streaming tests passed.
|
||||
- 3,761 App tests passed / 3 skipped.
|
||||
- 8,444 complete Release tests passed / 5 skipped.
|
||||
- Release solution build passed.
|
||||
- `logs/connected-world-gate-20260725-221008/report.json` passed on exact commit
|
||||
`e937cc36`: two sessions, seven checkpoints, two graceful zero-code exits,
|
||||
zero failures, zero render-shadow mismatches, and zero pending deltas.
|
||||
|
||||
Exact rollback, newest commit first:
|
||||
|
||||
```text
|
||||
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
|
||||
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
|
||||
```
|
||||
|
||||
J3.4 is the next clean slice. It moves canonical `ClientObjectTable` ownership
|
||||
under the Runtime entity/object lifetime group without moving retained UI,
|
||||
icons, paperdolls, grids, cooldown drawing, or interaction presentation.
|
||||
|
|
|
|||
|
|
@ -12,16 +12,21 @@
|
|||
| 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 | next | [`2026-07-25-modern-runtime-slice-j3-projection-store.md`](2026-07-25-modern-runtime-slice-j3-projection-store.md): key every graphical sidecar/workset by `RuntimeEntityKey` and remove the compatibility view |
|
||||
| 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 | next | [`2026-07-25-modern-runtime-slice-j3-object-table.md`](2026-07-25-modern-runtime-slice-j3-object-table.md): move the existing `ClientObjectTable` into the Runtime entity/object lifetime group while App remains a synchronous borrower |
|
||||
|
||||
J3.2 passes the Release solution build and 8,441 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. It adds no frame queue, backend
|
||||
dependency, or gameplay behavior change. The exact rollback for J3.2 is:
|
||||
J3.3 passes the Release solution build, 3,761 App tests with three skips, and
|
||||
8,444 complete tests with five expected skips. Its final exact-binary
|
||||
seven-checkpoint connected lifecycle/reconnect route also passes with graceful
|
||||
exits, zero render-shadow mismatches, and zero pending deltas. Runtime is now
|
||||
the sole GUID/incarnation/local-ID authority; every materialized App sidecar,
|
||||
presentation workset, and live spatial visibility edge uses the exact
|
||||
`RuntimeEntityKey`. It adds no frame queue, backend dependency, allocation-order
|
||||
change, or gameplay behavior change. The exact rollback for J3.3 is:
|
||||
|
||||
```text
|
||||
git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
|
||||
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
|
||||
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
|
||||
```
|
||||
|
||||
## 1. Objective
|
||||
|
|
@ -197,6 +202,9 @@ 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
|
||||
|
|
@ -286,8 +294,12 @@ failure; record and revert only the exact failing J3 commit.
|
|||
J3 sub-slices are independently reversible:
|
||||
|
||||
```text
|
||||
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
|
||||
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
|
||||
git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
|
||||
git revert f7442d13e9ae7d5b077ffecb1f8a10899ad46edd
|
||||
```
|
||||
|
||||
Revert J3.2 before J3.1 when rolling back both.
|
||||
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.
|
||||
|
|
|
|||
138
docs/research/2026-07-25-slice-j3-3-complete-j3-4-handoff.md
Normal file
138
docs/research/2026-07-25-slice-j3-3-complete-j3-4-handoff.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# HANDOFF — J3.3 complete; start J3.4 canonical object-table ownership
|
||||
|
||||
## Outcome
|
||||
|
||||
Stop here. J3.3 is complete and certified.
|
||||
|
||||
Final code commits:
|
||||
|
||||
1. `420e5eea70fd2c29cf9c8614e6298a1f84d64045`
|
||||
— App projection sidecars and presentation worksets use exact
|
||||
`RuntimeEntityKey`.
|
||||
2. `e937cc36df39cf6ea1eaba2f9c0243d1929da702`
|
||||
— spatial residence, visibility, quiescence, rebucketing, retirement, and
|
||||
origin recenter preserve that same exact key.
|
||||
|
||||
Do not reopen J3.3 unless a reproducible gate fails. The next slice is J3.4.
|
||||
|
||||
## Read in this order
|
||||
|
||||
1. `AGENTS.md`
|
||||
2. `docs/plans/2026-07-25-modern-runtime-slice-j3-object-table.md`
|
||||
3. `docs/plans/2026-07-25-modern-runtime-slice-j3.md`
|
||||
4. `docs/research/2026-07-25-slice-j3-3-exact-projection-store.md`
|
||||
5. `claude-memory/project_modern_runtime_architecture.md`
|
||||
6. `claude-memory/project_live_entity_runtime.md`
|
||||
7. `docs/architecture/acdream-architecture.md`
|
||||
8. `docs/architecture/code-structure.md`
|
||||
|
||||
The first plan is the authoritative J3.4 execution plan. The parent plan
|
||||
defines J3.5/J3.6 and final acceptance.
|
||||
|
||||
## Current architecture
|
||||
|
||||
- `RuntimeEntityDirectory` is the only server-GUID/incarnation/local-ID
|
||||
authority.
|
||||
- `RuntimeEntityRecord` is presentation-free.
|
||||
- `LiveEntityProjectionStore` is the only materialized App sidecar store.
|
||||
- Every App materialized owner uses exact `RuntimeEntityKey`.
|
||||
- `GpuWorldState` retains the exact key across all spatial lifetime changes.
|
||||
- `LiveEntityRuntime` is an App projection/lifecycle host, not canonical
|
||||
identity.
|
||||
- No queue, copied gameplay world, extra frame, or rendering behavior change
|
||||
was introduced.
|
||||
|
||||
The remaining J3.4 split is visible in two places:
|
||||
|
||||
- `LiveEntityRuntime` still constructs `RuntimeEntityDirectory`.
|
||||
- `GameWindow` still constructs the live `ClientObjectTable`.
|
||||
|
||||
J3.4 replaces those two independent construction points with one
|
||||
presentation-free Runtime entity/object lifetime-group root, then makes all App
|
||||
controllers and Runtime session routing borrow its exact instances.
|
||||
|
||||
## Required behavior
|
||||
|
||||
Preserve verbatim:
|
||||
|
||||
- canonical create acceptance before object-table CreateObject mutation;
|
||||
- `CreateIntegrationVersion` revalidation after synchronous callbacks;
|
||||
- logical DeleteObject mutation before App projection teardown;
|
||||
- pickup/parent leave-world without object-table deletion;
|
||||
- optimistic move, authoritative confirm, and rejection rollback;
|
||||
- ViewContents/container replacement and nullable unknown-object move notices;
|
||||
- current pre-Connect subscription order;
|
||||
- object-table clear before graphical projection reset;
|
||||
- synchronous press-time UI and controller reads.
|
||||
|
||||
Do not move retained UI, item icons, paperdolls, grids, cooldown drawing,
|
||||
selection presentation, or higher-level inventory transactions into Runtime in
|
||||
J3.4. Those are borrowers now and later J4 work.
|
||||
|
||||
## Baseline and gates
|
||||
|
||||
Final J3.3 baseline:
|
||||
|
||||
- focused exact ownership/streaming: 104 passed;
|
||||
- App: 3,761 passed / 3 skipped;
|
||||
- complete Release: 8,444 passed / 5 skipped;
|
||||
- Release build: pass;
|
||||
- connected report:
|
||||
`logs/connected-world-gate-20260725-221008/report.json`;
|
||||
- connected result: two sessions, seven checkpoints, both graceful exit code
|
||||
zero, zero failures, zero render-shadow mismatches, zero pending deltas.
|
||||
|
||||
Standard commands:
|
||||
|
||||
```powershell
|
||||
dotnet build AcDream.slnx -c Release --no-restore
|
||||
dotnet test AcDream.slnx -c Release --no-build
|
||||
```
|
||||
|
||||
Run the focused Runtime/Core/App matrix listed in the J3.4 plan before the full
|
||||
suite. Commit the J3.4 code before running the connected gate so the report
|
||||
identifies one immutable binary. Use credentials supplied by the user/session;
|
||||
never write them into source or documentation.
|
||||
|
||||
## Worktree cautions
|
||||
|
||||
These tracked paths can appear modified from Windows metadata/line-ending
|
||||
behavior while remaining content-identical to the index:
|
||||
|
||||
- `src/AcDream.App/Interaction/PlayerInteractionMovementSink.cs`
|
||||
- `src/AcDream.App/Rendering/LiveAnimationPresentationContext.cs`
|
||||
- `src/AcDream.Core/Physics/CellArray.cs`
|
||||
- `src/AcDream.Core/Vfx/ParticleSystem.cs`
|
||||
- `tests/AcDream.Core.Tests/Vfx/ParticleSystemTests.cs`
|
||||
|
||||
Do not stage or rewrite them unless `git diff -- <path>` shows a real task
|
||||
change.
|
||||
|
||||
`.test-out/`, nested `.test-out/`, and `logs/` contain local test/evidence
|
||||
artifacts, including very large prepared packages. Do not stage them and do not
|
||||
recursively delete them without first verifying the exact absolute target.
|
||||
|
||||
## Exact rollback
|
||||
|
||||
If J3.3 itself must be rolled back, revert newest first:
|
||||
|
||||
```text
|
||||
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
|
||||
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
|
||||
```
|
||||
|
||||
For a J3.4 failure, revert only the new J3.4 commit. Do not use the J3.3
|
||||
rollback as a shortcut.
|
||||
|
||||
## Final J3 goal
|
||||
|
||||
J3.4 establishes one Runtime entity/object ownership root. J3.5 publishes one
|
||||
ordered per-session entity/object delta stream consumed by graphical and
|
||||
direct hosts without a second queue or mirror. J3.6 proves failure recovery,
|
||||
no-window lifecycle, multiple-instance isolation, exact teardown convergence,
|
||||
Release parity, and the connected route.
|
||||
|
||||
The J3 campaign is complete only when J3.6 proves zero leaked canonical
|
||||
records, tombstones, App projections, resources, container entries, parent
|
||||
candidates, deltas, and subscriptions. That is the next clean boundary before
|
||||
J4 gameplay-state services and later Slice K Linux/headless multi-session work.
|
||||
128
docs/research/2026-07-25-slice-j3-3-exact-projection-store.md
Normal file
128
docs/research/2026-07-25-slice-j3-3-exact-projection-store.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
# Modern runtime J3.3 exact projection-store closeout
|
||||
|
||||
## Result
|
||||
|
||||
J3.3 is complete in two production commits:
|
||||
|
||||
1. `420e5eea70fd2c29cf9c8614e6298a1f84d64045` — exact-key App
|
||||
projection store and presentation-owner cutover.
|
||||
2. `e937cc36df39cf6ea1eaba2f9c0243d1929da702` — exact-key spatial
|
||||
residence, visibility, quiescence, rebucketing, and retirement correction.
|
||||
|
||||
The second commit is the final exact binary certified by the connected gate.
|
||||
|
||||
`AcDream.Runtime.Entities.RuntimeEntityDirectory` remains the sole owner of
|
||||
current server GUID, `INSTANCE_TS` incarnation, Runtime local ID, reverse
|
||||
lookup, accepted snapshot/timestamps, parent state, session epoch, tombstones,
|
||||
and per-GUID operation versions.
|
||||
|
||||
`AcDream.App.World.LiveEntityProjectionStore` now owns materialized graphical
|
||||
sidecars only. Its key is the complete `RuntimeEntityKey`:
|
||||
|
||||
```text
|
||||
Runtime local ID + INSTANCE_TS incarnation
|
||||
```
|
||||
|
||||
There are three explicit states:
|
||||
|
||||
1. canonical-only Runtime registration with no App sidecar;
|
||||
2. one materialized App sidecar under its exact key;
|
||||
3. retryable teardown retaining only the unfinished suffix for that exact key.
|
||||
|
||||
The temporary `ActiveRecordView`, `_activeRecords`, detached
|
||||
`LiveEntityRecord(EntitySpawn)` fixture path, and broad materialized/visible
|
||||
`WorldEntity` collection APIs are deleted. Consumers use focused borrowed
|
||||
queries or allocation-free exact-key record views.
|
||||
|
||||
## Exact owner cutover
|
||||
|
||||
The following App owners now carry the exact key:
|
||||
|
||||
- world projection and loaded/pending spatial residence;
|
||||
- spatial visibility transitions and world-generation quiescence;
|
||||
- hydration and recovery;
|
||||
- animation and spatial-animation schedules;
|
||||
- remote motion, remote teleport, and movement observations;
|
||||
- projectile and ordinary-root worksets;
|
||||
- entity effect profiles and moving lights;
|
||||
- equipped-child roots and render registrations;
|
||||
- render-scene journal identity;
|
||||
- radar, targeting, selection, liveness, and teardown lookups.
|
||||
|
||||
`GpuWorldState` preserves the exact key through loaded-to-loaded rebucketing,
|
||||
pending residence, landblock retirement/reload, persistent rescue, and
|
||||
full-origin recenter. A delayed visibility edge therefore cannot match a later
|
||||
incarnation that reused the same numeric local ID. DAT-static entities retain
|
||||
their existing non-Runtime path and are not assigned a fabricated server-live
|
||||
identity.
|
||||
|
||||
No asynchronous queue, copied gameplay world, extra input frame, local-ID
|
||||
allocation-order change, renderer order change, or gameplay behavior change
|
||||
was introduced.
|
||||
|
||||
## Automated acceptance
|
||||
|
||||
At final commit `e937cc36`:
|
||||
|
||||
- focused ownership/streaming tests: 104 passed;
|
||||
- App tests: 3,761 passed / 3 skipped;
|
||||
- complete Release solution: 8,444 passed / 5 skipped;
|
||||
- Release solution build: pass.
|
||||
|
||||
Coverage includes canonical-only registration, exact sidecar claim, same-
|
||||
incarnation refresh, factory/resource rollback, local-ID wrap and stale-key
|
||||
rejection, loaded/pending rebucketing, landblock detach/reload, origin
|
||||
recenter, reentrant visibility callbacks, GUID replacement, hydration,
|
||||
animation/effect/light/equipped-child ownership, and retryable teardown.
|
||||
|
||||
Source guards reject a GUID-keyed App `LiveEntityRecord` authority map and
|
||||
local-ID-only ownership in the materialized presentation/spatial worksets.
|
||||
The divergence-register audit found no new behavioral divergence: J3.3 changes
|
||||
ownership and identity plumbing only. AD-32's moved Runtime source pointers
|
||||
were refreshed without changing its scope.
|
||||
|
||||
## Connected lifecycle acceptance
|
||||
|
||||
Raw evidence:
|
||||
`logs/connected-world-gate-20260725-221008/report.json`.
|
||||
|
||||
Result: PASS on exact commit
|
||||
`e937cc36df39cf6ea1eaba2f9c0243d1929da702`.
|
||||
|
||||
- Two fresh processes/sessions completed.
|
||||
- Seven of seven checkpoints passed.
|
||||
- Both processes exited gracefully with exit code zero.
|
||||
- The report contains zero failures.
|
||||
- Every checkpoint has zero render-scene shadow mismatches.
|
||||
- Every checkpoint converged with zero pending render deltas.
|
||||
- The only warning is 25 expected world-edge landblock misses.
|
||||
|
||||
This certifies fresh login, outdoor/dungeon travel, same-location revisit,
|
||||
graceful logout, and fresh-process reconnect on the exact final binary.
|
||||
|
||||
## Exact rollback
|
||||
|
||||
Revert newest first:
|
||||
|
||||
```text
|
||||
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
|
||||
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
|
||||
```
|
||||
|
||||
Do not revert J3.2 unless canonical Runtime identity itself is also being
|
||||
rolled back.
|
||||
|
||||
## Next slice
|
||||
|
||||
Start J3.4 in
|
||||
`docs/plans/2026-07-25-modern-runtime-slice-j3.md`.
|
||||
The executor-ready transfer prompt is
|
||||
`docs/research/2026-07-25-slice-j3-3-complete-j3-4-handoff.md`.
|
||||
|
||||
J3.4 moves the existing canonical `ClientObjectTable` and its placement/
|
||||
container lifetime under one Runtime entity/object group. App remains a
|
||||
synchronous borrower for retained UI, item icons, paperdolls, grids, cooldown
|
||||
drawing, and interaction presentation. It must preserve object add/update/
|
||||
remove, container replacement, optimistic move rollback, stack responses,
|
||||
GUID reuse, session clear, and press-time event ordering without adding a
|
||||
queue or copied inventory model.
|
||||
Loading…
Add table
Add a link
Reference in a new issue