Docs Quick code
Waiting, timing and tasks
wait, game time, wait_until, and running several things at once with run_async, every and after.
#wait
wait(2) -- pause this code for 2 seconds
wait(0) -- pause until the next frame
self.move(0, 0, 5, 1) -- glide 5 tiles over 1 s, and wait until it arrives
self.move(0, 0, 5, 1, false) -- the same glide, but carry on at once
wait()pauses only this code; the player, other scripts and the world keep going.- It works anywhere — in loops, inside your own functions, deep in a chain of calls — and the code carries on exactly where it was.
- When a Code node finishes, its script goes on to the next node.
- One run at a time: while a script is still running on an object (paused in a
wait(), a glide or a Wait node), pressing E again — or its timer coming round — doesn't start a second copy. - Code stops if its object is removed, and when the player leaves the level.
- Code in a dialogue runs all at once: waits are skipped there.
#Game time
| Function | Gives |
|---|---|
dt() |
Seconds since the last frame (about 0.016 at 60 frames a second). |
time() |
Seconds since the level started (game time — it stops while the game is paused). |
frame() |
How many frames since the level started. |
Use dt() for movement and cooldowns that run at the same speed on every computer:
local speed = 4 -- tiles per second
local cooldown = 0
while true do
cooldown -= dt()
if key_down("Q") and cooldown <= 0 then
self.move(0, 0, -1, 0.2, false)
cooldown = 0.5 -- at most twice a second
end
wait(0)
end
The time of day is separate: hour(), set_hour(h), is_night(), day(); and on-screen
countdowns are start_timer(name, seconds), time_left(name).
#wait_until
wait_until(function() return switch_on("bridge_down") end)
popup("The bridge is down!")
-- With a time limit: gives false if it ran out first.
if not wait_until(function() return self.distance(player) < 2 end, 10) then
popup("You took too long")
end
It checks every frame.
#Running things at the same time
Usually code does one thing after another. A task is code that runs alongside — its own waits don't hold up the rest:
| Function | Does |
|---|---|
run_async(fn, …) |
Starts fn now, alongside this code (extra values go to fn). |
every(seconds, fn) |
Calls fn every few seconds (the first time after seconds). |
after(seconds, fn) |
Calls fn once, seconds from now. |
cancel(task) |
Stops one of these. |
task_running(task) |
true while it hasn't finished or been cancelled. |
Each gives back a task to cancel later.
-- A lamp that blinks while the code below does other things.
local blink = every(0.5, function()
self.hidden = not self.hidden
end)
-- A bomb: tick, tick, boom.
after(3, function()
particles("explosion", 2)
shake(0.3)
self.remove()
end)
-- Two things moving at once.
run_async(function() object("door_left").move(-1, 0, 0, 1) end)
object("door_right").move(1, 0, 0, 1)
wait(5)
cancel(blink)
Tasks belong to the object whose code started them: they stop when it's removed, and all of them stop when the player leaves the level.
#Asking the player
local pick = choice("Buy the sword for 10 coins?", ["Yes", "No"])
if pick == "Yes" and money_count() >= 10 then
take("Coin", 10)
give("Sword")
end
choice(question, options) shows the choices, waits for the pick and gives its text. (In a
dialogue, where code can't wait, use a Choice node instead; there choice() gives "".)