Cyber

  • Template: cart_cyber - press "Use this template" and you have a working game.
  • Docker image: ghcr.io/notnullgames/null0-cart-cyber:latest
  • Your code: cart/main.cy, interpreted by cyber, baked into main.wasm
  • Bindings: carts/cyber/null0.cy (editor definitions - the runtime provides the API itself)
  • WASI is available, so ordinary file and stdio calls work.
  • See carts made with Cyber
  • API docs for Cyber

building

You do not install cyber, 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-cyber:latest mygame

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

Cyber notes

  • use null0, then null0.clear(null0.BLUE).
  • The VM is re-entered per callback via persist_main, so top-level state persists across frames.

a cart, in Cyber

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

use null0

fn load():
    null0.clear(null0.BLUE)
    null0.draw_circle(100, 100, 50, null0.RED)
    null0.draw_text(null0.FONT_DEFAULT, 'hello from Cyber', 170, 92, null0.WHITE)

-- callbacks (optional - implement as needed)
--
--   fn update():
--       pass
carts/cyber/simple/main.cy

callbacks

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

func update():

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