🌙Lua is the classic game-scripting language, and null0 uses GopherLua so it works inside the host’s interpreter. Plain globals, tables for structs, require for extra files.
- Template: cart_lua - press "Use this template" and you have a working game.
- Docker image:
ghcr.io/notnullgames/null0-cart-lua:latest - Your code:
cart/main.lua, interpreted by GopherLua, baked into main.wasm - Bindings:
carts/lua/null0.lua(editor definitions - the runtime provides the API itself) - WASI is available, so ordinary file and stdio calls work.
- See carts made with Lua
- API docs for Lua
building
You do not install GopherLua, baked into main.wasm - the docker image has it, and the current null0 bindings, baked in. There is nothing in your project to keep in sync with the engine.
docker run --rm --user $(id -u):$(id -g) \
-v ./cart:/src -v ./webroot:/out \
ghcr.io/notnullgames/null0-cart-lua:latest mygameThe template wraps that in npm start, which also serves the result and rebuilds when you save.
Lua notes
- The API is plain globals, structs are tables, and
requireworks for extra cart files. - GopherLua, not C Lua - the host interpreter has no exception-handling, which C Lua needs.
null0.luais LuaLS definitions for your editor; it is not shipped inside the cart.
a cart, in Lua
This is carts/lua/simple/main.lua in the engine repo - the same file CI builds into the cart below, so it always compiles.
-- the null0 API is available as plain globals - no require() needed. -- null0.lua (in carts/lua) has LuaLS definitions for editor completion. function load() clear(BLUE) draw_circle(100, 100, 50, RED) draw_text(FONT_DEFAULT, 'hello from Lua', 170, 92, WHITE) end -- other callbacks you can implement: -- -- function update() end -- function unload() end -- function buttonDown(button, player) endcarts/lua/simple/main.lua
callbacks
A cart implements the callbacks it cares about. In Lua they look like this:
function update() endSee anatomy of a cart for the full list and what each one is passed.