Skip to main content

Overview

Godot supports exporting to all major desktop platforms: Windows, macOS, and Linux. Desktop exports provide the best performance and access to native platform features.

Supported platforms

  • Windows 7 and later
  • 32-bit and 64-bit builds
  • DirectX 11/12 or Vulkan rendering
  • Native executable (.exe)

Windows export

Creating Windows preset

  1. Go to Project > Export
  2. Click Add… and select Windows Desktop
  3. Configure settings
# Windows export settings
Binary Format:
  64 Bits: true  # Create 64-bit executable
  32 Bits: false  # Optional 32-bit build
  
Embedded PCK: true  # Embed game data in .exe

Application:
  Name: "My Game"
  Icon: "res://icon.ico"  # .ico file
  Company Name: "Your Company"
  Product Name: "My Game"
  File Version: "1.0.0.0"
  Product Version: "1.0.0.0"
  Copyright: "© 2024 Your Company"

Export Windows build

# 64-bit build
godot --headless --export-release "Windows Desktop" "builds/windows/MyGame.exe"

# With console (for debugging)
godot --headless --export-debug "Windows Desktop" "builds/windows/MyGame_debug.exe"

Windows icon

Create a .ico file with multiple sizes:
# Using ImageMagick
convert icon_16.png icon_32.png icon_48.png icon_256.png icon.ico

# Or use online tools like:
# https://www.icoconverter.com/

Code signing (Windows)

Sign your executable for Windows SmartScreen:
# Using signtool (Windows SDK)
signtool sign /f certificate.pfx /p password /t http://timestamp.digicert.com MyGame.exe

# Self-signed certificate (for testing)
makecert -r -pe -n "CN=Your Company" -sv cert.pvk cert.cer
pvk2pfx -pvk cert.pvk -spc cert.cer -pfx certificate.pfx
Code signing requires a certificate from a trusted Certificate Authority for production releases.

Windows installer

Create an installer with Inno Setup:
; installer.iss
[Setup]
AppName=My Game
AppVersion=1.0.0
DefaultDirName={pf}\My Game
DefaultGroupName=My Game
OutputDir=builds\installer
OutputBaseFilename=MyGame_Setup

[Files]
Source: "builds\windows\MyGame.exe"; DestDir: "{app}"
Source: "builds\windows\*.dll"; DestDir: "{app}"

[Icons]
Name: "{group}\My Game"; Filename: "{app}\MyGame.exe"
Name: "{commondesktop}\My Game"; Filename: "{app}\MyGame.exe"

[Run]
Filename: "{app}\MyGame.exe"; Description: "Launch My Game"; Flags: nowait postinstall
Compile installer:
iscc installer.iss

macOS export

Creating macOS preset

  1. Go to Project > Export
  2. Click Add… and select macOS
  3. Configure settings
# macOS export settings
Binary Format:
  Universal: true  # Intel + Apple Silicon
  
Application:
  Name: "My Game"
  Icon: "res://icon.icns"  # .icns file
  Identifier: "com.yourcompany.mygame"
  Version: "1.0.0"
  Short Version: "1.0"
  Copyright: "© 2024 Your Company"
  
Minimum macOS Version: "10.13"  # High Sierra

Codesign:
  Enable: true
  Identity: "Developer ID Application: Your Name"
  Entitlements: "res://entitlements.plist"
macOS export requires a Mac for code signing and notarization. You can export unsigned builds on any platform, but they won’t run properly on macOS without signing.

macOS icon

Create .icns file:
# Create iconset folder
mkdir MyIcon.iconset

# Generate required sizes
sips -z 16 16     icon.png --out MyIcon.iconset/icon_16x16.png
sips -z 32 32     icon.png --out MyIcon.iconset/[email protected]
sips -z 32 32     icon.png --out MyIcon.iconset/icon_32x32.png
sips -z 64 64     icon.png --out MyIcon.iconset/[email protected]
sips -z 128 128   icon.png --out MyIcon.iconset/icon_128x128.png
sips -z 256 256   icon.png --out MyIcon.iconset/[email protected]
sips -z 256 256   icon.png --out MyIcon.iconset/icon_256x256.png
sips -z 512 512   icon.png --out MyIcon.iconset/[email protected]
sips -z 512 512   icon.png --out MyIcon.iconset/icon_512x512.png
sips -z 1024 1024 icon.png --out MyIcon.iconset/[email protected]

# Create .icns
iconutil -c icns MyIcon.iconset

Code signing (macOS)

# Sign the app
codesign --force --deep --sign "Developer ID Application: Your Name" MyGame.app

# Verify signature
codesign -vvv --deep --strict MyGame.app
spctl -a -vvv -t install MyGame.app

Notarization (macOS)

Required for macOS 10.15+:
# Create DMG
hdiutil create -volname "My Game" -srcfolder MyGame.app -ov -format UDZO MyGame.dmg

# Submit for notarization
xcrun notarytool submit MyGame.dmg \
  --apple-id "[email protected]" \
  --team-id "TEAM_ID" \
  --password "app-specific-password" \
  --wait

# Staple notarization ticket
xcrun stapler staple MyGame.dmg

Create DMG installer

