diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs
index 2968ece..d62a80d 100644
--- a/src/AcDream.App/Rendering/GameWindow.cs
+++ b/src/AcDream.App/Rendering/GameWindow.cs
@@ -767,6 +767,7 @@ public sealed class GameWindow : IDisposable
var entity = new AcDream.Core.World.WorldEntity
{
Id = _liveEntityIdCounter++,
+ ServerGuid = spawn.Guid,
SourceGfxObjOrSetupId = spawn.SetupTableId.Value,
Position = worldPos,
Rotation = rot,
diff --git a/src/AcDream.App/Streaming/GpuWorldState.cs b/src/AcDream.App/Streaming/GpuWorldState.cs
index 264c155..9711e9a 100644
--- a/src/AcDream.App/Streaming/GpuWorldState.cs
+++ b/src/AcDream.App/Streaming/GpuWorldState.cs
@@ -135,7 +135,7 @@ public sealed class GpuWorldState
{
foreach (var entity in lb.Entities)
{
- if (_persistentGuids.Contains(entity.Id))
+ if (entity.ServerGuid != 0 && _persistentGuids.Contains(entity.ServerGuid))
_persistentRescued.Add(entity);
}
}
diff --git a/src/AcDream.Core/World/WorldEntity.cs b/src/AcDream.Core/World/WorldEntity.cs
index 708d825..b98abf5 100644
--- a/src/AcDream.Core/World/WorldEntity.cs
+++ b/src/AcDream.Core/World/WorldEntity.cs
@@ -5,6 +5,12 @@ namespace AcDream.Core.World;
public sealed class WorldEntity
{
public required uint Id { get; init; }
+ ///
+ /// Server-assigned GUID (from CreateObject). Zero for dat-hydrated
+ /// scenery/static entities that don't come from the server.
+ /// Used by GpuWorldState for persistent-entity rescue on landblock unload.
+ ///
+ public uint ServerGuid { get; init; }
public required uint SourceGfxObjOrSetupId { get; init; }
///
/// World-space position. Settable so Phase 6.7 position-update events