# Zig

Compile Zig games to WebAssembly and host them on Wavedash.

Source: https://docs.wavedash.com/engines/zig

<GithubLink href="https://github.com/wvdsh/examples/tree/main/example-zig" />
<PlaytestLink href="https://wavedash.com/playtest/zig-example/1d2e07e7-5b95-4e09-9c83-f88d1e155a1f" />

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:

```bash
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:

```zig
// 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:

```javascript
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

```bash
#!/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

```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](/sdk/overview) for the full API.
