Docs Quick code
Examples
Ready-to-use recipes — doors and keys, enemies, bosses, waves, shops, timers, elevators, lasers, loot tables and more.
Each recipe says where the code goes. "On the object's script" means: make a script (Scripts tab), drop it on the object, start it with the Event named, and put the code in a Code node.
#A door that needs a key
On the door's script, Event: Player presses E.
if has("* key") > 0 then
take("Gold key")
play("door")
self.move(0, 3, 0, 1) -- slide up out of the way
self.opened = true
else
self.say("It's locked.")
end
#A pressure plate that opens a gate
On the plate's script, Event: Player enters the level.
on("touched", function()
if not self.pressed then
self.pressed = true
self.tween("y", self.y - 0.1, 0.2)
object("gate").move(0, 3, 0, 1.5)
end
end)
#A coin counter on screen
A level script, Event: Player enters the level.
hud_text("coins", "Coins: {Coin}", "top_right") -- {Coin} shows how many the player has
#A guard that chases you when it sees you
On the guard's script, Event: Player enters the level.
local alert = false
while self.exists do
local sees = self.distance(player) < 8 and line_of_sight(self, player)
if sees and not alert then
alert = true
self.say("Halt!")
self.follow(player, 3.5, 1.2)
elseif not sees and alert then
alert = false
self.stop()
self.go_home(2, false)
end
if alert and self.distance(player) < 1.5 then
hurt(2)
wait(0.8) -- a hit at most every 0.8 s
end
wait(0.1)
end
#A boss with phases
On the boss's script (it has Health), Event: Player enters the level.
local phase = 1
show_hud("Boss bar")
on("hurt", function()
hud_bar("Boss", self.hp, self.max_hp, "top_center")
if phase == 1 and self.hp < self.max_hp / 2 then
phase = 2
send("boss_phase", {phase = 2})
self.tint("red")
self.say("Now I'm angry!")
end
end)
on("destroyed", function()
banner("Victory!")
hud_clear("Boss")
set_switch("boss_beaten")
end)
-- Attack pattern: phase 2 attacks twice as often.
while self.exists do
wait(phase == 1 and 3 or 1.5)
if self.exists then
self.play("attack")
if self.distance(player) < 3 then hurt(10) end
end
end
The arena's level script:
on_message("boss_phase", function(d)
shake(0.25, 0.6)
object("arena_bars").hide()
music_fade("boss_fast", 1)
end)
#Waves of enemies
A level script, Event: Player enters the level.
local waves = [
{enemy = "Slime", count = 4, gap = 1.0},
{enemy = "Goblin", count = 3, gap = 1.5},
{enemy = "Troll", count = 1, gap = 0},
]
for i, w in waves do
banner("Wave " .. (i + 1))
for n = 1, w.count do
spawn(w.enemy, 8, 0, 8)
wait(w.gap)
end
wait_until(function() return #objects("enemy") == 0 end)
end
banner("All waves cleared!")
win()
#A shop with a question
On the shopkeeper's script, Event: Player presses E.
local pick = choice("What will it be?", ["Potion (5)", "Sword (20)", "Nothing"])
local prices = {["Potion (5)"] = 5, ["Sword (20)"] = 20}
local items = {["Potion (5)"] = "Potion", ["Sword (20)"] = "Sword"}
if prices[pick] ~= nil then
if money_count() >= prices[pick] then
take("Coin", prices[pick])
give(items[pick])
self.say("Pleasure doing business!")
else
self.say("Come back with more coins.")
end
end
#A countdown
A level script, Event: Player enters the level.
start_timer("escape", 60, "lose") -- 60 seconds, then the player loses
wait_until(function() return in_zone("Exit") end)
stop_timer("escape")
banner("Escaped with " .. round(time_left("escape")) .. " s to spare!")
win()
#A bouncy elevator
On the platform's script, Event: Every few seconds (6 s).
self.tween("y", 3, 2, "smooth")
wait(1.5)
self.tween("y", 0, 1.2, "bounce")
#A laser that hurts what it hits
On the turret's script, Event: Every few seconds (1 s).
local dir = vec(0, 0, -1) -- the way it faces
local hit = raycast(self, dir, 15)
if hit ~= nil then
particles("sparks")
if hit.object ~= nil and hit.object.has_tag("enemy") then
hit.object.hurt(5)
elseif hit.object ~= nil and hit.object.name == "player" then
hurt(5)
end
end
#Random loot from a data table
A Data table "Loot" with columns name, weight: Coin 70, Gem 25, Crown 5.
On a chest's script, Event: Player presses E.
if self.opened then
self.say("Empty.")
return
end
local total = 0
for name, row in data("Loot") do total += row.weight end
local roll = random(0, total)
for name, row in data("Loot") do
roll -= row.weight
if roll <= 0 then
give(name)
popup("You found: " .. name)
break
end
end
self.opened = true
self.play("open")
#Lamps that light up at night
A level script, Event: Player enters the level.
every(5, function()
for lamp in objects("lamp") do
lamp.hidden = not is_night()
end
end)
#A helper library
A script named "Utils" (not on any object):
function count_tagged(tag)
return #objects(tag)
end
function say_all(tag, text)
for o in objects(tag) do o.say(text) end
end
Anywhere else:
local u = require("Utils")
if u.count_tagged("villager") > 3 then
u.say_all("villager", "What a crowd!")
end
#Debugging an enemy
while self.exists do
watch(self.name .. " hp", self.hp)
watch(self.name .. " state", self.mood or "calm")
if self.hp ~= nil and self.hp < 0 then breakpoint() end
wait(0.2)
end