Skip to content
Download

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.

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 = 3
end
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") end
end
  • 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 tables Audio, 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)
  • Sequences with waiting. An action that happens little by little is written in a straight line. wait, waitSteps and waitUntil pause 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, and Save.get("inventario", {}) returns it.
  • Lists of instances. all("Zumbi") returns the list, and each("Zumbi", function(z) ... end) goes through all of them.
  • Code split into files. local jogo = require("src.jogo") loads src/jogo.lua, good for what belongs to the whole game (score, lives).

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.

  • 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 data folder.
  • For C++ projects, the installer needs C++ support. See Installation.