Search documentation

Find pages, sections, and content across all docs.

WavedashDocs

SDK setup

Get the Wavedash SDK running in your game

The Wavedash SDK gives your game access to player accounts, leaderboards, achievements, multiplayer, cloud saves, and more. This page walks you through getting it set up.

How the SDK works

When your game runs on Wavedash, the platform makes Wavedash available in the browser before your code starts. During local development, wavedash dev does the same thing with a sandbox version so you can test everything offline.

Methods that talk to servers are asynchronous and return Promises. Methods that read local state (like the current player) are synchronous.

View the SDK on GitHub

Typed access in JavaScript/TypeScript

Optionally install @wvdsh/sdk-js and import Wavedash directly in your game script for editor autocomplete and type safety:

npm install @wvdsh/sdk-js
import Wavedash from "@wvdsh/sdk-js";

Wavedash.init({ debug: true });
Wavedash.on(Wavedash.Events.LOBBY_JOINED, (payload) => {
  console.log(`Joined lobby ${payload.lobbyId}`);
});

The import gives you the host's injected SDK instance with full TypeScript types — methods, events, and payloads all autocomplete. Importing from anywhere in your codebase returns the same SDK singleton.

Initialization

Call Wavedash.init(config?) once — before any other SDK method — to apply your settings and mark the game as loaded. init() is synchronous and returns a boolean (true on first call, false if already initialized). You do not need to await it.

init() also calls loadComplete() internally, so a single init() is enough for most games. See Load lifecycle below if you want to report progress and signal load completion separately.

func _ready():
    WavedashSDK.backend_connected.connect(_on_connected)
    WavedashSDK.init({"debug": true, "deferEvents": true})
    WavedashSDK.ready_for_events()

func _on_connected(payload):
    print("SDK is ready!")
    var username = WavedashSDK.get_username()
    print("Playing as: ", username)
using System.Collections.Generic;

void Awake()
{
    Wavedash.SDK.Init(new Dictionary<string, object>
    {
        { "debug", true },
        { "deferEvents", true }
    });
    Wavedash.SDK.ReadyForEvents();
}

void Start()
{
    var user = Wavedash.SDK.GetUser();
    if (user != null)
        Debug.Log($"Playing as: {user["username"]}");
}
Wavedash.init({ debug: true, deferEvents: true });
Wavedash.readyForEvents();

const user = Wavedash.getUser();
console.log(`Playing as: ${user.username}`);

Load lifecycle

Wavedash tracks two separate signals while your game boots:

  1. Load progress — a 0-to-1 value the shell uses to render its loading bar. Call updateLoadProgressZeroToOne(progress) while your game is downloading assets or initializing.
  2. Load complete — fires once, when the player can actually interact. init() calls this for you, or you can call loadComplete() directly if you want to signal completion before you're ready to initialize the full SDK (e.g., hand-off from a splash screen).
// Report progress while assets download
Wavedash.updateLoadProgressZeroToOne(0.2);
await downloadAssets();
Wavedash.updateLoadProgressZeroToOne(0.8);
await startRuntime();

// Either of these works — init() calls loadComplete() internally
Wavedash.init({ debug: false });
// Wavedash.loadComplete(); // only needed if you call it before init()

Both methods are idempotent — calling them twice is a no-op.

Ready-state getters

The SDK exposes three boolean getters for defensive code that needs to know where you are in the lifecycle:

GetterTrue when
initializedinit() has been called at least once
eventsReadyThe deferred event queue has been flushed (either by init() or a manual readyForEvents())
gameLoadedloadComplete() has fired
if (!Wavedash.initialized) Wavedash.init();
if (Wavedash.eventsReady && Wavedash.gameLoaded) {
  // SDK is fully booted and serving events
}

Loading third-party scripts

Wavedash.loadScript(src) is a small helper that appends a <script> tag to the page and resolves once it finishes loading. Useful for lazy-loading analytics, engine runtimes, or any script you don't want to block initial page load.

await Wavedash.loadScript("https://cdn.example.com/analytics.js");
// analytics global is now available

Overlay

Call toggleOverlay() to show or hide the Wavedash in-game overlay (friends list, invites, settings). Wire it to a pause button or a keyboard shortcut so players can reach Wavedash's built-in UI without leaving your game.

WavedashSDK.toggle_overlay()
Wavedash.SDK.ToggleOverlay();
Wavedash.toggleOverlay();

Response format

Most async SDK methods that talk to Wavedash services return a response object. Check success before using data.

const response = await Wavedash.getLeaderboard("high-scores");

