Lua

  • 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 mygame

The 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 require works for extra cart files.
  • GopherLua, not C Lua - the host interpreter has no exception-handling, which C Lua needs.
  • null0.lua is 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) end
carts/lua/simple/main.lua

callbacks

A cart implements the callbacks it cares about. In Lua they look like this:

function update() end

See anatomy of a cart for the full list and what each one is passed.