Docs Quick code
Objects
self, player, object() and objects(); moving, turning, easing, following; their fields and their own values.
#Getting hold of one
| Code | What it is |
|---|---|
self |
The object this script is on (nil in a level script). |
player |
The player character. |
object("front_door") |
The object with that Script name in this level (Properties ▸ Object ▸ Script name; capitals don't matter). |
objects("enemy") |
A list of every object whose model has that tag. |
other |
What this object just bumped into, or the player after a touched event; nil otherwise. |
nearest("enemy"), objects_near(self, 5) |
See Finding things. |
spawn("Goblin", x, level, z) |
A new copy of a prefab or model — it gives the new object. |
Call commands with a dot or a colon — self.move(…) and self:move(…) are the same. An object
that isn't there (removed, or object() found nothing) doesn't crash the code: commands on it
do nothing, obj.exists is false, and the Output panel says so once.
#Moving and turning
| Command | Does |
|---|---|
move(dx, dy, dz, seconds = 1, wait = true, ease = "smooth") |
Glide by an offset: dx / dz in tiles, dy in height levels. |
move_to(x, y, z, seconds = 1, wait = true) |
Glide to a tile (x, level, z). |
go_home(seconds = 1, wait = true) |
Glide back to where it was placed. |
teleport(x, y, z) or teleport(vec) |
Jump there at once. Works on player too. |
turn(degrees, seconds = 0.5, wait = true) |
Turn round its middle; + is to the left. |
face(degrees, seconds = 0.3, wait = true) |
Turn to a direction (0 faces -Z, 90 faces -X). |
look_at(target, seconds = 0.3, wait = true) |
Turn to face an object, the player or a position. |
tween(what, to, seconds = 1, ease = "smooth", wait = true) |
Glide one of "x", "y", "z", "position", "turn" or "scale" to a value. |
set_scale(size, seconds = 0) |
Grow or shrink it (1 = normal). |
follow(target, speed = 3, keep = 1.5) |
Keep walking after something, stopping keep tiles away. |
flee(target, speed = 3) |
Keep walking away from it. |
stop() |
Stop following / fleeing / gliding. |
Gliding commands wait until they arrive, unless you pass wait = false — then the code
carries on while it moves. seconds = 0 jumps there at once.
Easing — how a glide speeds up and slows down: "smooth" (the usual), "linear", "in",
"out", "bounce", "elastic", "back".
self.tween("y", self.y + 2, 0.6, "back") -- pops up with a little overshoot
self.move(0, -2, 0, 0.8, true, "bounce") -- drops and bounces
self.set_scale(1.5, 0.3) -- grows over 0.3 s
Followers walk straight at their target and stop at anything solid (they don't walk through
things); for a real route use path_to. Objects with Patrol or
Chase behaviors move themselves — leave those to their behaviors.
#Looks and sounds
| Command | Does |
|---|---|
hide() / show() |
Invisible and walk-through / back again. |
remove() |
Gone for the rest of the game. |
tint(color) |
Colour it: "red", "gold", "#ff8800"; tint("") gives its own colours back. |
say(text, seconds = 2.5) |
A speech bubble over it. |
play(animation, keep = false) |
One of its part animations (Model tab ▸ Timeline). |
particles(effect, size = 1) |
A particle effect on it. |
attach(model, point = "Right hand") / detach(point) |
Show a model on one of its attachment points. |
show_hud() / hide_hud() |
Its Attached HUD (nameplate, health bar…). |
#Health
obj.hp and obj.max_hp read an object's health (objects with the Health behavior, and
player). obj.hurt(n) and obj.heal(n) change it — hurting an object with Health shows the hit
and can defeat it, like an attack. An object without Health can still have its own hp value
(below): hurt takes from that, and obj.hp = 5 sets it.
#Asking about it
| Field / command | Value |
|---|---|
x, y, z |
Where it is, in tiles / levels (fractions mid-glide). Setting one moves it there. |
position |
The same as a vector; set it to move it: self.position = vec(4, 0, 9). |
name |
Its Script name. |
exists |
false if it was removed, or object() found nothing. |
model, tags |
Its model's name, and its model's tags (a list). |
hidden |
true while hidden (set it to hide or show it). |
turn |
Which way it faces, in degrees (set it to turn it at once). |
distance(other) |
Tiles between this and other (an object or player). |
touching(what) |
true if it's touching what: an object, player, or a tag ("enemy", "any"). |
can_move(dx, dy, dz) |
true if that move wouldn't run into anything solid. |
has_tag(tag) |
true if its model has that tag. |
#Their own values
Any object (and the player) can hold its own values — health of a crate, whether a chest was opened, who a villager is angry with:
self.opened = true
self.hits = (self.hits or 0) + 1
object("gate").locked_by = "Mira"
player.coins_found = 3
They last while the game runs and are saved with the game. Each level keeps its objects' values for when the player comes back; the player's own values go with the player.
Starting values can be typed in the editor: select the object, Properties ▸ Values for code, one per line:
hp = 10
loot = ["Coin", "Gem"]
angry = false
Code reads them as self.hp (in the object's own script) or object("name").hp, and can change
them. (The names of the built-in fields above — x, name, model… — are taken.)
#Bumping and touching
Objects don't push each other (gliding objects pass through things), but scripts can notice when they meet, and check before moving:
-- React when something bumps into it: in code…
on("bumped", function(what)
if what.name == "goal" then win() end
end)
-- …or with an Event node "It bumps into something" (Bumps into: player / any / tags);
-- there, `other` is what it bumped into.
-- Check before you move: step along X until something is in the way.
for i = 1, 10 do
if not self.can_move(1, 0, 0) then break end
self.move(1, 0, 0, 0.25)
end
- Boxes count as touching when they meet or overlap; ground tiles never count.
- Removed and hidden objects don't count.
can_moveonly cares about solid objects (not Walk-through or pickups) and the player.