diff --git a/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs b/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs index 0e6e47ed..064cb264 100644 --- a/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs +++ b/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs @@ -349,6 +349,12 @@ public sealed unsafe class EnvCellRenderer : IDisposable lock (lb.Lock) { + // TEMP diagnostic #105 (strip with fix): a registration landing AFTER + // this landblock was already finalized starts a fresh pending list that + // only commits if ANOTHER finalize arrives — and that one will REPLACE + // (not merge) the committed set. One-shot per landblock per pending list. + if (lb.InstancesReady && lb.PendingInstances is null) + Console.WriteLine($"[late-register] lb=0x{landblockId:X8} cell=0x{envCellId:X8} registered AFTER finalize — starting a new pending list ({(lb.Instances?.Count ?? 0)} already committed)"); lb.PendingInstances ??= new List(capacity: 32); lb.PendingInstances.Add(cellInstance); lb.PendingEnvCellBounds ??= new Dictionary(); @@ -403,6 +409,13 @@ public sealed unsafe class EnvCellRenderer : IDisposable { if (lb.PendingInstances is not null) { + // TEMP diagnostic #105 (strip with fix): REPLACE semantics — if a + // previous finalize already committed instances for this landblock, + // this swap DISCARDS them in favor of the new pending set. A partial + // pending set (finalize racing a still-registering promote job) + // silently loses buildings. + if (lb.Instances is { Count: > 0 }) + Console.WriteLine($"[finalize-replace] lb=0x{landblockId:X8} DISCARDING {lb.Instances.Count} committed instances, replacing with {lb.PendingInstances.Count} pending"); lb.Instances = lb.PendingInstances; lb.PendingInstances = null; }