JavaScript

  • Template: cart_js - press "Use this template" and you have a working game.
  • Docker image: ghcr.io/notnullgames/null0-cart-quickjs:latest
  • Your code: cart/main.js, interpreted by QuickJS, baked into main.wasm
  • Bindings: carts/js/null0.d.ts (editor definitions - the runtime provides the API itself)
  • WASI is available, so ordinary file and stdio calls work.

building

You do not install QuickJS, baked into main.wasm - the docker image has it, and the current null0 bindings, baked in. That is the whole point: 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-quickjs:latest mygame

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

JavaScript notes

  • The API is plain globals - nothing to import. Callbacks are ESM exports of main.js.
  • Structs are plain objects ({ r: 0, g: 121, b: 241, a: 255 }); array args know their own length, so you never pass the count.
  • std and os from QuickJS are available as globals, as is WASI.
  • Drop null0.d.ts + jsconfig.json next to main.js for editor completion and typechecking.

a cart, in JavaScript

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

export function load() {
  clear(BLUE)
  draw_circle(100, 100, 50, RED)
}

// callbacks (optional - implement as needed)

// export function update() {}
// export function unload() {}
// export function buttonUp(button, player) {}
// export function buttonDown(button, player) {}
// export function keyUp(key) {}
// export function keyDown(key) {}
// export function mouseDown(button) {}
// export function mouseUp(button) {}
// export function mouseMoved(x, y) {}
carts/js/simple/main.js

callbacks

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

export function update () {}

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

more JavaScript carts

the API, in JavaScript

Every null0 function, spelled the way JavaScript spells it. These are read out of the generated bindings themselves, so they match what your editor completes.

colors (7)

Tint a color with another color.

function color_tint(color: Color, tint: Color): Color

Fade a color.

function color_fade(color: Color, alpha: number): Color

Change the brightness of a color.

function color_brightness(color: Color, factor: number): Color

Invert a color.

function color_invert(color: Color): Color

Blend 2 colors together.

function color_alpha_blend(dst: Color, src: Color): Color

Change contrast of a color.

function color_contrast(color: Color, contrast: number): Color

Interpolate colors.

function color_bilinear_interpolate(color00: Color, color01: Color, color10: Color, color11: Color, coordinateX: number, coordinateY: number): Color
graphics (75)

Create a new blank image.

function new_image(width: number, height: number, color: Color): Image

Copy an image to a new image.

function image_copy(image: Image): Image

Create an image from a region of another image.

function image_subimage(image: Image, x: number, y: number, width: number, height: number): Image

Clear the screen.

function clear(color: Color): void

Draw a single pixel on the screen.

function draw_point(x: number, y: number, color: Color): void

Draw a line on the screen.

function draw_line(startPosX: number, startPosY: number, endPosX: number, endPosY: number, color: Color): void

Draw a filled rectangle on the screen.

function draw_rectangle(posX: number, posY: number, width: number, height: number, color: Color): void

Draw a filled triangle on the screen.

function draw_triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, color: Color): void

Draw a filled ellipse on the screen.

function draw_ellipse(centerX: number, centerY: number, radiusX: number, radiusY: number, color: Color): void

Draw a filled circle on the screen.

function draw_circle(centerX: number, centerY: number, radius: number, color: Color): void

Draw a filled polygon on the screen.

function draw_polygon(points: Vector[], color: Color): void

Draw a filled arc on the screen.

function draw_arc(centerX: number, centerY: number, radius: number, startAngle: number, endAngle: number, segments: number, color: Color): void

Draw a filled round-rectangle on the screen.

function draw_rectangle_rounded(x: number, y: number, width: number, height: number, cornerRadius: number, color: Color): void

Draw an image on the screen.

function draw_image(src: Image, posX: number, posY: number): void

Draw a tinted image on the screen.

function draw_image_tint(src: Image, posX: number, posY: number, tint: Color): void

Draw an image, rotated, on the screen.

function draw_image_rotated(src: Image, posX: number, posY: number, degrees: number, offsetX: number, offsetY: number, filter: ImageFilter): void

