> ## Documentation Index
> Fetch the complete documentation index at: https://docs.summerengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Export and ship skill for AI agents

> Prepare a game export: check templates and targets, validate release assets, build after approval. A Summer Engine skill for AI agents.

`export-and-ship` is a skill from the [Summer skill library](/mcp/skills): a guide your AI agent reads when the task matches, so it builds the good version on the first try. Prepare a game export: check templates and targets, validate release assets, build after approval.

| | |
| - | - |
| Status | Stable |
| Domains | Deployment, Project |
| Version | `1.0.3` |
| Engine version | `>=4.6` |
| Recommended set | Yes, installed by `--recommended` |

## When your agent uses it

* The user wants to assess or prepare a Summer game export — Steam, itch, HTML5, iOS, Android targets as available in the installed build
* The user says 'publish my game', 'release it', or 'ship a build to players' — produce the build they will upload

## Install

`summer setup` installs every skill for your agent. To add only this one:

```bash theme={null}
npx -y summer-engine@latest skills install export-and-ship --agent claude-code
```

Swap `claude-code` for your agent, such as `codex` or `cursor`. See [Skills](/mcp/skills#quick-start) for every option.

## The skill

## Overview

Shipping is a checklist, not a creative act. This skill first inventories the
export templates and targets actually present in the installed Summer Engine
build. It can then validate platform-specific assets and configuration and
produce a local build for an available target after approval. It does not
upload, host, submit, or promise a target that is absent from the installation.

**Core principle:** prove the target is locally available, then read its list,
satisfy the list, and build. Treat store submission and hosting as separate
user-controlled workflows.

## Steps

### 1. Prove local export capability

Do this before presenting destinations, writing presets, or constructing an
export command.

1. Read `engineBinaryPath` from `summer_get_project_context`.
2. Resolve the matching export-template directory for that exact Summer
   technical base.
3. Inventory the installed templates (`summer_export_templates` lists them and
   installs Summer's macOS, Windows and web templates) and any
   `custom_template/release` paths already configured in `export_presets.cfg`.
4. Build a capability table with `available`, `missing prerequisite`, or
   `impossible on this build` for every requested target.

A stock Summer Mono install ships only the macOS template. Web export is
incompatible with that Mono build. Run `summer_export_templates` before marking
another target missing: it installs Summer's macOS and Windows templates. Linux,
Android, and iOS require a matching custom template or an external CI/build
environment, plus their platform toolchains where applicable.

**Hard gate:** an absent template or toolchain means the target is unavailable.
Do not create its preset, recommend it as a local option, or invoke an export
command. Route it to an explicitly configured external CI job or stop and tell
the user which prerequisite is missing. An export pack is not a runnable
platform build and must not be presented as one.

### 2. Pick among proven destinations

Offer only targets marked `available` by step 1. Record other requested
destinations as blocked follow-ups with their exact prerequisite.

> Locally proven targets: **macOS**. Requested but blocked: **Windows**
> (install the template with `summer_export_templates`), **Web** (non-Mono
> build), **Android**
> (template + Android toolchain). Which proven target should I prepare?

Each destination has a different list. Multiple destinations = multiple lists. Don't shortcut — the iOS list does not satisfy the Steam list.

### 3. Run the pre-flight checklist

Always do this first, regardless of destination.

**Preferred (Summer MCP):**

```
summer_get_diagnostics            # any errors? if yes, abort.
summer_get_console                # any "import failed" warnings?
summer_get_scene_tree             # is the main scene set?
```

**Fallback (no MCP):** ask the user to confirm in Summer Engine: Project →
Project Settings → Application → Run → Main Scene is set, and the Output panel
has no errors.

#### Pre-flight blockers (any one = stop)

| Check | How | Blocker because |
| - | - | - |
| Main scene is set | `project.godot` has `application/run/main_scene` | Game launches to nothing without it |
| No script errors | `summer_get_script_errors` clean | Won't compile in export |
| No `print()` debug spam in hot loops | `Grep "print(" -- "**/*.gd"` | Spammy console for users |
| No hardcoded debug paths | `Grep "user://debug" or "/Users/" or "C:\\\\"` | Breaks on user machines |
| `.gitignore` excludes `.godot/`, `.import/`, `*.tmp` | Read `.gitignore` | Build artifacts in repo |
| LICENSE file present | Read `LICENSE` at repo root | Steam + itch require licensing clarity |
| `attribution.md` for community assets | Read `attribution.md` or equivalent | CC-BY assets need credit; missing = takedown risk |
| Version number set | `application/config/version` in `project.godot` | Required by Steam, useful everywhere |
| Game name set | `application/config/name` | Window title, build artifact name |

If any check fails, list them in one message and ask:

> Pre-flight failed on N items: \<list>. Fix these before exporting? I can take them one by one.

### 4. Per-platform distribution requirements

These lists describe distribution requirements only. They do not establish
local export capability. Walk a list only after step 1 proves its target or
the user has selected an external build environment that does.

#### a) Steam

| Asset | Resolution | Format | Path / use |
| - | - | - | - |
| Game icon | 256×256 | PNG, transparent | Used in Steam library, taskbar |
| Library capsule | 600×900 | PNG | "Box art" in library grid |
| Library hero | 3840×1240 | PNG | Wide banner at top of game's library page |
| Library logo | 1280×720, transparent BG | PNG | Title overlay on hero |
| Header capsule | 460×215 | PNG | Store search results, friend activity |
| Main capsule | 616×353 | PNG | Front-page features |
| Small capsule | 231×87 | PNG | Sidebar |
| Page background | 1438×810 | JPG | Behind store page content |
| Screenshots | ≥ 1280×720, 16:9 | PNG/JPG | At least 5 |
| Trailer | 1080p, MP4, ≤ 2 min | MP4 | Required for Coming Soon → Released |
| Steam page text | English required + any localized | Markdown / plaintext | Short description (300 chars), full description, controls |

Build config for Steam:

* Export only the platform builds proven in step 1. Additional Steam platforms
  require their own matching template or external build job.
* Export options: `Embed PCK = true` for single-EXE distribution.
* Steam SDK integration: GodotSteam (`https://godotsteam.com`) is the standard. Add the GDExtension before exporting.
* App ID must be set in the Steam SDK init code.
* Build separately for each platform; Steam Pipe uploads handle distribution.

#### b) itch.io

Lower bar than Steam. itch is forgiving.

| Asset | Resolution | Required? |
| - | - | - |
| Cover image | 630×500 | Yes |
| Screenshots | Any 16:9 | At least 3 |
| Game title + tagline | text | Yes |
| Description | Markdown | Yes |
| Build files | ZIP per platform OR `butler` upload | Yes |

Build config:

* Package each proven platform build as a ZIP.
* Or use `butler push` (itch's CLI) for atomic versioning and patches.
* A browser build is optional and requires a separately proven non-Mono Web
  export environment.

#### c) Web (HTML5) — unavailable on the stock Mono build

Do not recommend or attempt this target from the stock Mono installation.
Route it to a verified non-Mono Summer-compatible build environment first.
Once that prerequisite is proven, these browser constraints apply:

* No threading without `cross-origin-isolated` headers (most hosts don't set them).
* No ENet — use WebSocket / WebRTC if multiplayer.
* Long initial load — first-paint is critical. Add a loading screen.
* File size matters — strip unused features in export preset (no encryption, no debugging, no JavaScript eval if not needed).

Build config:

* Export preset: **Web**.
* Output `.html` + `.wasm` + `.pck` + `.js`.
* Disable: "Variant: Editor support", "Encryption".

Known traps:

* Audio: Chrome blocks autoplay. First user click must trigger audio context resume.
* Local saves: use `user://` (maps to IndexedDB on web). Test that saves persist across reload.

#### d) iOS App Store

| Asset | Resolution / Format |
| - | - |
| App icon | 1024×1024 PNG (Apple generates the rest) |
| Launch screen | Storyboard (the engine generates it) |
| Screenshots | 6.5" iPhone: 1242×2688 / 2688×1242 (≥ 3); 12.9" iPad if iPad-eligible |
| App Store description | text per locale, ≤ 4000 chars |
| Keywords | ≤ 100 chars, comma-separated |
| Support URL | required |
| Privacy policy URL | required (any data collection) |

Build config:

* Export preset: **iOS**.
* Bundle ID: `com.<your-org>.<game-name>`. Must match Apple Developer portal.
* Apple Developer account required (\$99/year).
* Code signing: distribution certificate + provisioning profile.
* Build via macOS only (Xcode toolchain).
* TestFlight first (always). Don't go straight to App Store review.

#### e) Google Play (Android)

| Asset | Resolution / Format |
| - | - |
| App icon | 512×512 PNG (32-bit, transparent) |
| Feature graphic | 1024×500 PNG |
| Phone screenshots | 16:9 or 9:16, ≥ 1080p, ≥ 2 |
| Tablet screenshots | optional but boosts visibility |
| App description | text per locale, ≤ 4000 chars |
| Short description | ≤ 80 chars |

Build config:

* Export preset: **Android**.
* Build as **AAB** (Android App Bundle), NOT APK — Play Store requires AAB since 2021.
* Signing: Play App Signing (Google holds the key) + an upload key.
* Target API level: latest required by Play Store policy (typically the previous year's API level).
* Test on real device + emulator before submission.

#### f) macOS DMG (outside Steam)

* Export preset: **macOS** (universal binary).
* Codesign + notarize via Apple — unsigned builds get a Gatekeeper warning users can't easily bypass.
* Notarization requires Apple Developer account (\$99/year).
* DMG packaging: `create-dmg` CLI or `hdiutil`.

#### g) Windows installer (outside Steam)

* Export preset: **Windows Desktop** (x86\_64).
* Code-signing certificate ($75–$300/year from a CA) — without it, SmartScreen flags the EXE.
* Installer: NSIS or InnoSetup are the standards. Or just ship a ZIP.

### 5. Build config consistency check

Before producing builds, verify `export_presets.cfg` for each target:

```
Read export_presets.cfg
```

For each preset:

| Field | Production value | Why |
| - | - | - |
| `binary_format/embed_pck` | `true` | Single EXE per platform |
| `texture_format/etc2_astc` | `true` for mobile | Smaller texture compression |
| `application/short_version` | matches `application/config/version` | Steam reads it |
| `script_encryption_key` in `export_credentials.cfg` | set only when the user explicitly chooses script encryption | The similarly named preset field does not exist |
| `application/icon` | path to your `.ico` / `.icns` / `.png` | Otherwise the default engine icon ships |

### 6. Propose the build sequence

> Capability proof: macOS available locally; Windows needs its template
> (`summer_export_templates`); Linux requires external CI; Web is unavailable
> on this Mono build. Pre-flight is clean
> for the macOS preset. May I produce that one proven build now?

### 7. Produce a proven build

CLI export is the standard scripted path. **Get the binary from `summer_get_project_context` → `engineBinaryPath`.** Do not type an engine binary name from memory:

* There is no `godot` on a Summer user's machine.
* `summer` is the npm CLI, not the engine. It takes subcommands and would never accept `--export-release`.
* On macOS the engine is `/Applications/Summer.app/Contents/MacOS/Summer`; on Windows, `%LOCALAPPDATA%\Summer\current\Summer.exe`.

After step 1 has marked a preset `available`, substitute only that exact proven
preset and output:

```bash theme={null}
ENGINE=<engineBinaryPath>
PROJ=<absolute project dir>
PROVEN_PRESET=<exact available preset name>
PROVEN_OUTPUT=<output path valid for that target>

"$ENGINE" --headless --path "$PROJ" --export-release "$PROVEN_PRESET" "$PROVEN_OUTPUT"
```

`--path` is not optional in a script — without it the export targets the current working directory.

The quoted preset name must match a `name=` in `export_presets.cfg` exactly. That file is plain text you can write yourself if it is missing: a hand-written preset plus this command was measured producing a runnable 144 MB `.app`, exit code 0.

To enable another target, prove one of these before returning to step 2:

* a matching installed export template;
* a valid `custom_template/release="<path>"` for the current technical base;
* an external CI/build job with the matching template and platform toolchain.

### Export-option cautions

* **`script/encryption_key` does not exist.** The real key is `script_encryption_key`, and it lives in a separate `export_credentials.cfg`, not `export_presets.cfg`. Writing the wrong name produces an **unencrypted build with no error at all**.
* **There is no `debug` field in a preset.** Debug versus release is chosen by `--export-debug` versus `--export-release`, nothing else.

On Apple Silicon, `binary_format/architecture="arm64"` is the natural guess, and it fails leaving a **0-byte `.app` that looks like success**. Only `"universal"` ships.

See `headless-scripting` for the wider pattern this is one instance of.

If the user is on a CI system (GitHub Actions etc), point them at a cross-compile workflow: the engine can export Windows and Linux from a Linux runner.

### 8. Verify each build

For each build:

* Launch it. Confirm the title screen renders.
* Run for 30 seconds. Confirm no console errors.
* Check the file size (anything over 500 MB needs justification — usually unstripped textures or unused assets).
* For mobile: install on a real device, not just the emulator.

### 9. Hand off distribution

Per platform, point the user at the correct upload path:

* **summer.games:** `summer_export_game` writes the summer.games `.zip`; `store.upload_file` uploads it to the game's store listing after the user confirms the exact game, file and version (needs `summer login --store`; through `summer_call` when your client does not list it). If the store refuses this machine's sign-in, the user uploads the `.zip` in Studio instead. The `publish-your-game` skill takes it from there to `store.publish`.
  * Per platform, the store takes: iPhone, Android, macOS and Windows in the Summer apps = one summer.games bundle (`summer_export_game` `targets`, format `bundle`; no template, no signing; a game without a server targets `ios`/`android` only). Web = an HTML5 `.zip` on Summer's WebGPU Forward+ template (`targets:["web"]`; the project must render with Forward+ or Mobile). A macOS or Windows download for the store page = `targets:["macos"]` or `["windows"]` with format `download`. Download exports need the template: `summer_export_templates` `install` fetches it from Summer's CDN.
  * Hosted games: if `summer_export_game` fails with "… is in the source graph's authority\_engine domain, which the client pack leaves out", an authority root in `source-domains.json` holds a file the client loads (often the composition `.tres`). Narrow that root to the server-only files, or move the shared file under a `shared` path, then export again. Every exporter message is in the `multiplayer-publish` skill's export-errors.md; the folder rules are in `multiplayer-project`.
  * Every summer.games bundle: export with the released Summer editor from the download page, never a development build, and export again after updating Summer. Otherwise its scripts can fail to compile on players' devices and the game opens to an empty window, though every upload check passes. `release-readiness` check 7 proves it.
  * Every file the game reads by path at run time (`FileAccess`, `DirAccess`, `load_from_file`) that Summer doesn't import, such as a `.bin` or `.json`, must match the **summer.games** preset's own `include_filter` (Resources > Filters to export non-resource files/folders); a filter on another preset doesn't carry over. A left-out file is no export error, it is just missing on players' devices. Never use `SystemFont` for phone text: on iPhone it draws every glyph as a box. `release-readiness` check 8 lists the pack.
  * iPhone and Android bundles: the Summer Games apps start only exports on their Summer version line (same MAJOR.MINOR, patch no newer). Export with the current Summer release and export again after every Summer minor update, or players see "The game could not start" on phones while desktop works. `release-readiness` check 9.
  * Hosted games, before the upload: a clean export does not prove players can join. Run `release-readiness` on the `.zip`: the bundle's `server.pck`, started with no scene, must load the authority scene (the server preset needs the `summer_authority` custom feature), and `Summer.initialize` must pass no hard-coded Game ID. Otherwise every online join fails with `world_start_timeout`.
  * Store page art: key art, covers and icons carry no text, logos or UI (the store page shows the title). Screenshots are real gameplay and may show the game's own HUD; add no captions, logos or overlays. Capture them with `summer_capture_gameplay` (offscreen, no editor needed; `resolution` `1920x1080`, or `1080x1920` for portrait; get past a title menu with the game's own flags in `args`, e.g. `["--autostart"]`, or `steps` such as `[{"press":"Play"},{"wait":3000},{"shot":true}]`), or `summer_screenshot` target `game` while the editor runs the game.
* **Steam:** `steamcmd` + Steam Pipe (`builder_app_xxx.vdf`). Set up depots first in Steamworks.
* **itch.io:** `butler push <path> <user>/<game>:<channel>` (e.g. `butler push build/win <user>/mygame:windows`).
* **Web (itch hosted):** zip + drop into itch upload UI as "playable in browser".
* **iOS:** Archive in Xcode → upload via Xcode Organizer → TestFlight → App Store.
* **Android:** Play Console → Internal testing → Closed → Open → Production.

Skill does NOT execute these uploads itself. It produces the builds and points at the right command.

## Pre-flight checklist (master)

Use this as a one-shot grep before any export:

| Check | Pass condition |
| - | - |
| Main scene set | `project.godot` has `application/run/main_scene = "res://..."` |
| No script errors | `summer_get_script_errors` empty |
| No debug `print()` spam | Grep returns \< 20 hits across project (or each is intentional) |
| No hardcoded user paths | Grep for `/Users/`, `C:\\`, `/home/` returns 0 hits |
| Version number set | `application/config/version = "1.0.0"` (or higher) |
| Game name set | `application/config/name = "<actual name>"` |
| Icon assets present | Per-platform icon files exist at the paths referenced in `export_presets.cfg` |
| LICENSE file | Exists at repo root |
| Attribution file | Exists if any community assets used |
| Release mode selected | Build invocation uses `--export-release` |
| Export preset `embed_pck = true` | For all desktop release presets |
| `.gitignore` excludes build artifacts | `build/`, `.godot/`, `.import/`, `*.tmp` listed |
| Screenshots ≥ minimum count for platform | 3 for itch, 5 for Steam, 2 for Play |
| No leftover dev assets in `res://` | No `_test_`, `_old_`, `_temp_` files in the export paths |

## Common mistakes

| Don't | Do | Why |
| - | - | - |
| Ship debug builds to Steam | Use `--export-release` after capability proof | Debug builds leak paths and run slower |
| Use 256×256 icon for iOS | 1024×1024 (Apple downscales) | iOS rejects undersized icons |
| Skip Steam trailer | Record at least 30 sec gameplay before launch | Steam blocks the release without it |
| Ship APK to Play Store | Build AAB | Play requires AAB since 2021 |
| Skip code-signing on macOS / Windows | Get a cert; without it, users can't run the build | Gatekeeper / SmartScreen blocks unsigned binaries |
| Skip notarization on macOS | Notarize after signing | Quarantined apps can't run on most modern macOS |
| Ship without `LICENSE` | Add MIT or commercial license to repo root | Steam + itch + most platforms require it |
| Forget attribution for CC-BY assets | `attribution.md` listing each asset's source + license | Otherwise = takedown notice + ban |
| Auto-upload via skill | Produce builds; user uploads | Uploads have side effects (versioning, refunds, metadata changes) |
| Push 1.0.0 first | Push 0.9.0 internal first, then 1.0.0 to public | Internal testing catches the embarrassing-launch-day bugs |
| Same build for all stores | Per-store metadata + separate upload | Steam wants `.exe`, Play wants `.aab`, web wants `.html` |

## Anti-patterns

* **"Just enable all export options."** Encryption + JS eval + edit-time features bloat the binary. Disable what you don't use.
* **"I'll fix the icon later."** Apple and Google reject submissions with placeholder icons. They'll take a week to re-review.
* **Unsigned macOS builds outside Steam.** Apple Gatekeeper is strict. The user-facing workaround ("right-click → Open → confirm") is bad UX.
* **Embed PCK = false on desktop.** Splits the binary into multiple files; users delete the PCK by accident; bad first-run experience.
* **Trailer is a slideshow.** Steam's algorithm down-weights gameplay-less trailers. Show actual gameplay in the first 5 seconds.

## Collaborative protocol

This skill produces release artifacts. Always ask before each build is invoked. Group platforms — "I'm about to build Windows + Mac + Linux release configs into `build/`. OK?". See `summer_docs_read` id `reference/collaborative-protocol`.

## Want a working starter?

No template — this is a workflow. Each project's export config and store assets are project-specific.

## See also

* `summer_docs_read` id `reference/mcp-tools-reference` — full MCP tool list
* `summer_docs_read` id `reference/godot-version` — Summer compatibility and
  export-template versioning
* `summer_docs_read` id `reference/collaborative-protocol` — "May I write" pattern
* `headless-scripting` — the headless CLI pattern the export command follows
* `tune-performance` — pre-ship performance pass

## From a shell

No Summer MCP tools in this session? Run each one as a command; when `summer --version` is missing or below 4.0, use `npx -y summer-engine@latest` in place of `summer`. Fields are flags in kebab-case (`--scene-path res://main.tscn`) or one `--input '<json>'`, and `summer ops describe <op>` prints the exact input. The `summer-cli` skill has the rest.

| In this skill | Command |
| - | - |
| `summer_docs_read` | `summer docs read` |
| `summer_capture_gameplay` | `summer engine capture-gameplay` |
| `summer_export_game` | `summer engine export-game` |
| `summer_export_templates` | `summer engine export-templates` |
| `summer_get_console` | `summer engine get-console` |
| `summer_get_diagnostics` | `summer engine get-diagnostics` |
| `summer_get_project_context` | `summer engine get-project-context` |
| `summer_get_scene_tree` | `summer engine get-scene-tree` |
| `summer_get_script_errors` | `summer engine get-script-errors` |
| `summer_inspect_node` | `summer engine inspect-node` |
| `summer_project_setting` | `summer engine project-setting` |
| `summer_screenshot` | `summer engine screenshot` |
| `store.publish` | `summer store publish` |
| `store.upload_file` | `summer store upload-file` |

## Related skills

* [`debug`](/skills/debug): Disciplined bug, crash and error loop: script errors, console, debugger, hypothesis, fix, verify.
* [`tune-performance`](/skills/tune-performance): Profile a slow game, find rendering, physics or script hotspots, and propose fixes with expected gains.
* [`publish-your-game`](/skills/publish-your-game): Publish a game on Summer Games through MCP: store page, art, build upload, submit, owner approval link.

***

Source: [`library/skills/export-and-ship/SKILL.md`](https://github.com/SummerEngine/summer/blob/main/library/skills/export-and-ship/SKILL.md), rendered from `summer-engine@4.3.0` on npm.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.