💠Onyx is a small language built for WebAssembly from the start, so a cart is about as simple as it gets.
- Template: cart_onyx - press "Use this template" and you have a working game.
- Docker image:
ghcr.io/notnullgames/null0-cart-onyx:latest - Your code:
cart/main.onyx, compiled with onyx - Bindings:
carts/onyx/null0.onyx(baked into the docker image for you) - WASI is available, so ordinary file and stdio calls work.
- See carts made with Onyx
- API docs for Onyx
building
You do not install onyx - 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-onyx:latest mygameThe template wraps that in npm start, which also serves the result and rebuilds when you save.
Onyx notes
#load "null0.onyx", and keep an emptymainaround.- Text takes a
u32pointer, not astr- onyx cannot alias a foreign import name, so wrap literals withcstr("...")from the bindings.
a cart, in Onyx
This is carts/onyx/simple/main.onyx in the engine repo - the same file CI builds into the cart below, so it always compiles.
#load "null0.onyx"
// onyx needs a main, even though null0 never calls it
main :: () {}
load :: () {
clear(BLUE);
draw_circle(100, 100, 50, RED);
// a string crosses as a pointer to null-terminated utf8; cstr() from the
// bindings does that conversion
draw_text(FONT_DEFAULT, cstr("hello from Onyx"), 170, 92, WHITE);
}
#export "load" load
// callbacks (optional - implement as needed)
//
// update :: () {}
// #export "update" update
carts/onyx/simple/main.onyxThis toolchain needs an entry point to exist even though null0 never uses it for gameplay. Leave it empty: main :: () {}
callbacks
A cart implements the callbacks it cares about. In Onyx they look like this:
#export "load" loadSee anatomy of a cart for the full list and what each one is passed.