Search documentation

Find pages, sections, and content across all docs.

WavedashDocs

Zig

Compile Zig games to WebAssembly and host them on Wavedash.

View example project on GitHub Playtest the example project

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 Wavedash 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 Wavedash = window.Wavedash;

const imports = {
  env: {
    wavedash_init() { Wavedash.init({ debug: true }); },
    wavedash_update_progress(p) { Wavedash.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, Wavedash 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 Wavedash.uploadLeaderboardScore(...), Wavedash.setAchievement(id, true), and Wavedash.getUser(). See the SDK reference for the full API.