acdream/docs/research/2026-07-25-slice-j3-entity-ownership-inventory.md
Erik b0fecc5f65 docs(runtime): pin J3 entity ownership migration
Reconcile J3 with later gameplay lifetime groups, inventory the current mixed entity/object ownership, and define the staged canonical identity, projection, object-table, delta, teardown, and no-window gates.

Co-authored-by: Codex <codex@openai.com>
2026-07-25 19:51:50 +02:00

4.9 KiB

Slice J3 entity ownership inventory

Baseline

Production base: 9496c01b.

The accepted J2 binary passes 8,428 Release tests with five skips and the seven-checkpoint connected lifecycle/reconnect gate at logs/connected-world-gate-20260725-193936/report.json.

At this baseline:

  • LiveEntityRuntime.cs is 2,866 lines and is referenced by roughly 100 App source/test files;
  • it owns both canonical GUID/incarnation/timestamp state and graphical projection/component state;
  • InboundPhysicsStateController and ParentAttachmentState are already presentation-free but still reside in App;
  • ClientObjectTable is a presentation-free Core type, but its production instance is publicly owned by GameWindow;
  • the retained render scene is a derived projection and is not a second gameplay/GUID authority.

Existing retail oracle

J3 changes ownership, not behavior. It preserves the already cited ports:

  • CObjectMaint::CreateObject
  • CObjectMaint::DeleteObject @ 0x00508460
  • CPhysicsObj::set_description @ 0x00514F40
  • CPhysicsObj::change_cell @ 0x00513390
  • CPhysicsObj::exit_world @ 0x00514E60
  • ACCWeenieObject::ServerSaysMoveItem @ 0x0058DBB0
  • the SmartBox CreateObject/event flow in docs/research/2026-07-13-retail-projectile-vfx-pseudocode.md

No new AC algorithm or constant is introduced. Any later behavioral question returns to named retail before implementation.

Field ownership

State J3 owner Notes
Server GUID and INSTANCE_TS Runtime One current incarnation only
Runtime local identity and reverse lookup Runtime Issued by Runtime; never inferred by App
Latest accepted immutable spawn Runtime Includes accepted raw properties and timestamps
Position/state/vector/movement/object-description authority versions Runtime Reentrant operation validation
Full cell and canonical landblock Runtime Authoritative object placement, not streaming residency
Raw/final physics state and object clock Runtime Existing behavior; later physics relocation is J5
Parent candidates and accepted parent relation Runtime Exact arrival and generation order
Session lifetime version, GUID operation versions, tombstones Runtime Retryable replacement/delete/clear
ClientObjectTable and placement/container indices Runtime Existing Core type, same instance
WorldEntity and mesh/resource registration App projection Keyed by local identity + incarnation
Loaded/pending bucket and derived visibility App projection Streaming fact, not object identity
Animation/effect/light/projectile presentation App projection No references from Runtime
Hydration/recovery/appearance synchronization flags App projection Retryable graphical transaction
Selection geometry, radar and paperdoll App projection Borrow canonical object facts

HasPartArray, PhysicsBody, and movement-manager/physics-host fields are presentation-independent simulation facts. J3 must not push them into App just to simplify the split. Their behavior and final lifetime-group relocation are handled in J5.

Current mixed-owner hazards

  1. Local IDs are currently reserved when App materializes a WorldEntity. Runtime must own the allocator while preserving that graphical allocation order until parity is proven.
  2. Logical tombstones currently retain App teardown plans on LiveEntityRecord. J3 replaces this with a typed, exact, retryable projection acknowledgement.
  3. Active animation/remote/projectile worksets currently live beside the GUID map. They move intact to the App projection store.
  4. GpuWorldState and several presentation controllers accept server GUID as their primary key. They must consume Runtime local identity plus incarnation and treat GUID only as immutable payload metadata.
  5. GameWindow.Objects makes the graphical shell appear to own the canonical object table. J3 replaces it with a Runtime lifetime-group owner borrowed by UI and presentation composition.

Do not retry

Dead direction Why
Copy the GUID map into Runtime while keeping App's map Creates two worlds and ambiguous teardown
Let App allocate an independent local ID Breaks cross-host identity and stale-incarnation rejection
Put WorldEntity or App component interfaces in Runtime Makes headless a hidden graphical host
Deliver projection updates through a later-frame queue Changes accepted presentation and input timing
Move vitals/spells/combat opportunistically in J3 Splits the J4/J5 lifetime groups
Re-key everything by GUID and call it a projection cache Leaves App as a second identity authority

J3.1 first move

InboundPhysicsStateController, ParentAttachmentState, their immutable result types, and dedicated tests move into AcDream.Runtime.Entities unchanged. App temporarily composes these Runtime owners until the canonical directory and projection store cut over in later J3 sub-slices.