diff --git a/Theriapolis.Core/Tactical/ChunkStreamer.cs b/Theriapolis.Core/Tactical/ChunkStreamer.cs index 97347fc..3df98c7 100644 --- a/Theriapolis.Core/Tactical/ChunkStreamer.cs +++ b/Theriapolis.Core/Tactical/ChunkStreamer.cs @@ -127,12 +127,19 @@ public sealed class ChunkStreamer active.Add(new ChunkCoord(cx, cy)); } - // Synchronously generate any missing active chunks (the player needs - // them this frame). Pre-warm the next ring on the threadpool. + // Synchronously make every active chunk live in the cache. Get() + // handles all three paths: hit cache, drain a pre-warmed inflight + // task, or generate fresh. The previous version skipped chunks in + // _inflight, which left them stuck there indefinitely once they + // entered the active set on a later frame — visible to renderers + // that subscribe to OnChunkLoaded (e.g. the Godot port) as + // permanently-uncached gaps. The MonoGame TacticalRenderer dodged + // this by calling Get() inside its draw loop; M4 of the port made + // that drain unnecessary by fixing it here. foreach (var cc in active) { - if (!_cache.ContainsKey(cc) && !_inflight.ContainsKey(cc)) - _ = Get(cc); // synchronous generate + cache + if (!_cache.ContainsKey(cc)) + _ = Get(cc); // hits cache, drains inflight, or generates } for (int cy = centre.Y - chunkRadius - 1; cy <= centre.Y + chunkRadius + 1; cy++)