# Haxe

Compile Haxe games to JavaScript and ship them to Wavedash with a one-line build.

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

<GithubLink href="https://github.com/wvdsh/examples/tree/main/example-haxe" />
<PlaytestLink href="https://wavedash.com/playtest/haxe-example/03fe7645-2822-49bd-ba35-97223ac8266c" />

Haxe targets JavaScript natively, so any Haxe program that renders to a `<canvas>` runs on Wavedash. No runtime is shipped alongside your game — the compiler emits a single `.js` file you load from a static HTML shell.

## Build for web

Write a `build.hxml` that emits JavaScript:

```hxml
-cp src
-main Main
-js build/main.js
-D js-es=6
-D no-traces
```

Then run `haxe build.hxml`. The compiler writes `build/main.js`. Commit a matching `build/index.html` that includes it:

```html
<!doctype html>
<html>
  <head><meta charset="utf-8" /><title>My Haxe Game</title></head>
  <body>
    <canvas id="gameCanvas"></canvas>
    <script src="./main.js"></script>
  </body>
</html>
```

## SDK integration

Call the JavaScript SDK from Haxe with `js.Syntax.code`. Wavedash injects `Wavedash` as a global before your script runs.

<Urgent>
**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.
</Urgent>

```haxe
import js.Browser;

class Main {
  static function main() {
    // DOM is being parsed — report that we've started.
    js.Syntax.code("Wavedash.updateLoadProgressZeroToOne(0.2)");
    Browser.window.addEventListener("load", onLoad);
  }

  static function onLoad(_) {
    // Window "load" fires once all subresources (images, scripts) are ready.
    js.Syntax.code("Wavedash.updateLoadProgressZeroToOne(0.7)");

    // set up your canvas, game loop, input handlers, etc.

    // Assets and game state initialized — signal ready and start the loop.
    js.Syntax.code("Wavedash.updateLoadProgressZeroToOne(1.0)");
    js.Syntax.code("Wavedash.init({ debug: true })");

    Browser.window.requestAnimationFrame(loop);
  }
}
```

For anything more than a one-off call, wrap the SDK in a Haxe extern so the compiler can type-check your usage:

```haxe
@:native("Wavedash")
extern class Wavedash {
  static function init(config: Dynamic): Bool;
  static function updateLoadProgressZeroToOne(progress: Float): Void;
  static function uploadLeaderboardScore(id: String, score: Int, keepBest: Bool): js.lib.Promise<Dynamic>;
  // ...add more as you need them
}
```

## wavedash.toml

```toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./build"
entrypoint = "index.html"
```

<Note>
The example repo commits both `build/index.html` and a prebuilt `build/main.js` so you can run `wavedash dev` without a Haxe toolchain on hand.
</Note>