Draw an image, flipped, on the screen.

function draw_image_flipped(src: Image, posX: number, posY: number, flipHorizontal: boolean, flipVertical: boolean, flipDiagonal: boolean): void

Draw an image, scaled, on the screen.

function draw_image_scaled(src: Image, posX: number, posY: number, scaleX: number, scaleY: number, offsetX: number, offsetY: number, filter: ImageFilter): void

Draw some text on the screen.

function draw_text(font: Font, text: string, posX: number, posY: number, color: Color): void

Save an image to persistant storage.

function save_image(image: Image, filename: string): void

Load an image from a file in cart.

function load_image(filename: string): Image

Resize an image, return copy.

function image_resize(image: Image, newWidth: number, newHeight: number, filter: ImageFilter): Image

Scale an image, return copy.

function image_scale(image: Image, scaleX: number, scaleY: number, filter: ImageFilter): Image

Replace a color in an image, in-place.

function image_color_replace(image: Image, color: Color, replace: Color): void

Tint a color in an image, in-place.

function image_color_tint(image: Image, color: Color): void

Fade a color in an image, in-place.

function image_color_fade(image: Image, alpha: number): void

Copy a font to a new font.

function font_copy(font: Font): Font

Scale a font, return a new font.

function font_scale(font: Font, scaleX: number, scaleY: number, filter: ImageFilter): Font

Load a BMF font from a file in cart.

function load_font_bmf(filename: string, characters: string): Font

Load a BMF font from an image.

function load_font_bmf_from_image(image: Image, characters: string): Font

Measure the size of some text.

function measure_text(font: Font, text: string, textLength: number): Dimensions

Meaure an image (use 0 for screen).

function measure_image(image: Image): Dimensions

Load a TTY font from a file in cart.

function load_font_tty(filename: string, glyphWidth: number, glyphHeight: number, characters: string): Font

Load a TTY font from an image.

function load_font_tty_from_image(image: Image, glyphWidth: number, glyphHeight: number, characters: string): Font

Load a TTF font from a file in cart.

function load_font_ttf(filename: string, fontSize: number): Font

Invert the colors in an image, in-place.

function image_color_invert(image: Image): void

Calculate a rectangle representing the available alpha border in an image.

function image_alpha_border(image: Image, threshold: number): Rectangle

Crop an image, in-place.

function image_crop(image: Image, x: number, y: number, width: number, height: number): void

Crop an image based on the alpha border, in-place.

function image_alpha_crop(image: Image, threshold: number): void

Adjust the brightness of an image, in-place.

function image_color_brightness(image: Image, factor: number): void

Flip an image, in-place.

function image_flip(image: Image, horizontal: boolean, vertical: boolean): void

Change the contrast of an image, in-place.

function image_color_contrast(image: Image, contrast: number): void

Use an image as an alpha-mask on another image.

function image_alpha_mask(image: Image, alphaMask: Image, posX: number, posY: number): void

Create a new image, rotating another image.

function image_rotate(image: Image, degrees: number, filter: ImageFilter): Image

Create a new image of a gradient.

function image_gradient(width: number, height: number, topLeft: Color, topRight: Color, bottomLeft: Color, bottomRight: Color): Image

Unload an image.

function unload_image(image: Image): void

Unload a font.

function unload_font(font: Font): void

Clear an image.

function clear_image(destination: Image, color: Color): void

Draw a single pixel on an image.

function draw_point_on_image(destination: Image, x: number, y: number, color: Color): void

Draw a line on an image.

function draw_line_on_image(destination: Image, startPosX: number, startPosY: number, endPosX: number, endPosY: number, color: Color): void

Draw a filled rectangle on an image.

function draw_rectangle_on_image(destination: Image, posX: number, posY: number, width: number, height: number, color: Color): void

Draw a filled triangle on an image.

function draw_triangle_on_image(destination: Image, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, color: Color): void

Draw a filled ellipse on an image.

function draw_ellipse_on_image(destination: Image, centerX: number, centerY: number, radiusX: number, radiusY: number, color: Color): void

Draw a circle on an image.

