🐹Go carts are built with tinygo, and the API is CamelCase to match the language. You get goroutines, slices and maps in a cart under a megabyte.
- Template: cart_go - press "Use this template" and you have a working game.
- Docker image:
ghcr.io/notnullgames/null0-cart-go:latest - Your code:
cart/main.go, compiled with tinygo - Bindings:
carts/go/null0/null0.go(baked into the docker image for you) - WASI is available, so ordinary file and stdio calls work.
- See carts made with Go
- API docs for Go
building
You do not install tinygo - 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-go:latest mygameThe template wraps that in npm start, which also serves the result and rebuilds when you save.
Go notes
- The API is
CamelCasehere, wrapping the raw//go:wasmimportdeclarations. - There is no working directory -
os.ReadFile("/main.lua")works,os.ReadFile("main.lua")does not.
a cart, in Go
This is carts/go/simple/main.go in the engine repo - the same file CI builds into the cart below, so it always compiles.
package main
import null0 "null0"
//export load
func load() {
null0.Clear(null0.BLUE)
null0.DrawCircle(100, 100, 50, null0.RED)
null0.DrawText(null0.FONT_DEFAULT, "hello from Go", 170, 92, null0.WHITE)
}
// tinygo needs a main, even though null0 never calls it
func main() {}
// callbacks (optional - implement as needed)
//
// //export update
// func update() {}
carts/go/simple/main.goThis toolchain needs an entry point to exist even though null0 never uses it for gameplay. Leave it empty: func main() {}
callbacks
A cart implements the callbacks it cares about. In Go they look like this:
//export load
func load() {}See anatomy of a cart for the full list and what each one is passed.