# Deploy your game on Metaloot Metaloot hosts the player layer for your browser game: accounts, automatic sign-in, cloud saves, playtime tracking, items/artifacts/currency, and a public gamer profile. You host the game build anywhere (any static host works); Metaloot handles the rest. Every step below is idempotent and copy-pasteable. An agent with shell access can complete this guide unattended except step 3 (a human copies one token, once). ## How it works - Your game runs on its own origin (its own host/domain) — untrusted code never shares the platform origin. - When a player clicks Play on Metaloot, they're redirected to your game URL with a scoped session token in the URL fragment (`#mlt=...`). The fragment never reaches your server logs; the Metaloot SDK picks it up, stores it, and strips it. - The token is scoped to YOUR game only: it can read/write that player's saves, items, and playtime for your game, and nothing else. - Without a token (player opened the game directly), the SDK runs in guest mode: every call resolves to null and the game keeps working. ## Step 1 — Add the SDK to your game Download the SDK into your project (vendoring is recommended so your game has zero runtime dependency on Metaloot being reachable): ```bash curl -fsSL https://web-production-3191c.up.railway.app/sdk/metaloot.js -o vendor/metaloot.js ``` Load it before your game code in your entry HTML: ```html ``` Then integrate (all optional — pick what your game needs): ```js // Identity (resolves after auth settles; user is null in guest mode) const { user, totalSeconds } = await Metaloot.ready; if (user) console.log("playing as", user.username, user.avatar); // Optional: lets guest mode link back to your Metaloot listing Metaloot.init({ platform: "https://web-production-3191c.up.railway.app", game: "your-slug" }); // Cloud saves (any JSON, up to 256 KB per slot) await Metaloot.saves.put("main", { level: 3, gold: 120 }); const save = await Metaloot.saves.get("main"); // { data, updatedAt } — data is null if empty // Items, artifacts, currency (appear on the player's Metaloot profile) await Metaloot.items.grant({ key: "gold", name: "Gold", kind: "currency", icon: "🪙", quantity: 25 }); // increments await Metaloot.items.grant({ key: "excalibur", name: "Excalibur", kind: "artifact", icon: "⚔️", rarity: "legendary", quantity: 1, mode: "set" }); // Characters (the player's roster on their profile) await Metaloot.characters.upsert({ key: "hero", name: "Hero", class: "Knight", level: 4, stats: { kills: 12 } }); // Playtime is tracked automatically — no code needed. ``` Rules: - The game MUST stay fully playable in guest mode (user === null). - Never block gameplay on SDK calls; they're network calls — fire and forget. - `kind` is one of `item`, `artifact`, `currency`. `rarity` is one of `common`, `rare`, `epic`, `legendary`. ## Step 2 — Host your build Any static host or server works: Railway, Cloudflare Pages, Vercel, Netlify, your own box. Requirements: - Publicly reachable URL (https in production). - If your host injects a `PORT` env var (e.g. Railway), make sure your server binds to it. Note your final URL — that's your `playUrl`. ## Step 3 — Get a developer token (one-time, human step) 1. Sign in at https://web-production-3191c.up.railway.app 2. Open your profile (avatar, top right → it's at https://web-production-3191c.up.railway.app/profile/me) 3. In the **Developer** panel, click **Reveal developer token** and copy it. ```bash export METALOOT_DEV_TOKEN="" ``` Tokens last 30 days; reveal again any time to get a fresh one. ## Step 4 — Create metaloot.json In your repo root: ```json { "slug": "your-slug", "name": "Your Game", "playUrl": "https://your-game.example.com", "genre": "Action Roguelike", "blurb": "One-line pitch shown on the game card.", "heroTagline": "Longer tagline shown on the game page hero.", "description": ["A paragraph about the game.", "Another paragraph."], "gameplay": ["How it plays."], "keySystems": ["Dashing", "Crafting"] } ``` Required: `slug` (lowercase letters/digits/hyphens), `name`, `playUrl`. Everything else is optional. ## Step 5 — Register (idempotent; re-run on every deploy) ```bash curl -fsS -X POST https://web-production-3191c.up.railway.app/api/v1/games/register \ -H "Authorization: Bearer $METALOOT_DEV_TOKEN" \ -H "Content-Type: application/json" \ -d @metaloot.json ``` Success response: ```json { "ok": true, "slug": "your-slug", "listingUrl": "https://web-production-3191c.up.railway.app/game/your-slug", "launchUrl": "https://web-production-3191c.up.railway.app/api/v1/launch/your-slug" } ``` Errors are machine-readable: `{ "ok": false, "error": "invalid_play_url", "message": "..." }` — fix the named field and re-run. ## Step 6 — Verify Open the `listingUrl` and click **Play**. You should land in your game already signed in (the SDK's `Metaloot.ready` resolves with your user). Play a bit, then check your profile — playtime, saves, and any items you granted are there. ## Game API reference (what the SDK calls) All endpoints require `Authorization: Bearer ` and are CORS-enabled: - `GET /api/v1/game/me` → `{ user, game, totalSeconds }` - `GET /api/v1/game/saves/{slot}` → `{ slot, data, updatedAt }` - `PUT /api/v1/game/saves/{slot}` (JSON body ≤ 256 KB) - `POST /api/v1/game/playtime` (heartbeat; the SDK sends one per minute while visible) - `GET/POST /api/v1/game/items` (grant body: `{ key, name, kind, icon, rarity, description, quantity, mode }`) - `GET/POST /api/v1/game/characters` (upsert body: `{ key, name, class, level, stats }`) A game backend can hold the player's token (have your client send it) and call these server-to-server — grants from a server can't be forged by players in devtools.