Doku
Spawncade hostet fertige Browser-Games. Du lädst einen Ordner hoch und bekommst eine Adresse. Auf dieser Seite steht alles, was es dazu gibt.
In drei Minuten live
Du brauchst einen Ordner mit einer index.html und allem, was dazugehört. Genau das, was ein Web-Export ausspuckt.
spawncade login spawncade deploy dist
Der erste Deploy legt das Spiel an, wählt eine Adresse aus dem Titel und schreibt spawncade.json in den Ordner. Danach genügt spawncade deploy dist.
Die CLI liegt noch nicht auf npm. Spawncade läuft gerade mit einer Handvoll Leuten. Wenn du dabei sein willst, schreib an info@create-dot.com, dann bekommst du sie.
Die CLI
| spawncade login | Anmelden |
| spawncade games | Deine Spiele auflisten |
| spawncade deploy [ordner] | Hochladen und live schalten |
| spawncade versions | Alle Fassungen eines Spiels |
| spawncade rollback | Eine ältere Fassung wieder live |
| spawncade rename <name> | Adresse ändern, alte leitet um |
| spawncade delete | Spiel löschen |
| spawncade token neu <name> | Deploy-Token für CI |
Ein Deploy-Token gehört in ein Repository-Secret als SPAWNCADE_TOKEN. Es darf genau ein Spiel veröffentlichen und sonst nichts: kein Rollback, kein Umbenennen, kein Löschen. Das sind Entscheidungen, keine Veröffentlichungen.
Für KI-Agenten
Wenn du dein Spiel mit Claude Code, Cursor oder Codex baust, kann der Agent selbst deployen. Es gibt einen MCP-Server dafür.
claude mcp add spawncade -- /voller/pfad/zu/spawncade-mcp
Danach reicht: „Deploye das Spiel auf Spawncade.“ Der Agent kann hochladen, Fassungen auflisten und zurückrollen. Anmelden musst du dich einmal selbst, mit spawncade login.
Den Startbefehl absolut angeben, also mit vollem Pfad. Agenten starten MCP-Server mit einer sehr schlanken Umgebung, und der PATH darin ist nicht der aus deiner Shell.
Das SDK
Optional. Ein Spiel läuft auch ohne. Wenn du Spielstände über Geräte hinweg oder eine Bestenliste willst, sind das ein paar Zeilen.
<script type="module">
import { Spawncade } from 'https://api.spawncade.app/sdk.js'
const vp = Spawncade.init({ gameId: 'DEINE-GAME-ID' })
await vp.auth.signIn()
</script>
Die Game-ID steht im Dashboard bei deinem Spiel. signIn() meldet anonym an: kein Formular, kein Passwort, der Spieler merkt nichts. Auf demselben Gerät findet er seinen Spielstand wieder.
Spielstände
await vp.saves.set('spielstand', { level: 4, muenzen: 120 })
const stand = await vp.saves.get('spielstand')
Beliebiges JSON, bis 100 KB pro Eintrag und 1 MB pro Spieler und Spiel. Ein Spieler sieht nur seine eigenen Stände, dafür sorgt die Datenbank und nicht der Code im Browser.
Vom Gerät aufs Konto
await vp.auth.secure(email, passwort)
Macht aus dem anonymen Spieler ein richtiges Konto, ohne dass etwas verlorengeht: dieselbe ID, derselbe Spielstand, derselbe Eintrag in der Bestenliste. Der richtige Moment dafür ist nicht der Spielstart, sondern wenn jemand etwas zu verlieren hat.
Bestenlisten
await vp.leaderboard.submit('highscore', 4200)
const oben = await vp.leaderboard.top('highscore', 10)
// [{ place: 1, score: 9100, name: 'Bert', isYou: false, achievedAt: '…' }, …]
await vp.player.setName('Anna')
Ein Eintrag pro Spieler, sein bester Wert. name ist null, solange jemand keinen gesetzt hat: was dann in der Liste steht, entscheidest du.
Der Punktestand kommt aus dem Browser des Spielers und lässt sich behaupten. Solange die Spiellogik im Client läuft, ist das nicht zu verhindern, nur zu begrenzen: die Datenbank nimmt höchstens 30 Einträge pro Minute und Liste.
Grenzen
| Bundle | 250 MB, einzelne Datei bis 100 MB |
| Spielstand | 100 KB pro Eintrag, 1 MB pro Spieler und Spiel |
| Bestenliste | 30 Einträge pro Minute und Liste |
| Adresse | 3 bis 40 Zeichen, Kleinbuchstaben, Ziffern, Bindestriche |
| Deploy sichtbar | nach spätestens 60 Sekunden überall |
Jedes Spiel läuft auf seiner eigenen Subdomain, getrennt von allen anderen und von der Plattform. Die Auslieferung setzt Cross-Origin-Opener-Policy und Cross-Origin-Embedder-Policy, damit Godot- und Unity-Exporte mit SharedArrayBuffer laufen.