Docs menu

Docs ▸ Agents

For AI agents

  • Add --json to any command: stdout is exactly one JSON object, { ok, data, errors[], warnings[], logPath }. logPath is the run's log (for play, build, check and publish). Without a valid gameshipper.json they write nothing into the folder, so a CONFIG_MISSING or CONFIG_INVALID result has no logPath.
  • Every error and warning has a stable code and a plain-English message. Errors always have a fix; warnings have one whenever there's something to do.
  • Nothing ever prompts when --json or --yes is set, or when stdin isn't a terminal. Missing input comes back as INPUT_REQUIRED, naming the flag to pass.
  • Exit codes: 0 success, 1 a target or check failed, 2 invalid config, usage or missing input, or a login or token you must provide. A signal ends the run with an INTERRUPTED result and exit code 128 + the signal number (130 for Ctrl+C). Ctrl+C during an interactive play just ends the session: an ok result with a PLAY_STOPPED warning, still exit 130.
  • help --json returns every command and flag.
  • check --json returns 18 checks, each with a stable id, a status (pass, warn, fail, info or skip) and, for warn and fail, a code and a fix. Every failed check is also an error in errors, and every warning in warnings, so exit code 1 means at least one check failed. Open data.deckScreenshot to see what the game showed at Steam Deck size.
  • play --screenshot 5,10,15,20,25 --json saves store screenshots without a person; data.screenshots lists them. They show whatever the game shows without input, so look at them before you upload them.
  • publish --json never prompts. Without a saved Steam or itch.io login it returns STEAM_LOGIN_REQUIRED or ITCH_LOGIN_REQUIRED (exit code 2): the human runs the command in the error's fix once in their own terminal, then you publish again.
  • npx gameshipper mcp serves the same commands as MCP tools, with the same results (see MCP server and Claude Code plugin).

The loop: status --json, init --yes --json, then play --smoke --json until it comes back clean (ok: true, so no errors; warnings don't block), then build --json, then check --json until nothing fails that you can fix. When the human wants it uploaded: publish --dry-run --json, then publish --json.

What play --smoke reports

Code Level What happened
GAME_CONSOLE_ERROR error The game logged an error or threw, with the file and line.
GAME_FILE_MISSING error The game requested a file that isn't in the build.
GAME_PATH_CASE warning Comes with GAME_FILE_MISSING when the file exists with different letter case (Player.png vs player.png). Builds treat those as different files on every OS, so the request fails everywhere. The fix names the real file.
GAME_LOAD_FAILED error The page failed to load, or never finished loading.
GAME_CRASHED error The game's process crashed.
SMOKE_NO_RESULT, SMOKE_TIMEOUT error The game never reported back, or froze and had to be stopped.
GAME_USES_INTERNET warning The game loaded something from the internet while running, so it won't work offline.
GAME_CONSOLE_WARNING warning The game logged a warning.
STEAM_INIT_FAILED error Steam is running but didn't start for the game's App ID (usually one the signed-in account doesn't own).
STEAM_NOT_RUNNING warning Steam isn't running, so window.steam was a no-op.
STEAM_OVERLAY_FAILED warning The native overlay window (see Steam) couldn't start, so Shift+Tab shows no overlay.
PLUGIN_LOAD_FAILED error A plugin's module failed to load in the game.
SCREENSHOT_FAILED warning A screenshot couldn't be saved. With --screenshot it's also an error when fewer were saved than asked for.
GAME_NAVIGATION_BLOCKED warning The game tried to take its window to a page that isn't the game's, like about:blank or file:, or an embedded site tried to open a link. Web, mail and steam: links the game itself opens aren't reported: they open in the player's browser or app. But while the page has an embedded frame from another site, or one that failed to load, the game's own window.open() and target="_blank" links are blocked too, because Electron can't tell which frame opened a window.

Each code lists at most 10 issues, then one more issue counting the rest. data.smoke.summary.events holds the first 100 diagnostic events; data.smoke.eventsLog names a JSON-lines file with all of them, including everything the game logged.

Other problems have codes too, such as CDN_FETCH_FAILED, CDN_CHANGED, ENTRY_MISSING, CONFIG_INVALID, ICON_TOO_SMALL, ICON_NOT_SQUARE, STEAM_SDK_MISSING, STEAM_SDK_INVALID, STEAM_SDK_CACHE_FAILED (Gameshipper's cache can't be written), STEAM_NATIVE_DOWNLOAD_FAILED (another OS's native Steam bridge couldn't be downloaded), STEAM_UNSUPPORTED_PLATFORM (a warning: Steam has no libraries for that OS and CPU, like arm64 Linux, so it runs without Steam), PLUGIN_LOAD_FAILED, PLUGIN_IMPORTS_NOT_COPIED (a warning, see Plugins), PLUGIN_HOOK_FAILED and PACKAGE_FAILED from a build, or GAME_EXITED when a game quits with an error during play, each with its fix. An icon problem only stops build: play warns with the same code and uses the default icon.

What check reports

Check Not met Code
offline.requests fail CHECK_OFFLINE
launch.run fail (warn when this computer's OS isn't a target) CHECK_NOT_LAUNCHED, CHECK_LAUNCH_FAILED
launch.errors warn CHECK_GAME_ERRORS
launch.frame fail (warn when the frame is mostly one colour) CHECK_BLANK_FRAME, CHECK_MOSTLY_BLANK_FRAME
launch.exit fail CHECK_EXIT_CODE
launch.other-os info
deck.layout warn (skip when the page couldn't be laid out at 1280x800) CHECK_DECK_LAYOUT
deck.gamepad warn CHECK_NO_GAMEPAD
deck.text-input always passes; lists text fields
review.builds fail CHECK_BUILD_MISSING
review.steam-appid fail CHECK_STEAM_APPID_FILE
review.mac-signing fail on a Mac, warn elsewhere CHECK_MAC_NOT_NOTARIZED, CHECK_MAC_SIGNING_UNKNOWN
review.icon warn CHECK_DEFAULT_ICON
review.app-id warn CHECK_TEST_APP_ID
store.images fail (also when older than the key art or logo) CHECK_STORE_IMAGES
store.screenshots fail CHECK_SCREENSHOTS
store.trailer, ai.disclosure info

A check that couldn't run here is skip, and its message says why.