Ruffle is an open-source Flash Player emulator written in Rust. Wavedash has first-class support for Ruffle: upload your .swf, point wavedash.toml at it, and the platform wraps the SWF in Ruffle automatically. You don't need to bundle the Ruffle runtime or write any SDK code in your Flash game.
Upload your SWF
- Put your compiled
.swffile in your upload directory (e.g.build/game.swf). - In
wavedash.toml, add a[ruffle]section pointing at the file:
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./build"
[ruffle]
version = "0.2.0-nightly.2026.2.24"
executable = "game.swf"
- Run
wavedash devto test locally. When ready to ship, upload your build and publish it from the Developer Portal.
Ruffle version
version pins the Ruffle nightly the platform loads for you. Check ruffle.rs/builds for available builds. The platform tracks the @ruffle-rs/ruffle npm package versions (nightly builds formatted as 0.2.0-nightly.YYYY.M.D).
SDK integration
None required in your SWF. The platform runs the SDK init automatically — Wavedash.updateLoadProgressZeroToOne(...) is called while the Ruffle runtime downloads and your SWF loads, then Wavedash.loadComplete() fires once the SWF is ready to play.
If you want to call the SDK from ActionScript, use ExternalInterface.call(...):
import flash.external.ExternalInterface;
if (ExternalInterface.available) {
ExternalInterface.call("Wavedash.setAchievement", "first_win", true);
}
Custom loader script
If you need to run JavaScript before your SWF starts — for example, to set up save-data bridges, attach Ruffle player event listeners, or register ExternalInterface hooks — add a loader_url:
[ruffle]
version = "0.2.0-nightly.2026.2.24"
executable = "game.swf"
loader_url = "loader.js"
Place loader.js in your upload directory alongside the SWF. It runs after the Ruffle runtime is ready and the player element exists, but before player.load() is called for your SWF. At that point both window.Wavedash and window.rufflePlayer (the RufflePlayer Web Component) are available, so the loader is the right place to attach event listeners, register ExternalInterface bridges, or hook save-data persistence:
// build/loader.js
window.rufflePlayer.addEventListener("loadeddata", () => {
console.log("SWF ready");
});
The platform owns the Ruffle load config (autoplay, letterbox, allowScriptAccess, etc.) and you can't override those defaults from the loader.
The Ruffle runtime is loaded from jsDelivr — the platform doesn't host its own copy. First-time loads fetch from the CDN, then the browser caches the wasm for subsequent plays.