if (response.success) {
  console.log(`Leaderboard: ${response.data.name}`);
} else {
  console.error(`Error: ${response.message}`);
}

When a call fails, message explains what went wrong.

Error handling

Wrap async service calls in try/catch and check success:

func _on_leaderboard(response):
    if not response.get("success", false):
        push_error(response.get("message", "leaderboard error"))
        return
    var board = response["data"]
try
{
    var board = await Wavedash.SDK.GetLeaderboard("high-scores");
    if (board == null)
    {
        Debug.LogWarning("Leaderboard call failed");
        return;
    }
}
catch (Exception ex)
{
    Debug.LogException(ex);
}
try {
  const response = await Wavedash.getLeaderboard("high-scores");
  if (!response.success) {
    console.error(response.message);
    return;
  }
  useBoard(response.data);
} catch (e) {
  console.error(e);
}

Configuration options

Pass these to init() when you need non-default behavior:

OptionWhat it does
debugTurns on verbose logging in the browser console
deferEventsQueues lobby and multiplayer events until you call readyForEvents()
p2pCustom P2P networking settings (see Types reference)

If you set deferEvents: true, make sure you call readyForEvents() once your game is done loading. Otherwise queued events will never reach your handlers.

Launch params

When a player opens your game through a URL with wvdsh_-prefixed query parameters, Wavedash strips the prefix and passes them to your game as key-value pairs. Call getLaunchParams() after init() to read them.

The most common use case is lobby invite links — when a player clicks an invite link, the lobby param contains the lobby ID so your game can join automatically.

WavedashSDK.init({})
var params = WavedashSDK.get_launch_params()
if params.has("lobby"):
    WavedashSDK.join_lobby(params["lobby"])
Wavedash.SDK.Init(new Dictionary<string, object>());
var parameters = Wavedash.SDK.GetLaunchParams();
if (parameters.TryGetValue("lobby", out var lobbyId))
    await Wavedash.SDK.JoinLobby(lobbyId);
Wavedash.init();
const params = Wavedash.getLaunchParams();
if (params.lobby) {
  await Wavedash.joinLobby(params.lobby);
}

How it works

  1. A player visits a URL like https://wavedash.com/games/my-game?wvdsh_lobby=abc123
  2. Wavedash strips the wvdsh_ prefix from matching query parameters
  3. The resulting key-value pairs ({ lobby: "abc123" }) are passed to your game
  4. Your game reads them with getLaunchParams() and acts on them

Only query parameters prefixed with wvdsh_ are forwarded to your game. Other query parameters are ignored.

Built-in params

ParamDescription
lobbyLobby ID — the player followed an invite link. Join with joinLobby(). See Multiplayer lobbies.

You can also pass custom data by adding wvdsh_-prefixed query parameters to any game URL. For example, ?wvdsh_mode=ranked would appear as { mode: "ranked" } in getLaunchParams().

Connection events

Listen for connection changes to show online/offline status in your UI:

func _ready():
    WavedashSDK.backend_connected.connect(_on_connected)
    WavedashSDK.backend_disconnected.connect(_on_disconnected)
    WavedashSDK.backend_reconnecting.connect(_on_reconnecting)

func _on_connected(payload):
    print("Connected (attempt %d)" % payload["connectionCount"])

func _on_disconnected(payload):
    print("Disconnected (was ever connected: %s)" % payload["hasEverConnected"])

func _on_reconnecting(payload):
    print("Reconnecting (retry %d)" % payload["connectionRetries"])
void Awake()
{
    Wavedash.SDK.OnBackendConnected += data =>
        Debug.Log($"Connected (attempt {data["connectionCount"]})");
    Wavedash.SDK.OnBackendDisconnected += data =>
        Debug.Log($"Disconnected (was ever connected: {data["hasEverConnected"]})");
    Wavedash.SDK.OnBackendReconnecting += data =>
        Debug.Log($"Reconnecting (retry {data["connectionRetries"]})");
}
Wavedash.on(Wavedash.Events.BACKEND_CONNECTED, (payload) => {
  console.log(`Connected (attempt ${payload.connectionCount})`);
});
Wavedash.on(Wavedash.Events.BACKEND_DISCONNECTED, (payload) => {
  console.log(`Disconnected (was ever connected: ${payload.hasEverConnected})`);
});
Wavedash.on(Wavedash.Events.BACKEND_RECONNECTING, (payload) => {
  console.log(`Reconnecting (retry ${payload.connectionRetries})`);
});

What's next

See the Events reference for the complete event list.