function draw_circle_on_image(destination: Image, centerX: number, centerY: number, radius: number, color: Color): void

Draw a filled polygon on an image.

function draw_polygon_on_image(destination: Image, points: Vector[], color: Color): void

Draw a filled round-rectangle on an image.

function draw_rectangle_rounded_on_image(destination: Image, x: number, y: number, width: number, height: number, cornerRadius: number, color: Color): void

Draw an image on an image.

function draw_image_on_image(destination: Image, src: Image, posX: number, posY: number): void

Draw a tinted image on an image.

function draw_image_tint_on_image(destination: Image, src: Image, posX: number, posY: number, tint: Color): void

Draw an image, rotated, on an image.

function draw_image_rotated_on_image(destination: Image, src: Image, posX: number, posY: number, degrees: number, offsetX: number, offsetY: number, filter: ImageFilter): void

Draw an image, flipped, on an image.

function draw_image_flipped_on_image(destination: Image, src: Image, posX: number, posY: number, flipHorizontal: boolean, flipVertical: boolean, flipDiagonal: boolean): void

Draw an image, scaled, on an image.

function draw_image_scaled_on_image(destination: Image, src: Image, posX: number, posY: number, scaleX: number, scaleY: number, offsetX: number, offsetY: number, filter: ImageFilter): void

Draw some text on an image.

function draw_text_on_image(destination: Image, font: Font, text: string, posX: number, posY: number, color: Color): void

Draw a outlined (with thickness) rectangle on the screen.

function draw_rectangle_outline(posX: number, posY: number, width: number, height: number, thickness: number, color: Color): void

Draw a outlined (with thickness) triangle on the screen.

function draw_triangle_outline(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, thickness: number, color: Color): void

Draw a outlined (with thickness) ellipse on the screen.

function draw_ellipse_outline(centerX: number, centerY: number, radiusX: number, radiusY: number, thickness: number, color: Color): void

Draw a outlined (with thickness) circle on the screen.

function draw_circle_outline(centerX: number, centerY: number, radius: number, thickness: number, color: Color): void

Draw a outlined (with thickness) polygon on the screen.

function draw_polygon_outline(points: Vector[], thickness: number, color: Color): void

Draw a outlined (with thickness) arc on the screen.

function draw_arc_outline(centerX: number, centerY: number, radius: number, startAngle: number, endAngle: number, segments: number, thickness: number, color: Color): void

Draw a outlined (with thickness) round-rectangle on the screen.

function draw_rectangle_rounded_outline(x: number, y: number, width: number, height: number, cornerRadius: number, thickness: number, color: Color): void

Draw a outlined (with thickness) rectangle on an image.

function draw_rectangle_outline_on_image(destination: Image, posX: number, posY: number, width: number, height: number, thickness: number, color: Color): void

Draw a outlined (with thickness) triangle on an image.

function draw_triangle_outline_on_image(destination: Image, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, thickness: number, color: Color): void

Draw a outlined (with thickness) ellipse on an image.

function draw_ellipse_outline_on_image(destination: Image, centerX: number, centerY: number, radiusX: number, radiusY: number, thickness: number, color: Color): void

Draw a outlined (with thickness) circle on an image.

function draw_circle_outline_on_image(destination: Image, centerX: number, centerY: number, radius: number, thickness: number, color: Color): void

Draw a outlined (with thickness) polygon on an image.

function draw_polygon_outline_on_image(destination: Image, points: Vector[], thickness: number, color: Color): void

Draw a outlined (with thickness) round-rectangle on an image.

function draw_rectangle_rounded_outline_on_image(destination: Image, x: number, y: number, width: number, height: number, cornerRadius: number, thickness: number, color: Color): void
gui (10)

Begin a GUI window. Returns false if the window is collapsed or closed - skip its contents, but still call gui_end_window.

function gui_begin_window(title: string, rect: Rectangle): boolean

End the current GUI window.

function gui_end_window(): void

A button. Returns true when it is clicked.

function gui_button(label: string): boolean

A static text label.

function gui_label(text: string): void

A block of wrapping text.

function gui_text(text: string): void

