Skip to content

Server loop

Repeated server.lua logic runs through Scheduler:OnTick(), once per simulation tick.

local function Tick()
local agent = Agents:GetLocalAgent()
if agent == nil or agent.Health == nil then
return
end
-- Server logic
end
Scheduler:OnTick(Tick)

Retrieve live objects again. An agent or item cached across rounds may become unavailable.

Keep a target tick for infrequent checks:

local TickDuration = Time:TickToSeconds(1)
local IntervalTicks = math.ceil(0.25 / TickDuration)
local NextUpdateTick = 0
local function Tick()
if Time.Tick < NextUpdateTick then
return
end
NextUpdateTick = Time.Tick + IntervalTicks
-- At most four times per second
end
Scheduler:OnTick(Tick)

math.ceil(seconds / tickDuration) avoids shortening a positive interval by one tick due to conversion precision.

Reflex server execution has a limited budget. Inspect the remainder through CpuLimit:

if CpuLimit.RemainingCpuTime < 0.2 then
return
end

This is an emergency guard, not a substitute for optimization. Reduce expensive scan frequency, return early, avoid identical messages, and do not traverse the same array repeatedly.

OnTick() returns an EventSubscription:

local subscription
subscription = Scheduler:OnTick(function()
if DefusalGame.IsGameEnded then
subscription:Cancel()
return
end
end)

Keep the reference when the loop must stop before reload.

server.lua has no OnFrame, UI, cameras, or client input. Missing-member access can terminate current Lua logic. Do not probe unavailable APIs inside the main loop.

Reference: Scheduler, Time, CpuLimit, and Agent.