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
|
|
@ -37,6 +37,32 @@ public class GpuWorldStateTwoTierTests
|
|||
Assert.True(state.IsLoaded(0xAAAAFFFFu)); // landblock still resident
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveEntitiesFromLandblock_DropsStaticLayerButRetainsLiveProjection()
|
||||
{
|
||||
var state = new GpuWorldState();
|
||||
WorldEntity staticEntity = MakeStubEntity(1);
|
||||
var liveEntity = new WorldEntity
|
||||
{
|
||||
Id = 2,
|
||||
ServerGuid = 0x70000002u,
|
||||
SourceGfxObjOrSetupId = 0x01000001u,
|
||||
Position = System.Numerics.Vector3.Zero,
|
||||
Rotation = System.Numerics.Quaternion.Identity,
|
||||
MeshRefs = System.Array.Empty<MeshRef>(),
|
||||
};
|
||||
state.AddLandblock(MakeStubLandblock(
|
||||
0xAAAAFFFFu,
|
||||
staticEntity,
|
||||
liveEntity));
|
||||
|
||||
state.RemoveEntitiesFromLandblock(0xAAAAFFFFu);
|
||||
|
||||
Assert.Same(liveEntity, Assert.Single(state.Entities));
|
||||
Assert.DoesNotContain(staticEntity, state.Entities);
|
||||
Assert.True(state.IsLoaded(0xAAAAFFFFu));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddEntitiesToExistingLandblock_MergesIntoExistingRecord()
|
||||
{
|
||||
|
|
@ -118,7 +144,6 @@ public class GpuWorldStateTwoTierTests
|
|||
int callCount = 0;
|
||||
var state = new GpuWorldState(
|
||||
wbSpawnAdapter: null,
|
||||
wbEntitySpawnAdapter: null,
|
||||
onLandblockUnloaded: id => { observed = id; callCount++; });
|
||||
|
||||
state.AddLandblock(MakeStubLandblock(0xA9B4FFFFu, MakeStubEntity(1)));
|
||||
|
|
@ -144,7 +169,6 @@ public class GpuWorldStateTwoTierTests
|
|||
int callCount = 0;
|
||||
var state = new GpuWorldState(
|
||||
wbSpawnAdapter: null,
|
||||
wbEntitySpawnAdapter: null,
|
||||
onLandblockUnloaded: _ => callCount++);
|
||||
|
||||
// Landblock never loaded.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue