Docs Quick code
Functions
Writing functions, return values, closures, functions as values, and methods on tables.
#Writing one
function heal_party(amount)
heal(amount)
popup("Healed " .. amount)
end
heal_party(20)
- Functions written at the top of the code (not inside anything) can be called from anywhere in that code — even above where they're written — and from the script's other Code nodes: write helpers once per script.
- Missing values are
nil; extra ones are dropped (Check warns when you pass too many). - A function can call itself (recursion). Calls more than 200 deep are stopped — usually a function calling itself forever.
#return
function damage_for(level)
if level <= 1 then return 5 end
return 5 + level * 3
end
local d = damage_for(4) -- 17
A function gives back one value (nil without a return). For several, return a list or a
table, and take it apart again:
function min_max(list)
local lo, hi = list[0], list[0]
for v in list do
lo = min(lo, v)
hi = max(hi, v)
end
return [lo, hi]
end
local lo, hi = min_max([4, 9, 1]) -- 1, 9 (several names from a list take its items)
return on its own leaves the function (or the whole Code node, at the top) early.
#Functions can wait
A function can wait(), glide objects, or ask the player a choice() — the code pauses inside
it and carries on later exactly where it was:
function flash(obj, times)
for i = 1, times do
obj.hide()
wait(0.2)
obj.show()
wait(0.2)
end
end
flash(object("beacon"), 3)
popup("Done flashing")
The one exception: functions the language calls for you — the compare function of sort,
and the ones given to map, filter and pcall — run all at once (a wait inside them is
skipped).
#Local functions
local function square(x) return x * x end -- only this code sees it
A local function can call itself, and is the way to keep a helper private to one Code node.
#Functions are values
A function can be put in a variable, a list or a table, passed to another function and returned from one:
local say = popup -- a game function as a value
say("Hi")
local double = function(x) return x * 2 end
local squares = [1, 2, 3]:map(function(x) return x * x end) -- [1, 4, 9]
every(2, function() popup("Two seconds passed") end) -- see Waiting and tasks
#Closures
A function made inside another keeps the locals it was made with — each copy its own:
function make_counter()
local n = 0
return function()
n += 1
return n
end
end
local next_id = make_counter()
next_id() -- 1
next_id() -- 2
This is how timers, handlers and tasks keep their own state:
for i = 1, 3 do
local lamp = object("lamp" .. i)
after(i * 0.5, function() lamp.show() end) -- each one remembers its own lamp
end
#Methods: functions in tables
local enemy = {hp = 10}
function enemy.hit(self, n) -- a function stored in the table
self.hp -= n
end
function enemy:heal(n) -- the colon adds a hidden first parameter, self
self.hp += n
end
enemy:hit(4) -- the colon passes the table itself as self
enemy.hit(enemy, 1) -- the same, written out
enemy:heal(2) -- hp is now 7
Objects work the same way: self.move(…) and self:move(…) are the same thing.
#Catching errors
local ok, result = pcall(function()
return risky_thing()
end)
if not ok then
print("That didn't work: " .. result)
end
pcall(fn, …) runs fn and gives [true, its result], or [false, the error message] instead
of stopping the code. error("message") stops with your own message; assert(condition, "message") stops when the condition is false.