mpmux by Mighty Painting
~/mpmux/docs ❯ less guide/wasm-canvases/contents ↓

11. Wasm canvases#

In this chapter you run small interactive programs in the Viewer: a Wasm guest that draws on a canvas and takes touch, mouse and keys. mpmux runs it itself, on the desktop and on Android, without a browser and without a web engine. An agent can write one to show you something you can play with: a simulation, a plot you can scrub, a small game.

This is experimental: the API may still change.

Run one#

mpmux-cli media show life.wasm

The guest starts in the Viewer and draws at the display's pace while it animates. Tap or click the canvas to give it the keys; tap the terminal to take them back. At the bottom of the canvas, a small graph shows how long each frame took (min, average and max over the last frames, and how many drawing operations the last one made).

A guest runs only while the Viewer shows it. Showing the same file again starts it anew.

▶ watch the clip

The examples#

contrib/wasm-canvas holds a template and examples. Build them once:

cd contrib/wasm-canvas
cargo build --release --target wasm32-unknown-unknown --examples

Then show the folder's README in the Viewer and tap an example's name:

mpmux-cli media show README.md

media show sends the files a document links to along with it, so the README works as a launcher. The guest runs in the README's place; Back returns to the list.

Example Shows
shapes every drawing call once: a reference card
life Conway's Game of Life; drag to draw cells
paint finger painting with smoothed strokes
plot three signals scrolling by, with a crosshair
snake the game: arrow keys, WASD or swipes
stopwatch arcs and text; tap to start and stop
stuck a guest that hangs on purpose: the Viewer stops it

The same works from a page: an HTML file in the Viewer that links to a .wasm file it carries (<a href="guests/life.wasm">) runs the guest in the page's place.

Write one#

A guest is a WebAssembly module, written in Rust, Zig, C or WAT. It exports a few functions, and mpmux calls them:

Export Called
frame(time: f64, width: f32, height: f32) -> i32 to draw one frame; time is seconds since the start. Return 1 to be called again on the next display frame, 0 to wait for input.
pointer(kind: i32, x: f32, y: f32) optional: 0 down, 1 move, 2 up, in canvas points
key(code: i32, down: i32) optional: a key while the canvas has the keys. Characters come as their code point (letters lower case), the rest as codes in canvas::key (arrows, Enter, Escape, ...).

It draws by calling mpmux's functions (module mpmux; colors are 0xRRGGBBAA):

Call Draws
clear(rgba) fills the canvas
fill_rect, fill_rounded_rect, fill_circle, line shapes
text(x, y, size, rgba, ptr, len) UTF-8 text from the guest's memory
begin_path, move_to, line_to, quad_to, cubic_to, close_path a path
fill_path(rgba), stroke_path(width, rgba) the path, filled or outlined
log(ptr, len) a line in mpmux's log

The template's src/canvas.rs wraps these for Rust, with helpers for polygons, arcs, a random number generator and colors. Copy the folder, keep canvas.rs, and write your own frame and pointer in src/lib.rs.

Limits#

A guest gets nothing but its canvas: no files, no network, no clock but time. Its module is at most 8 MB and its memory at most 16 MB; a frame draws at most 50 000 operations.

A frame that takes longer than 2 seconds stops the guest, and the Viewer says so; the rest of mpmux stays responsive, because the guest runs on a thread of its own. To see how long a guest's frames take before you show it:

cargo run --release -p mpmux-wasm-canvas --example measure -- guest.wasm

The runtime is the mpmux-wasm-canvas crate, on Makepad's stitch interpreter. Its documentation (crates/mpmux-wasm-canvas/src/lib.rs) is the full API.

For agents#

The mpmux media skill (installed by mpmux-cli agents install) tells an agent when a guest fits and how to show one. To offer several guests at once, write a Markdown document that links to them by relative path and show the document.

Next#

Chapter 12 shows how to plan and share the work with your agent.