Zig compiles to WebAssembly via the wasm32-freestanding target. The output is a .wasm binary loaded by a hand-written JavaScript entrypoint (web/game.js).
Setup
No extra toolchain installation is needed -- Zig supports wasm32-freestanding out of the box. Build with:
zig build-exe src/main.zig \
-target wasm32-freestanding \
-fno-entry \
-rdynamic \
-O ReleaseSmall \
-femit-bin=build/web/game.wasm
SDK integration
Declare the two Wavedash SDK functions as extern imports. Wavedash injects WavedashJS into the page, and web/game.js bridges them into the WASM env namespace:
// src/main.zig
extern fn wavedash_init() void;
extern fn wavedash_update_progress(p: f32) void;
export fn wd_init(width: f32, height: f32) void {
// ... game setup ...
wavedash_update_progress(1.0);
wavedash_init();
}
Call wavedash_update_progress(...) with intermediate values during async asset loading. wavedash_init() automatically signals load completion, so call it last.
On the host side, web/game.js provides the implementations:
const sdk = await window.WavedashJS;
const imports = {
env: {
wavedash_init() { sdk.init({ debug: true }); },
wavedash_update_progress(p) { sdk.updateLoadProgressZeroToOne(p); },
// ...your other imports (draw primitives, score updates, etc.)...
}
};
const response = await fetch("./game.wasm");
const bytes = await response.arrayBuffer();
const result = await WebAssembly.instantiate(bytes, imports);
Build script
#!/usr/bin/env sh
set -eu
mkdir -p build/web
zig build-exe src/main.zig \
-target wasm32-freestanding \
-fno-entry -rdynamic -O ReleaseSmall \
-femit-bin=build/web/game.wasm
cp web/game.js build/web/game.js
cp web/index.html build/web/index.html
wavedash.toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./build/web"
Other SDK features
Once initialized, WavedashJS also exposes leaderboards, achievements, stats, and user data. Bridge these the same way -- declare additional extern fn imports in Zig and provide implementations in web/game.js that call sdk.uploadLeaderboardScore(...), sdk.setAchievement(...), sdk.storeStats(), and sdk.getUser(). See the SDK reference for the full API.