WavedashDocs

MonoGame

Run MonoGame projects in the browser via Blazor WebAssembly or KNI.

View the example on GitHub

MonoGame targets the browser through .NET's Blazor WebAssembly or via community Emscripten-based toolchains like KNI or nkast's MonoGame.Web. The output is a set of static files — HTML, JS, WASM, and assets — that Wavedash can host.

Build for web

The exact steps depend on which web target you use:

Blazor WebAssembly (MonoGame 3.8.2+)

  1. Create or convert your project to use the Blazor WebAssembly host
  2. Run dotnet publish -c Release
  3. The output is in bin/Release/net8.0/publish/wwwroot (or similar)

Community Emscripten targets

  1. Follow the toolchain's instructions to produce a web build
  2. The output is typically a folder with index.html, a .wasm file, and asset bundles

Point upload_dir at whichever folder contains the final browser-ready output.

SDK integration

Wavedash injects WavedashJS into the page before your game loads. To call it from C#, use JavaScript interop:

using System.Runtime.InteropServices.JavaScript;

public partial class WavedashBridge
{
    [JSImport("WavedashJS.getUser", "wavedash")]
    internal static partial JSObject GetUser();

    [JSImport("WavedashJS.uploadLeaderboardScore", "wavedash")]
    internal static partial Task SubmitScore(string id, int score, bool keepBest);

    [JSImport("WavedashJS.setAchievement", "wavedash")]
    internal static partial void SetAchievement(string id);

    [JSImport("WavedashJS.loadComplete", "wavedash")]
    internal static partial void LoadComplete();
}

Or use a small JavaScript file that you call via JSRuntime:

window.wavedashGetUsername = function() {
  var user = WavedashJS.getUser();
  return user ? user.username : "";
};

Load progress

Report completion from C# once your first scene is interactive:

protected override void LoadContent()
{
    base.LoadContent();
    // ... load textures, fonts, audio ...
    WavedashBridge.LoadComplete();
}

Intermediate progress reporting depends on your toolchain. For Emscripten-based targets (KNI, MonoGame.Web), forward Module.setStatus from wwwroot/index.html:

var Module = {
  setStatus: function(text) {
    var m = text.match(/\((\d+(?:\.\d+)?)\/(\d+(?:\.\d+)?)\)/);
    if (m) WavedashJS.updateLoadProgressZeroToOne(parseFloat(m[1]) / parseFloat(m[2]));
  }
};

For Blazor WebAssembly, hook Blazor.start({ loadBootResource }) to observe resource downloads and call WavedashJS.updateLoadProgressZeroToOne() as each one resolves.

wavedash.toml

game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./bin/Release/net8.0/publish/wwwroot"
entrypoint = "index.html"

MonoGame web builds can be large. Enable compression (Brotli or Gzip) in your publish settings to reduce load times.