Timers and waiting
Scripts must never block. There is no sleep. A handler that loops for a second freezes the whole server, or the player's game, for that second. Use timers instead.
One-shot and repeating timers
modkit.setTimeout(5000, function()
print("five seconds later")
end)
local id = modkit.setInterval(60000, function()
modkit.world.announce("Remember to read the rules.", "Server")
end)
modkit.clearTimer(id)
Both functions return a timer id. modkit.clearTimer(id) stops either kind.
Resolution
The server checks its timers about every 25 ms. The client checks about every 200 ms. A timer never fires early, but it can fire that much late. modkit.setInterval(0, fn) runs on every check, which is the closest thing to a tick event.
Server scripts only get to run when the game calls into one of the hooked objects.
A wait function with coroutines
If you prefer code that reads from top to bottom, wrap setTimeout in a coroutine. This is plain Lua, the host needs nothing special.
local function wait(ms)
local co = coroutine.running()
modkit.setTimeout(ms, function() coroutine.resume(co) end)
coroutine.yield()
end
local function thread(fn) coroutine.wrap(fn)() end
modkit.events.add("playerSpawned", function(player)
thread(function()
wait(1500)
local fresh = modkit.players.get(player.steamId)
if fresh and fresh.hasDino then fresh:message("You have been alive for 1.5 seconds.") end
end)
end)
Two things to remember.
waitonly works insidethread(...). Calling it from a plain handler raises an error.- A
playertable is a snapshot. After a wait, fetch a fresh one withmodkit.players.get(steamId). The player may have left or respawned in the meantime.
Splitting long work
Work on a few items per timer run instead of all at once.
local queue = modkit.players.list()
local id
id = modkit.setInterval(50, function()
local player = table.remove(queue)
if not player then modkit.clearTimer(id) return end
player:notify("Server restart in five minutes.")
end)
Reference: timers natives.