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
|
|
@ -78,19 +78,20 @@ public class StreamingControllerTests
|
|||
// Note: LoadedLandblock's actual fields are LandblockId, Heightmap,
|
||||
// Entities (positional record). Adjust if the first positional arg
|
||||
// name differs.
|
||||
var lb = new LoadedLandblock(0x32320FFEu, new LandBlock(), System.Array.Empty<WorldEntity>());
|
||||
const uint landblockId = 0x3232FFFFu;
|
||||
var lb = new LoadedLandblock(landblockId, new LandBlock(), System.Array.Empty<WorldEntity>());
|
||||
// A.5 T10-T12 follow-up: use a real empty mesh instance instead of
|
||||
// default! so any future test that flows MeshData through the apply
|
||||
// callback gets a non-null reference to inspect rather than an NRE.
|
||||
var stubMesh = new AcDream.Core.Terrain.LandblockMeshData(
|
||||
System.Array.Empty<AcDream.Core.Terrain.TerrainVertex>(),
|
||||
System.Array.Empty<uint>());
|
||||
fake.Pending.Enqueue(new LandblockStreamResult.Loaded(0x32320FFEu, LandblockStreamTier.Near, lb, stubMesh));
|
||||
fake.Pending.Enqueue(new LandblockStreamResult.Loaded(landblockId, LandblockStreamTier.Near, lb, stubMesh));
|
||||
|
||||
controller.Tick(50, 50);
|
||||
|
||||
Assert.Single(applied);
|
||||
Assert.True(state.IsLoaded(0x32320FFEu));
|
||||
Assert.True(state.IsLoaded(landblockId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -102,12 +103,13 @@ public class StreamingControllerTests
|
|||
fake.EnqueueLoad, fake.EnqueueUnload, fake.DrainCompletions,
|
||||
(_, _) => { }, state, nearRadius: 2, farRadius: 2);
|
||||
|
||||
var lb = new LoadedLandblock(0x32320FFEu, new LandBlock(), System.Array.Empty<WorldEntity>());
|
||||
const uint landblockId = 0x3232FFFFu;
|
||||
var lb = new LoadedLandblock(landblockId, new LandBlock(), System.Array.Empty<WorldEntity>());
|
||||
state.AddLandblock(lb);
|
||||
fake.Pending.Enqueue(new LandblockStreamResult.Unloaded(0x32320FFEu));
|
||||
fake.Pending.Enqueue(new LandblockStreamResult.Unloaded(landblockId));
|
||||
|
||||
controller.Tick(50, 50);
|
||||
|
||||
Assert.False(state.IsLoaded(0x32320FFEu));
|
||||
Assert.False(state.IsLoaded(landblockId));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue