Record the exact f46ddb5c rollback, 8,441-test Release gate, and seven-checkpoint connected lifecycle/reconnect pass. Update the canonical project state and pin J3.3's exact-key App projection-store execution plan.
Co-authored-by: Codex <codex@openai.com>
122 lines
6.2 KiB
Markdown
122 lines
6.2 KiB
Markdown
# 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`.
|
|
|
|
## J3.2 ownership checkpoint
|
|
|
|
Commit `f46ddb5cdb1e145752bea49aeb1d62bfe71284d3` implements the first
|
|
canonical split:
|
|
|
|
- `RuntimeEntityDirectory` owns the only active GUID map, exact-incarnation
|
|
tombstones, reverse local-ID map, session lifetime epoch, per-GUID operation
|
|
versions, accepted inbound snapshot owner, and parent-relation owner;
|
|
- `RuntimeEntityRecord` owns the presentation-free canonical snapshot,
|
|
`INSTANCE_TS`, authoritative cell/state/timestamp versions, object clock,
|
|
PhysicsBody/physics-host facts carried for J5, and Runtime-issued local ID;
|
|
- App's `LiveEntityRecord` is now a projection sidecar around that canonical
|
|
record;
|
|
- the temporary `ActiveRecordView` is dictionary-shaped only to preserve the
|
|
large synchronous App call surface during J3.2. It stores no GUID map and
|
|
resolves every lookup through `RuntimeEntityDirectory`; J3.3 deletes it;
|
|
- Runtime-only ownership/lifetime tests and App source guards protect the
|
|
boundary.
|
|
|
|
The checkpoint passes 110 Runtime tests, 3,758 App tests with three skips, and
|
|
8,441 complete Release tests with five skips. Its exact-binary connected gate
|
|
also passes all seven checkpoints with graceful exits, zero render-shadow
|
|
mismatches, and zero pending deltas:
|
|
`logs/connected-world-gate-20260725-200749/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.
|