-
-
Notifications
You must be signed in to change notification settings - Fork 4
Feature: Chunk Send and Request Management
This feature set controls chunk pipeline pressure with explicit budgets, fairness rotation, and stale-request cleanup.
Main patch:
patches/VintagestoryLib/Vintagestory.Server/ServerSystemSendChunks.cs.patch
At the top of OnServerTick, Stratum reads three config slices and derives per-tick budgets:
StratumChunkSendingConfig stratumChunkSending = StratumRuntime.Config.Performance.ChunkSending;
StratumChunkGenerationConfig stratumChunkGeneration = StratumRuntime.Config.Performance.ChunkGeneration;
StratumChunkRequestManagementConfig stratumChunkRequestManagement = StratumRuntime.Config.Performance.ChunkRequestManagement;
int stratumChunkBudget = stratumBudgetEnabled ? Math.Max(1, stratumChunkSending.MaxChunksPerServerTick) : int.MaxValue;
int stratumColumnRequestBudget = stratumGenerationBudgetEnabled ? Math.Max(1, stratumChunkGeneration.MaxColumnRequestsPerServerTick) : int.MaxValue;Those budgets are consumed as each connected client is processed.
Client order is rotated each tick so one client does not permanently go first:
int offset = stratumClientBudgetRotation % count;
stratumClientBudgetRotation = (stratumClientBudgetRotation + 1) % count;
...
clients.Reverse(0, offset);
clients.Reverse(offset, count - offset);
clients.Reverse();Per-client chunk budget and generation budget are clamped when enabled:
num2 = Math.Min(num2, Math.Max(1, stratumChunkSending.MaxChunksPerClientTick));
num2 = Math.Min(num2, Math.Max(0, stratumChunkBudget));
columnRequestBudget = Math.Min(columnRequestBudget, Math.Max(1, stratumChunkGeneration.MaxColumnRequestsPerClientTick));
columnRequestBudget = Math.Min(columnRequestBudget, Math.Max(0, stratumColumnRequestBudget));When the request budget is exhausted and a new column would be needed, the tick records deferred generation.
Chunk candidates can be sorted toward projected movement direction:
double projectedChunkX = (position.X + position.Motion.X * inverseHorizontalSpeed * config.ForwardPredictionBlocks) / MagicNum.ServerChunkSize;
double projectedChunkZ = (position.Z + position.Motion.Z * inverseHorizontalSpeed * config.ForwardPredictionBlocks) / MagicNum.ServerChunkSize;
Array.Sort(octagonPoints, (left, right) => GetStratumProjectedChunkDistance(left, projectedChunkX, projectedChunkZ).CompareTo(GetStratumProjectedChunkDistance(right, projectedChunkX, projectedChunkZ)));This only activates when:
ChunkRequestManagement.EnabledPrioritizeMovingDirectionForwardPredictionBlocks > 0- movement speed is above
MinimumMovementSpeed
Stratum tracks chunk-column requests it enqueues:
stratumTrackedChunkColumnRequests[mapChunkIndex] = new StratumTrackedChunkColumnRequest(chunkX, chunkZ, server.ElapsedMilliseconds);Cleanup runs on an interval and can cancel requests that are old and no longer near any connected player:
if (nowMs - request.RequestedAtMilliseconds < config.MinimumPendingAgeSeconds * 1000L)
{
continue;
}
if (cancelledRequests >= config.MaxCancelledRequestsPerCleanup || IsStratumChunkColumnStillWanted(request, config))
{
continue;
}
if (RemovePendingStratumChunkColumnRequest(mapChunkIndex))
{
cancelledRequests++;
}chunk.pipeline and chunk.serialize timings are recorded, and chunk pipeline counters are sent to StratumPerformanceStats via RecordChunkSendTick(...).
patches/VintagestoryLib/Vintagestory.Server/ServerSystemSendChunks.cs.patch-
sources/VintagestoryLib/Vintagestory/Server/StratumConfig.cs(Performance.ChunkSending,ChunkGeneration,ChunkRequestManagement) wiki/Performance.md