Docs Reference

Contents

Command line

The gamewright command is the core: it checks, bakes, plays and verifies a pack, and serves the Director's tools. The Studio runs this same core for you, and every download of the Studio has the command beside it (installing says where). From a checkout of the source, run it as node core/src/cli/main.ts <command>. This page is the CLI's own help, so it always matches the code.

gamewright <command> [options]

new

gamewright new [--json] (--sample NAME | --starter TEMPLATE | --empty) [--name "Title"] DIR

Start a game in DIR, a folder that is new or empty: a sample as it is, a template's starter (the smallest game on it, playable at once, with its sample's look and sound), or nothing, for the Director's brief. The game is the person's, made now, its ids from its name (game.<slug>, brief.<slug>); --name defaults to the sample's name, or for a starter to DIR's. JSON: {ok, dir, game: {id, name, template}}.

new

gamewright new --list [--json]

The samples (name, title, template, description) and the templates (id, name, description, starter) a new game can start from.

validate

gamewright validate [--json] <pack>

Check a pack: file names, strict JSON, schemas, then the game as a whole (references, kits, events, brains, screens, builders, cues, expressions) and static analysis (obtainability, unreachable states). A game is checked with its template.

strings

gamewright strings [--json] [--locale CODE] <pack>

Every text a person reads, by its Locale key, with a Locale's translation: what a translation works from.

store

gamewright store [--json] [--out DIR] [--shots] [--timeout S] <pack>

The store page kit: page.md (what the game is, how to play, what a person can change, credits) and ai-disclosure.md (what AI made, from the documents' and files' own records, as itch.io and Steam ask), under <pack>/.gamewright/store. --shots draws cover.png (630x500, its poster) and screenshots/ (1920x1080, from its look Playtest) through the player.

analyze

gamewright analyze [--json] <pack>

The same checks, reporting what a player can obtain and which brain states are never reached.

bake

gamewright bake [--json] <pack>

Check, resolve and write the bundle the player runs, into <pack>/.gamewright/build/<hash12>/.

digest

gamewright digest [--json] [--seed S] <pack|bundle>

Bake if needed, then have the engine load the bundle and print its world digest.

sim

gamewright sim [--json] [--seed S] [--ticks N] [--tour F] [--replay F] [--trace F] [--record F]
           [--asserts TEST] [--locale CODE] <pack|bundle>

Run the game headless in the engine; --asserts checks Playtest TEST's asserts where the run ends. --locale shows it in a language its Locales carry (here and below).

shot

gamewright shot [--json] --out F.png [--seed S] [--ticks N] [--at NAME] [--hour H] [--size WxH]
           [--locale CODE] [--options F] [--sees KIND] <pack|bundle>

Render one frame (through tools/heavy.sh). --options draws it as a person with those options sees it (an Options file: captions, colour filter, text size); --sees as a person with that colour blindness does (protanopia, deuteranopia or tritanopia; here and below).

tour

gamewright tour [--json] --tour F [--out DIR] [--seed S] [--locale CODE] [--options F] [--sees KIND]
           <pack|bundle>

Run a tour with its shots in the player (through tools/heavy.sh).

play

gamewright play [--seed S] [--level ID] [--at NAME] [--hour H] [--locale CODE] <pack|bundle>

Play the game in a window; --level starts in that Level or PlatformLevel, as a level select screen would.

verify

gamewright verify [--json] [--level L0|L1|L2|L3|L4|L5[,...]] [--seed S] [--judge-budget USD] <pack>

The verification ladder: L0 spec (validate), L1 boot (600 ticks twice, the same state hash, a clean log), L2 play (every Playtest through sim, with trace metrics), L3 frames (tour shots in the player, through tools/heavy.sh, with property checks), L4 judge (a vision model asked where the player, threats and goals are in L3's frames and what the player is to do; the Anthropic API with ANTHROPIC_API_KEY, else claude -p; costs money, at most --judge-budget, default $1), L5 web (every Playtest tour in headless Chromium on the web export, ending on the desktop's state hash). --level runs every rung up to the one named, but L4 only when named.

export

gamewright export [--json] --to linux|windows|macos|web [--out DIR] [--shots] <pack>

Bake the game and write it as one zip a person can hand on, named for it ("Ember Shore (Linux).zip"), into DIR (default: here): the player for that system with the game beside it, or for the web a folder any static host serves. The player is this version's, from GAMEWRIGHT_PLAYERS (a folder of player zips) or downloaded from gamewright.diy once and kept. macOS needs a Mac, for now. Beside it go its store page and AI disclosure; --shots draws its store pictures too (a few minutes, "<name> - store pictures"). JSON: {ok, to, zip, bytes, game: {id, name}, hash12, player}.

solve

gamewright solve [--json] [--level ID]... [--max-states N] <pack>

Prove a grid game's Levels solvable: print each one's witness (the shortest solution) and what the search saw.

reach

gamewright reach [--json] <pack>

Prove a platformer's levels completable: print each one's witness (inputs that reach the exit), the rooms a generator laid and how far the hero jumps.

fmt

gamewright fmt [--check] [--schemas <dir>]... <paths...>

Rewrite documents in canonical form (--check: only report).

hash

gamewright hash <file>

Print a document's content hash (sha256 over RFC 8785 JSON).

codegen

gamewright codegen [--check]

Regenerate TypeScript types and GDScript classes from schemas/v1 (--check: only report stale files).

changes

gamewright changes list|show|approve|reject|undo|redo|lock|unlock [--pack <dir>] [--json]

Review and decide the pack's proposed change sets: list [--status s,...]; show <id>; approve|reject|undo|redo <id>; lock|unlock <docId> [--item <id>] [--pointers /a,/b] [--reason r]. Approve checks the whole game first, as validate does.

import

gamewright import [--json] [--name NAME] [--origin O] [--ai A] [--license L] [--author A] [--url U]
           [--no-use] <pack> <file>...

Bring your own pictures (PNG, JPEG, WebP) and sounds (Ogg Vorbis, WAV, MP3) into a game: each kept under its hash in assets/ with an Asset saying what it is and where it came from (--origin made_by_me|made_for_me|made_by_others, --ai no_ai|ai_assisted|ai_generated), and a Sprite or a Sound that uses it (not with --no-use). Undo with changes undo.

mcp

gamewright mcp [--pack <dir>] [--session <id>]

Serve the Director's tools to Claude Code or any MCP client over stdio, for the pack in <dir> (default: here; a new folder starts at the brief). Claude Code config: docs/director/.mcp.json.

serve

gamewright serve [--pack <dir>] [--no-verify] [--grant-fd N]

The session daemon Gamewright Studio talks to: JSON-RPC 2.0 over a WebSocket on 127.0.0.1 (schemas/v1/session.schema.json). Its first stdout line is {"port":…,"token":…}; it runs until SIGTERM, SIGINT or its stdin closes. --no-verify proposes without running the ladder on each proposal. --grant-fd is the web Studio host's (GAMEWRIGHT_HOSTED=1): its owner's key and what they may spend arrive on that pipe.

runner

gamewright runner --games DIR... [--host URL] [--pair CODE] [--name NAME] [--config FILE] [--plan]

Offer this computer's games to the web Studio: they open at gamewright.diy/app, and their builds, playtests and Director run here (docs/design/m12-runner.md). A folder with a game.json is one game, else each folder in it with one is. The first run pairs with a code from <host>/computers and keeps the token in ~/.config/gamewright/runner.json (mode 0600). --plan: the Director's turns run in Claude Code on your Claude plan.

director

gamewright director [--pack <dir>] [--model M] [--budget USD] [--new] MESSAGE

One turn of the in-app Director on the Anthropic API (your key: ANTHROPIC_API_KEY, else gamewright key set's): every event a line of JSON on stdout, the conversation kept in <dir>/.gamewright/director/studio.json.

key

gamewright key set|status|forget [--json]

Your Anthropic API key for the in-app Director: set reads it from stdin into your system's keychain (else a file only you can read); status says whether one is kept and where; forget removes it.

host

gamewright host --data <dir> [--port 8080] [--listen 0.0.0.0] [--dev-mail]

The web Studio's host: sign-in by emailed code, each person's games and a session daemon on the one they have open, the Studio's web export at /studio/, an admin console for ADMIN_EMAILS (docs/design/web-studio.md). Mail goes through Resend (RESEND_API_KEY); --dev-mail writes it to stderr instead. From the host's machine: host users list|add EMAIL [--role admin|member] [--name N]|remove EMAIL --data DIR, and host session EMAIL --data DIR (prints a signed-in cookie). As root, host check-isolation --data DIR proves daemons reach nothing but their owner's folder (one JSON line; exit 2 when not root).

version

gamewright version

Print the Gamewright version.

help

gamewright help

Show this help.

For every command

--schemas adds a directory of *.schema.json files next to schemas/v1 (repeatable); --kits-dir reads kit registrations from another folder than engine/addons/gamewright/kits; --library reads templates from another library than library/. Engine jobs take --timeout SECONDS; their JSON is {ok, status, reason, bundleDir, result} with the engine's own result.

Generated from gamewright help (core/src/cli/main.ts).