-
-
Notifications
You must be signed in to change notification settings - Fork 4
Feature: Event Tick Adaptive Throttle
Tsu edited this page Jun 5, 2026
·
2 revisions
This feature lets Stratum reduce non-critical event listener load during overloaded ticks.
Patched EventManager.TriggerGameTick(...) in:
patches/VintagestoryLib/Vintagestory.Common/EventManager.cs.patch
When the previous tick is overloaded, Stratum can multiply effective intervals for non-critical entity listeners.
bool stratumAdaptiveThrottle = stratumEvtCfg != null
&& stratumEvtCfg.Enabled
&& stratumEvtCfg.AdaptiveThrottleWhenOverloaded
&& stratumEvtCfg.AdaptiveOverloadedMultiplier > 1
&& StratumRuntime.PreviousTickOverloaded;
int stratumAdaptiveMul = stratumAdaptiveThrottle ? Math.Max(1, stratumEvtCfg!.AdaptiveOverloadedMultiplier) : 1;
int stratumAdaptiveCritMs = stratumEvtCfg != null ? Math.Max(0, stratumEvtCfg.AdaptiveCriticalIntervalMs) : 50;int stratumEffectiveInterval = gameTickListener.Millisecondinterval;
if (stratumAdaptiveThrottle && stratumEffectiveInterval > stratumAdaptiveCritMs)
{
stratumEffectiveInterval *= stratumAdaptiveMul;
}So low-interval critical listeners keep normal cadence, while higher-interval listeners can be throttled during overload.
Block listeners are also routed through a gate hook:
if (ShouldTriggerBlockGameTick(gameTickListenerBlock, ellapsedMilliseconds, world))
{
gameTickListenerBlock.OnTriggered(world, gameTickListenerBlock.Pos, ellapsedMilliseconds);
blockListenersTriggered++;
}
else
{
gameTickListenerBlock.LastUpdateMilliseconds = ellapsedMilliseconds;
blockListenersSkipped++;
}With extension points:
protected virtual bool ShouldTriggerBlockGameTick(GameTickListenerBlock listener, long ellapsedMilliseconds, IWorldAccessor world)
{
return true;
}
protected virtual void RecordBlockGameTickListeners(int ready, int triggered, int skipped)
{
}If event subsection timings are enabled, Stratum records timing buckets like:
eventTick.gtEntityeventTick.gtBlockeventTick.dcEntityeventTick.dcBlock
It can also record slow listener timings with configurable thresholds.
The patch also avoids per-tick key list allocation for single delayed block callbacks by reusing:
private List<BlockPos> singleDelayedCallbackBlockKeys = new List<BlockPos>();patches/VintagestoryLib/Vintagestory.Common/EventManager.cs.patchVintagestoryLib/Vintagestory.Common/EventManager.cs-
sources/VintagestoryLib/Vintagestory.Server/StratumConfig.cs(Performance.EventTick)