
Godot Export Builds
- 226 installs
- 454 repo stars
- Updated July 28, 2026
- thedivergentai/gd-agentic-skills
Use godot-export-builds for development tasks
About
godot-export-builds: A skill for development. This provides functionality for development workflows.
- godot-export-builds
Godot Export Builds by the numbers
- 226 all-time installs (skills.sh)
- +24 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,757 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-export-buildsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 226 |
|---|---|
| repo stars | ★ 454 |
| Last updated | July 28, 2026 |
| Repository | thedivergentai/gd-agentic-skills ↗ |
What it does
Use godot-export-builds for development tasks
Files
Export & Builds
Expert guidance for building and distributing Godot games across platforms.
NEVER Do (Expert Export Rules)
Platform & Validation
- NEVER export to production without a 'Smoke Test' — "It runs in editor" is NOT enough. Web, Mobile, and Console have unique memory/shader constraints.
- NEVER skip macOS Notarization — Apple's Gatekeeper will block unsigned apps. Use
notarytoolOR distribute exclusively via Steam/App Store. - NEVER use ad-hoc file paths —
res://is read-only in builds. Useuser://for saves and logs, or paths will fail on locked file systems.
Performance & Size
- NEVER use 'Debug' templates for release — Debug binaries are bloated and slow. Always use
--export-releaseto strip profiling overhead. - NEVER include raw resources in builds — Check your export filters. If you include
.md,.txt, or.psdfiles, you're wasting player bandwidth and disk space. - NEVER ignore VRAM compression — Large textures in Web/Mobile builds will crash the GPU driver. Enable ASTC/ETC2 compression in Import settings.
Security
- NEVER commit keystores or raw passwords to Git — Use Environment Variables and CI Secrets (
export_android_signing_env.ps1). - NEVER allow debug commands in Production — Use
OS.has_feature("release")to purge console/cheats from the final build. - NEVER bake shaders on export for Dedicated Servers — The Shader Baker (Godot 4.5+) is for visual clients. Enabling it for headless servers is wasted build time.
---
Available Scripts
MANDATORY: Read the appropriate script before implementing the corresponding pattern.
export_headless_pipeline.ps1
Expert PowerShell script for automated multi-platform headless exports.
export_version_sync.gd
Editor script to sync Git tags/hashes with 'application/config/version'.
export_post_process_hook.gd
EditorExportPlugin for automating post-build tasks (Zipping, Manifests).
export_feature_flag_manager.gd
Expert manager for runtime behavior swapping via build feature flags.
export_pck_patch_loader.gd
Runtime patching logic for mounting external PCK archives and DLC.
export_android_signing_env.ps1
Secure environment variable setup for Android release keystores.
export_custom_build_stripper.py
SCons configuration for stripping unused Godot modules to reduce binary size.
export_macos_notarize_cmd.ps1
CLI procedure for macOS code signing and notarization outside the App Store.
export_build_size_report.gd
Editor tool for auditing resource sizes to optimize build footprints.
export_ci_github_actions.yml
Professional CI/CD workflow for automated multi-platform Godot releases.
export_steam_upload.ps1
Expert script for automating SteamPipe uploads using steamcmd and VDF manifests.
export_universal_manager.gd
Editor tool to programmatically iterate and export all defined presets in one click.
---
Export Templates
Install via Editor: Editor → Manage Export Templates → Download
Basic Export Setup
Create Export Preset
1. Project → Export 2. Add preset (Windows, Linux, etc.) 3. Configure settings 4. Export Project
Windows Export
# Export settings
# Format: .exe (single file) or .pck + .exe
# Icon: .ico file
# Include: *.import, *.tres, *.tscnWeb Export
# Settings:
# Export Type: Regular or GDExtension
# Thread Support: For SharedArrayBuffer
# VRAM Compression: Optimized for sizeExport Presets File
# export_presets.cfg
[preset.0]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
export_path="builds/windows/game.exe"
[preset.0.options]
binary_format/64_bits=true
application/icon="res://icon.ico"Command-Line Export
# Export from command line
godot --headless --export-release "Windows Desktop" builds/game.exe
# Export debug build
godot --headless --export-debug "Windows Desktop" builds/game_debug.exe
# PCK only (for patching)
godot --headless --export-pack "Windows Desktop" builds/game.pckPlatform-Specific
Android
# Requirements:
# - Android SDK
# - OpenJDK 17
# - Debug keystore
# Editor Settings:
# Export → Android → SDK Path
# Export → Android → KeystoreiOS
# Requirements:
# - macOS with Xcode
# - Apple Developer account
# - Provisioning profile
# Export creates .xcodeproj
# Build in Xcode for App StoremacOS
# Settings:
# Codesign: Developer ID certificate
# Notarization: Required for distribution
# Architecture: Universal (Intel + ARM)Feature Flags
# Check platform at runtime
if OS.get_name() == "Windows":
# Windows-specific code
pass
if OS.has_feature("web"):
# Web build
pass
if OS.has_feature("mobile"):
# Android or iOS
passProject Settings for Export
# project.godot
[application]
config/name="My Game"
config/version="1.0.0"
run/main_scene="res://scenes/main.tscn"
config/icon="res://icon.svg"
[rendering]
# Optimize for target platforms
textures/vram_compression/import_etc2_astc=true # MobileBuild Optimization
Reduce Build Size
# Remove unused imports
# Project Settings → Editor → Import Defaults
# Exclude editor-only files
# In export preset: Exclude filters
*.md
*.txt
docs/*Strip Debug Symbols
# Export preset options:
# Debugging → Debug: Off
# Binary Format → Architecture: 64-bit onlyCI/CD with GitHub Actions
# .github/workflows/export.yml
name: Export Godot Game
on:
push:
tags: ['v*']
jobs:
export:
runs-on: ubuntu-latest
container:
image: barichello/godot-ci:4.2.1
steps:
- uses: actions/checkout@v4
- name: Export Windows
run: |
mkdir -p builds/windows
godot --headless --export-release "Windows Desktop" builds/windows/game.exe
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: windows-build
path: builds/windows/Version Management
# version.gd (AutoLoad)
extends Node
const VERSION := "1.0.0"
const BUILD := "2024.02.06"
func get_version_string() -> String:
return "v" + VERSION + " (" + BUILD + ")"Best Practices
1. Test Export Early
Export to all target platforms early
Catch platform-specific issues fast2. Use .gdignore
# Exclude folders from export
# Create .gdignore in folder3. Separate Debug/Release
Debug: Keep logs, dev tools
Release: Strip debug, optimize sizeExpert Export Patterns
1. Platform-Specific-Patching (Delta Updates)
Pattern for mounting external PCK archives to update game content without a full reinstall.
- Implementation:
func _load_patch(patch_path: String) -> bool:
if FileAccess.file_exists(patch_path):
return ProjectSettings.load_resource_pack(patch_path, true) # true = replace files
return false- Expert Note: Patched resources with the same path will override the base PCK. Use this for DLC, localized assets, or hotfixes.
2. VRAM-Compression-Audit
Ensuring the correct texture formats for target hardware.
- S3TC/BPTC: Mandatory for Desktop (Forward+). BPTC is superior for Normal Maps and HDR.
- ETC2: Standard for older Android/iOS devices. Does not support transparency on many Android GPUs [13].
- ASTC: Modern mobile standard. High quality/size ratio. Preferred for newer high-end mobile devices.
- Rule: ALWAYS disable compression for Pixel Art to maintain crisp edges [13].
4. Steam-Upload-Pipeline (SteamPipe)
Automating the distribution process to Steam branches.
- VDF Manifest: Create a
app_build.vdffile defining the app ID, branch (e.g.,beta), and content folders. - Implementation:
# export_steam_upload.ps1
$SteamCMD = "C:\steamcmd\steamcmd.exe"
& $SteamCMD +login $env:STEAM_USER $env:STEAM_PASS +run_app_build "res://builds/app_build.vdf" +quit- Expert Note: Use Environment Variables for credentials to keep the VDF file generic and safe for version control.
5. Universal-Build-Manager (One-Click Export)
Iterating through all export presets to generate a full suite of release binaries.
- Implementation:
func export_all():
var config := ConfigFile.new()
config.load("res://export_presets.cfg")
for section in config.get_sections():
if section.begins_with("preset."):
var preset_name = config.get_value(section, "name")
var path = config.get_value(section, "export_path")
OS.execute(OS.get_executable_path(), ["--headless", "--export-release", preset_name, path])- Benefit: Ensures consistency across platforms by automating the "human error" phase of manual exporting.
Reference
Related
- Master Skill: godot-master
# Expert Android Signing Environment Setup (PowerShell)
# Injects keystore credentials via env vars for secure CI builds.
$env:GODOT_ANDROID_KEYSTORE_PATH = "C:/Keys/release.keystore"
$env:GODOT_ANDROID_KEYSTORE_USER = "game_alias"
$env:GODOT_ANDROID_KEYSTORE_PASS = "secure_password" # Use CI Secrets in production
Write-Host "Android Signing Environment Prepared."
# Usage in Godot Export:
# Set 'Release User' and 'Release Password' in export preset to reference these env vars.
@tool
extends EditorScript
## Expert Build Size Analyzer.
## Scans resources and identifies the largest contributors to build size.
func _run() -> void:
var files = _get_all_files("res://")
var sorted_files = []
for f in files:
var size = FileAccess.get_file_size(f)
sorted_files.append({"path": f, "size": size})
sorted_files.sort_custom(func(a, b): return a.size > b.size)
print("--- Top 20 Largest Resources ---")
for i in range(min(20, sorted_files.size())):
var f = sorted_files[i]
print("%s: %.2f MB" % [f.path, f.size / 1024.0 / 1024.0])
func _get_all_files(path: String) -> Array:
var arr = []
var dir = DirAccess.open(path)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if dir.current_is_dir():
arr.append_array(_get_all_files(path + file_name + "/"))
else:
arr.append(path + file_name)
file_name = dir.get_next()
return arr
name: Godot Expert Export CI
on: [push, pull_request]
jobs:
export:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Godot Build
uses: firebelley/godot-export@v5.2.1
with:
godot_executable_download_url: https://downloads.tuxfamily.org/godotengine/4.2.1/Godot_v4.2.1-stable_linux_headless.64.zip
export_debug: false
export_templates_download_url: https://downloads.tuxfamily.org/godotengine/4.2.1/Godot_v4.2.1-stable_export_templates.tpz
verbose: true
# Note: Presets must match export_presets.cfg
- name: Archive Production Build
uses: actions/upload-artifact@v4
with:
name: game-builds
path: build/
# Expert Custom Build Stripper (SCons)
# Usage: Copy to godot root and run 'scons platform=windows target=template_release'
# Disables unused modules to reduce binary size significantly.
module_navigation_enabled = "no"
module_mobile_vr_enabled = "no"
module_text_server_fb_enabled = "no"
module_upnp_enabled = "no"
# For specialized 2D apps, disable 3D:
# disable_3d = "yes"
# Optimize for size
optimize = "size"
class_name ExportFeatureFlagManager
extends Node
## Expert runtime Feature Flag management.
## Swaps logic/API endpoints based on build features.
func is_debug() -> bool:
return OS.has_feature("debug")
func is_release() -> bool:
return OS.has_feature("release")
func is_mobile() -> bool:
return OS.has_feature("mobile")
func get_api_endpoint() -> String:
if is_debug():
return "https://dev.api.game.com"
return "https://api.game.com"
## Rule: Never hardcode 'is_debug' flags. Rely on Godot's built-in feature flags.
# Expert Headless Export Pipeline (PowerShell)
# Automates multi-platform Godot exports for CI/CD.
$GODOT_BIN = "godot" # Path to godot headless/editor binary
$BUILD_DIR = "./builds"
# Ensure build directory exists
if (!(Test-Path $BUILD_DIR)) { New-Item -ItemType Directory -Path $BUILD_DIR }
# Platform Targets
$PRESETS = @("Windows Desktop", "Linux/X11", "Web")
foreach ($PRESET in $PRESETS) {
$OUT_DIR = "$BUILD_DIR/$($PRESET -replace ' ', '_')"
if (!(Test-Path $OUT_DIR)) { New-Item -ItemType Directory -Path $OUT_DIR }
Write-Host "Exporting: $PRESET..."
& $GODOT_BIN --headless --export-release $PRESET "$OUT_DIR/game"
if ($LASTEXITCODE -ne 0) {
Write-Error "Export failed for $PRESET"
exit $LASTEXITCODE
}
}
Write-Host "Full Build Pipeline Completed Successfully."
# Expert macOS Notarization CLI Steps
# Required for distribution outside the Mac App Store.
# 1. Sign the APP
# codesign --deep --force --options runtime --sign "Developer ID Application: Company" Game.app
# 2. Package into ZIP/DMG
# /usr/bin/ditto -c -k --keepParent Game.app Game.zip
# 3. Submit for Notarization
# xcrun notarytool submit Game.zip --apple-id "me@company.com" --password "app-specific-pw" --team-id "TEAMID" --wait
# 4. Staple the ticket
# xcrun stapler staple Game.app
class_name ExportPCKPatchLoader
extends Node
## Expert PCK Patching/DLC Loader.
## Downloads and mounts external .pck files at runtime.
const PATCH_URL = "https://cdn.game.com/updates/patch_v1.pck"
const LOCAL_PATH = "user://patch_v1.pck"
func load_patch() -> void:
# Assume file is already downloaded via HTTPRequest
if FileAccess.file_exists(LOCAL_PATH):
var success = ProjectSettings.load_resource_pack(LOCAL_PATH)
if success:
print("PCK Patch loaded successfully!")
else:
printerr("Failed to load PCK archive.")
## Tip: Use this for DLC, localized assets, or fixing bugs without full app updates.
@tool
extends EditorExportPlugin
## Expert Post-Export Hook.
## Automates tasks like zipping or cleaning up files after a build finishes.
func _get_name() -> String:
return "ExportPostProcessor"
func _export_end() -> void:
# Note: Use OS.execute to trigger external zip tools or manifest generators.
var build_path = get_option("export_path")
print("Post-processing build at: ", build_path)
# Logic to Zip files or notify Deployment Slack here...
pass
## Rule: Use EditorExportPlugin to unify export workflows for all team members.
extends Node
## Editor tool to programmatically iterate and export all defined presets in one click.
func export_all() -> void:
var config := ConfigFile.new()
var err = config.load("res://export_presets.cfg")
if err != OK:
push_error("Failed to load export_presets.cfg")
return
for section in config.get_sections():
if section.begins_with("preset."):
var preset_name = config.get_value(section, "name")
var path = config.get_value(section, "export_path")
print("Exporting preset: ", preset_name, " to ", path)
# Execute Godot headless for export
var output = []
var exit_code = OS.execute(OS.get_executable_path(), ["--headless", "--export-release", preset_name, path], output)
if exit_code == 0:
print("Successfully exported ", preset_name)
else:
push_error("Failed to export ", preset_name, ". Exit code: ", exit_code)
@tool
extends EditorScript
## Expert Version Syncing.
## Pulls latest Git tag/hash and injects it into 'project.godot'.
func _run() -> void:
var output = []
var exit_code = OS.execute("git", ["describe", "--always", "--tags"], output)
if exit_code == 0:
var version_str = output[0].strip_edges()
ProjectSettings.set_setting("application/config/version", version_str)
ProjectSettings.save()
print("Project version synced to Git: ", version_str)
else:
printerr("Git sync failed. Ensure 'git' is in the system PATH.")
## Rule: Automate versioning during export to ensure build traceability.
#!/bin/bash
# skills/export-builds/code/headless_build.sh
# Expert Headless Export Pattern for Godot 4.x
# Usage: ./headless_build.sh <platform> <version>
PLATFORM=$1 # "Windows Desktop", "Linux/X11", "macOS", "Web"
VERSION=$2
EXPORT_DIR="builds/$VERSION"
mkdir -p "$EXPORT_DIR"
echo "Starting Headless Export for $PLATFORM (Version: $VERSION)..."
# 1. Automate Versioning
# Injects the version number into project.godot before building.
sed -i "s/config\/version=.*/config\/version=\"$VERSION\"/" project.godot
# 2. Run Headless Export
# --headless: Runs without opening the editor window.
# --export-release: Builds optimized release binary.
godot --headless --export-release "$PLATFORM" "$EXPORT_DIR/game_binary"
# 3. Handle Secrets (Post-Build)
# Example: Sign the Windows binary with a certificate stored in ENV.
if [ "$PLATFORM" == "Windows Desktop" ]; then
echo "Signing Windows Binary..."
# signtool sign /f "$WINDOWS_CERT_PATH" /p "$WINDOWS_CERT_PASS" "$EXPORT_DIR/game_binary.exe"
fi
# 4. Deploy (e.g., to itch.io via butler)
# butler push "$EXPORT_DIR" user/game:$PLATFORM --version $VERSION
echo "Build Complete: $EXPORT_DIR"
# skills/export-builds/scripts/version_manager.gd
extends Node
## Version Manager Expert Pattern
## Handles version injection, build metadata, and display strings.
class_name VersionManager
# Configuration - can be updated by CI/CD scripts
const MAJOR = 1
const MINOR = 0
const PATCH = 0
const STATUS = "dev" # dev, alpha, beta, rc, stable
const BUILD_HASH = "local" # Git hash injected during export
# Computed properties
var version_string: String:
get: return "%d.%d.%d" % [MAJOR, MINOR, PATCH]
var full_version_string: String:
get: return "%s-%s (%s)" % [version_string, STATUS, BUILD_HASH]
func _ready() -> void:
print_verbose("Version Manager Initialized: ", full_version_string)
_update_window_title()
func _update_window_title() -> void:
if OS.is_debug_build():
DisplayServer.window_set_title(
"%s | DEBUG | %s" % [ProjectSettings.get_setting("application/config/name"), full_version_string]
)
else:
# Optionally keep version in title for non-final builds
if STATUS != "stable":
DisplayServer.window_set_title(
"%s %s" % [ProjectSettings.get_setting("application/config/name"), version_string]
)
func is_feature_enabled(feature_tag: String) -> bool:
return OS.has_feature(feature_tag)
## EXPERT USAGE:
## label.text = VersionManager.full_version_string