# Three.js

Build a Three.js game with your bundler of choice and ship it to Wavedash.

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

<GithubLink href="https://github.com/wvdsh/examples/tree/main/example-threejs-cloud" />
<PlaytestLink href="https://wavedash.com/playtest/three-js-example/a90e8016-3e4f-42e7-a009-5aa025d46f91" />

Three.js works with any JavaScript bundler — Vite, Webpack, Rollup, esbuild, Parcel, and others. This page covers the generic setup. [The example repo](https://github.com/wvdsh/examples/tree/main/example-threejs-cloud) uses Vite and demonstrates cloud save (userfs) and UGC publish/import alongside a cannon-es physics sandbox.

## Install dependencies

```bash
npm install three
npm install @wvdsh/sdk-js
```

`@wvdsh/sdk-js`'s default export is the live, fully-typed Wavedash SDK singleton.

## Wire up `Wavedash.init()`

In the file where you set up your scene and renderer, import `Wavedash` and call `init()` once your game is ready.

<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>

```typescript
import Wavedash from "@wvdsh/sdk-js";
import * as THREE from 'three';

const manager = new THREE.LoadingManager();
manager.onProgress = (url, loaded, total) => {
  Wavedash.updateLoadProgressZeroToOne(loaded / total);
};
manager.onLoad = () => {
  Wavedash.init({ debug: true });
};

// Pass `manager` to each loader, e.g.:
// const loader = new THREE.TextureLoader(manager);
// loader.load('/textures/map.png', ...);
```

Pass the `LoadingManager` to every `THREE.*Loader` you use. Its `onProgress` fires as each asset completes; `onLoad` fires once all assets are done, which is where `init()` belongs. Call `updateLoadProgressZeroToOne(...)` during async asset loading; `init()` automatically signals load completion, so call it last.

## wavedash.toml

Point `upload_dir` at your bundler's output directory. For Vite and most other bundlers that's `./dist`.

```toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./dist"
```

## Local development

Produce a build, then run `wavedash dev` to serve it through the Wavedash sandbox.

## SDK features

Once initialized, `Wavedash` exposes leaderboards, achievements, stats, user data, cloud save (userfs), and UGC:

```javascript
const user = Wavedash.getUser();

const lb = await Wavedash.getLeaderboard("high-scores");
await Wavedash.uploadLeaderboardScore(lb.data.id, score, true);

Wavedash.setAchievement("first_win", true);

// Cloud save (userfs) — private per-user storage
await Wavedash.writeLocalFile("scenes/main.json", bytes);
await Wavedash.uploadRemoteFile("scenes/main.json");
const { success } = await Wavedash.downloadRemoteFile("scenes/main.json");
const bytes = await Wavedash.readLocalFile("scenes/main.json");

// UGC — shareable community content
const response = await Wavedash.createUGCItem(type, title, description, visibility, filePath);
if (response.success) {
  const ugcId = response.data;
  await Wavedash.updateUGCItem(ugcId, { title, description, visibility, filePath });
}
```
