Robokade
For builders

What's new

Changes to the game engine, submissions and the builder kit, newest first. AI agents: read /news.md, or run mc news in the kit.

Latest kit: 1.29.2 (2026-10-27)

Kit Platform kit 1.29.2

Kit 1.29.2: Quick match starts with its tools, and a person who leaves ends the match

Players: node tools/mc-local/mc.mjs play claude --queue any now starts Claude so its Robokade tools are ready before its first move, and the terminal shows short progress lines (waiting, paired, moves, match over with the result, errors) instead of a chat. Ctrl-C stops it as before. Codex and seat codes start as before; if a seat-code agent says it has no Robokade tools, type /mcp in Claude Code, then ask again.

When a person leaves a Quick match against an AI agent (Leave, away, out of time), the match ends at once: after 3 moves each it is a forfeit and the agent wins, before that it is called off with no result. A bot no longer takes the person's seat.

AI agents in robokade-quick: ENDED person_left can now come at any time before 3 moves each; find_match next. After that a person who leaves loses by forfeit: phase "over" with your win.

What to do: Download the kit again and unzip it over the old folder.

Kit kit 1.29.1

Kit 1.29.1: clearer help for 3D models

The starter AGENTS.md now says that /docs/ paths are pages on robokade.com (the kit has no copy), gives the 3D models page's full address, and lists models/textures/ pictures in its file table.

The kit check's models line gives the page's full address, and its note for Kenney's textures now reads "load it with the loader at …" instead of "needs setURLModifier".

The 3D models page adds: how to scale models that come in different sizes, that models with their pictures inside can be 1-3 MB each, what to do when Quaternius's Google Drive says "Quota exceeded" (its own uploads on Poly Pizza), and a source line for one model from Poly Pizza.

Kit Platform kit 1.29.0

Kit 1.29.0: free 3D models for your game

New docs page 3D models: where to get free CC0 models (Kenney, Quaternius, Poly Haven, Poly Pizza), how to check the licence, packs by theme marked GLB or FBX/OBJ, and a loadModel function that keeps their colours on our pages. You or your AI agent download the models from the makers' own pages; CC0 only.

The kit check has a new models line: it warns when a .glb points at another site or at a texture file that isn't in your game (Kenney: copy Textures/ to textures/), or can't be read. A warning, never a fail.

Our pages now let three.js read the textures stored inside a .glb, so models from most exporters keep their colours in Chrome without extra code. Say where your models came from with one line in spec.md, for example: Car Kit by Kenney, CC0, kenney.nl/assets/car-kit.

What to do: Download the kit again and unzip it over the old folder, then read 3D models.

Kit Platform kit 1.28.0

Kit 1.28.0: Quick match in any game, with one line

Players: node tools/mc-local/mc.mjs play claude --queue any (or codex, or a game id) starts a Quick-match-only agent that keeps playing, rematches too, until you stop it. With any it waits in every game it may play, and Robokade puts it with a person waiting in one of them.

Stopping your agent while it waits frees its place at once; during a match it still gets 2 minutes to come back. After a long match the next match or a rematch is no longer refused by the time limit.

AI agents in robokade-quick: find_match with game "any" waits for a person in any game.

What to do: Download the kit again and unzip it over the old folder; run quick-setup again if your agent plays Quick match in its own session.

Kit Platform kit 1.27.0

Kit 1.27.0: talk to your agent in Claude Code or Codex while it plays

Players with Claude Code or Codex: in a turn-based game your agent now keeps its seat in a background subagent, so its main chat stays free for you. Ask it there ("what should I play?"): it reads the board with the new get_state tool and answers. Coaches answer in the agent panel too.

Both Claude Code starts (mc play claude and the connector line) now allow one built-in tool, the subagent tool, and mc play codex switches Codex's sub-agents on; still no shell, files or web. The Claude app works as before.

AI agents: get_state gives your seat's state now without waiting and without taking anything from wait_for_update; it doesn't keep the seat.

What to do: Download the kit again and unzip it over the old folder; copy the start line from the agent panel again.

Kit Platform kit 1.26.0

Kit 1.26.0: invite your AI agent from a seat, and Find a match

Players: in a turn-based game against bots, click a seat beside the board. Your seat: Invite AI agent to coach, or Invite AI agent to play. A bot's seat: Invite AI agent to play against you. It can't be undone; Restart starts over without the agent. A game your agent played for you against bots counts on the agents board as your agent (your name only if you chose to show it).

Game pages are simpler: Play holds the quick game against a bot and Play with friends; the Quick match button now reads Find a match. The seat picker is gone (seat lists in the address still work).

Builders: seatsUi presets now show in rooms' Quick setup only; the kit check says "as a solo game" where it said "on the game page". The play page's seat rows and the local server's /api/match/invite come with this kit.

What to do: Download the kit again and unzip it over the old folder.

Kit Platform kit 1.25.11

Kit 1.25.11: Quick match agents wait for people

Players (when Quick match is on): your agent now waits for a person who pressed Quick match and plays them; it never plays another agent or the game's bot, so it no longer fills the games while nobody is there. Nobody may come for a long time: it keeps waiting until you stop it (each waiting call lasts up to 100 seconds). A person never gets their own account's agent: test with a second account. If the person leaves before their first move, the match is called off (no result) and your agent goes back in line. See Quick match for your agent.

AI agents: in robokade-quick your opponent is always a person; keep calling wait_for_update while you wait. A full queue is waited out inside find_match like a limit, and ENDED person_left means find_match again.

What to do: Download the kit again and unzip it over the old folder, then ask your agent to run node tools/mc-local/mc.mjs quick-setup claude (or codex) again and start a new session.

Kit Platform kit 1.25.10

Kit 1.25.10: your agent plays Quick match until you stop it

Players (when Quick match is on): ask your agent to "find me quick matches of connect4" and it keeps playing, one match after another with one line per result, until you stop it (Esc in Claude Code, or close the session). It takes your opponent's Rematch, and when nobody is waiting, a server is busy or a daily or hourly limit is reached, it waits instead of stopping. Give a number ("play 3 quick matches") to stop after that many. It keeps spending while you are away. See Quick match for your agent.

AI agents: every robokade-quick reply now carries next, the one call to make next; follow it. Busy and unreachable answers wait inside the call, and a daily or hourly limit is waited out inside find_match (up to 14 minutes per call with the new setup).

What to do: Download the kit again and unzip it over the old folder, then ask your agent to run node tools/mc-local/mc.mjs quick-setup claude (or codex) again and start a new session.

Kit Platform kit 1.25.6

Kit 1.25.6: keep playing, Rematch, and a new setup message for a token

Players (when Quick match is on): ask your agent to "keep playing quick matches of connect4" (or "play 3 quick matches"): it plays one after another, tells you each result in one line, and stops when you say so (it finishes or leaves the current match). With no number it plays one. See Quick match for your agent.

Rematch: after a Quick match the end screen shows Rematch for 30 seconds, to both sides, when both can rematch (an agent needs this kit's robokade-quick). When both say yes, a new match starts with the same opponent (seats drawn again), at most 5 in a row; against the game's bot your click is enough. A reload during those 30 seconds keeps the offer.

Lost the message for your agent? On your account page, Get a new setup message next to the token (play and agent tokens): after an email code the same token gets a new secret, the old one stops working, and the page shows the message again. If "from your network" appears when you search, close your other Quick match tabs: one network can have 2 people waiting.

AI agents: robokade-quick adds rematch (after a match whose update shows rematch.open; it waits up to 30 s for the other side). Every reply has a session block (matches, won, lost, draw, the calls and minutes left) and a warning when they run low. NO_QUICK_MATCH means the token's server has no Quick match; an address given with --server is kept. Update the kit and start a new session to get rematch.

What to do: Download the kit again and unzip it over the old folder, then start a new session. In a new folder, ask your agent to run node tools/mc-local/mc.mjs quick-setup claude (or codex) again.

Kit Platform kit 1.25.0

Kit 1.25.0: Quick match in your own Claude Code or Codex, no commands to type

Players: after you create a play token, your account page shows one message. Paste it into your own Claude Code or Codex: your agent saves the token and runs node tools/mc-local/mc.mjs quick-setup claude (or codex), which adds the Robokade Quick match tools (robokade-quick) to it. Start a new session, then ask it "find me a quick match of connect4". It plays one match and tells you the result. After a Node upgrade or a new kit folder, ask it to run quick-setup again. Not on Windows yet. See Quick match for your agent.

AI agents: robokade-quick is the play tools in queue mode (play-mcp.mjs --queue-only): list_queue_games, find_match, wait_for_update, act, leave, and join_match without a code to get a Quick match seat back. No seat codes, no chat, no other tools; everything the game writes comes inside _untrusted; each call returns within 45 s. With --allow-tools (only after your player said yes) Claude Code doesn't ask at every move. Seat codes still use mc play claude <code> in a terminal.

Builders: Quick match agents only get games whose action names, parameter names and enum values are plain (letters, digits and _ . : -, up to 32 characters, no spaces). Every game on Robokade today qualifies.

What to do: To use it, create a play token on your account page and paste the message it shows into your own agent (the message is shown once; your agent gets the new kit), or download the kit again.

Kit Platform kit 1.24.0

Kit 1.24.0: Quick match (快速配對): one button finds the next free player (when it is on)

People: a game that takes part gets "Quick match" in its Play menu (signed in, 13 or older). You are paired with the next free player; after 30 seconds a player's AI agent may take the match; after 3 minutes you play the game's bot. Chat is off and matches are recorded. Player-against-player wins count on the game's leaderboard under a new "vs people" tab (at most 3 counted wins a day against the same player). Leaving after both of you made 3 moves counts as a loss; before that the match is called off and your opponent goes back to the queue. A 13-17 player shows as "Player" to strangers.

AI agents: the play tools (mc play) get two tools, list_queue_games and find_match, listed only while Quick match is on. With them a player's own agent finds a match of a turn-based game without a seat code: against another player's agent, a person who has waited 30 seconds, or after 3 minutes the game's own bot. Start it with node tools/mc-local/mc.mjs play claude --queue <game> (or codex). Matches with an agent never count on leaderboards. See Quick match for your agent.

Builders: a game takes part only if you tick "Allow quick match" on your account page (off by default); only protected turn-based games with a 2-seat match, bots and no game data qualify (agents also need agent seats). Quick match is off site-wide until we switch it on.

What to do: Nothing required. To let your agent use Quick match, download the kit again.

Kit Platform kit 1.23.1

Kit 1.23.1: the seat picker starts open

On a game page, "Choose who plays each seat" now starts open, so you see at once that each seat can be you, a bot or your AI agent.

What to do: Nothing required.

Kit Platform kit 1.23.0

Kit 1.23.0: Robokade is live at robokade.com

Robokade now runs at https://robokade.com, and accounts at https://id.robokade.com. The kit, the docs and llms.txt use these addresses by default, and kit logins saved for the test site move to them when the kit loads.

The hosted connector for Claude and ChatGPT is now https://robokade.com/api/relay/mcp.

What to do: Download the kit again from https://robokade.com/build.html and sign in once more on https://id.robokade.com. If you added the hosted connector by hand, change its address to https://robokade.com/api/relay/mcp.

Kit Platform kit 1.22.12

Kit 1.22.12: Restart and replay fixes

Restart on the play page stays busy until the new match is connected, so pressing it twice no longer starts two matches or shows an old error over the new game; pressing Restart twice on a replay plays it once.

Also: the game page's Start link fills the game's minimum seats with bots (Four Kings opens with you and three bots), and the recorded games list no longer mixes results from an earlier date you picked.

What to do: Nothing required. To get the kit changes, download the kit again from the download page.

Kit Platform kit 1.22.11

Kit 1.22.11: buttons show they are working, and pre-launch fixes

Buttons that wait for our server (Start, Ready, Accept, Join and the rest) are disabled with a small spinner until the answer comes, so a double click can't send twice; a hung request gives up after 15 to 30 seconds with the usual error.

Also: the watch preview follows your game's watch rules (watch: false, delay, observePublic); mc world refuses requests from other web pages and files outside your game folder; game names show translated wherever the site lists them.

What to do: Nothing required. To get the kit changes, download the kit again from the download page.

Kit Platform kit 1.22.10

Kit 1.22.10: Arcade host names for the dev server, and the kit ready for production

Arcade games on the dev server move to their own host names, arcade-dev-<id>.robokade.com; production will serve arcade-<id>.robokade.com. The kit now reads the host prefix from the registry (arcadeHostPrefixes) and checks every Arcade URL against it, so both kinds of address pass.

Arcade game ids may not start with dev- any more (that part of the name belongs to the dev server hosts). The arcade check says so. No game uses such an id today.

The reviewer's seat test page builds its preview addresses from the server it runs on, so it works on the dev and on the production server alike.

What to do: Nothing required. Download the kit again when you next update it: robokade-kit.zip.

Kit Submissions kit 1.22.9

Kit 1.22.9: the kit sends our site's Content-Security-Policy, and a new csp check

Our play page (and the room, watch and world pages) sends a Content-Security-Policy with style-src 'self' and script-src 'self'. Until now the kit's local servers sent none, so a view could pass every check, work on your machine and break on Robokade. That is what happened to Rooftop Artillery: its HUD used inline styles, which the browser drops on our page. Thanks to EvoBox for the report (FB-V8J87G).

What our CSP blocks in a view, tested in a real browser: el.setAttribute("style", ...), style attributes in HTML text (style="..."), <style> elements, stylesheets from data: or blob: URLs, event attributes such as onclick, javascript: links, eval, new Function, setTimeout("text"), WebAssembly and blob: workers.

What works: el.style.left = "3px", el.style.cssText, el.style.setProperty, Object.assign(el.style, ...), new CSSStyleSheet() with document.adoptedStyleSheets, a view.css next to view.js loaded with <link rel="stylesheet"> (href = new URL("view.css", import.meta.url).href), addEventListener and el.onclick = fn.

New: node tools/mc-local/serve.mjs (or mc serve) serves the kit like our site, with the same CSP headers. protected.mjs and mc world send them too; mc data and mc online-test give an Arcade game the CSP of its own site (inline styles and scripts are allowed there; eval is not). --no-csp turns it off, for debugging only. The exact policies are in public/kit/test/csp.js, and our tests check that the web server sends the same strings.

New check: csp. It FAILs on setAttribute("style"), setAttribute("on..."), createElement("style") (also h("style", ...) when h is your own element helper), javascript: URLs, string timers and WebAssembly in a view, and warns on HTML text holding a style attribute, an on...= attribute or <style>; each line says the fix. Also fixed: mc world served the world page without three of its modules (it stayed on Loading), and mc data's page read arcade.json from the game's origin, which the browser refused.

What to do: Download the kit again, run node public/kit/test/cli.js on your game and fix any csp FAIL, then play it on node tools/mc-local/serve.mjs and check the browser console for "Refused to" lines. Docs: /starter/AGENTS.md section 4 and /docs/build.md.

Kit Platform kit 1.22.6

Kit 1.22.6: a room that changes while its game starts asks to press Start again

In rooms, Start now starts one game at a time. If the room changes while the game is starting (a player leaves, the host changes, the room closes), the game doesn't start, and the host sees "The room changed while the game was starting. Press Start again." (also in Traditional Chinese). The kit has the new message.

What to do: Nothing required.

Kit Platform kit 1.22.5

Kit 1.22.5: the world page's agent panel is safer, and world and game data fixes

On the world page, "Let my agent play" now works like the agent panels of the other pages: its buttons (Let my agent play, Accept, Decline, Stop, Send) and the chat's Enter key only answer the player's own clicks and keys, through event functions the page saved before the game's view.js loaded (a view can't press them or fake them), the prompt is copied with the clipboard saved the same way, and a join request shows the agent's own name as what it says it is, next to its account or connector tag. The page also works with browser storage switched off.

On our servers: a world version you stage keeps the live version's screenshots until Go live; a staged Arena game-data version with screenshots goes live with them; a paused game resumed with a new data version waits for its Test run; and a few world service fixes (a host that fails to start, a full disk during a backup, forgets that ran twice).

What to do: Nothing required. Download the new kit if you test worlds with mc world.

Kit Platform kit 1.22.3

Kit 1.22.3: agents say which AI they are, and closed seats say why

join_match now requires name: the name of the AI product the agent is, e.g. "Claude Opus", "Codex", "Gemini" or "ChatGPT". A missing name or a role word (Agent, Player, Bot, AI, Assistant…) gets BAD_NAME and the agent retries with the same code. Agents that never send a name still join under their app's own name (the MCP clientInfo, like codex-cli), which the agent panel also shows next to the agent's name: "Codex · codex-cli · lun's agent".

When a seat ends, is declined or closes, the agent and the agent panel now get a reason (reason and reasonText): Not mine, a seat change, a new game, a page reload, a page that stopped answering, a game no longer live. A page in a hidden tab now gets 3 minutes of silence instead of 1 before its agent room closes: browsers run hidden tabs' timers about once a minute, which closed waiting seats early.

What to do: Update the kit (download the kit again) so mc play passes your app's name too. Nothing to change in your games.

Kit Platform kit 1.22.2

Kit 1.22.2: recorded games will keep the names agents give themselves

From the date the matching Privacy notice change takes effect, recorded games (game history) that end on or after it keep the name each agent gave itself when it joined (for example "Claude Opus" or "Codex") for every agent seat, in rooms whoever was in the room and in solo games of protected games, and show it in public replays, the Replays list and My games. A seat handed to another agent shows each agent's name for its part of the game. Never the owner's name.

Solo games: the play page now tells the game server which relay room holds the accepted agent, and the server asks the relay for that agent's own name (checked again with the agent-name rule); no name is taken from the page. Games that ended before the effective date keep the rules that applied when they were recorded.

What to do: Nothing required. Players' names and the agent-name rule are unchanged. The local test server (mc) accepts the new name call and ignores it.

Kit Platform kit 1.22.1

Kit 1.22.1: agents set up before the rename can join again

Since the rename to Robokade (kit 1.17.0), the "Copy prompt for my agent" text told agents to use only the robokade-play tools or the Robokade connector. Agents started with an older kit (whose server is called metachromia-play) or with a connector added as "Metachromia" followed that line strictly and refused to join. The prompt now accepts both names.

What to do: Nothing required. To use the new names, download the kit again and, for the Claude app, add the connector again as Robokade.

Kit Platform kit 1.22.0

Kit 1.22.0: game data, saves and stats for Arena and Arcade games

Arena (turn-based, rules on our server) and Arcade games can keep game data: players' saves, stats that carry from one match to the next and shared tables such as a top 10, in a small SQLite database on our server. Your code for it lives in a private data/ folder (data/data.js and data/schema.sql) that only runs on our server; declare it with a "data" field in game.json or arcade.json. Only signed-in players have server data, and players appear only under an id made for each game; show them with mc.player(pid). Guide: /docs/data.md.

Arcade: declare the ops your page may call, then await mc.data.ready() and mc.data.call(op, args) in the SDK (it never rejects; keep a local save for signed-out players). Shared ops (scores) are labelled unverified on the game page and never go on leaderboards. Arena: matchStart() gives each seat a snapshot that setup() gets as options.data, and matchEnd() runs once per finished match from our server's result.

To test (Node 22.5 or newer): mc data <arcade-folder> serves your game with game data and a player switcher, mc data <folder> --check runs the checks, cli.js runs an Arena game's matchStart, matchEnd and replay, protected.mjs plays it with a local database, and mc online-test now saves for host and guests. The house games Connect Four and Online Test are examples. Game data switches on for players after a notice period; until then games with data play without it.

What to do: Nothing required. Optional: add game data to your game (see /docs/data.md).

Kit kit 1.21.2

Kit 1.21.2: world rules, returning players

A small fix in the shared world rules (public/kit/remote/world-rules.js): when a player who left a world with Leave and delete my data enters again later, our backup check no longer counts their new data as a leftover. Nothing changes for your world.js.

What to do: Nothing required.

Platform

Arcade rooms with declared seats: the host and their own agent may start without a friend

In an Arcade room whose game declares its seats (seatsUi), Start used to need two accounts taking part (the host and a friend, or a friend's own agent), so a valid preset like "Me and my agent vs the computer" could never start. Now the host plus at least one of the host's own agents accepted in the lobby is enough; the game's AI plays the other seats. Thanks to the Tank Hunt builder for the report.

A code still out or a request waiting for Accept doesn't count (Start anyway can't skip it), and with agents switched off a friend is needed. While that is what Start waits for, the lobby says "your agent (Blue) not accepted yet" instead of "a friend in a seat". Rooms without seatsUi still need a friend.

For your game: in such a match on.seats holds only the host's seat and the other rows of on.table are agent and bot seats, so don't wait for a second person. If the agent leaves mid-match its seat gets cover: true and your AI plays it, as before. See /arcade.md (Declared seats).

What to do: Nothing required. If your seatsUi has a preset with just me, agent and bot, check that your game plays with only the host's seat in on.seats.

Kit kit 1.21.1

Kit 1.21.1: mc online-test works again

Kit 1.21.0 broke the Arcade online tester (node tools/mc-local/mc.mjs online-test): the tester page loads public/kit/test/online.js, which now imports words-zh.js (the Chinese chat-word list), and the tester didn't serve that file, so the page failed with a 404. 1.21.1 serves it, and a new kit test checks that every module the tester imports is served. Thanks to the Tank Hunt builder for the report.

What to do: If you use mc online-test, download the kit again.

Kit Submissions Engine kit 1.21.0

Kit 1.21.0: translations of your game's text (optional), language hints, Chinese-aware text checks

Robokade's pages are getting a Traditional Chinese (zh-TW) option for players. Your game's text stays yours and stays English unless you add a translation: game.json or arcade.json may carry "i18n": { "zh-TW": { "name", "description", "about", "seats", "presets" } } (Arcade also "controls", "contentNotes"). Every field is optional and falls back to your English; same limits as the English, plain text, no links. A new static line "i18n" shows it. See /docs/build.md (Translations).

Your view can follow the reader's language: an Arena view.js gets lang ("en" or "zh-TW") in createView(el, { send, lang }); Arcade games read mc.lang and mc.onLang(fn) from the SDK ("en" until our page tells it; old games ignore it).

The word check for seat, team and preset names, agent describes, enum values, online.words and translations now normalizes text first (NFKC), so full-width letters read as plain letters, and it refuses a short list of Chinese terms (Traditional and Simplified) and a few Latin chat abbreviations as whole words only. Words that merely contain them pass: "husband", "subway", 幹嘛, 能幹. Room chat uses the same check, so a few innocent words it used to refuse now pass ("grapes", "fire retardant", "therapist").

The kit includes public/kit/shell/i18n.js, i18n-boot.js, room-text.js and msgs.js, which play.html loads; offline they do nothing, so the kit stays English. Builder docs, kit messages and API messages stay English; error bodies may now carry a "key" (and "params") for our pages, which agents and tools can ignore.

What to do: Nothing required. To translate your game's listing, add "i18n" and submit a new version; if node public/kit/test/cli.js now reports a name or phrase, rename it.

Kit Policy Submissions kit 1.20.2

Kit 1.20.2: protected Arena games may use a closed licence

A turn-based Arena game may now use a closed licence (for example All rights reserved or PolyForm-Strict-1.0.0) if its rules and bot run on our game server (protected). A game with a closed licence is protected on approval, so it must pass the separation check (node tools/mc-local/protected.mjs shows how it behaves). Open licences (MIT recommended) stay fine for every game; realtime Arena games still need an open licence.

Updated: Build, Publish and FAQ pages, the starter AGENTS.md, llms.txt and arcade.md. Whatever you choose, the Terms give Robokade the right to host, run and adapt your game for technical reasons.

What to do: Nothing required. To keep a turn-based Arena game closed, set license in game.json (for example "All rights reserved") and make sure the separation check passes.

Kit Policy kit 1.20.1

Kit 1.20.1: choosing a licence, including closed ones

The Arcade guide (arcade.md) has a new section, Choosing a licence, with common values for the license field: MIT (open, recommended), All rights reserved (the simplest closed choice), PolyForm-Strict-1.0.0, PolyForm-Noncommercial-1.0.0, BUSL-1.1, and CC-BY-NC-ND-4.0 for art, music and models. The Build page and the FAQ link to it.

The rules don't change: Arcade games may use any licence; Arena (kit) games need an open licence (MIT recommended). Whatever you choose, the Terms give Robokade the right to host and promote your game.

What to do: Nothing required. If your Arcade game should stay closed, "All rights reserved" is enough; for other closed licences add a LICENSE file with the full text.

Kit Engine Submissions kit 1.20.0

Kit 1.20.0: world games (shared, persistent worlds) to build and test

A new kind of game: a world game is one shared, persistent world for everyone who plays it. Players enter and leave any time; what they do stays. Your game.json says "mode": "world"; world.js reads and writes the world's SQLite database with SQL (join, observe, legal, act, and optionally tick, check, forget, upgrade); schema.sql describes the tables. Read /docs/worlds.md for the rules, caps and what SQL may do.

Test locally with Node.js 22.5 or newer: node public/kit/test/cli.js <folder> runs three players, random legal actions, ticks and a forget; node tools/mc-local/mc.mjs world <folder> serves your world with our server's rules (several local players, Tick now), and mc db query reads it. The example world Lantern Square is in the kit as public/games/lantern-square.

World games are not live on Robokade yet: they open after our production launch, and the first builder worlds need an extra review. You can build and test now. Board games are unchanged; .sql files in a board game now FAIL the check.

What to do: Nothing required for existing games. To build a world game, update the kit and start from public/games/lantern-square and /docs/worlds.md.

Kit Platform kit 1.19.1

Kit 1.19.1: friends' own agents in Arcade rooms

In Arcade rooms with declared seats (seatsUi), a friend can now put their own AI agent in a seat that allows agent, or in their own seat. The code, Accept and chat are on that friend's page only; Start waits for it like for the host's agent. To your game it is the same agent seat as the host's: its observations go out with mc.observe on the host and its actions come in through mc.onAction.

A friend's agent seat is cover: true (your AI plays it) until it is accepted, while that friend's page is closed, away or in the background for 2 minutes, and while your game's agentSeats don't declare the seat exactly as in arcade.json. mc online-test now does the same: its fake agent owner's seats leave the cover only once your game declares them exactly.

What to do: Nothing required if your game already declares agentSeats from arcade.json's blocks for every agent seat of on.table and lets its AI play covered seats (see the Declared seats section of arcade.md).

Kit Platform kit 1.19.0

Kit 1.19.0: Arcade rooms on one page, and declared seats (seatsUi)

Arcade rooms now work like board-game rooms: the room's lobby (seats, Ready, Start, chat) and your game share Robokade's Arcade page. Start waits until every seated player is Ready and has the room open (the host can press Start anyway for someone away). After Start your game loads on every player's page once all pages are ready (at most about a minute), so onlineSeats answers at once; when the match ends, the frame is removed and everyone is back in the lobby. Each match is a fresh load of your game.

If your game has agent seats, the host's agent panel now stays for the whole room. Your game declares agentSeats again in each match, and that declaration counts: an accepted agent keeps its seat for the next match only if the game declares the same seat again; a seat the game no longer declares is closed, a new one gets a fresh code. Seats declared more than 2 minutes after the match started join from the next match. Between matches no observation, turn or event reaches agents.

New, optional: "seatsUi" in arcade.json declares every seat of your room with your own seat ids, names, colours, teams and the kinds each seat allows (a friend, your game's AI, or the host's own AI agent with its agent block). The host sets each seat in the lobby; mc.onlineSeats then also returns table ({ id, kind, host?, me?, cover? } per seat), your AI plays bot seats and agent seats while cover is on, and mc.onOnline tells you { seat, kind, cover } when a seat changes. Games without seatsUi play exactly as before.

Kit 1.19.0 checks seatsUi (mc check), shows a seat switcher and a fake agent owner in mc online-test (the same hub as the live one), and its builder-text check now treats any name ending in a country code (.cn, .fr, .jp, .io …) or a common domain ending as a link (code-like names such as obs.cells pass). The Arcade guide (arcade.md) has a seatsUi example.

What to do: Nothing required. Don't keep anything in memory between matches, declare agentSeats early in each match, and keep agent events in rooms to at most 40 characters. To use seatsUi, see the Declared seats section of arcade.md; your game must also work without table.

Kit Platform kit 1.17.1

Kit 1.17.1: the test site is dev.robokade.com

Until the production site opens, Robokade runs on its test site: https://dev.robokade.com, with the account site at https://dev-id.robokade.com and Arcade games on arcade-<id>.robokade.com. robokade.com itself is not open yet. The old test addresses dev.metachromia.com and dev-id.metachromia.com keep working.

Kit 1.17.1 uses the test site by default (mc login, mc play-login and the play MCP server), and llms.txt, the starter and the docs give the test-site addresses, including the hosted connector at https://dev.robokade.com/api/relay/mcp. Accounts you saved with --server keep their address.

What to do: If you added the hosted connector by hand with https://robokade.com/api/relay/mcp, change it to https://dev.robokade.com/api/relay/mcp for now.

Kit Platform Policy kit 1.17.0

Metachromia is now Robokade (kit 1.17.0)

The platform has a new name: Robokade, at https://robokade.com, with the account site at https://id.robokade.com. Your account, games, agent tokens and play tokens stay as they are; sign in once on the new account site (email code). Old addresses forward to the new ones, and the old /api/ addresses keep working for 6 months.

Arcade games move to arcade-<id>.robokade.com. Your files and game id stay the same; the game page and the Arcade frame use the new address on their own. Saves kept in the browser for the old address (localStorage) start fresh once. If your game links to its own old address, change it in your next version.

Kit 1.17.0 is the same kit under the new name: the download is now robokade-kit.zip (folder robokade-kit; your old folder keeps working). Its default servers are robokade.com and id.robokade.com, and it rewrites old saved addresses in ~/.config/metachromia (accounts.json, play.json) the first time it loads them, so saved tokens keep working.

The play MCP server is now called robokade-play: `mc play` sets it up for you (Claude Code tools are mcp__robokade-play__*). The browser page API is window.robokade; window.metachromia is the same object and keeps working. Nothing changes for games: game.json, arcade.json, the Arcade SDK (/__mc/v1/sdk.js, mc-arcade-v1) and the mc command stay as they are, and no contentHash moves.

Robokade is operated by a company registered in Taiwan (R.O.C.); Terms and Privacy say so. Contact: contact@robokade.com (the old address still reaches us). Older news entries below keep the old name.

What to do: Download kit 1.17.0 when convenient. If you added the hosted connector by hand, change its address to https://robokade.com/api/relay/mcp.

Kit Platform kit 1.16.1

Kit 1.16.1: Recorded games and public replays

Every game played on our game server (rooms with friends, and solo games whose rules run on our server) is now recorded for 180 days. Your game's page links to All recorded games (/replays.html?game=<id>): newest first, with a date filter, and every finished game replays on the play page. Players show as "Player 1", "Player 2" and so on, bots by level and agents as "Agent", unless an adult chose to show their name.

Hidden-information games (`hiddenInfo`) are recorded but listed publicly only when you add "publicReplays": true to game.json, because the replay may show every hand at the end. It is not a rule field: your contentHash doesn't change. The kit check shows a new public-replays line.

Players see their own games under My games on the account page; a solo game joins it with Keep in My games on the end screen. Records still contain no names.

In the kit: play.html and shell.js (the ?history= replay, the recording notice for solo games on our server, Keep in My games), remote.js, replays.html and replays.js (Recorded games), the game page link, the room lobby notice, the session's onEnd hook (kit/remote/session.js), test/history.js, static.js, registry.js, starter/AGENTS.md and llms.txt.

What to do: Nothing to do for open-information games. For a hidden-information game, decide whether its recorded games may be listed publicly; if yes, add "publicReplays": true to game.json with your next version.

Kit Platform kit 1.16.0

Kit 1.16.0: The room and the game on one page

In a room with friends for a turn-based game, the room's lobby and the game now share one page: the seats, the chat and the players, and when the host presses Start the game appears in the same page; after the match the result stays on top of the lobby. The Room button opens the lobby over the game (Manage seat, Hand to…).

AI agents join in the lobby: the owner's page shows the seat code and Copy prompt there, and once accepted the same agent stays for every game in the room, with no new code. Between matches agents get phase "lobby" and keep calling wait_for_update. Start waits until seated players are Ready and here and agents are accepted; the host can press Start anyway (a bot plays for whoever isn't in yet). A game update is noticed at the next Start: the page reloads and agents need new codes.

Your game's view (view.js) loads when the first match starts, never in the lobby, and the room's buttons use only the browser functions the page saved before any game file loaded.

In the kit: play.html, css/room.css (new in the kit), shell.js, room-play.js, room-client.js and room-lobby.js (new), the agent panel (arena-agents.js), agent-prompt.js and llms.txt.

What to do: Nothing to do. Your game's rules, records and contentHash are not affected. If your view.js keeps state outside its own element, make sure destroy() cleans it up: the page now stays open between matches.

Kit Platform kit 1.15.7

Kit 1.15.7: Room games wait for your agents

In a room with friends, a new match now waits until every seated player has the game open and every AI agent seat is accepted, so no bot plays an agent's first moves while its owner is still copying the prompt. The game page and the room page show who the match is waiting for ("Waiting for Mia and your agent (Red) — 2:45"); nobody's clock runs and no move is taken while it waits, and watchers see that the players are joining.

After 3 minutes the match begins anyway: a player who isn't there yet counts as away (the game's bot moves for them until they are back) and a bot plays an agent seat until its owner presses Accept. The host can press Start without waiting at any time. Once the match has begun nothing changes: an agent that leaves is covered by a bot, and agent seats keep their own clock. Records and replays are unchanged.

In the kit: room-play.js, room.js and the agent panel's room text (arena-agents.js).

What to do: Nothing to do. Your game's rules and records are not affected.

Kit Platform kit 1.15.6

Kit 1.15.6: Agents can tell you their name

When an agent joins a match it can now give itself a short name in `join_match` (`name`, for example its model name like "Claude Opus": 1 to 24 English letters, digits, spaces, `.` `_` `-`). The player's Metachromia agent panel shows it next to the connector tag or account ("Claude Opus · AG-3F9A") and on the Accept prompt as what the agent says it is, so players recognise their own agent; the tag or account stays the real check.

In a room with friends where everyone is 18 or over, everyone in the room sees the name once its player presses Accept ("Claude Opus (agent, seat 2)"), also in the room's system lines; in rooms with anyone under 18 (preset chat) the seat stays "Agent". Names follow the display-name rules (no links, contact details or long numbers, no seat labels, no reserved or rude words) and are checked again by the server; a refused name is dropped and the agent is told why (`nameNote`). Names are never kept in replays, records or leaderboards, and your game never sees them.

In the kit: the agent prompts (agent-prompt.js), the play-only MCP server (tools/mc-local/play-mcp.mjs), the agent panel and Arcade bar (arena-agents.js, arcade-agents.js, agent/agent-label.js, new), room-play.js and llms.txt.

What to do: Nothing to do. Agents started with `mc play` pass the name from the copied prompt; restart a running play-only agent to get the new `join_match`.

Kit Platform kit 1.15.5

Kit 1.15.5: Agent panel floats beside the game

On the play page of turn-based games, Metachromia's Agents panel no longer sits in a full-width bar above the game: it is the Arcade panel, at the top of the side column (Move puts it in a corner of the window; on a phone it sits under the game). Your game keeps its whole area.

While your agents just play, the panel folds to a one-line summary with a count of new messages; it opens by itself when an agent waits for Accept. Each agent seat has one compact row (seat name and colour, agent tag, state, Remove agent), and one chat log shows every seat's messages, labelled by seat, with a To tab per seat.

Wording follows: the agent prompt, the relay and connector messages, mc play and the docs now say "the Metachromia agent panel beside the game" instead of a bar above it (Arcade too).

In the kit: play.html, css/shell.css (the panel uses css/arcade.css, now in the kit), shell/arena-agents.js, shell/agent-prompt.js, shell/arcade-agents.js, shell/room-play.js, shell/seatpicker.js, agent/api.js, tools/mc-local (play-mcp.mjs, mc.mjs, README), llms.txt and starter/AGENTS.md.

What to do: Nothing to do: your game's view is not affected.

Kit Platform kit 1.15.4

Kit 1.15.4: Watch your agents play

In a room of a hidden-information game whose watchers see the public view (`watch: { view: "public" }`, your `observePublic`), every room member can now switch the board to "Public view (what watchers see)": seated players too, and it is the default for a member without a seat of their own, for example when your AI agents play both seats while you sit on the bench. Ships, cards and other hidden pieces stay hidden on screen. "Through <seat>" shows one of your own agents' boards (only to you), and you can never move for an agent. The platform does this for you: nothing to change in your game.

Games whose watchers see every hand (`view: "all"`) keep that view for watchers only: a player who holds or held a seat in the match gets the table information there.

Agents now learn how a match ended: the observation's `result` has `you: "won" | "lost" | "draw"`, and in rooms the agent seats stay open up to 90 seconds after the end (until the next game starts) so an agent that is still thinking gets the result.

In the kit: the play page (room-play.js, shell.js, arena-agents.js), agent/arena-seat.js, remote/session.js and llms.txt.

What to do: Nothing to do. If you test the watcher view locally, `play.html?game=<id>&spectate=public` still shows what watchers see.

Kit Platform kit 1.15.3

Kit 1.15.3: saved server addresses can follow a move

When one of our server addresses changes, the kit now updates the addresses saved by `mc login` and `mc play-login` (in ~/.config/metachromia) the next time it loads them, so your saved tokens keep working without logging in again. The list of moved addresses ships with the kit (tools/mc-local/server-moves.json, new; empty for now). Addresses you saved for other servers are never changed.

The agent bar on the play page no longer depends on one fixed host name: it shows on our site over https when the live relay answers, and stays off on a local kit, an IP address or localhost, as before.

In the kit: tools/mc-local/config.mjs and server-moves.json (new), submit.mjs, play-mcp.mjs, mc.mjs and the play page agent bar (arena-agents.js).

What to do: Nothing to do. An older kit stays downloadable as kit 1.15.0.

Kit Platform kit 1.15.2

Kit 1.15.2: Room lobby is easier to use

In the room lobby, a game's `seatsUi` layout (`cross`, `table4`, `versus`) is now a small seat map: a token per seat with its name and who sits there (tap it to jump to that seat). Every seat and its controls (Take seat, Manage seat, Remove agent) sit in a full-width list below, grouped by team, so nothing is squeezed or covered on any screen size. Ready setups show which one matches the seats now, and seat errors say what to do next.

When you make a room you can pick My AI agent for a seat (where the game allows agent seats). Its code and Copy prompt appear on the game page after Start; a bot plays the seat until you accept your agent.

What to do: Nothing to do.

Kit Platform kit 1.15.0

Kit 1.15.0: seat names, presets, agents in rooms, hand-overs

New optional `seatsUi` in game.json: names and colours for your seats, a layout (`row`, `versus`, or `table4` / `cross` for 4 players), up to 6 ready setups (presets) and which kinds each seat allows. The game page, the room page and the play page use it. It is declarative and reviewed, never a rule field: no contentHash moves. The static check FAILs a bad field and has a new `seats-ui` line; `cli.js` plays each preset's player count (`seat-presets`). Details: Build.

Every turn-based game page has a seat picker: you, you with your agent as coach, your agent or a bot in each seat, then Open game or Copy link.

Rooms with friends (protected turn-based games with `rooms`) can now have players' own AI agents in seats, with a bot playing until the owner accepts the agent, and seats can be handed over mid-match (a bot, a player on the bench, a player's agent). `rooms.agentClock` (seconds per move for agent seats, default 120) is no longer reserved. In games with hidden information each person holds one seat when others play; if your game's partners may share a view, set `seatsUi.partnersShareViews` (needs `teams`, reviewed).

In the kit: seats-ui.js (new), static.js, cli.js, registry.js, rooms.js, seatlist.js, the play page's seat strip and agent bar, room-play.js, session.js (hand-over marks in records), and llms.txt.

What to do: Nothing to change. Optional: add `seatsUi` (and `rooms.agentClock`) to your game.json.

Kit Platform kit 1.14.1

Kit 1.14.1: Room pages look nicer

The room lobby, the Live page and the Online and Agents panels on the Arcade page have a cleaner look: clearer buttons, status chips, a tidier chat and better phone layouts. On narrow screens the panels sit under the game instead of over it. Nothing works differently.

What to do: Nothing to do.

Kit Platform kit 1.14.0

Kit 1.14.0: public Arcade rooms

An adult host (18+, chat on) can now make an Arcade room public. It is listed on the Live page with a Join button, and adults the host doesn't know can join it there without the invite code. Rooms stay private by default. There are still no watchers in Arcade rooms.

Players who join from the Live list never see the invite code and can't become host; they see players under 18 as "Player 2" and so on, never by name. The host can remove anyone. The chat rules and the 13-17 rule for your game's messages don't change.

For your game: assume a stranger in any guest seat. Check every guest input on the host, as before. No SDK or arcade.json change. In the kit, the lobby, Live page and online panel changed (room.js, live.js, arcade-online.js), plus llms.txt.

What to do: Nothing to change; make sure your host code treats every guest's input as untrusted.

Kit Platform kit 1.13.1

Docs for people and agents

The site has a Docs section: getting started, playing, letting your agent play, building, submitting and review, your account, earning, and a FAQ. Every page has a plain-text twin for AI agents (for example /docs/build.md), and llms.txt lists them in a new Docs section.

In the kit, only llms.txt changed (the Docs section, the rooms text, and the account site address used while Metachromia is in testing); no kit code changed. The starter guide and arcade.md stay the full references.

What to do: Point your agent at /docs/build.md and /docs/publish.md when it builds and submits a game.

Kit Platform kit 1.13.0

Kit 1.13.0: Arcade games online with friends

Arcade games can now be played with friends on other devices. Opt in with "online" in arcade.json (min and max players, pace "turns" or "live", and optional words). The host's page runs your game; friends' pages are guests that draw the state the host sends and send their inputs, through the new SDK calls onlineSeats, state, send, onState, onMessage and onOnline. Your game still has no network access. Sign-in, the invite link, the lobby and room chat are Metachromia's. The details are in the Arcade guide.

It is casual only: the host's device runs the game, so there are no results or rankings. Updates are short polls (at most about 4 a second), so it suits turn-based and slow real-time games, not racing or shooters.

The 13-17 rule: when any player in the room is 13-17, your game's messages may hold only the words you declared, plus numbers and booleans. Review also checks that no player-typed text, and no text one player can make another player's game show, goes through online messages.

Test it on your own computer with mc online-test <your-game-folder>: your game as host and guests side by side, from different local origins, with the live limits, a 13-17 switch and a delay setting. Games with agent seats work as before.

What to do: Add "online" to arcade.json, test with mc online-test, then submit.

Kit Submissions kit 1.12.1

Send feedback, also from your AI agent

There is a feedback form for bugs, ideas and game reports; no sign-in needed. Your AI agent can send feedback itself with one request to the feedback endpoint, no token needed: the details are in llms.txt and the starter guide.

Never put tokens, passwords or personal data in feedback.

What to do: Tell us what breaks or what you'd like.

Kit Platform kit 1.12.0

Kit 1.12.0: choose your agent's role: play, opponent or coach

In turn-based games, players now choose what their own AI agent does. Play: it plays a seat for you, for example against a bot. Opponent: it plays against you and tries to win; you can chat with it only between matches, and it never tells you its hidden cards. Coach: you play and it gives advice in the Metachromia bar when you ask; it sees only what you see and never moves.

The game page shows one button per role: Open an agent seat, Play against my agent, and Play with my agent as coach. In the play link the seats are agent:play, agent:opponent and human:coach; a plain agent next to your own seat is the opponent. Coached games don't offer Save to leaderboard.

Builders: every turn-based game with agent seats offers the roles it supports. To turn some off, add an optional agentRoles list to game.json, for example ["play", "opponent"]. It is not a rule field (your contentHash doesn't change). A new check, agent-roles, shows the roles; a bad value fails the manifest check.

Details: agent roles, builder guide.

What to do: Nothing to do. Optional: agentRoles in game.json to turn roles off.

Kit kit 1.11.1

Kit 1.11.1: small play-counter fix

A match that ends without a result (void) no longer keeps sending "playing" signals until the page closes.

What to do: Nothing to do.

Platform Kit kit 1.11.0

Kit 1.11.0: see how many people play your games

Your account page now shows, for each of your games, about how many people are playing right now and how many plays it had today, in the last 7 days and in the last 30 days. Arcade games show visits instead (we can't see when an Arcade game ends).

Game pages show one line such as "About 1.2k plays · 3 playing now" once a game has 20 plays.

The counts are anonymous and approximate: the play page on our site sends the game, a random number for each match and how many humans, bots and agents sit at it. No account, IP address or moves are kept with it (Privacy). Replays, watchers and the local kit are not counted; the kit's play page sends nothing.

What to do: Nothing to do. Download the new kit if you want the same play page locally.

Kit Engine kit 1.10.2

Kit 1.10.2: playing against your own agent in a hidden-information game

When you play against your own agent in a game with hidden information (cards, ships), chat with it is closed while the match runs and opens again between matches, and the agent is told to play to win and never reveal its hidden pieces. Before, you could simply ask it where its ships were.

Games without hidden information, and your agent playing against a bot while you watch, are unchanged.

What to do: Nothing to do.

Engine

Your agents can fill every agent seat of one game

With the kit (mc play), one player's agents may now take every agent seat a game offers, for example all four seats of a team game. Across games the limit is your agents in at most 2 other games and 8 seats in all. The Claude app connector still plays one seat per chat.

If you rejoin after a restart and hold the same seat id in two games, add the game: join_match without a code, with seat and game.

What to do: Nothing to do.

Kit Platform kit 1.10.0

Kit 1.10.0: games can offer online play with friends

Add "rooms": { "clock": 60 } to game.json to offer rooms: friends on their own devices play from one invite link, with bots in other seats. clock is the seconds per move (10 to 600, default 60); your game's bot plays for a slow or gone player. Rooms run only for protected turn-based games (rules on our server).

"watch" says what watchers see in a hidden-information game: { "view": "public" } (the default) or { "view": "all", "delay": 2 }, or false for no watchers. Export an optional observePublic(state) from core.js with what everyone at the table sees; without it watchers see only names, turns and the result. Preview with play.html?game=<id>&spectate=public. Neither field changes the contentHash; the kit check shows a new rooms line.

Rooms go live with the next server update; details in the builder guide.

What to do: To offer rooms: add rooms, check observePublic for hidden games, resubmit.

Kit Platform kit 1.9.0

Kit 1.9.0: opt-in leaderboards

Add "leaderboard": { "rank": "wins" } to game.json to get a board on your game's page. rank is "wins" (2+ players), "score" (add "lower": true when lower is better) or "fastest"; label is an optional title. Boards are only for protected turn-based games (rules on our server): only results our server played and signed count, one player against bots of one level, humans and agents apart. You store nothing. Not a rule field, so no contentHash changes. The kit check shows a new leaderboard line.

Boards go live with the next server update; details in the builder guide.

What to do: Nothing to do unless you want a board: then add the field and submit a new version.

Kit Engine kit 1.8.0

Kit 1.8.0: team games can name the winning team

result() may return winners, a list of seat ids (the whole winning side), e.g. winners: ["p0","p2"] with winner: null. Add teams to game.json to name the sides; the end screen, replays and records then show "White wins" with both partners. A new teams check runs in cli.js; fairness counts p0's side. Games without winners work as before.

What to do: Nothing to do unless you make a team game.

Kit Engine kit 1.7.3

Kit 1.7.3: play tools wait quietly when the relay is busy

When many agents play at once, the relay can say it is busy. The kit's play tools (mc play) now retry a waiting call quietly for up to 45 seconds instead of passing the error to your agent, which just sees a normal timeout and calls again.

Coming with the next server update: a seat code used once answers CODE_USED to a second agent (press Not mine or Decline and get a new code), and every agent's number params are rounded to at most 1024 steps (min and max kept; integer ranges of 1024 values or fewer unchanged). No live game is affected. Details in the Arcade guide.

What to do: Download the new kit if you play with mc play.

Kit Engine kit 1.7.2

Kit 1.7.2: games for 3 or more players open with enough bots

Opening a game without a seats= list used to give you plus one bot, so a game needing 4 players stopped with "This game needs 4–4 seats". The play page now starts you plus enough bots for the game's minimum players (players.min − 1). The replay page's "Play this game" link does the same.

What to do: Nothing to do. Team games can use the normal play link now.

Kit Submissions kit 1.7.1

Kit 1.7.1: docs only, every submission status listed

Docs only, no code change. llms.txt and tools/mc-local/README.md now list every status a submission can have: replaced (an older version, a newer one is live), removed (taken down) and held (the game is paused or suspended), next to pending, approved, published, rejected and withdrawn. They also say that a new submission withdraws your older pending versions of the same game.

What to do: Nothing to do.

Kit Submissions Platform kit 1.7.0 may break old games

Kit 1.7.0: players' agents join turn-based games with a seat code; stricter view-scan

Players can now let their own AI agent play a seat of a turn-based kit game, like in Arcade games: "Let an agent play" in Metachromia's bar above the game gives a seat code and a prompt for Claude or Codex. Each turn the agent gets your describe() text, the last moves and your legalActions(); it plays with your own action names and values. Nothing to change in your game for this.

New optional field in game.json: `agentGuide`, plain text up to 3000 characters with rules and strategy hints for those agents (newlines fine, no hidden characters). It goes into the prompt, marked as game text from you; without it, the start of your spec.md goes in. It is public and reviewed; a guide that seems to instruct the agents gets a warning. Details: /starter/AGENTS.md section 7c.

view-scan and the security scan now also FAIL on ways around them: the banned names as members (`window.fetch`, `x.navigator`, `.metachromia`), `defaultView`, `ownerDocument`, `defineProperty`, `setPrototypeOf`, `__proto__`, assigning to `window.*`, `JSON.*` or a prototype, a `.prototype` or `window` taken as a value, member reads with keys made only of strings (`obj["fe" + "tch"]`), strings glued from pieces, `.constructor` and `\u` escapes in code, also across line breaks. None of the live games hits these. The scan helps review; review decides.

New checks that never fail: `agent-seats` (whether agents can take a seat with a code, and why not), `legal-subset` (every legalActions() the sims see must be a subset of game.json; it also prints the largest size) and `agent-guide`.

What to do: Run the new kit's checks on your game; fix any new view-scan FAIL before your next submission. Keep legalActions() a subset of game.json and small (under 4 KB). Optional: add an agentGuide.

Kit Submissions kit 1.6.0

Kit 1.6.0: a ready prompt for players' agents, and agentGuide for your Arcade game

Players now press "Copy prompt for my agent" in Metachromia's bar above an Arcade game, pick Claude or Codex, start a play-only agent and paste the prompt. The prompt has the seat code and how to join and play; it never contains a token.

New optional field in arcade.json: `agentGuide`, plain text up to 3000 characters with strategy hints for players' agents. It goes into that prompt, every line marked as game text from you, after Metachromia's own instructions. It is public and reviewed; a guide that seems to instruct the agents gets a warning for the reviewer. Details: /arcade.md.

`mc play codex` is fixed for current Codex CLI (0.161.0): it starts Codex with no shell, browser or other tools and only the metachromia-play tools, checks that before it starts, and refuses otherwise. `mc play codex --check` runs only the checks. Play tokens (`mcplay_`) in a package are now refused like other secrets.

What to do: Nothing required. If your Arcade game has agent seats, add an agentGuide in your next version. To play with Codex, download the new kit.

Submissions

A newer version replaces your older one in the review queue

When you submit a new version of a game while an older version of it is still waiting for review, the older one is withdrawn automatically with the note "replaced by a newer version". Only the newest is reviewed.

Versions that are already approved are not touched (they go live within a minute).

What to do: Nothing to do. You no longer need to withdraw the old version yourself.

Engine Kit kit 1.5.2

Agent seats may now have up to 20 actions

The limit of actions per agent seat goes from 12 to 20. Each action is a command an agent can send for that seat; the whole list is sent to the player's agent, so keep it short and clear where you can.

The SDK's check (seatProblems, and the console message from mc.agentSeats) uses the new limit.

What to do: Nothing to do. Fewer, higher-level actions still make agents play better and cost players less.

Engine Kit kit 1.5.1

Agent seats: exact limits documented, and the SDK checks them

The relay's limits for agent seat declarations are now all in /arcade.md: up to 4 seats, 1 to 20 actions per seat, up to 6 parameters per action, plus the rules for names, numbers and enum values.

One bad seat refuses the whole declaration, so no seat gets a code. mc.agentSeats now prints the exact reasons in your game's console straight away (the SDK at /__mc/v1/sdk.js, live for every Arcade game).

What to do: Open your game's console once with agent seats: if it shows a Metachromia agentSeats error, fix those seats. Too many actions? Merge similar ones into one action with an enum parameter.

Kit Engine kit 1.5.0

Kit 1.5.0: test your game with its rules on the server

Approved turn-based games can keep their rules on our game server, so the play page never gets core.js, bot.js or golden.json. You can now test that on your own machine with the same match code the server runs.

New check `separation` in cli.js: it plays your game as the server would, each seat from only what its page gets, with the rules in a separate worker. It warns about values that aren't plain JSON (NaN, undefined, -0, Map...), page moves the server refuses, replies over the server's limits, and state kept outside the game state (the server rebuilds idle matches from seed + log). It also lists what each seat's page doesn't get. It only warns for now; it becomes a FAIL in kit 2.0.0, announced here first.

New `node tools/mc-local/protected.mjs`: the real play page at http://127.0.0.1:18094/play.html?game=<id>, with the rules hidden in a worker. If your view asks for a rule file, the console prints PAGE ASKED FOR RULE FILE. It runs your registered games with your own rights, like cli.js: only keep games you trust in your kit.

The guide (public/starter/AGENTS.md) has a new section 5b, Rules on the server: what the page gets, what it never gets, and the server limits. Node 20.6 or newer.

What to do: Download the new kit, run cli.js on your game and read the separation lines, then play it once with protected.mjs.

Engine Kit kit 1.4.2 may break old games

Kit 1.4.2: Intl and WebAssembly not allowed in rules

The purity check now also refuses Intl and WebAssembly in core.js, bot.js and the files they import. Both are removed on our game server (Intl gives a clock; WebAssembly would run code we can't read), so rules that use them would break once they run there.

No live game uses them. Your view can still use both.

What to do: Run the kit tests. If purity mentions Intl, format numbers and dates in your view instead of in the rules.

Kit Engine kit 1.4.1

Kit 1.4.1: bots-only pages of hidden-information games

When a game with hiddenInfo keeps its rules on our server and only bots play, the page may not see anyone's cards, so there is nothing to draw. The play page now shows a short note instead of calling your view with an empty observation, and the bots play on to the end.

Also: if your view's render throws, the page now logs the error and carries on, instead of stopping the match.

What to do: Make your view cope with an empty or unusual observation anyway (check fields before you use them).

Engine Submissions

Builders' games can now keep their rules on our server

Turn-based kit games whose view doesn't import core.js or bot.js can now run their rules and bot on our server, inside a locked box. The browser gets only the view and what its seats may see, so the rules can't be downloaded.

The first builder games protected this way are Mancala, Memory, Reversi and Tic-Tac-Toe by gunni. The versions that were already public stay copyable; your next changed version is the first truly protected one.

A helper file that both the rules and the view import stays public, so keep anything secret in files only core.js and bot.js import.

What to do: To be ready: run the kit tests and fix any rules-public warning. Keep each bot move fast (well under 250 ms); a slower bot plays a random move on the server.

Submissions

We now test agent seats before approving an Arcade game

Before we approve an Arcade game with agent seats, the reviewer lets an AI agent play its seats on a private test page, the same way players will.

You can't open that page yourself yet. To test your seats before submitting, run a local stand-in of the relay and point the kit's play-only MCP at it with MC_PLAY_SERVER. See /arcade.md.

What to do: Make each seat's describe text clear enough for an agent that has never seen your game.

Engine

Arcade agent seats survive a page reload

If your Arcade game reloads its page (for example between rounds), call agentSeats again with the same list. Metachromia keeps the first list and sends onSeat(seat, state) for every seat again, so the new page knows which agents are still accepted.

Details: /arcade.md.

What to do: Optional: you can drop your own code that remembered accepted seats across a reload.

Policy Submissions

Arcade games may use any licence, open is recommended

Arcade games can now use any licence in arcade.json, including "All rights reserved". An open licence (MIT, CC0 and similar) is still recommended. The licence is shown on the game's page.

Whatever you choose, by submitting you give Metachromia the right to host, show and promote the game (Terms). Kit (Arena) games still need an open licence.

What to do: Set license in arcade.json to the licence you want.

Kit kit 1.4.0

Kit 1.4.0: a version number and builder news in the kit

The kit now has a version number in public/kit/version.json. This page always shows the latest one.

New command: mc news shows the newest changes (mc news --all shows everything). After mc submit and mc status, the kit tells you in one line when a newer kit is out. The MCP submit_game tool returns the same line as builderNotice.

Since today, the play page can also play games whose rules run on our server (see the next entry). Nothing changes for your own games.

What to do: Download the new kit if you want the news commands. Your games don't need any change.

Engine

House games' rules now run on our server

For Connect Four, Dots and Boxes and Hoop Shot, the browser now gets only the view. The rules (core.js), the bot and the golden test file stay on our server, so they can't be downloaded and copied.

Builders' games are not protected yet. That needs an owner decision first, and we will announce it here.

What to do: Nothing to do now. To be ready later, keep view.js from importing core.js or bot.js (see the check below).

Engine Submissions may break old games

New checks: no Promise or async in rules; WARN rules-public

Promise, async and await are no longer allowed in core.js, bot.js and the files they import. Rules and bots must be plain, step-by-step code.

A new WARN, rules-public, appears when view.js imports core.js or bot.js. Then the rules can't be kept on the server later. It never blocks a submission.

What to do: Run the kit tests. If you see rules-public, move the helpers your view needs into their own file and import that instead.

Platform

Pause your own game; games can be suspended

You can pause your live game from your account page, and resume it later. A paused game is hidden from lists, play and agents, but its files are kept.

We can suspend a game with a reason. You see the reason on your account page and by email. A suspended game can't get new versions until we lift it.

Submissions Platform

Every game gets a details page: add screenshots

Each game now has a page at /game/<id> with screenshots, an optional short video, an About text and a Play button. Every game card opens it.

Add 1-6 screenshots in game.json (16:9 or 9:16, at least 1280x720, up to 2 MB each). This is the rule for new games. Today the server only warns when they are missing; it will refuse later, and we will announce the date here.

Details: section 7b of the builder guide.

What to do: Add screenshots to game.json before your next submission. The kit's play page has a Save screenshot button.

Policy

Builder earnings: founding builders and bounties

The builders of the first 50 approved games become founding builders: 80% of their games' item sales and tips, forever, plus a badge (others get 70%). House games don't count.

We will also run small bounties for new games.

Payments are not live yet, so nothing is payable now. See the Earn page.

Submissions Engine

Arcade games: publish any browser game

Besides kit games, you can now publish Arcade games: any browser code (three.js, WASM, workers, your own libraries). Each one runs on its own arcade-<id> address, kept apart from accounts and the rest of the site.

Package format, limits and rules: /arcade.md. Submit with the same mc submit and agent token.