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
|
|
@ -20,7 +20,7 @@ namespace AcDream.Core.Tests.Streaming;
|
|||
/// dat-hydration paths (AddLandblock, AddEntitiesToExistingLandblock,
|
||||
/// RemoveLandblock, RemoveEntitiesFromLandblock), and that the
|
||||
/// pending-bucket merge in AddLandblock does NOT double-fire for live
|
||||
/// entities that already had OnCreate at <see cref="GpuWorldState.AppendLiveEntity"/>.
|
||||
/// entities, whose logical activation belongs to LiveEntityRuntime.
|
||||
/// </summary>
|
||||
public sealed class GpuWorldStateActivatorTests
|
||||
{
|
||||
|
|
@ -99,9 +99,9 @@ public sealed class GpuWorldStateActivatorTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void AddLandblock_DoesNotDoubleFire_OnPendingMerge()
|
||||
public void PendingLiveProjection_DoesNotFireLogicalActivator()
|
||||
{
|
||||
// Live entity (ServerGuid!=0) arrives via AppendLiveEntity first —
|
||||
// Live entity (ServerGuid!=0) arrives via spatial projection first —
|
||||
// OnCreate fires once at that point. Then AddLandblock for the
|
||||
// same canonical id pulls the pending entity into the loaded list.
|
||||
// The new fire-site MUST NOT call OnCreate again (the live entity
|
||||
|
|
@ -109,13 +109,12 @@ public sealed class GpuWorldStateActivatorTests
|
|||
var p = BuildPipeline(scriptId: 0xAAu);
|
||||
var live = Live(serverGuid: 0xCAFEu, pos: Vector3.Zero);
|
||||
|
||||
p.State.AppendLiveEntity(0xA9B4FFFFu, live);
|
||||
p.State.PlaceLiveEntityProjection(0xA9B4FFFFu, live);
|
||||
var emptyLb = MakeStubLandblock(0xA9B4FFFFu);
|
||||
p.State.AddLandblock(emptyLb);
|
||||
|
||||
p.Runner.Tick(0.001f);
|
||||
Assert.Single(p.Recording.Calls); // exactly one — no double-fire
|
||||
Assert.Equal(0xCAFEu, p.Recording.Calls[0].EntityId);
|
||||
Assert.Empty(p.Recording.Calls);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue