Skip to main content

Threads

Runs code over time without freezing the game.

Create starts a function right away.
Wait pauses only that function; the game keeps running. When the time is up, the function continues where it left off.

Have a quick look at threads api before reading what's below.

See example
_thread.Create(function()
print("thread: start") -- 1st print
_thread.Wait(1000) -- pause THIS function for ~1 second
print("thread: ~1 second later") -- 3rd print
end)
print("main: keeps going without waiting") -- 2nd print
Why pass arguments to Create

If the loop is over before the thread wakes, every thread sees the final value.
So in case you wanna cache a value, you can pass it to the thread.

local current = 0
for i = 1, 3 do
current = i
_thread.Create(function(n)
_thread.Wait(n * 200)
print("with args:", n) -- 1, 2, 3
end, current)
end

local current = 0
for i = 1, 3 do
current = i
_thread.Create(function()
_thread.Wait(current * 200)
print("shared local:", current) -- 3, 3, 3
end)
end

A thread that returns or errors stops by itself. The error is printed to the log; the game and other threads continue.

Timing​

  • First thread tick (for Wait) is right before OnLoad is called
  • Threads wake once per frame, so a wait ends on a frame boundary, up to 1 frame late (~16ms@60fps, ~100ms@10fps). That is normal jitter.
  • Loops do not accumulate the lateness: 30 x Wait(1000) takes ~30s plus at most 1 frame.
  • Wait(100) waits 100 milliseconds of real time, plus up to 1 extra tick: At 60fps that is somewhere between 100ms and 116.7ms.
  • Wait(0) means next tick. So does anything shorter than one tick: at 60fps, everything below ~16.7ms (Wait(1), Wait(10), Wait(16)) wakes after ~16.7ms.
  • Threads due on the same frame wake in no guaranteed order.

Rules​

Wait only works on a Create thread: not in the main script body, and not inside metamethods (both error). pcall/xpcall are fine.

The game hangs without Wait

A loop that never ends needs a Wait inside it. Without one, the thread never gives control back and the whole game freezes.

See example
_thread.Create(function()
while true do
doSomething()
-- _thread.Wait(1000) -- commented out: doSomething runs forever,
-- the thread never yields, the game freezes
end
end)

Game Clock​

local GameTime, FrameCount = _thread.Now()

GameTime since the engine started. Only differences mean anything (t1 - t0 = elapsed time).

_thread.Create(function()
local t0 = _thread.Now()
_thread.Wait(5000)
print("waited", _thread.Now() - t0) -- 5.0
end)
Wrong clocks

Do not time with os.clock() (counts CPU time, not wall time) or os.time()