A checkbox. Returns the (possibly changed) state.

function gui_checkbox(label: string, state: boolean): boolean

A slider. Returns the (possibly changed) value.

function gui_slider(value: number, low: number, high: number): number

Set the current layout row - the column widths (negative for flexible), and the row height.

function gui_layout_row(widths: number[], height: number): void

Finish building the GUI for this frame. Called automatically at the end of update if you do not call it.

function gui_end(): void

Draw the GUI to an image (0 is the screen).

function gui_draw(dst: Image): void
input (12)

Has the key been pressed? (tracks unpress/read correctly.)

function key_pressed(key: Key): boolean

Is the key currently down?

function key_down(key: Key): boolean

Has the key been released? (tracks press/read correctly.)

function key_released(key: Key): boolean

Is the key currently up?

function key_up(key: Key): boolean

Has the button been pressed? (tracks unpress/read correctly.)

function gamepad_button_pressed(gamepad: number, button: GamepadButton): boolean

Is the button currently down?

function gamepad_button_down(gamepad: number, button: GamepadButton): boolean

Has the button been released? (tracks press/read correctly.)

function gamepad_button_released(gamepad: number, button: GamepadButton): boolean

Get current position of mouse.

function mouse_position(): Vector

Has the button been pressed? (tracks unpress/read correctly.)

function mouse_button_pressed(button: MouseButton): boolean

Is the button currently down?

function mouse_button_down(button: MouseButton): boolean

Has the button been released? (tracks press/read correctly.)

function mouse_button_released(button: MouseButton): boolean

Is the button currently up?

function mouse_button_up(button: MouseButton): boolean
sound (7)

Load a sound from a file in cart.

function load_sound(filename: string): Sound

Play a sound.

function play_sound(sound: Sound, loop: boolean): void

Stop a sound.

function stop_sound(sound: Sound): void

Unload a sound.

function unload_sound(sound: Sound): void

Speak some text and return a sound. Set things to 0 for defaults.

function tts_sound(text: string, phonetic: boolean, pitch: number, speed: number, throat: number, mouth: number, sing: boolean): Sound

Create Sfx sound.

function sfx_sound(params: SfxParams): Sound

Create Sfx parameters.

function sfx_generate(type: SfxPresetType): SfxParams
tile (38)

Load a tilemap (a Tiled map, exported as JSON) from a file in cart.

function load_tilemap(filename: string): Tilemap

Unload a tilemap.

function unload_tilemap(tilemap: Tilemap): void

Update a tilemap's animation timers (deltaTime is in seconds).

function tile_update(tilemap: Tilemap, deltaTime: number): void

Get the size of a tilemap, in tiles.

function tile_map_size(tilemap: Tilemap): Dimensions

Get the size of a single tile of a tilemap, in pixels.

function tile_tile_size(tilemap: Tilemap): Dimensions

Get a custom property of a tilemap, by name (PROP_NONE when there is no such property.)

function tile_map_prop(tilemap: Tilemap, name: string): TilemapProp

Get the number of custom properties on a tilemap.

function tile_map_prop_count(tilemap: Tilemap): number

Get a custom property of a tilemap, by index (PROP_NONE when out of range.)

function tile_map_prop_at(tilemap: Tilemap, index: number): TilemapProp

Draw a tilemap on the screen.

function tile_draw(tilemap: Tilemap, posX: number, posY: number): void

Draw a tilemap on the screen, tinted by a color.

function tile_draw_tint(tilemap: Tilemap, posX: number, posY: number, tint: Color): void

Draw a tilemap on an image.

function tile_draw_on_image(dst: Image, tilemap: Tilemap, posX: number, posY: number): void

Render a whole tilemap to a new image.

function tilemap_image(tilemap: Tilemap): Image

Get the number of layers in a tilemap. Layers are numbered depth-first, so the children of a group layer have their own indexes too.

function tile_layer_count(tilemap: Tilemap): number

Get the index of a layer of a tilemap, by name (-1 when there is no such layer.)

function tile_layer_index(tilemap: Tilemap, name: string): number

Get the name of a layer of a tilemap.

