C3

  • Template: cart_c3 - press "Use this template" and you have a working game.
  • Docker image: ghcr.io/notnullgames/null0-cart-c3:latest (linux/amd64 only - runs emulated on Apple Silicon)
  • Your code: cart/main.c3, compiled with c3c
  • Bindings: carts/c3/null0.c3 (baked into the docker image for you)
  • WASI is available, so ordinary file and stdio calls work.
  • See carts made with C3
  • API docs for C3

building

You do not install c3c - 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) --platform linux/amd64 \
  -v ./cart:/src -v ./webroot:/out \
  ghcr.io/notnullgames/null0-cart-c3:latest mygame

The template wraps that in npm start, which also serves the result and rebuilds when you save.

C3 notes

  • module main plus import null0.

a cart, in C3

This is carts/c3/simple/main.c3 in the engine repo - the same file CI builds into the cart below, so it always compiles.

module main;
import null0;

fn void load() @export("load") {
    null0::clear(null0::BLUE);
    null0::draw_circle(100, 100, 50, null0::RED);
    null0::draw_text(null0::FONT_DEFAULT, "hello from C3", 170, 92, null0::WHITE);
}

// callbacks (optional - implement as needed)
//
//   fn void update() @export("update") {}
carts/c3/simple/main.c3

callbacks

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

fn void load() @export("load") {}

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