agentleFS
Simone-TarantinoSimone-Tarantino/godot-superpowers/skills/export-config/SKILL.md

export-config

Skill2 starsChanged 6 months agoMITView on GitHub

Configure Godot 4.x export presets for Windows, macOS, Linux, Web, Android, iOS — set up export_presets.cfg, signing, icons, and CLI build commands. Includes a pre-flight checklist and CI build snippet.

  • Reads credentials

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before any release export:

    line 154
  2. Very specific:

    Rate-limited template download: when many parallel jobs hit GitHub mirrors → pin chickensoft-games/setup-godot to a release that caches …

    line 288

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Export Config

Configure Godot exports cleanly for distribution. Reference: Exporting projects.

Prerequisites

  1. Export templates installed: Editor → Manage Export Templates → Download (matches your editor version)
  2. export_presets.cfg in .gitignore (it can contain keystore paths and signing secrets); commit export_presets.cfg.example if useful
  3. Icon assets: Source .png 1024×1024 for the icon; Godot generates platform variants

export_presets.cfg structure

This file is auto-generated by Godot but understandable. Each preset is a numbered section:

[preset.0]

name="Windows Desktop"
platform="Windows Desktop"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter="docs/*, test/*, *.gdignore, *.md"
export_path="builds/windows/MyGame.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false

[preset.0.options]

custom_template/debug=""
custom_template/release=""
binary_format/embed_pck=false
debug/export_console_wrapper=1
binary_format/architecture="x86_64"
codesign/enable=false
application/icon="res://icon.ico"
application/file_version="1.0.0.0"
application/product_version="1.0.0.0"
application/company_name="MyStudio"
application/product_name="MyGame"
application/file_description="MyGame"
application/copyright="© 2026 MyStudio"
ssh_remote_deploy/enabled=false

Recommended: configure presets through the editor UI (Project → Export). It writes the file. Then commit a sanitized template.

Per-platform presets

Windows Desktop

  • Architecture: x86_64
  • Embed PCK: false (separate .pck ships smaller patches; true for single-file)
  • Code signing: osslsigncode or signtool (Windows SDK). For most indie releases, leave unsigned (users see a SmartScreen warning that goes away after enough downloads).
  • Icon: .ico file via application/icon
  • Console wrapper: 1 for debug builds, 0 for release (no console window)

macOS Desktop

  • Architecture: universal (x86_64 + arm64) — required for Apple Silicon
  • Bundle identifier: reverse DNS, e.g. com.mystudio.mygame
  • Codesign: application/codesign/enable = true and provide a Developer ID certificate; otherwise users see Gatekeeper warning
  • Notarization: required for distribution outside Mac App Store; via xcrun notarytool or Godot's built-in
  • Icon: .icns file

Linux

  • Architecture: x86_64 (also arm64 if targeting Pi / Steam Deck)
  • Distribution format: AppImage (recommended for desktop), tarball, or Flatpak
  • Embed PCK: true — single binary easier to distribute
  • Set executable: chmod +x post-build

Web (HTML5)

  • Custom HTML shell: optional but useful for branding the loading screen
  • Threads: requires CORS headers (Cross-Origin-Embedder-Policy: require-corp, Cross-Origin-Opener-Policy: same-origin); itch.io has a setting for this
  • Embed PCK: true (single .pck request fewer)
  • VRAM compression: true for smaller download
  • Limits: 2GB max memory; large textures can crash mobile browsers

Android

  • Java SDK + Android SDK required; configure paths in Editor Settings → Export → Android
  • Keystore: generate with keytool -genkey -v -keystore my.keystore -alias mygame -keyalg RSA -validity 10000. Store outside repo. Never commit.
  • Min SDK: 24 (Godot 4.4 default); covers Android 7+
  • Target SDK: latest (required by Play Store)
  • Architectures: arm64-v8a (required for Play Store), optionally armeabi-v7a for older devices
  • Permissions: declare only what's needed (Internet for online; nothing for offline single-player)

iOS

  • Xcode required (macOS-only)
  • Apple Developer account with provisioning profile
  • Team ID + Bundle ID in preset
  • App icons: full set (use appicon.co or similar)
  • Architectures: arm64
  • Use TestFlight for beta distribution