function tile_layer_name(tilemap: Tilemap, layer: number): string

Get the kind of a layer of a tilemap.

function tile_layer_type(tilemap: Tilemap, layer: number): TileLayerKind

Get the size of a layer of a tilemap, in tiles.

function tile_layer_size(tilemap: Tilemap, layer: number): Dimensions

Get whether a layer of a tilemap is visible. Drawing a layer that Tiled marked hidden draws nothing.

function tile_layer_visible(tilemap: Tilemap, layer: number): boolean

Get a custom property of a layer of a tilemap, by name (PROP_NONE when there is no such property.)

function tile_layer_prop(tilemap: Tilemap, layer: number, name: string): TilemapProp

Get the number of custom properties on a layer of a tilemap.

function tile_layer_prop_count(tilemap: Tilemap, layer: number): number

Get a custom property of a layer of a tilemap, by index (PROP_NONE when out of range.)

function tile_layer_prop_at(tilemap: Tilemap, layer: number, index: number): TilemapProp

Draw a single layer of a tilemap on the screen.

function tile_draw_layer(tilemap: Tilemap, layer: number, posX: number, posY: number): void

Draw a single layer of a tilemap on the screen, tinted by a color.

function tile_draw_layer_tint(tilemap: Tilemap, layer: number, posX: number, posY: number, tint: Color): void

Draw a single layer of a tilemap on an image.

function tile_draw_layer_on_image(dst: Image, tilemap: Tilemap, layer: number, posX: number, posY: number): void

Render a single layer of a tilemap to a new image.

function tile_layer_image(tilemap: Tilemap, layer: number): Image

Get the gid of the tile at a column/row in a tilemap layer.

function tile_get_tile(tilemap: Tilemap, layer: number, column: number, row: number): number

Set the gid of the tile at a column/row in a tilemap layer. Swapping a gid is how a cart keeps changing state in the map itself.

function tile_set_tile(tilemap: Tilemap, layer: number, column: number, row: number, gid: number): void

Draw a single tile from a tilemap on the screen.

function tile_draw_tile(tilemap: Tilemap, gid: number, posX: number, posY: number): void

Get a copy of the image of a single tile in a tilemap.

function tile_image(tilemap: Tilemap, gid: number): Image

Get a custom property of a tile of a tilemap, by name (PROP_NONE when there is no such property.) These come from the tileset, so every tile with this gid shares them.

function tile_gid_prop(tilemap: Tilemap, gid: number, name: string): TilemapProp

Get the number of custom properties on a tile of a tilemap.

function tile_gid_prop_count(tilemap: Tilemap, gid: number): number

Get a custom property of a tile of a tilemap, by index (PROP_NONE when out of range.)

function tile_gid_prop_at(tilemap: Tilemap, gid: number, index: number): TilemapProp

Get the number of objects on an object-layer of a tilemap.

function tile_object_count(tilemap: Tilemap, layer: number): number

Get an object from an object-layer of a tilemap.

function tile_object(tilemap: Tilemap, layer: number, index: number): TilemapObject

Get the index of an object on an object-layer of a tilemap, by name (-1 when there is no such object.)

function tile_object_index(tilemap: Tilemap, layer: number, name: string): number

Get a custom property of an object of a tilemap, by name (PROP_NONE when there is no such property.)

function tile_object_prop(tilemap: Tilemap, layer: number, index: number, name: string): TilemapProp

Get the number of custom properties on an object of a tilemap.

function tile_object_prop_count(tilemap: Tilemap, layer: number, index: number): number

Get a custom property of an object of a tilemap, by index (PROP_NONE when out of range.)

function tile_object_prop_at(tilemap: Tilemap, layer: number, index: number, propIndex: number): TilemapProp
utilities (5)

Get system-time (ms) since unix epoch.

function current_time(): bigint

Get the change in time (seconds) since the last update run.

function delta_time(): number

Get a random integer between 2 numbers.

function random_int(min: number, max: number): number

Get the random-seed.

function random_seed_get(): bigint

Set the random-seed.

function random_seed_set(seed: bigint): void