Games in Lua
When you create a project, you choose the language of the game: Lua or C++. In Lua, Play opens the game right away, with no compiling and nothing else to install. It is the recommended way to start.
What a script looks like
Section titled “What a script looks like”Each object has a script next to it: the object Jogador uses objects/Jogador.lua. The script defines the object’s events as functions that receive the instance, self:
function onSpawn(self) self.vidas = 3end
function onUpdate(self) self.hspeed = axis("esquerda", "direita") * self.velocidade if pressed("pular") and self:onGround() then self.vspeed = -4 end if held("atirar") then spawn("Bala", self.x, self.y, "Instancias") endend- What belongs to the instance uses
self: the fields (self.x,self.hspeed,self.sprite) and the methods (self:destroy(),self:onCollide(...),self:moveAndStop()). - Everything else is a plain function:
spawn,count,held,pressed,axis,drawText,goTo,random, and the tablesAudio,Save,Ui,camera. - You can keep whatever you want in
self(self.vidas = 3): each instance has its own. - The variables created in the Inspector arrive as fields of
self(self.velocidade), already with each instance’s value. - A function of the script is called by other objects with a colon:
inimigo:levarDano(1).
The names are the same as in the API reference, which shows the examples in C++. To turn them into Lua:
| In C++ | In Lua |
|---|---|
hspeed = 2; |
self.hspeed = 2 |
destroy(); |
self:destroy() |
spawn<Bala>(x, y, "Instancias"); |
spawn("Bala", self.x, self.y, "Instancias") |
onCollide<Inimigo>([this](Inimigo& outro) { ... }); |
self:onCollide("Inimigo", function(outro) ... end) |
after(60, [this] { ... }); |
self:after(60, function() ... end) |
count<Moeda>() |
count("Moeda") |
Audio::play("tiro", {.volume = 0.4f}); |
Audio.play("tiro", { volume = 0.4 }) |
Ui::get("Hud")["Vida"].setValue(0.5f); |
Ui.get("Hud")["Vida"]:setValue(0.5) |
scene().camera.shake(3, 0.2f); |
camera.shake(3, 0.2) |
Save::set("recorde", pontos); |
Save.set("recorde", pontos) |
Only in Lua
Section titled “Only in Lua”- Sequences with waiting. An action that happens little by little is written in a straight line.
wait,waitStepsandwaitUntilpause only the sequence; the game keeps running:
self:run(function() wait(2) -- 2 segundos spawn("Chefe", 160, 40, "Instancias") waitUntil(function() return not any("Chefe") end) -- até o chefe morrer fadeTo("Vitoria")end)- Tables in Save.
Save.set("inventario", { "espada", "escudo" })stores a whole table, andSave.get("inventario", {})returns it. - Lists of instances.
all("Zumbi")returns the list, andeach("Zumbi", function(z) ... end)goes through all of them. - Code split into files.
local jogo = require("src.jogo")loadssrc/jogo.lua, good for what belongs to the whole game (score, lives).
Writing the code
Section titled “Writing the code”Abrir código (open code, in the object’s Inspector) opens the script in a tab of the editor itself, with colors and autocomplete: when you type self., self: or Audio. a list of what exists shows up, with how to use it beside. Tab or Enter accept the suggestion. Play saves what is open before running.
An error in the script shows in the Saída (Output) with the file and the line; clicking it takes you there. The game doesn’t close: the rest keeps running.
What to know before choosing
Section titled “What to know before choosing”- A project is in Lua or in C++: the two don’t mix.
- Lua is slower than C++ in the script’s own calculations. In an ordinary game this doesn’t show: a thousand objects with scripts take about 5% of a frame’s time. Only with several thousand at once does it start to weigh.
- An exported Lua game carries its scripts, readable, in the
datafolder. - For C++ projects, the installer needs C++ support. See Installation.
