Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Web builds: games in the browser

The engine includes browser-build tooling. Hosted playable demos are not yet deployed on ponko.dev. Build the public battle, flow, and ants examples locally using the instructions below.

Building your game

Once:

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.130   # the wasm-bindgen version in your Cargo.lock

Then, from your game’s folder, with web/build.sh and web/index.html copied from the engine’s repository:

web/build.sh --bin my_game               # -> target/web/my_game/
python3 -m http.server -d target/web/my_game 8000

and open http://localhost:8000. In the engine’s repository, web/build.sh battle builds an example.

The output folder is a static site: put it on any web host (GitHub Pages, itch.io, your own server). It holds the page, the game (game_bg.wasm, about 3 MB compressed) and a copy of assets/.

What’s different in a browser

Assets are fetched before setup. There’s no file system, so the build script lists your assets/ folder in assets/index.json, and the engine downloads every file in it before running your setup. load_texture and the other loading functions then work as usual.

One thread. Browsers can run WebAssembly on several threads only on specially configured servers, so web builds use one. Parallel queries (par_for_each) still work, just on a single core: the battle’s 20,000 units take about 4.5 ms per tick in Chrome, against 0.5 ms native on all cores of the same machine. Plan for tens of thousands of units on the web, rather than millions.

Measure time with the engine’s Instant. std::time::Instant::now() panics in browsers. ponko::Instant is the same type on desktop and works on the web:

#![allow(unused)]
fn main() {
use ponko::*;
let start = Instant::now();
// ... work ...
let ms = start.elapsed().as_secs_f64() * 1000.0;
let _ = ms;
}

Settings come from the address, not the environment. There are no environment variables in a browser. The inspector reads ?inspector=1 (on), ?inspector=open (on and open) or ?inspector=0 instead of CRABBY_INSPECTOR.

The page is yours. The engine draws into <canvas id="crabby"> if the page has one, and adds a canvas otherwise. web/index.html makes the canvas fill the page; change it to put the game anywhere. Browsers only allow sound once the player has clicked or pressed a key, so sounds played before that (music at startup, say) may stay silent.

Not available on the web: the control endpoint and MCP tools, hot reload of files, hot patching of code, and anything that writes files (ctx.save_screenshot, saving the world to a path). println! output goes nowhere; panics appear in the browser’s developer console.

C and C++

Not yet: web builds work for Rust games. C and C++ games would need to be compiled with Emscripten, which the engine doesn’t support so far.