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 and activate it (source ./emsdk_env.sh).
em++ src/main.cpp -std=c++17 -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 WavedashJS into the page before your Emscripten module loads. Use EM_JS to call the two SDK functions from C++:
#include <emscripten.h>
EM_JS(void, wavedash_init, (), {
WavedashJS.init({ debug: true });
});
EM_JS(void, wavedash_progress, (double p), {
WavedashJS.updateLoadProgressZeroToOne(p);
});
int main() {
// ... 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
#!/usr/bin/env sh
set -eu
mkdir -p build/web
em++ src/main.cpp -std=c++17 -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
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./build/web"
Other SDK features
Once initialized, WavedashJS also exposes leaderboards, achievements, stats, and user data. Add more EM_JS wrappers for the calls you need:
EM_JS(void, wavedash_submit_score, (const char* id, int score), {
WavedashJS.uploadLeaderboardScore(UTF8ToString(id), score, true);
});
EM_JS(void, wavedash_set_achievement, (const char* id), {
WavedashJS.setAchievement(UTF8ToString(id));
WavedashJS.storeStats();
});
See the SDK reference for the full API.
Emscripten memory growth, threads, and file packaging settings can affect load time and compatibility. Test with wavedash dev before pushing.