refactor(world): separate live lifetime from spatial buckets
Introduce LiveEntityRuntime as the canonical owner of each accepted server-object incarnation, stable local identity, timestamped state, parent relations, runtime components, and exactly-once teardown. Split logical registration from rebucketing so pending landblocks, equipment attachment, pickup re-entry, and GUID replacement reuse the same entity and effect owners. Keep canonical materialized and visible target/radar views distinct, preserve retail leave_world versus exit_world semantics, gate root simulation while cell-less, and track transitional pre-Create F754 owners through delete and session reset. Remove stale-spawn rehydration and make GpuWorldState spatial-only for live objects. Add lifecycle, generation, pending, unload, attachment, event-publication, local-ID, rollback, and effect-cleanup coverage; update architecture, milestones, memory, and the divergence register. Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
parent
8a5d77f7f4
commit
8dd996053d
24 changed files with 2449 additions and 631 deletions
|
|
@ -188,8 +188,9 @@ src/AcDream.App/
|
|||
├── Net/
|
||||
│ └── LiveSessionController.cs # owns WorldSession lifecycle, login/handshake, reconnect
|
||||
├── World/
|
||||
│ ├── InboundPhysicsStateController.cs # shipped: timestamps + accepted spawn snapshots
|
||||
│ └── LiveEntityRuntime.cs # target: full lifecycle + ServerGuid↔entity.Id translation
|
||||
│ ├── InboundPhysicsStateController.cs # timestamps + accepted spawn snapshots
|
||||
│ ├── LiveEntityRuntime.cs # shipped: logical lifetime + ServerGuid↔entity.Id translation
|
||||
│ └── ParentAttachmentState.cs # parent generations + pending ParentEvent relations
|
||||
├── Interaction/
|
||||
│ └── SelectionInteractionController.cs # owns WorldPicker, selection state, Use/PickUp dispatch
|
||||
├── Streaming/ # LandblockStreamer + immutable LandblockBuild completion
|
||||
|
|
@ -226,16 +227,13 @@ The eventual `GameEntity` aggregation (target state described in
|
|||
Until then, the parallel-dicts problem is bounded inside one class
|
||||
instead of spread across `GameWindow`.
|
||||
|
||||
`InboundPhysicsStateController` is the first shipped slice of that boundary:
|
||||
it owns the nine-channel retail timestamp gates and the latest accepted
|
||||
immutable CreateObject snapshot. It deliberately owns no renderer adapter,
|
||||
local entity ID, physics body, animation, effect, or spatial bucket; those
|
||||
move together in the `LiveEntityRuntime` extraction.
|
||||
|
||||
`ParentAttachmentState` is a focused interim pending queue for ParentEvent:
|
||||
it keys unresolved relations by child and parent generation, distinguishes
|
||||
atomic incarnation replacement from true deletion, and migrates into
|
||||
`LiveEntityRuntime` with the general mixed packet queue.
|
||||
`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. `ParentAttachmentState` is runtime-owned and keys unresolved
|
||||
relations by child and parent generation. A future general mixed packet queue
|
||||
still has to cover the non-Parent packet families tracked by divergence AD-32.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -280,22 +278,36 @@ constructed without a live socket (offline mode).
|
|||
**Verification:** Visual login + Holtburg traversal + door interaction
|
||||
identical to pre-extraction.
|
||||
|
||||
### Step 3 — `LiveEntityRuntime` (or `EntityRuntimeRegistry`)
|
||||
### Step 3 — `LiveEntityRuntime` — SHIPPED 2026-07-14
|
||||
|
||||
**Scope:** Centralize the parallel dictionaries — `_entitiesByServerGuid`,
|
||||
the streaming entity lists, the player controller's player entity —
|
||||
into one owner. Surface the ServerGuid↔entity.Id translation as a
|
||||
single API (eliminating the trap from L.2g slice 1c).
|
||||
**Shipped scope:** One `LiveEntityRecord` per server-object incarnation now owns
|
||||
ServerGuid↔local-ID translation, accepted state, runtime components, parent
|
||||
relations, logical resource activation, exact teardown, and spatial projection
|
||||
state. `RegisterLiveEntity`, `RebucketLiveEntity`, and `UnregisterLiveEntity`
|
||||
make the lifetime boundary explicit. Landblock unload/reload moves the same
|
||||
`WorldEntity`; it cannot reconstruct from a stale CreateObject or replay setup
|
||||
scripts. Equipped children use an attached projection and never enter the
|
||||
top-level target/radar/status view. Canonical materialized lookup remains
|
||||
available while a projection is pending; the separate visible view is the only
|
||||
surface radar, picking, status, and targeting consume. Pickup/parent leave-world
|
||||
clears cell membership and pauses root movement/animation without destroying the
|
||||
retained owners. Top-level spawn publication is one-shot per incarnation, so
|
||||
leave/re-entry restores presentation without duplicating plugin event replay.
|
||||
|
||||
**Behavior change:** None.
|
||||
**Remaining target:** the player-specific controller is still a separate
|
||||
aggregation, and AD-32 still tracks the future non-Parent mixed-packet queue.
|
||||
|
||||
**Behavior change:** Spatial withdrawal and re-entry now preserve logical
|
||||
identity and active resources instead of replaying create-time effects.
|
||||
|
||||
**Risk:** Medium-high. Entity lookup is in every hot path. The change
|
||||
is structural (one owner instead of three) but the lookup semantics
|
||||
must be byte-identical.
|
||||
|
||||
**Test:** Entity-spawn / despawn / lookup tests in
|
||||
`tests/AcDream.App.Tests/`. Existing visual verification at Holtburg
|
||||
catches any drift in interaction.
|
||||
**Test:** `LiveEntityRuntimeTests` cover duplicate CreateObject, generation
|
||||
replacement, appearance mutation, loaded/pending rebucketing, attached
|
||||
projection, pickup leave/re-entry, canonical-versus-visible lookup, resource
|
||||
rollback, GUID reuse, and idempotent session teardown.
|
||||
|
||||
**Verification:** Walk Holtburg, click NPC, open door, pick up item.
|
||||
All four M1 demo targets must still work.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue