# Go

Compile Go games to WebAssembly and publish them on Wavedash.

Source: https://docs.wavedash.com/engines/go

<GithubLink href="https://github.com/wvdsh/examples/tree/main/example-go" />
<PlaytestLink href="https://wavedash.com/playtest/go-example/de004bfa-5aa2-478f-adb8-ce49cc35df42" />

Go compiles to WebAssembly via `GOOS=js GOARCH=wasm`. The output is a `.wasm` binary loaded by the standard `wasm_exec.js` shim and a `web/game.js` entrypoint.

## Setup

No extra installation is needed -- the Go toolchain includes the `js/wasm` target. You also need the `wasm_exec.js` shim shipped with your Go installation:

```bash
GOOS=js GOARCH=wasm go build -o build/web/game.wasm ./src
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" build/web/
```

## SDK integration

Go accesses browser globals through `syscall/js`. Call the two Wavedash SDK functions directly:

```go
package main

import "syscall/js"

func main() {
    sdk := js.Global().Get("Wavedash")

    // ... game setup and loop ...

    sdk.Call("updateLoadProgressZeroToOne", 1)
    sdk.Call("init")

    select {} // keep the program running
}
```

Call `updateLoadProgressZeroToOne(...)` with intermediate values during async asset loading. `init()` automatically signals load completion, so call it last.

The `web/game.js` entrypoint loads `wasm_exec.js`, streams the WASM binary with incremental progress, then instantiates and runs it:

```javascript
const sdk = await window.WavedashJS;
sdk.updateLoadProgressZeroToOne(0);

await loadScript("./wasm_exec.js");

// Reserve the last 5% for compile/instantiate.
const response = await fetch("./game.wasm");
const total = +response.headers.get("Content-Length") || 0;
let wasmBytes;
if (!total || !response.body) {
  wasmBytes = new Uint8Array(await response.arrayBuffer());
} else {
  const reader = response.body.getReader();
  const chunks = [];
  let received = 0;
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    chunks.push(value);
    received += value.length;
    sdk.updateLoadProgressZeroToOne((received / total) * 0.95);
  }
  wasmBytes = new Uint8Array(received);
  let pos = 0;
  for (const c of chunks) { wasmBytes.set(c, pos); pos += c.length; }
}
sdk.updateLoadProgressZeroToOne(0.95);

const go = new Go();
const { instance } = await WebAssembly.instantiate(wasmBytes, go.importObject);
go.run(instance);
```

## Build script

```bash
#!/usr/bin/env sh
set -eu
mkdir -p build/web

GOOS=js GOARCH=wasm go build -ldflags="-s -w" -o build/web/game.wasm ./src
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" build/web/wasm_exec.js
cp web/game.js  build/web/game.js
cp web/index.html build/web/index.html
```

## wavedash.toml

```toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./build/web"
```

## Other SDK features

Once initialized, `Wavedash` also exposes leaderboards, achievements, stats, and user data. Access them the same way via `syscall/js`:

```go
sdk.Call("setAchievement", "first_win", true)
user := sdk.Call("getUser")
```

See the [SDK reference](/sdk/overview) for the full API.
