Bevy compiles to WebAssembly via wasm-bindgen and wasm-pack (or trunk). The output is a set of static files — HTML, JS, WASM, and assets — that Wavedash can host.
Build for web
Using Trunk (recommended):
trunk build --releaseThe output is in the dist/ folder. (wasm-pack build --target web --release also works, but only for a library crate with crate-type = ["cdylib"] — the linked example is a binary crate built with Trunk.)
SDK integration
Wavedash injects Wavedash into the page before your WASM module loads. Bridge the SDK calls you need with wasm-bindgen inline JS:
use bevy::prelude::*;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(inline_js = "
export function wavedash_update_progress(p) { window.Wavedash.updateLoadProgressZeroToOne(p); }
export function wavedash_init() { window.Wavedash.init({ debug: true }); }
")]
extern "C" {
fn wavedash_update_progress(p: f64);
fn wavedash_init();
}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.
Call init() from Rust once your game is set up — for example at the end of a Startup system. Bevy's App::run() takes over the browser event loop, so code in your HTML shell after the WASM module starts isn't a reliable place for it:
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
// ... spawn camera, entities, UI ...
wavedash_update_progress(1.0);
wavedash_init(); // also signals load complete
}Load progress
Call wavedash_update_progress(...) with intermediate values while you load assets, and call wavedash_init() last.
wavedash.toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./dist"
entrypoint = "index.html"SDK features
From the JavaScript side of your HTML shell, Wavedash exposes leaderboards, achievements, stats, and user data:
const user = Wavedash.getUser();
const lb = await Wavedash.getLeaderboard("high-scores");
if (lb.success) {
await Wavedash.uploadLeaderboardScore(lb.data.id, score, true);
}
Wavedash.setAchievement("first_win", true);To call these from Rust, add corresponding wasm-bindgen externs in the SDK integration block above.
Bevy's default window size and asset paths assume a desktop environment. Mount your canvas into a container that fills the viewport and keep asset paths relative so the build works from any subpath.