diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index 6d49feb0181018..003eed59e0360d 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -52,6 +52,8 @@ public sealed class GasTileOverlaySystem : SharedGasTileOverlaySystem new DefaultObjectPool>>( new DefaultPooledObjectPolicy>>(), 64); + private bool _doSessionUpdate; + /// /// Overlay update interval, in seconds. /// @@ -192,7 +194,7 @@ public GasOverlayData GetOverlayData(GasMixture? mixture) /// /// Updates the visuals for a tile on some grid chunk. Returns true if the visuals have changed. /// - private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index, GameTick curTick) + private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index) { ref var oldData = ref chunk.TileData[chunk.GetDataIndex(index)]; if (!gridAtmosphere.Tiles.TryGetValue(index, out var tile)) @@ -200,7 +202,7 @@ private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayC if (oldData.Equals(default)) return false; - chunk.LastUpdate = curTick; + chunk.LastUpdate = _gameTiming.CurTick; oldData = default; return true; } @@ -258,11 +260,11 @@ private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayC if (!changed) return false; - chunk.LastUpdate = curTick; + chunk.LastUpdate = _gameTiming.CurTick; return true; } - private void UpdateOverlayData(GameTick curTick) + private void UpdateOverlayData() { // TODO parallelize? var query = EntityQueryEnumerator(); @@ -276,7 +278,7 @@ private void UpdateOverlayData(GameTick curTick) if (!overlay.Chunks.TryGetValue(chunkIndex, out var chunk)) overlay.Chunks[chunkIndex] = chunk = new GasOverlayChunk(chunkIndex); - changed |= UpdateChunkTile(gam, chunk, index, curTick); + changed |= UpdateChunkTile(gam, chunk, index); } if (changed) @@ -291,13 +293,28 @@ public override void Update(float frameTime) base.Update(frameTime); AccumulatedFrameTime += frameTime; - if (AccumulatedFrameTime < _updateInterval) return; - AccumulatedFrameTime -= _updateInterval; + if (_doSessionUpdate) + { + UpdateSessions(); + return; + } + + if (AccumulatedFrameTime < _updateInterval) + return; - var curTick = _gameTiming.CurTick; + AccumulatedFrameTime -= _updateInterval; // First, update per-chunk visual data for any invalidated tiles. - UpdateOverlayData(curTick); + UpdateOverlayData(); + + // Then, next tick we send the data to players. + // This is to avoid doing all the work in the same tick. + _doSessionUpdate = true; + } + + public void UpdateSessions() + { + _doSessionUpdate = false; if (!PvsEnabled) return; @@ -315,11 +332,11 @@ public override void Update(float frameTime) _sessions.Add(player); } - if (_sessions.Count > 0) - { - _updateJob.CurrentTick = curTick; - _parMan.ProcessNow(_updateJob, _sessions.Count); - } + if (_sessions.Count == 0) + return; + + _parMan.ProcessNow(_updateJob, _sessions.Count); + _updateJob.LastSessionUpdate = _gameTiming.CurTick; } public void Reset(RoundRestartCleanupEvent ev) @@ -352,7 +369,7 @@ private record struct UpdatePlayerJob : IParallelRobustJob public ObjectPool> ChunkIndexPool; public ObjectPool>> ChunkViewerPool; - public GameTick CurrentTick; + public GameTick LastSessionUpdate; public Dictionary>> LastSentChunks; public List Sessions; @@ -415,7 +432,7 @@ public void Execute(int index) if (previousChunks != null && previousChunks.Contains(gIndex) && - value.LastUpdate != CurrentTick) + value.LastUpdate > LastSessionUpdate) { continue; }