# Using create-dmg tool
create-dmg \
  --volname "My Game" \
  --window-pos 200 120 \
  --window-size 800 400 \
  --icon-size 100 \
  --icon "MyGame.app" 200 190 \
  --hide-extension "MyGame.app" \
  --app-drop-link 600 185 \
  "MyGame.dmg" \
  "MyGame.app"

Linux export

Creating Linux preset

  1. Go to Project > Export
  2. Click Add… and select Linux/X11
  3. Configure settings
# Linux export settings
Binary Format:
  64 Bits: true
  
Embedded PCK: true

Texture Format:
  ETC2: false  # Desktop doesn't need mobile compression

Export Linux build

# Export executable
godot --headless --export-release "Linux" "builds/linux/MyGame.x86_64"

# Make executable
chmod +x builds/linux/MyGame.x86_64

Linux desktop entry

Create .desktop file for desktop integration:
# MyGame.desktop
[Desktop Entry]
Type=Application
Name=My Game
Comment=An awesome game
Exec=/usr/bin/mygame
Icon=/usr/share/icons/mygame.png
Terminal=false
Categories=Game;ArcadeGame;

Package for Linux

# Create AppImage structure
mkdir -p MyGame.AppDir/usr/bin
mkdir -p MyGame.AppDir/usr/share/icons

# Copy files
cp MyGame.x86_64 MyGame.AppDir/usr/bin/
cp icon.png MyGame.AppDir/usr/share/icons/
cp MyGame.desktop MyGame.AppDir/

# Create AppImage
appimagetool MyGame.AppDir MyGame.AppImage

Cross-platform considerations

File paths

# Use OS-independent paths
var save_path = "user://savegame.dat"  # Cross-platform user directory

# Get user directory
var user_dir = OS.get_user_data_dir()
print(user_dir)
# Windows: C:\Users\Username\AppData\Roaming\Godot\app_userdata\GameName
# macOS: ~/Library/Application Support/Godot/app_userdata/GameName
# Linux: ~/.local/share/godot/app_userdata/GameName

Platform detection

func _ready():
    match OS.get_name():
        "Windows":
            setup_windows()
        "macOS":
            setup_macos()
        "Linux", "FreeBSD", "NetBSD", "OpenBSD", "BSD":
            setup_linux()

Native dialogs

# File dialog
var file_dialog = FileDialog.new()
file_dialog.access = FileDialog.ACCESS_FILESYSTEM
file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
file_dialog.add_filter("*.txt", "Text Files")
add_child(file_dialog)
file_dialog.popup_centered_ratio(0.8)

# Native OS file dialog
func open_file_native():
    DisplayServer.file_dialog_show(
        "Open File",
        OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS),
        "*.txt",
        false,
        DisplayServer.FILE_DIALOG_MODE_OPEN_FILE,
        _on_file_selected
    )

Steam integration

Integrate with Steam (using GodotSteam):
var steam

func _ready():
    OS.set_environment("SteamAppId", "YOUR_APP_ID")
    
    if Engine.has_singleton("Steam"):
        steam = Engine.get_singleton("Steam")
        
        var init = steam.steamInit()
        if init.status == 1:  # Success
            print("Steam initialized")
            var username = steam.getPersonaName()
            print("Steam user: ", username)

func unlock_achievement(achievement_name: String):
    if steam:
        steam.setAchievement(achievement_name)
        steam.storeStats()

Distribution

Steam

  1. Register Steamworks account
  2. Create app in Steamworks
  3. Upload builds using SteamPipe
  4. Configure store page
  5. Submit for review

GOG

  1. Apply to GOG as developer
  2. Submit game for curation
  3. If accepted, use GOG Galaxy SDK
  4. Build with GOG pipeline

itch.io

# Using butler (itch.io upload tool)
butler push builds/windows user/game:windows
butler push builds/linux user/game:linux
butler push builds/macos user/game:mac

Epic Games Store

  1. Apply to Epic Games Store
  2. Integrate Epic Online Services
  3. Submit build through Epic Developer Portal

Performance optimization

Use appropriate renderer

Forward+ for high-end, Mobile for broader compatibility.

Profile regularly

Use built-in profiler to identify bottlenecks.

Optimize assets

Compress textures, optimize meshes, reduce shader complexity.

Multi-threading

Use threading for heavy operations outside render loop.

Launch options

# Run with custom resolution
./MyGame --resolution 1920x1080

# Run in windowed mode
./MyGame --windowed

# Run in fullscreen
./MyGame --fullscreen

# Custom user data directory
./MyGame --user-data-dir /path/to/data
Handle in code:
func _ready():
    var args = OS.get_cmdline_args()
    for arg in args:
        if arg == "--windowed":
            DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
        elif arg.begins_with("--resolution="):
            var res = arg.split("=")[1].split("x")
            var size = Vector2i(int(res[0]), int(res[1]))
            DisplayServer.window_set_size(size)

Troubleshooting

Install required libraries:
sudo apt install libgl1 libasound2 libpulse0
App needs to be code signed and notarized for macOS 10.15+.
Code sign with a trusted certificate to avoid SmartScreen warnings.

Next steps

Android

Export for Android devices

iOS

Export for iOS devices

Web

Export for web browsers

Build docs developers (and LLMs) love