Playground: disposable chain, test WCHI, wiped without warning
Builder docs

What you need

The repositories, access, and local tooling required to build an Arcade game.

The public arcade is curated. Build and test your game, then submit a GitHub issue with the repository, exact commit, WASM hash and game details. We review and test it privately before listing it. You do not need to run an arcade server to submit.

You build from the template; the SDK comes with it as a committed tarball, so there is no registry to sign into.

The repositories

RepoYour relationship to it
arcade-xayamanThe template: fork this. A complete, working game and the reference every Arcade game copies. Your game starts as a fork.
arcade-platformReference + SDK source. The host GSP, the judge, and @xayaarcade/sdk live here. You read it for the ABI/judge authority, and you vendor SDK updates from it (vendor-sdk.sh needs this checkout). Not forked.
arcade-xayashipsA second worked example, read-only. A different game (a naval duel) on the same template: useful to see which choices are game-specific. Not forked.
arcade-xayatrailsA third worked example, read-only. A 2..4-seat trail battle: a complete submission (rules blob, bundle, tests) to compare yours against. Not forked.
arcade-dungeonchannelA fourth worked example, read-only. A 2..4-seat hidden-information dungeon crawl: a one-byte cfgSuffix (01) and both optional additive surfaces, arcade_share_weights and arcade_ejected_mask. Not forked.

You only ever fork one repo: arcade-xayaman. The rest you read, vendor from, clone to run, or submit to. (The arcade site itself is the operator's: you never touch it; your game gets listed on it as part of registration.)

That table is the repos an Arcade builder touches. Most are private during the curated phase: access on request. /repos indexes every repository this site points you at: what it is, whether you can clone it today, how to ask for access, and whether your relationship to it is clone, read or consume. Go there before assuming a repository you found on GitHub is the current one; several of the obvious names are frozen pre-split monorepos that predate the Arcade entirely.

AI-assisted building

The template's .claude/settings.json enables the agent skills plugin, so Claude Code loads them when you open your fork and trust the folder: building-channel-games (the channel protocol plus the whole Arcade path: its ARCADE.md is the working summary of these docs) and building-persistent-games (the other architecture, meaning fully on-chain worlds, the libxayagame GSP and XayaX, plus the determinism and operations material both paths rest on). They cover the template layout, the blob contract, testing, and submission. The same corpus is browsable on this site at /skills, and downloadable there as a zip for an agent other than Claude Code.

Tooling

ToolVersionWhy
Dockerany recentThe rules blob, the C++ test battery and the frontend image all build inside pinned containers (blob/Dockerfile.blob-builder, blob/tests/Dockerfile.testenv, docker/Dockerfile.frontend). The first blob/tests/run-tests.sh builds the test image and downloads the pinned wasmtime C API inside that build, so that one run needs network access.
Node.js20.9 floor, 22 for the gatesThe template declares no engines field of its own, so nothing enforces a version: the floor comes from Next 16 (engines.node is >=20.9.0), the frontend image builds on node:20-alpine (docker/Dockerfile.frontend), and CI pins Node 22 (.github/workflows/ci.yml). 22 is what every gate is actually proven on: use it. The SDK installs from the committed tarball (no private registry); the other dependencies come from the public npm registry as usual.
Python 3anyblob/check-blob.sh's structural gate parses the wasm sections in stdlib-only Python: deliberately dependency-free, so the check runs anywhere, including where Docker is not available.
GitanyFork, commit the reproducible blob, track the vendored SDK.
A POSIX shellanyThe build/verify scripts are bash.

The build containers are x86_64-only. The blob builder pins wasi-sdk 24.0 for x86_64-linux by version and sha256 (blob/Dockerfile.blob-builder), and the C++ test image pins wasmtime 46.0.1 for x86_64-linux the same way (blob/tests/Dockerfile.testenv): it has to, because the determinism and fuel legs must run your blob under exactly the runtime the chain runs it under. The strip step is byte-sensitive on top of that. On an arm host (Apple Silicon and similar) run the containers under x86_64 emulation, or the reproduced hash will not match. Set BUILDX_NO_DEFAULT_ATTESTATIONS=1 for image builds so BuildKit provenance does not churn image IDs.

Neither of those two images needs repository access to build: the blob builder starts from debian:bookworm-slim and the C++ test image from the public xaya/libxayagame image, and both pull their toolchains straight from upstream releases, checksum-verified.

No wallet, no name, no money

Building, testing and submitting an Arcade game costs nothing. The offline ladder (Testing) runs with no chain, no relay and no funds at all. A playground hands you pre-funded, pre-named dev wallets, so a real two-player match over a real channel there needs no browser wallet, no Xaya p/ name and no WCHI; npm run dev:playground is the committed script that points your dev server at a playground, and PLAYGROUND_ORIGIN names it (Quickstart Part 3). A submission asks for artifacts and facts, not a signature. So you can go clone → build and test → submit a GitHub issue without spending anything.

A wallet, a p/ name and WCHI are for playing on the real arcade. A name is an ERC-721 you own; registering one costs WCHI plus POL for gas, and the fee is read live from the chain's name policy (xaya-arcade/src/lib/chain/name-check.ts) and shown on /account before you sign. Wagering costs whatever you stake, with one exception worth knowing before you play for money: the first three paid matches at a stake amount and player count nobody has played yet pay their pot to the operator, which starts that stake's payout queue. After that, each match pays earlier winners in queue order, for every game; the operator can seed a pool again later the same way. None of that is on the build path.

What you do not do

You can build, run, and fully test a game with just the template and the tooling above. The go-live plumbing is not yours: you submit, and an operator's Accept runs it for you; attaching a build to the public playground runs the same steps:

  • On-chain registration: the blob and reg admin moves (automated at Accept; the moderator signs with the arcade's admin wallet).
  • The path your game is served at: every game lives at /g/<slug>/ on the arcade's games origin, separate from the shell's hostname (see Overview). You build the bundle slug-agnostic against the placeholder base path /__arcade_base__, and the platform bakes the real /g/<slug> mount in (automated at Accept: arcade-platform/games-host/src/bake.ts). The placeholder must appear both in index.html and in the script chunk that loads arcade-config.json: building with the template's build-export.sh --bundle and its vendored SDK gives you both. You never choose, see or hardcode a path.
  • The shell content row: the registry entry that makes your game appear in this site (automated at Accept, via the site's runtime overlay: no rebuild).

One step stays a deliberate operator action, run after your game is live and never required for free play:

  • Wager enablement: the ArcadeWager registerGame call, which names your payout address as the game's fee recipient, and the reg-move wagering block (Hosting & registration §4).

Next: Getting started.