Project icon

Source: icon.png 1024×1024 with transparent background. Godot can convert to platform variants but .ico (Windows) and .icns (macOS) need manual generation:

# .ico (Windows) via ImageMagick
convert icon.png -define icon:auto-resize=256,128,96,64,48,32,16 icon.ico

# .icns (macOS)
mkdir icon.iconset
sips -z 16 16     icon.png --out icon.iconset/icon_16x16.png
sips -z 32 32     icon.png --out icon.iconset/icon_16x16@2x.png
sips -z 32 32     icon.png --out icon.iconset/icon_32x32.png
sips -z 64 64     icon.png --out icon.iconset/icon_32x32@2x.png
sips -z 128 128   icon.png --out icon.iconset/icon_128x128.png
sips -z 256 256   icon.png --out icon.iconset/icon_128x128@2x.png
sips -z 256 256   icon.png --out icon.iconset/icon_256x256.png
sips -z 512 512   icon.png --out icon.iconset/icon_256x256@2x.png
sips -z 512 512   icon.png --out icon.iconset/icon_512x512.png
sips -z 1024 1024 icon.png --out icon.iconset/icon_512x512@2x.png
iconutil -c icns icon.iconset

CLI build commands

# Debug build (fast, includes debug symbols)
godot --headless --path . --export-debug "Windows Desktop" builds/windows/MyGame_debug.exe

# Release build (optimized)
godot --headless --path . --export-release "Windows Desktop" builds/windows/MyGame.exe

# All presets (run separately):
godot --headless --path . --export-release "Windows Desktop" builds/windows/MyGame.exe
godot --headless --path . --export-release "macOS"           builds/macos/MyGame.dmg
godot --headless --path . --export-release "Linux/X11"       builds/linux/MyGame.x86_64
godot --headless --path . --export-release "Web"             builds/web/index.html
godot --headless --path . --export-release "Android"         builds/android/MyGame.apk

--export-debug if the platform supports it, --export-release otherwise. The preset name must match exactly what's in export_presets.cfg.

Pre-flight checklist

Before any release export:

  • Version bumped in project.godot (config/version="1.2.3")
  • Icon set on every platform preset
  • Bundle/app ID consistent across platforms
  • exclude_filter strips test/, docs/, tools/, .gdignore
  • print() / print_debug() calls behind a debug flag
  • Logging level set to WARN or ERROR for release
  • Autoloads load without errors when scene starts cold
  • All addons under addons/ are licensed for distribution (some are dev-only)
  • export_presets.cfg not committed (or sanitized version only)
  • No hardcoded paths from your machine in scripts
  • user:// paths used for save data, not absolute paths
  • display/window/size/viewport_* matches design resolution
  • No shaders that crash on the lowest-spec target hardware
  • Test build runs on a clean machine (not just dev box)

CI pipeline (GitHub Actions)

A real release pipeline runs tests first, then exports. A failing test must block the build, otherwise CI is just an expensive godot --export. The template below has two jobs: test (runs GUT or GdUnit4 headless on every push) and build (only on tags, only after test passes).

Reference: Command line tutorial → Running scripts. Verify the exact --script / --scene flags against godot-docs MCP for your Godot version before shipping the workflow.

.github/workflows/ci.yml — tests + builds

name: CI
on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]

env:
  GODOT_VERSION: 4.4.1   # bump in lockstep with project.godot config/features

jobs:
  test:
    name: Headless tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          lfs: true   # required if setup-git-godot is in use
      - uses: chickensoft-games/setup-godot@v2
        with:
          version: ${{ env.GODOT_VERSION }}
          use-dotnet: false
      - name: Import resources (warm .godot cache)
        run: godot --headless --import || true
      # GUT runner — preferred when addons/gut/ is present.
      # If the project uses GdUnit4 instead, swap the next step for:
      #   godot --headless --path . res://addons/gdUnit4/bin/GdUnitCmdTool.gd -a res://test
      - name: Run GUT tests
        run: |
          godot --headless --path . \
            -s addons/gut/gut_cmdln.gd \
            -gdir=res://test/unit \
            -gexit \
            -glog=2
      - name: Upload test logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-logs
          path: |
            user_data/logs/*.log
            test-results.xml
          if-no-files-found: ignore

  build:
    name: Export ${{ matrix.preset }}
    needs: test
    if: startsWith(github.ref, 'refs/tags/v')
    strategy:
      matrix:
        include:
          - { os: ubuntu-latest,  preset: "Linux/X11",       output: builds/linux/MyGame.x86_64 }
          - { os: windows-latest, preset: "Windows Desktop", output: builds/windows/MyGame.exe }
          - { os: macos-latest,   preset: "macOS",           output: builds/macos/MyGame.zip }
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
        with:
          lfs: true
      - uses: chickensoft-games/setup-godot@v2
        with:
          version: ${{ env.GODOT_VERSION }}
          use-dotnet: false
      - name: Install export templates
        run: godot --headless --quit --install-export-templates || true
      - name: Import resources
        run: godot --headless --import || true
      - name: Export ${{ matrix.preset }}
        run: |
          mkdir -p "$(dirname '${{ matrix.output }}')"
          godot --headless --path . --export-release "${{ matrix.preset }}" "${{ matrix.output }}"
        shell: bash
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.os }}-${{ github.ref_name }}
          path: ${{ matrix.output }}

What the workflow guarantees

  • test runs on every push and every PR — fast feedback.
  • build only runs on tag pushes (v1.2.3) and only after test passes (needs: test).
  • lfs: true in actions/checkout pulls Git LFS blobs (required if setup-git-godot is configured; otherwise binary assets resolve to LFS pointer text and the export fails with cryptic errors).
  • godot --headless --import warms the .godot/ cache so the export step does not stall on first-run import.
  • Artifacts are tagged with github.ref_name (the tag) so consecutive releases do not overwrite each other.

Required secrets / env

SecretWhenWhat for
GODOT_ANDROID_KEYSTORE_BASE64Android releaseBase64 of the .keystore (decoded into a temp file by an extra step)
GODOT_ANDROID_KEYSTORE_PASSWORDAndroid releaseKeystore password
GODOT_ANDROID_KEY_ALIASAndroid releaseKey alias inside the keystore
GODOT_MACOS_NOTARY_APPLE_IDmacOS releaseApple ID for xcrun notarytool
GODOT_MACOS_NOTARY_TEAM_IDmacOS releaseTeam ID
GODOT_MACOS_NOTARY_APP_PASSWORDmacOS releaseApp-specific password
ITCH_API_KEYWeb/desktop release if pushing to itchbutler push auth

Inject these into the build job via env: and reference them in the matching [preset.N.options] keys (e.g. keystore/release paths) only at runtime — never commit them.

Common CI gotchas

  • "Cannot import: file is corrupt" on a binary asset → almost always a missing LFS pull. Check actions/checkout has lfs: true and the runner ran git lfs pull.
  • "Could not find export template" → --install-export-templates may need a network call. Some self-hosted runners block it; pre-bake the template into the runner image.
  • Android signing fails silently → the keystore path in export_presets.cfg is still the dev-machine absolute path. Override with keystore/release="$RUNNER_TEMP/release.keystore" after decoding the secret.
  • macOS export hangs forever on a Linux runner → macOS preset must be exported on a macos-latest runner; cross-export only works for desktop Linux/Windows.
  • Rate-limited template download when many parallel jobs hit GitHub mirrors → pin chickensoft-games/setup-godot to a release that caches templates.

For mobile/web releases, use platform-specific runners (macOS for iOS, Linux for Android signing).

Common gotchas

  • Build hangs on first export: usually stuck importing assets. Run godot --headless --import first to warm the cache.
  • Web build crashes mobile browsers: too much VRAM. Reduce texture sizes, disable shadows.
  • macOS unsigned build "is damaged": xattr -cr /Applications/MyGame.app removes the quarantine bit (for testers; ship signed builds for users).
  • Android signing key lost = can't update Play Store listing. Back up the keystore.
  • Translation files: list *.translation in include_filter if you use them.
  • embed_pck=false + missing .pck next to executable = silent failure. Either embed or distribute both.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.