# C

Compile C games to WebAssembly with Emscripten and call the Wavedash SDK.

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

<GithubLink href="https://github.com/wvdsh/examples/tree/main/example-c" />
<PlaytestLink href="https://wavedash.com/playtest/c-example/8439b33c-a5b1-46b7-8aac-7a8e2903fbe2" />

C games target the browser through Emscripten, which compiles to WebAssembly. This works for custom engines, SDL2 projects, and any other C codebase.

## Setup

Install the [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html) and activate it (`source ./emsdk_env.sh`).

```bash
emcc src/main.c -O2 \
  -s ENVIRONMENT=web \
  -s ALLOW_MEMORY_GROWTH=1 \
  -o build/web/game.js
```

Emscripten produces `game.js` and `game.wasm`. You provide your own `web/index.html` that includes a canvas and loads the script.

## SDK integration

Wavedash injects `Wavedash` into the page before your Emscripten module loads. Use `EM_JS` to call the two SDK functions from C:

<Urgent>
**Calling `Wavedash.init()` is required.** Your game stays hidden behind the Wavedash loading screen until you do. Call it once your game is ready to play.
</Urgent>

```c
#include <emscripten.h>

EM_JS(void, wavedash_init, (), {
  Wavedash.init({ debug: true });
});

EM_JS(void, wavedash_progress, (double p), {
  Wavedash.updateLoadProgressZeroToOne(p);
});

int main(void) {
    // ... setup ...

    wavedash_progress(1.0);
    wavedash_init();

    // ... start game loop ...
    emscripten_set_main_loop(tick, 0, 1);
    return 0;
}
```

Call `wavedash_progress(...)` with intermediate values during async asset loading. `wavedash_init()` automatically signals load completion, so call it last.

## Build script

```bash
#!/usr/bin/env sh
set -eu
mkdir -p build/web

emcc src/main.c -O2 \
  -s ENVIRONMENT=web \
  -s EXPORTED_RUNTIME_METHODS='["UTF8ToString"]' \
  -s ALLOW_MEMORY_GROWTH=1 \
  -o 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. Add more `EM_JS` wrappers for the calls you need:

```c
EM_JS(void, wavedash_submit_score, (const char* id, int score), {
  Wavedash.uploadLeaderboardScore(UTF8ToString(id), score, true);
});

EM_JS(void, wavedash_set_achievement, (const char* id), {
  Wavedash.setAchievement(UTF8ToString(id), true);
});
```

See the [SDK reference](/sdk/overview) for the full API.

<Warning>
Emscripten memory growth, threads, and file packaging settings can affect load time and compatibility. Test with `wavedash dev` before pushing.
</Warning>
