Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Godot Engine — User Guide

Generated May 2026 from godotengine/godot at caf1670

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Godot Engine is a free, open-source 2D and 3D game engine that provides everything you need to create games and interactive applications. It ships with an integrated editor, its own Python-like scripting language (GDScript), C#/.NET support, and a GDExtension system for native C/C++ plugins. Godot exports to Windows, macOS, Linux, Android, iOS, Web (HTML5), and visionOS — all under the permissive MIT license.

This guide covers installation, editor usage, scripting, building from source, exporting projects, and troubleshooting. It is written for game developers, hobbyists, and teams evaluating or actively using Godot Engine.


Table of Contents


1. Quick Start

1.1 Your First Project in 5 Minutes

  1. Download the Godot editor from godotengine.org for your platform (Windows, macOS, or Linux).
  2. Run the executable — no installer required. Godot is a single self-contained binary.
  3. The Project Manager opens. Click New Project, choose a folder, name your project, and select a rendering method.
  4. Click Create & Edit to enter the editor.
  5. Add a Node2D root node, attach a new GDScript, and write:
extends Node2D

func _ready():
    print("Hello from Godot!")

func _process(delta):
    rotation += delta  # Spin the node
  1. Press F5 (or the play button). Godot asks you to select a main scene — pick your current scene. A window opens with your spinning node.

1.2 Quick Start from the Command Line

If you prefer the terminal, you can launch Godot directly:

# Open the project manager
godot --project-manager

# Open the editor for a specific project
godot --editor --path /home/user/my_game

# Run a project directly (no editor)
godot --path /home/user/my_game

# Run a specific scene
godot --path /home/user/my_game --scene res://levels/level_1.tscn

# Run headlessly (for servers, CI/CD)
godot --headless --path /home/user/my_game

1.3 Choosing a Rendering Method

When creating a project, you select one of three rendering methods:

Rendering Method Backend Best For
Forward+ Vulkan High-end 3D games, desktop/console
Mobile Vulkan Mobile 3D games, mid-range hardware
Compatibility OpenGL ES 3.0 2D games, low-end hardware, web exports

Tip

Forward+ is the most feature-complete renderer. If you are making a 2D game or targeting the web, choose Compatibility — it has the broadest hardware support and is the only renderer that works with WebGL 2.0.

Additional rendering drivers available on specific platforms:

Driver Platform Notes
Metal macOS, iOS Native Apple GPU API
Direct3D 12 Windows Alternative to Vulkan on Windows
OpenGL ES 3.0 All Compatibility mode fallback

1.4 Choosing a Scripting Language

Language Use Case Notes
GDScript General purpose, rapid prototyping Native to Godot, Python-like syntax, tightly integrated
C# Teams with .NET experience, large projects Requires the Mono build of Godot
GDExtension (C/C++) Performance-critical code, native plugins Compile extensions separately, load at runtime

2. Installation

2.1 Pre-Built Editor Binaries

Godot requires no installation. Download the binary for your platform and run it.

Windows

  1. Download the Windows ZIP from godotengine.org/download.
  2. Extract to any folder (e.g., C:\Godot\).
  3. Run Godot_v4.x-stable_win64.exe.

For C# support, download the .NET build instead of the standard build.

macOS

  1. Download the macOS ZIP.
  2. Extract and move Godot.app to /Applications/.
  3. On first launch, right-click → Open to bypass Gatekeeper.

Linux

  1. Download the Linux x86_64 binary.
  2. Extract and make executable:
chmod +x Godot_v4.x-stable_linux.x86_64
./Godot_v4.x-stable_linux.x86_64

Alternatively, install via your distribution's package manager or Flatpak:

# Flatpak (any distro)
flatpak install flathub org.godotengine.Godot

# Arch Linux (AUR)
yay -S godot

# Fedora
sudo dnf install godot

Note

The official download is always the most up-to-date. Distribution packages may lag behind releases.

2.2 Building from Source

Godot uses SCons (a Python-based build system). The CMakeLists.txt in the repository is only for Android Studio IDE support and is explicitly non-functional for building the engine.

Prerequisites

Platform Requirements
All Python 3.6+, SCons 4.0+
Windows Visual Studio 2019+ (with C++ workload) or MinGW-w64
macOS Xcode command-line tools, Vulkan SDK (for Vulkan renderer)
Linux GCC 9+ or Clang 6+, pkg-config, X11/Wayland dev libraries

Install SCons:

pip install scons

Building the Editor

# Clone the repository
git clone https://github.com/godotengine/godot.git
cd godot

# Build the editor (release with debug symbols)
scons platform=linuxbsd target=editor

# Build for Windows
scons platform=windows target=editor

# Build for macOS
scons platform=macos target=editor

Common Build Options

# Build with specific number of jobs (parallel compilation)
scons -j8 platform=linuxbsd target=editor

# Build debug version
scons platform=linuxbsd target=editor dev_build=yes

# Build with C# (Mono) support
scons platform=linuxbsd target=editor module_mono_enabled=yes

# Build export template (release)
scons platform=linuxbsd target=template_release

# Build export template (debug)
scons platform=linuxbsd target=template_debug

# Disable specific modules to reduce build size
scons platform=linuxbsd target=editor module_webrtc_enabled=no module_websocket_enabled=no

# Use compiler cache for faster rebuilds
scons platform=linuxbsd target=editor use_ccache=yes

Build Environment Variables

Variable Purpose
BUILD_NAME Custom build name embedded in the binary
GODOT_VERSION_STATUS Override the version status string
SCONS_CACHE Path to SCons cache directory (speeds up rebuilds)
SCONS_CACHE_LIMIT Maximum SCons cache size in MB
CCACHE Path to ccache binary for compiler caching
# Example: custom build with cache
export SCONS_CACHE="$HOME/.scons_cache"
export SCONS_CACHE_LIMIT=4096
export BUILD_NAME="my_custom_build"
scons -j$(nproc) platform=linuxbsd target=editor

Building for Android

Additional environment variables are required:

Variable Purpose
ANDROID_HOME / ANDROID_SDK_ROOT Path to Android SDK
GODOT_ANDROID_SIGN_KEYSTORE Path to signing keystore
GODOT_ANDROID_KEYSTORE_ALIAS Keystore alias
GODOT_ANDROID_SIGN_PASSWORD Signing password
export ANDROID_HOME="$HOME/Android/Sdk"
scons platform=android target=template_release arch=arm64

Cross-Compiling for macOS (from Linux)

export OSXCROSS_ROOT="/path/to/osxcross"
scons platform=macos target=editor osxcross_sdk=darwin21

Important

Godot uses SCons, not CMake. Running cmake on the Godot source tree will not build the engine. Always use scons.

2.3 Export Templates

Export templates are pre-compiled binaries for each target platform. You need them to export your game.

Installing via the editor:

  1. Open the editor.
  2. Go to Editor → Manage Export Templates.
  3. Click Download and Install for the matching engine version.

Installing manually:

  1. Download from godotengine.org/download.
  2. Place in the templates directory:
    • Windows: %APPDATA%\Godot\export_templates\<version>\
    • macOS: ~/Library/Application Support/Godot/export_templates/<version>/
    • Linux: ~/.local/share/godot/export_templates/<version>/

Building your own export templates:

# Release template
scons platform=linuxbsd target=template_release

# Debug template
scons platform=linuxbsd target=template_debug

3. Configuration

3.1 Project Configuration (project.godot)

Every Godot project has a project.godot file at its root. This INI-style file stores all project settings.

; project.godot
[application]
config/name="My Game"
config/description="An awesome game built with Godot."
run/main_scene="res://scenes/main.tscn"
config/features=PackedStringArray("4.4")
config/icon="res://icon.svg"

[display]
window/size/viewport_width=1920
window/size/viewport_height=1080
window/size/mode=2
window/stretch/mode="viewport"
window/stretch/aspect="expand"
window/vsync/vsync_mode=1

[input]
move_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"keycode":65)]
}

[rendering]
renderer/rendering_method="forward_plus"

Tip

You can edit project.godot by hand, but it is easier and safer to change settings through Project → Project Settings in the editor. The editor writes correct syntax and validates values.

3.2 Editor Settings

Editor preferences are stored per-user, not per-project:

  • Windows: %APPDATA%\Godot\editor_settings-4.tres
  • macOS: ~/Library/Application Support/Godot/editor_settings-4.tres
  • Linux: ~/.config/godot/editor_settings-4.tres

Access these via Editor → Editor Settings in the editor.

Key editor settings:

Setting Default Purpose
interface/editor/display_scale Auto UI scale for HiDPI displays
text_editor/theme/color_theme Adaptive Code editor color theme
text_editor/behavior/indent/type Tabs Tabs vs spaces
text_editor/behavior/indent/size 4 Indent width
filesystem/directories/default_project_path (platform-specific) Where new projects are created
run/window_placement/rect Centered Game window position during testing
network/debug/remote_host 127.0.0.1 Remote debugger host
network/debug/remote_port 6007 Remote debugger port

3.3 Default Window and Display Settings

Godot ships with these display defaults:

Setting Default Value
Window width 1152
Window height 648
VSync Enabled
Audio output latency 15 ms

Override these in project.godot under [display] or via Project → Project Settings → Display → Window.

3.4 Input Mapping

Define input actions in Project → Project Settings → Input Map. Actions map logical names to physical inputs:

# project.godot input section
[input]
jump={
"deadzone": 0.2,
"events": [Object(InputEventKey,"keycode":32)]
}

Use in code:

func _process(delta):
    if Input.is_action_just_pressed("jump"):
        velocity.y = -jump_force

3.5 Rendering Configuration

Setting Options Notes
Rendering method forward_plus, mobile, gl_compatibility Set at project creation or in Project Settings
Rendering driver Vulkan, OpenGL, Metal, Direct3D 12 Platform-dependent
Anti-aliasing MSAA (2x/4x/8x), FXAA, TAA Forward+ supports all; Compatibility is limited
Shadows Enabled/Disabled, resolution, filtering Significant performance impact

See the Admin Guide for complete rendering configuration reference.

3.6 Physics Configuration

Godot includes two physics engines:

Engine Scope Notes
Godot Physics 2D and 3D Built-in, default, well-integrated
Jolt Physics 3D Module-based, higher accuracy for complex 3D

Switch physics engines in Project → Project Settings → Physics → 3D → Physics Engine.

Note

Jolt Physics may emit extra enter/exit body events in certain edge cases with Area3D nodes. If you experience duplicate collision callbacks, check whether you are using overlapping detection areas. See the troubleshooting section for a workaround.


4. Core Usage

4.1 The Editor Interface

The Godot editor is a self-contained development environment with these main panels:

Panel Purpose
Scene Tree (top-left) Hierarchical view of all nodes in the current scene
Inspector (right) Properties of the selected node
FileSystem (bottom-left) Project file browser
2D/3D Viewport (center) Visual scene editing
Script Editor (center, toggle) Code editor for GDScript, C#, shaders
Output (bottom) Console output, warnings, errors
Debugger (bottom) Breakpoints, profiler, monitors, network
Animation (bottom) Animation editor and timeline

Switch between 2D, 3D, Script, and AssetLib views using the tabs at the top center of the editor.

4.2 Scene System

Everything in Godot is built from scenes and nodes:

  • A node is the fundamental building block — it can be a sprite, a collision shape, a camera, an audio player, or hundreds of other types.
  • A scene is a tree of nodes saved as a .tscn (text) or .scn (binary) file.
  • Scenes can be instanced inside other scenes, enabling composition and reuse.

Common Node Types

Category Nodes Use
2D Sprite2D, AnimatedSprite2D, Camera2D, TileMap 2D games
3D MeshInstance3D, Camera3D, DirectionalLight3D, WorldEnvironment 3D games
UI Control, Button, Label, TextEdit, Panel, VBoxContainer User interfaces
Physics 2D RigidBody2D, CharacterBody2D, StaticBody2D, Area2D 2D physics
Physics 3D RigidBody3D, CharacterBody3D, StaticBody3D, Area3D 3D physics
Audio AudioStreamPlayer, AudioStreamPlayer2D, AudioStreamPlayer3D Sound
Networking MultiplayerSpawner, MultiplayerSynchronizer Multiplayer
Navigation NavigationAgent2D/3D, NavigationRegion2D/3D Pathfinding

Scene Composition Pattern

Main Scene (Node2D)
├── Player (CharacterBody2D)  ← instanced from player.tscn
│   ├── Sprite2D
│   ├── CollisionShape2D
│   └── AnimationPlayer
├── Level (Node2D)            ← instanced from level_01.tscn
│   ├── TileMap
│   └── Enemies (Node2D)
│       ├── Enemy1            ← instanced from enemy.tscn
│       └── Enemy2            ← instanced from enemy.tscn
├── UI (CanvasLayer)          ← instanced from hud.tscn
│   ├── HealthBar
│   └── ScoreLabel
└── AudioStreamPlayer         ← background music

4.3 GDScript Fundamentals

GDScript is Godot's primary scripting language. It is Python-like but purpose-built for game development.

Basic Syntax

extends CharacterBody2D

# Constants
const SPEED = 300.0
const JUMP_VELOCITY = -400.0

# Exported variables (editable in Inspector)
@export var health: int = 100
@export var damage_multiplier: float = 1.0
@export var weapon_texture: Texture2D

# Onready variables (assigned when node enters tree)
@onready var sprite = $Sprite2D
@onready var animation_player = $AnimationPlayer

# Signals
signal health_changed(new_health: int)
signal died

func _ready():
    # Called when node enters the scene tree
    print("Player ready!")

func _process(delta: float):
    # Called every frame
    pass

func _physics_process(delta: float):
    # Called every physics frame (default 60/s)
    # Add gravity
    if not is_on_floor():
        velocity += get_gravity() * delta

    # Handle jump
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # Handle movement
    var direction = Input.get_axis("move_left", "move_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)

    move_and_slide()

func take_damage(amount: int):
    health -= amount * damage_multiplier
    health_changed.emit(health)
    if health <= 0:
        died.emit()
        queue_free()

Signals and Connections

# Defining a signal
signal score_changed(new_score: int)

# Emitting a signal
score_changed.emit(current_score)

# Connecting via code
func _ready():
    var button = $Button
    button.pressed.connect(_on_button_pressed)

    # With bound arguments
    var enemy = $Enemy
    enemy.died.connect(_on_enemy_died.bind(enemy.name))

func _on_button_pressed():
    print("Button pressed!")

func _on_enemy_died(enemy_name: String):
    print(enemy_name, " was defeated!")

Resources and Loading

# Preload (at parse time — constant path required)
const BulletScene = preload("res://scenes/bullet.tscn")

# Load (at runtime — dynamic path OK)
var texture = load("res://sprites/player.png")

# Instancing scenes
func spawn_bullet():
    var bullet = BulletScene.instantiate()
    bullet.position = global_position
    bullet.rotation = rotation
    get_parent().add_child(bullet)

Typed GDScript

# Variable types
var name: String = "Player"
var position: Vector2 = Vector2.ZERO
var items: Array[String] = []
var stats: Dictionary = {}

# Function signatures with types
func calculate_damage(base: int, multiplier: float) -> int:
    return int(base * multiplier)

# Nullable types
var target: Node2D = null

Coroutines and Await

# Await a signal
func play_cutscene():
    $AnimationPlayer.play("cutscene_intro")
    await $AnimationPlayer.animation_finished
    $DialogBox.show_text("Welcome, hero!")
    await $DialogBox.dialog_finished
    start_gameplay()

# Await a timer
func flash_damage():
    $Sprite2D.modulate = Color.RED
    await get_tree().create_timer(0.2).timeout
    $Sprite2D.modulate = Color.WHITE

Enums and Constants

enum State { IDLE, RUNNING, JUMPING, FALLING, ATTACKING }

var current_state: State = State.IDLE

func update_state():
    match current_state:
        State.IDLE:
            play_idle_animation()
        State.RUNNING:
            play_run_animation()
        State.JUMPING:
            apply_jump_force()
        State.FALLING:
            apply_gravity()
        State.ATTACKING:
            deal_damage()

Static Typing Benefits

# Untyped (slower, no autocomplete, runtime errors)
var speed = 300
var direction = Vector2()

# Typed (faster, better autocomplete, parse-time errors)
var speed: float = 300.0
var direction: Vector2 = Vector2.ZERO

4.4 C# Scripting

The .NET build of Godot supports C# scripting. C# scripts coexist alongside GDScript in the same project.

using Godot;

public partial class Player : CharacterBody2D
{
    [Export]
    public int Health { get; set; } = 100;

    [Export]
    public float Speed { get; set; } = 300.0f;

    public const float JumpVelocity = -400.0f;

    [Signal]
    public delegate void HealthChangedEventHandler(int newHealth);

    public override void _Ready()
    {
        GD.Print("Player ready!");
    }

    public override void _PhysicsProcess(double delta)
    {
        Vector2 velocity = Velocity;

        if (!IsOnFloor())
            velocity += GetGravity() * (float)delta;

        if (Input.IsActionJustPressed("jump") && IsOnFloor())
            velocity.Y = JumpVelocity;

        float direction = Input.GetAxis("move_left", "move_right");
        velocity.X = direction != 0 ? direction * Speed : Mathf.MoveToward(velocity.X, 0, Speed);

        Velocity = velocity;
        MoveAndSlide();
    }
}

Build C# solutions from the editor via MSBuild → Build or from the command line:

godot --headless --path /path/to/project --build-solutions

4.5 GDExtension (C/C++ Plugins)

GDExtension allows writing performance-critical code in C or C++ that loads as a native plugin:

  1. Write your extension using the godot-cpp bindings.
  2. Compile to a shared library (.dll, .so, .dylib).
  3. Register via a .gdextension file in your project.

Dump the GDExtension API schema for binding generation:

godot --headless --dump-extension-api

This outputs extension_api.json containing all engine classes, methods, and signals.

4.6 Shaders

Godot has its own shading language (similar to GLSL):

shader_type canvas_item;

uniform vec4 flash_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform float flash_intensity : hint_range(0.0, 1.0) = 0.0;

void fragment() {
    vec4 tex_color = texture(TEXTURE, UV);
    COLOR = mix(tex_color, flash_color, flash_intensity);
}

Shader types:

Type Use
canvas_item 2D nodes (Sprite2D, Control, etc.)
spatial 3D nodes (MeshInstance3D)
particles GPU particle processing
sky Sky rendering
fog Volumetric fog

Visual Shaders

For a node-based shader editor, use VisualShader resources. Drag and connect nodes to build shaders without writing code. Visual shaders compile to the same shader language and have equivalent performance.

4.7 The Animation System

Godot's animation system can animate any node property:

  1. Add an AnimationPlayer node to your scene.
  2. Create a new animation in the Animation panel.
  3. Add tracks for any property (position, scale, color, custom variables).
  4. Use keyframes to define values at specific times.
# Controlling animations from code
@onready var anim = $AnimationPlayer

func _ready():
    anim.play("idle")

func attack():
    anim.play("attack")
    await anim.animation_finished
    anim.play("idle")

AnimationTree provides advanced state machine control for blending animations:

@onready var anim_tree = $AnimationTree

func _physics_process(delta):
    anim_tree.set("parameters/blend_position", velocity.normalized())

4.8 Tween Animations

For simple, code-driven animations, use Tweens:

func fade_in():
    var tween = create_tween()
    tween.tween_property($Sprite2D, "modulate:a", 1.0, 0.5)

func bounce():
    var tween = create_tween()
    tween.set_trans(Tween.TRANS_BOUNCE)
    tween.set_ease(Tween.EASE_OUT)
    tween.tween_property(self, "position:y", position.y - 50, 0.3)
    tween.tween_property(self, "position:y", position.y, 0.3)

func chain_animations():
    var tween = create_tween()
    tween.tween_property(self, "scale", Vector2(1.2, 1.2), 0.1)
    tween.tween_property(self, "scale", Vector2.ONE, 0.1)
    tween.tween_callback(queue_free)

5. Common Tasks

5.1 Running and Testing Projects

From the Editor

Action Shortcut Description
Run project F5 Run the main scene
Run current scene F6 Run the scene you are editing
Run custom scene Ctrl+Shift+F5 Choose a scene to run
Stop running F8 Stop the running project
Debug break F12 Pause in the debugger

From the Command Line

# Run a project
godot --path /path/to/project

# Run a specific scene
godot --path /path/to/project --scene res://scenes/test_level.tscn

# Run with debug output
godot --path /path/to/project --verbose

# Run quietly (no stdout)
godot --path /path/to/project --quiet

# Suppress version header
godot --path /path/to/project --no-header

# Run with visible collision shapes (debug builds)
godot --path /path/to/project --debug-collisions

# Run with navigation mesh visualization (debug builds)
godot --path /path/to/project --debug-navigation

# Run with avoidance debug overlays (debug builds)
godot --path /path/to/project --debug-avoidance

# Run with path visualization (debug builds)
godot --path /path/to/project --debug-paths

# Run with canvas item redraw visualization (debug builds)
godot --path /path/to/project --debug-canvas-item-redraw

# Run with FPS counter in stdout
godot --path /path/to/project --print-fps

# Run with a maximum FPS cap (0 = unlimited)
godot --path /path/to/project --max-fps 30

# Run with fixed FPS (disables real-time sync — deterministic)
godot --path /path/to/project --fixed-fps 60

# Run with custom time scale (slow motion / fast forward)
godot --path /path/to/project --time-scale 0.5

# Run without vsync
godot --path /path/to/project --disable-vsync

# Disable the render loop entirely
godot --path /path/to/project --disable-render-loop

# Disable crash handler
godot --path /path/to/project --disable-crash-handler

# Run and quit after the first frame (useful for import/validation)
godot --path /path/to/project --quit

# Run and quit after N iterations
godot --path /path/to/project --quit-after 100

Display and Window Options

# Run with a custom resolution
godot --path /path/to/project --resolution 1920x1080

# Run fullscreen
godot --path /path/to/project --fullscreen

# Run maximized
godot --path /path/to/project --maximized

# Run windowed (override fullscreen project setting)
godot --path /path/to/project --windowed

# Run always-on-top
godot --path /path/to/project --always-on-top

# Run on a specific screen
godot --path /path/to/project --screen 1

# Run at a specific window position
godot --path /path/to/project --position 100,200

# Run in a single window (no subwindows)
godot --path /path/to/project --single-window

Audio and Rendering Options

# Run with a specific audio driver
godot --path /path/to/project --audio-driver PulseAudio

# Run with custom audio latency
godot --path /path/to/project --audio-output-latency 30

# Run with a specific rendering method
godot --path /path/to/project --rendering-method forward_plus

# Run with a specific rendering driver
godot --path /path/to/project --rendering-driver vulkan

# Run with a specific GPU
godot --path /path/to/project --gpu-index 1

# Run with a specific text driver
godot --path /path/to/project --text-driver <driver>

# Run with a specific tablet/pen driver
godot --path /path/to/project --tablet-driver <driver>

# Run with a specific display driver
godot --path /path/to/project --display-driver <driver>

# Run with render thread mode (safe or separate)
godot --path /path/to/project --render-thread separate

Passing Custom Arguments to Your Game

Use -- or ++ to separate engine arguments from your own:

# Everything after -- is accessible via OS.get_cmdline_user_args()
godot --path /path/to/project -- --level=5 --difficulty=hard --seed=42
# In your game code
func _ready():
    var args = OS.get_cmdline_user_args()
    for arg in args:
        if arg.begins_with("--level="):
            var level = arg.split("=")[1].to_int()
            load_level(level)

5.2 Debugging

Built-In Debugger

The editor includes a full debugger with breakpoints, call stack, and variable inspection:

  1. Open the Script editor.
  2. Click in the gutter (left of line numbers) to set a breakpoint.
  3. Run the project with F5 — it pauses at breakpoints.
  4. Inspect variables in the Debugger → Stack Variables tab.

Remote Debugging

Connect to a running instance from a separate editor:

# On the target machine, start with a debug server
godot --path /path/to/project --debug-server tcp://0.0.0.0:6007

# In the editor, connect via Editor → Editor Settings → Network → Debug

Debug Adapter Protocol (DAP)

For external editors (VS Code, etc.):

# Start the DAP server on a specific port
godot --editor --path /path/to/project --dap-port 6006

Language Server Protocol (LSP)

For code completion and diagnostics in external editors:

# Start the LSP server on a specific port
godot --editor --path /path/to/project --lsp-port 6008

Command-Line Debugger

# Start with the local stdout debugger
godot --path /path/to/project --debug

# Set breakpoints from the command line
godot --path /path/to/project --debug --breakpoints "res://player.gd:42,res://enemy.gd:15"

Profiling

# Enable profiling
godot --path /path/to/project --profiling

# GPU profiling
godot --path /path/to/project --gpu-profile

# GPU validation layers (catches graphics API misuse)
godot --path /path/to/project --gpu-validation

# Abort on GPU errors (debug builds)
godot --path /path/to/project --gpu-abort

# Simulate CPU load (add frame delay in ms)
godot --path /path/to/project --frame-delay 10

In the editor, open the Debugger → Profiler tab while the game runs to see per-function timing.

5.3 Exporting Projects

Setting Up Export Presets

  1. Go to Project → Export.
  2. Click Add and choose a platform.
  3. Configure settings (icon, permissions, signing, etc.).
  4. Click Export Project and choose a destination.

Each preset is stored in export_presets.cfg at the project root.

Command-Line Exports

# Export release build
godot --headless --path /path/to/project --export-release "Windows Desktop" /output/game.exe

# Export debug build
godot --headless --path /path/to/project --export-debug "Linux" /output/game.x86_64

# Export data pack only (no executable)
godot --headless --path /path/to/project --export-pack "Windows Desktop" /output/game.pck

# Export only changed files (for patching)
godot --headless --path /path/to/project --export-patch "Windows Desktop" /output/patch.pck

Important

You must have export templates installed that match your engine version before exporting. Mismatched versions will fail. If you have trouble downloading them from within the editor, see the troubleshooting section.

Platform-Specific Export Notes

Platform Key Requirements
Windows Optional: RCEDIT for icon/version info
macOS Code signing required for distribution; notarization for Gatekeeper
Linux Virtually no special requirements
Android Android SDK, JDK, debug keystore; set ANDROID_HOME
iOS macOS + Xcode required; provisioning profile needed
Web (HTML5) Must use Compatibility renderer (OpenGL ES 3.0 / WebGL 2.0)
visionOS Apple Vision Pro target; requires Xcode with visionOS SDK

5.4 2D Game Workflows

Tilemap Setup

  1. Create a TileMap node.
  2. In the Inspector, create a new TileSet.
  3. Add a tile atlas from a spritesheet.
  4. Paint tiles in the 2D viewport using the TileMap editor.

2D Platformer Controller

extends CharacterBody2D

const SPEED = 200.0
const JUMP_VELOCITY = -300.0

func _physics_process(delta):
    if not is_on_floor():
        velocity += get_gravity() * delta

    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    var direction = Input.get_axis("move_left", "move_right")
    velocity.x = direction * SPEED if direction else move_toward(velocity.x, 0, SPEED)

    move_and_slide()

Top-Down Controller

extends CharacterBody2D

const SPEED = 200.0

func _physics_process(delta):
    var input_dir = Input.get_vector("move_left", "move_right", "move_up", "move_down")
    velocity = input_dir * SPEED
    move_and_slide()

    if velocity.length() > 0:
        $Sprite2D.rotation = velocity.angle()

2D Camera with Smoothing

extends Camera2D

@export var target: Node2D
@export var smoothing: float = 5.0

func _process(delta):
    if target:
        global_position = global_position.lerp(target.global_position, smoothing * delta)

Sprite Animation

extends AnimatedSprite2D

func play_animation(direction: Vector2):
    if direction.x > 0:
        flip_h = false
        play("walk")
    elif direction.x < 0:
        flip_h = true
        play("walk")
    else:
        play("idle")

Parallax Backgrounds

ParallaxBackground
├── ParallaxLayer (scroll_scale = Vector2(0.2, 0.2))  ← far clouds
│   └── Sprite2D
├── ParallaxLayer (scroll_scale = Vector2(0.5, 0.5))  ← mountains
│   └── Sprite2D
└── ParallaxLayer (scroll_scale = Vector2(0.8, 0.8))  ← trees
    └── Sprite2D

2D Collision Detection

# Area2D-based detection (pickups, triggers)
extends Area2D

func _ready():
    body_entered.connect(_on_body_entered)

func _on_body_entered(body: Node2D):
    if body.is_in_group("player"):
        collect()
        queue_free()

func collect():
    # Award points, play sound, etc.
    pass

Raycasting in 2D

extends CharacterBody2D

@onready var raycast = $RayCast2D

func _physics_process(delta):
    if raycast.is_colliding():
        var collider = raycast.get_collider()
        var point = raycast.get_collision_point()
        var normal = raycast.get_collision_normal()
        handle_collision(collider, point, normal)

5.5 3D Game Workflows

Basic 3D Scene Setup

Node3D (Root)
├── DirectionalLight3D      ← Sun
├── WorldEnvironment         ← Sky, fog, tonemap
│   └── Environment resource
├── Camera3D                 ← Player camera
├── MeshInstance3D           ← Ground plane
│   └── StaticBody3D
│       └── CollisionShape3D
└── Player (CharacterBody3D)
    ├── MeshInstance3D
    └── CollisionShape3D

First-Person Controller

extends CharacterBody3D

const SPEED = 5.0
const JUMP_VELOCITY = 4.5
const MOUSE_SENSITIVITY = 0.002

@onready var camera = $Camera3D

func _ready():
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _unhandled_input(event):
    if event is InputEventMouseMotion:
        rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
        camera.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
        camera.rotation.x = clamp(camera.rotation.x, -PI/2, PI/2)

    if event.is_action_pressed("ui_cancel"):
        Input.mouse_mode = Input.MOUSE_MODE_VISIBLE

func _physics_process(delta):
    if not is_on_floor():
        velocity += get_gravity() * delta

    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
    var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
    if direction:
        velocity.x = direction.x * SPEED
        velocity.z = direction.z * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)
        velocity.z = move_toward(velocity.z, 0, SPEED)

    move_and_slide()

Third-Person Controller

extends CharacterBody3D

const SPEED = 5.0
const JUMP_VELOCITY = 4.5

@onready var camera_pivot = $CameraPivot
@onready var camera = $CameraPivot/SpringArm3D/Camera3D

func _unhandled_input(event):
    if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
        camera_pivot.rotate_y(-event.relative.x * 0.002)
        camera_pivot.rotate_x(-event.relative.y * 0.002)
        camera_pivot.rotation.x = clamp(camera_pivot.rotation.x, -PI/4, PI/4)

func _physics_process(delta):
    if not is_on_floor():
        velocity += get_gravity() * delta

    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
    var direction = (camera_pivot.global_transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
    direction.y = 0

    if direction:
        velocity.x = direction.x * SPEED
        velocity.z = direction.z * SPEED
        # Rotate model to face movement direction
        var target_rotation = atan2(direction.x, direction.z)
        rotation.y = lerp_angle(rotation.y, target_rotation, 0.15)
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)
        velocity.z = move_toward(velocity.z, 0, SPEED)

    move_and_slide()

3D Lighting and Environment

# Programmatic environment setup
func setup_environment():
    var env = Environment.new()
    env.background_mode = Environment.BG_SKY
    env.sky = Sky.new()
    env.sky.sky_material = ProceduralSkyMaterial.new()
    env.tonemap_mode = Environment.TONE_MAP_ACES
    env.ssao_enabled = true
    env.sdfgi_enabled = true  # Forward+ only
    $WorldEnvironment.environment = env

Importing 3D Models

Godot supports these 3D formats:

Format Support Notes
glTF 2.0 (.gltf/.glb) Full Recommended format
FBX Module Via the FBX module
OBJ Basic Static meshes only, no animation
Blender (.blend) Direct Requires Blender installed; auto-imports

Drop .glb or .gltf files into your project folder. Godot auto-imports them. Double-click to configure import settings (animation, scale, materials).

Raycasting in 3D

# Physics-based raycast
func raycast_from_camera():
    var space_state = get_world_3d().direct_space_state
    var cam = $Camera3D
    var from = cam.global_position
    var to = from + -cam.global_transform.basis.z * 100.0
    var query = PhysicsRayQueryParameters3D.create(from, to)
    var result = space_state.intersect_ray(query)
    if result:
        print("Hit: ", result.collider.name, " at ", result.position)

5.6 UI Development

UI Scene Structure

Control (Root)
├── MarginContainer
│   └── VBoxContainer
│       ├── Label (Title)
│       ├── HBoxContainer
│       │   ├── Button (Play)
│       │   ├── Button (Options)
│       │   └── Button (Quit)
│       └── HSeparator
└── PanelContainer (overlay)
    └── RichTextLabel

Responsive UI with Containers

Use Container nodes for automatic layout instead of manual positioning:

Container Layout
VBoxContainer Vertical stack
HBoxContainer Horizontal row
GridContainer Grid layout
MarginContainer Add margins around children
CenterContainer Center a single child
PanelContainer Add a panel background
ScrollContainer Scrollable area
TabContainer Tabbed interface
SplitContainer Resizable split pane

Theme System

# Apply a theme programmatically
var theme = Theme.new()
theme.set_color("font_color", "Button", Color.WHITE)
theme.set_font_size("font_size", "Button", 24)
$Control.theme = theme
extends Control

func _ready():
    $VBoxContainer/PlayButton.pressed.connect(_on_play)
    $VBoxContainer/OptionsButton.pressed.connect(_on_options)
    $VBoxContainer/QuitButton.pressed.connect(_on_quit)

func _on_play():
    get_tree().change_scene_to_file("res://scenes/game.tscn")

func _on_options():
    $OptionsPanel.visible = true

func _on_quit():
    get_tree().quit()

HUD / Heads-Up Display

extends CanvasLayer

@onready var health_bar = $HealthBar
@onready var score_label = $ScoreLabel

func update_health(value: float, max_value: float):
    health_bar.value = (value / max_value) * 100.0

func update_score(score: int):
    score_label.text = "Score: %d" % score

5.7 Audio

Playing Sounds

# One-shot sound effect
@onready var sfx_player = $AudioStreamPlayer
sfx_player.stream = preload("res://audio/explosion.ogg")
sfx_player.play()

# 2D positional audio (volume decreases with distance)
@onready var footstep = $AudioStreamPlayer2D
footstep.play()

# 3D positional audio
@onready var engine_sound = $AudioStreamPlayer3D
engine_sound.play()

Audio Buses

Configure audio buses in Project → Audio Bus Layout:

Master
├── Music (volume: -6 dB)
├── SFX (volume: 0 dB)
│   └── CompressorEffect
└── Voice (volume: +3 dB)
# Route audio to a specific bus
$AudioStreamPlayer.bus = "SFX"

# Adjust bus volume at runtime
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), -20.0)

# Mute a bus
AudioServer.set_bus_mute(AudioServer.get_bus_index("Music"), true)

Supported audio formats:

Format Type Notes
OGG Vorbis (.ogg) Compressed Recommended for music, loopable
WAV (.wav) Uncompressed Recommended for short sound effects
MP3 (.mp3) Compressed Supported but OGG preferred

Audio drivers by platform:

Platform Available Drivers
Linux PulseAudio, ALSA
Windows WASAPI, XAudio2
macOS CoreAudio

Interactive Music

Godot includes an Interactive Music module for adaptive game audio:

  1. Create an AudioStreamInteractive resource.
  2. Define clips and transitions between them.
  3. Control playback state from code based on game events (exploration → combat → boss fight).

5.8 Networking and Multiplayer

High-Level Multiplayer

extends Node

func _ready():
    multiplayer.peer_connected.connect(_on_peer_connected)
    multiplayer.peer_disconnected.connect(_on_peer_disconnected)

func host_game():
    var peer = ENetMultiplayerPeer.new()
    peer.create_server(7000, 4)  # port, max clients
    multiplayer.multiplayer_peer = peer

func join_game(address: String):
    var peer = ENetMultiplayerPeer.new()
    peer.create_client(address, 7000)
    multiplayer.multiplayer_peer = peer

func _on_peer_connected(id: int):
    print("Player connected: ", id)

func _on_peer_disconnected(id: int):
    print("Player disconnected: ", id)

@rpc("any_peer", "call_local")
func player_action(action: String):
    print("Player ", multiplayer.get_remote_sender_id(), " did: ", action)

MultiplayerSpawner and MultiplayerSynchronizer

Use these nodes for automatic replication:

  • MultiplayerSpawner — automatically spawns scenes on all peers when added on the authority.
  • MultiplayerSynchronizer — automatically syncs designated properties across peers every physics frame.

WebSocket

var socket = WebSocketPeer.new()

func _ready():
    socket.connect_to_url("wss://example.com/socket")

func _process(delta):
    socket.poll()
    var state = socket.get_ready_state()
    if state == WebSocketPeer.STATE_OPEN:
        while socket.get_available_packet_count():
            var data = socket.get_packet().get_string_from_utf8()
            print("Received: ", data)

Dedicated Server Pattern

# server.gd — run with: godot --headless --path . --script res://server.gd
extends SceneTree

func _init():
    var peer = ENetMultiplayerPeer.new()
    var error = peer.create_server(7000, 32)
    if error != OK:
        push_error("Failed to create server: %s" % error)
        quit(1)
        return
    multiplayer.multiplayer_peer = peer
    print("Server listening on port 7000")

5.9 Navigation and Pathfinding

2D Navigation

extends CharacterBody2D

@onready var nav_agent = $NavigationAgent2D

func _physics_process(delta):
    if nav_agent.is_navigation_finished():
        return

    var next_position = nav_agent.get_next_path_position()
    var direction = global_position.direction_to(next_position)
    velocity = direction * 200.0
    move_and_slide()

func set_target(target_pos: Vector2):
    nav_agent.target_position = target_pos

3D Navigation

extends CharacterBody3D

@onready var nav_agent = $NavigationAgent3D

func _physics_process(delta):
    if nav_agent.is_navigation_finished():
        return

    var next_position = nav_agent.get_next_path_position()
    var direction = global_position.direction_to(next_position)
    velocity = direction * 5.0
    velocity.y -= 9.8 * delta  # gravity
    move_and_slide()

Set up navigation:

  1. Add a NavigationRegion2D (or 3D).
  2. Assign a NavigationMesh and bake it.
  3. Add a NavigationAgent2D/3D to your moving entity.

5.10 Resource Management

Custom Resources

# weapon_data.gd
class_name WeaponData
extends Resource

@export var name: String
@export var damage: int
@export var fire_rate: float
@export var icon: Texture2D
@export var projectile_scene: PackedScene

Create instances in the editor: right-click in FileSystem → New Resource → select your resource type. Save as .tres files.

# Using custom resources
@export var weapon: WeaponData

func fire():
    var bullet = weapon.projectile_scene.instantiate()
    bullet.damage = weapon.damage
    add_child(bullet)

Scene Switching

# Simple scene change
func go_to_level(level_path: String):
    get_tree().change_scene_to_file(level_path)

# With loading screen (background loading)
func load_level_async(level_path: String):
    ResourceLoader.load_threaded_request(level_path)

func _process(delta):
    var progress = []
    var status = ResourceLoader.load_threaded_get_status("res://levels/level_2.tscn", progress)
    if status == ResourceLoader.THREAD_LOAD_LOADED:
        var scene = ResourceLoader.load_threaded_get("res://levels/level_2.tscn")
        get_tree().change_scene_to_packed(scene)
    elif status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
        $LoadingBar.value = progress[0] * 100

5.11 Saving and Loading Game Data

# Save game
func save_game():
    var save_data = {
        "player": {
            "position": {"x": player.position.x, "y": player.position.y},
            "health": player.health,
            "inventory": player.inventory
        },
        "level": current_level,
        "timestamp": Time.get_datetime_string_from_system()
    }

    var file = FileAccess.open("user://savegame.json", FileAccess.WRITE)
    file.store_string(JSON.stringify(save_data, "\t"))

# Load game
func load_game() -> bool:
    if not FileAccess.file_exists("user://savegame.json"):
        return false

    var file = FileAccess.open("user://savegame.json", FileAccess.READ)
    var data = JSON.parse_string(file.get_as_text())
    if data == null:
        return false

    player.position = Vector2(data.player.position.x, data.player.position.y)
    player.health = data.player.health
    player.inventory = data.player.inventory
    load_level(data.level)
    return true

Encrypted Save Files

func save_encrypted(data: Dictionary, password: String):
    var file = FileAccess.open_encrypted_with_pass("user://save.dat", FileAccess.WRITE, password)
    file.store_string(JSON.stringify(data))

func load_encrypted(password: String) -> Dictionary:
    var file = FileAccess.open_encrypted_with_pass("user://save.dat", FileAccess.READ, password)
    if file == null:
        return {}
    return JSON.parse_string(file.get_as_text())

5.12 Internationalization (i18n)

# Set the locale
TranslationServer.set_locale("es")

# In the editor, use tr() for translatable strings
$Label.text = tr("MAIN_MENU_TITLE")

Create CSV translation files:

keys,en,es,fr,de
MAIN_MENU_TITLE,My Game,Mi Juego,Mon Jeu,Mein Spiel
PLAY_BUTTON,Play,Jugar,Jouer,Spielen
QUIT_BUTTON,Quit,Salir,Quitter,Beenden

Or use the command-line locale flag:

godot --path /path/to/project --language es

5.13 Movie Recording

Record gameplay as video or image sequences:

# Record to AVI
godot --path /path/to/project --write-movie gameplay.avi

# Record as PNG sequence
godot --path /path/to/project --write-movie frames.png

# Record with fixed FPS for deterministic output
godot --path /path/to/project --write-movie output.avi --fixed-fps 60

Tip

Use --fixed-fps with --write-movie for frame-perfect recordings. This disables real-time synchronization, so every frame is captured regardless of system performance.

5.14 Headless and Server Mode

Run Godot without a display or audio (CI/CD pipelines, dedicated game servers):

# Headless mode (equivalent to --display-driver headless --audio-driver Dummy)
godot --headless --path /path/to/project

# Run a server script headlessly
godot --headless --path /path/to/project --script res://server.gd

5.15 Running Scripts Standalone

Execute GDScript files outside of a project context:

# Run a script directly
godot --headless --path /path/to/project --script res://tools/generate_data.gd

# Validate a script (parse without executing)
godot --headless --path /path/to/project --check-only

# Import resources and quit
godot --headless --path /path/to/project --import

5.16 Converting Godot 3.x Projects to 4.x

# Preview what would change (dry run)
godot --validate-conversion-3to4 --path /path/to/godot3_project

# Perform the conversion
godot --convert-3to4 --path /path/to/godot3_project

Warning

The 3-to-4 converter handles API renames and common patterns, but it cannot convert everything automatically. Manual adjustments will be required, especially for GDScript syntax changes, signal connections, and shader code. Always back up your project before converting.

5.17 Generating API Documentation

# Dump engine API as XML (for documentation tools)
godot --headless --doctool /path/to/output

# Dump GDExtension API as JSON (for binding generators)
godot --headless --dump-extension-api

5.18 XR / VR Development

# Run with XR enabled
godot --path /path/to/project --xr-mode on

# Disable XR
godot --path /path/to/project --xr-mode off

Godot supports OpenXR for VR/AR development. Enable the OpenXR module and configure it in Project → Project Settings → XR.

5.19 Accessibility

# Force accessibility on
godot --path /path/to/project --accessibility always

# Disable accessibility
godot --path /path/to/project --accessibility disabled

# Auto-detect (default)
godot --path /path/to/project --accessibility auto

5.20 Remote Filesystems

Load project data from a remote location:

godot --path /path/to/project --remote-fs 192.168.1.100:6010

5.21 Loading External Packs

Load a pre-exported .pck file instead of reading from the project directory:

godot --main-pack /path/to/game.pck

5.22 Recovery Mode

Start the editor without running tool scripts, editor plugins, or GDExtensions:

godot --editor --path /path/to/project --recovery-mode

This is useful when a broken plugin or tool script prevents the editor from opening.

5.23 Custom Main Loop

Run a custom MainLoop class instead of the default SceneTree:

godot --path /path/to/project --main-loop MyCustomMainLoop

5.24 Autoloads (Singletons)

Register global scripts that persist across scene changes:

  1. Go to Project → Project Settings → Autoload.
  2. Add a script and give it a name (e.g., GameManager).
  3. Access it from any script:
# game_manager.gd (autoloaded as GameManager)
extends Node

var score: int = 0
var current_level: String = ""

func reset():
    score = 0
    current_level = ""

# From any other script:
# GameManager.score += 100
# GameManager.save_game()

5.25 Editor Plugins

Extend the editor with custom tools:

# addons/my_plugin/plugin.gd
@tool
extends EditorPlugin

func _enter_tree():
    add_custom_type("CustomNode", "Node2D", preload("custom_node.gd"), preload("icon.png"))

func _exit_tree():
    remove_custom_type("CustomNode")

Activate plugins in Project → Project Settings → Plugins.

5.26 Version Control Integration

Godot supports Git and other VCS. Recommended .gitignore for Godot projects:

# Godot-generated (fully regenerated from source assets)
.godot/

# Mono/C# generated
.mono/
*.translation

# OS-specific
.DS_Store
Thumbs.db

# Build artifacts
build/
export/

Use text-based scene format (.tscn) and resource format (.tres) for meaningful diffs.

5.27 Performance Optimization Workflow

Key monitors to watch in the debugger (Monitors tab):

Monitor Concern Threshold
FPS Below 60
Process Time Above 16ms
Physics Process Time Above 16ms
Draw Calls Above 1000 (3D)
Object Count Continuously growing (leak)
Video Memory Above GPU capacity

Command-line tools for profiling:

# GPU profiling
godot --path /path/to/project --gpu-profile

# GPU validation layers (catches graphics API misuse)
godot --path /path/to/project --gpu-validation

# Simulate CPU load (stress testing)
godot --path /path/to/project --frame-delay 10

# Print FPS to stdout for benchmarks
godot --path /path/to/project --print-fps --fixed-fps 0

5.28 CI/CD Integration

Run Godot tasks in headless CI environments:

# Example GitHub Actions workflow
name: Build and Export
on: push

jobs:
  export:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Import project
        run: godot --headless --path . --import --quit

      - name: Export for Linux
        run: godot --headless --path . --export-release "Linux" build/game.x86_64

      - name: Export for Windows
        run: godot --headless --path . --export-release "Windows" build/game.exe

      - name: Export for Web
        run: godot --headless --path . --export-release "Web" build/index.html

5.29 Noise Generation

The built-in Noise module provides procedural noise:

var noise = FastNoiseLite.new()
noise.noise_type = FastNoiseLite.TYPE_PERLIN
noise.frequency = 0.05

# Generate terrain heightmap
func generate_terrain(width: int, height: int) -> Image:
    var image = Image.create(width, height, false, Image.FORMAT_RF)
    for x in width:
        for y in height:
            var value = noise.get_noise_2d(x, y)
            image.set_pixel(x, y, Color(value, value, value))
    return image

5.30 CSG (Constructive Solid Geometry)

Rapid 3D prototyping with boolean mesh operations:

CSGCombiner3D
├── CSGBox3D (operation: Union)
├── CSGCylinder3D (operation: Subtraction)  ← cuts a hole
└── CSGSphere3D (operation: Intersection)

CSG is intended for prototyping. Replace with imported meshes for production.

5.31 GridMap (3D Tilemaps)

GridMap is the 3D equivalent of TileMap:

  1. Create mesh items in a MeshLibrary.
  2. Add a GridMap node.
  3. Assign the MeshLibrary and paint cells in the 3D viewport.

5.32 Regex

Godot includes a built-in regular expression module:

var regex = RegEx.new()
regex.compile("\\b\\w+@\\w+\\.\\w+\\b")
var result = regex.search("Contact: [email removed]")
if result:
    print(result.get_string())  # [email removed]

# Find all matches
var results = regex.search_all("a@b.c and d@e.f")
for r in results:
    print(r.get_string())

5.33 SVG and Image Format Support

Godot supports a wide range of image formats through built-in modules:

Format Import Notes
PNG Native Recommended for sprites, lossless
JPEG Native Lossy, no transparency
WebP Module Lossy and lossless, small file size
SVG Module Vector graphics, rasterized on import
HDR Module High dynamic range images
BMP Module Legacy format
TGA Module Legacy format, used in some 3D pipelines
DDS Module DirectDraw Surface (GPU-compressed)
EXR Module OpenEXR for HDR imaging
KTX Module Khronos texture format
Basis Universal Module Supercompressed GPU textures

5.34 Running Unit Tests

If you built Godot with the test suite:

# Run all unit tests
godot --test

# Show test help
godot --test --help

Note

The --test flag is only available in builds compiled with the test suite enabled. Pre-built editor binaries do not include tests.


6. Troubleshooting

6.1 Installation and Startup Issues

Error: Unable to download export templates

Cause: Network issues, firewall blocking HTTPS, or CDN availability problems. This is a frequently reported issue (GitHub #108952) with 63+ community reports.

Solution:

  1. Check your internet connection and firewall settings.
  2. Try downloading templates manually from godotengine.org/download.
  3. Extract the .tpz file (it is a ZIP) into the templates directory:
    • Windows: %APPDATA%\Godot\export_templates\<version>\
    • macOS: ~/Library/Application Support/Godot/export_templates/<version>/
    • Linux: ~/.local/share/godot/export_templates/<version>/
  4. Ensure the version folder name matches exactly (e.g., 4.4.stable).

Prevention: Download templates once and keep a backup copy.

Error: Scene file is corrupt or missing

Cause: A .tscn or .scn file references nodes, scripts, or resources that no longer exist at the expected paths.

Solution:

  1. Open the .tscn file in a text editor and check ext_resource paths.
  2. Fix broken paths or remove stale references.
  3. Reimport the project: delete .godot/imported/ and reopen.

Prevention: Use Godot's built-in rename/move tools (right-click → Rename/Move in FileSystem) to keep references updated automatically.

Error: Failed to load resource

Cause: Resource file is corrupted, moved outside the editor, or uses an unsupported format.

Solution:

  1. Verify the file exists at the referenced path.
  2. If moved manually, update references or move it back.
  3. Try reimporting: right-click the file → Reimport.
  4. Delete .godot/imported/ and reopen the project to force reimport of all assets.

Error: Vulkan initialization failed

Cause: GPU or driver does not support Vulkan, or Vulkan runtime is not installed.

Solution:

  1. Update your GPU drivers to the latest version.
  2. On Linux, install the Vulkan loader: sudo apt install libvulkan1 vulkan-tools.
  3. Verify Vulkan support: vulkaninfo (Linux/macOS).
  4. Fall back to the Compatibility renderer: launch with --rendering-method gl_compatibility.

Prevention: Use the Compatibility renderer for projects targeting older hardware.

Error: OpenGL ES 3.0 not supported

Cause: GPU or driver does not support OpenGL ES 3.0 / OpenGL 3.3 (the minimum for the Compatibility renderer).

Solution:

  1. Update GPU drivers.
  2. Check if your GPU supports OpenGL 3.3 or newer.
  3. On Linux, verify with glxinfo | grep "OpenGL version".
  4. Very old GPUs (pre-2010) may not support the minimum requirements.

Error: INTERNAL ERROR when adding ReflectionProbe

Cause: A known rendering bug (GitHub #118619) where adding a ReflectionProbe node triggers an internal engine error.

Solution:

  1. Save your work before adding the node.
  2. If the error occurs, try switching to a different rendering method temporarily.
  3. Check the GitHub issue for the latest fix status and workarounds.

Error: Unrecognized UID on editor start

Cause: UID cache mismatch after moving, renaming, or externally modifying project files (GitHub #117362).

Solution:

  1. Close the editor.
  2. Delete .godot/uid_cache.bin.
  3. Reopen the project — Godot regenerates the UID cache.

Error: Editor freezes or system locks up after extended use

Cause: Known issue on Linux Mint with Godot 4.6+ (GitHub #117714). The editor can lock up the entire desktop after 2+ hours of use.

Solution:

  1. Save frequently (Ctrl+S).
  2. Restart the editor periodically for long sessions.
  3. Try using a different window compositor (X11 vs Wayland).
  4. Check system logs (journalctl) for GPU-related errors.
  5. Update GPU drivers and kernel.

Error: Shader compilation failed (Web export)

Cause: GLES3 shaders may fail on WebGL 2.0 with ANGLE backend (GitHub #118684).

Solution:

  1. Simplify shaders that use advanced features.
  2. Test in multiple browsers (Chrome, Firefox, Safari).
  3. Use the Compatibility renderer for web exports.
  4. Avoid shader features not supported by WebGL 2.0 (compute shaders, SSAO, etc.).

Error: C# Color.FromOkHsl returns wrong values on Linux

Cause: Platform-specific floating-point behavior (GitHub #118685).

Solution:

  1. Use Color.FromHsv() as an alternative.
  2. Check the issue tracker for the fix in newer versions.
  3. Manually compute OkHSL values if precision is critical.

Error: macOS Gatekeeper blocks Godot

Cause: The downloaded binary is not code-signed by Apple.

Solution:

  1. Right-click the app → Open (bypasses Gatekeeper on first launch).
  2. Or from Terminal: xattr -dr com.apple.quarantine /path/to/Godot.app.

Error: Editor is tiny / UI too small on HiDPI display

Cause: Display scale not detected correctly.

Solution:

  1. Go to Editor → Editor Settings → Interface → Editor → Display Scale.
  2. Set a custom scale (e.g., 150% or 200%).
  3. Restart the editor.

6.2 Build Errors

Error: scons: *** No SConstruct file found

Cause: Running SCons from the wrong directory.

Solution: Ensure you are in the root of the Godot source tree (where SConstruct exists).

cd /path/to/godot
scons platform=linuxbsd target=editor

Error: No suitable compiler found

Cause: The C++ compiler is not installed or not in PATH.

Solution:

  • Windows: Install Visual Studio with the "Desktop development with C++" workload.
  • Linux: sudo apt install build-essential (or gcc + g++).
  • macOS: xcode-select --install.

Error: ModuleNotFoundError: No module named 'SCons'

Cause: SCons is not installed in the active Python environment.

Solution:

pip install scons
# Or
pip3 install scons

Verify: scons --version.

Error: scons: *** [some_target] Error 1 with compiler errors

Cause: Incorrect compiler version, missing dependencies, or out-of-date source.

Solution:

  1. Ensure your compiler meets minimum requirements (GCC 9+, Clang 6+, MSVC 2019+).
  2. Install all platform dependencies (X11/Wayland dev packages on Linux).
  3. Pull the latest source: git pull && git submodule update --init.
  4. Clean the build: scons --clean then rebuild.

Error: Android build fails — ANDROID_HOME not set

Cause: The Android SDK path is not configured.

Solution:

export ANDROID_HOME="$HOME/Android/Sdk"
# or
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
scons platform=android target=template_release

Cause: Module dependencies are missing or incompatible.

Solution:

  1. Clean the build completely: scons --clean.
  2. Rebuild from scratch: scons -j$(nproc) platform=linuxbsd target=editor.
  3. If disabling a module, ensure no other enabled module depends on it.

6.3 Runtime Errors

Error: Condition "!is_inside_tree()" is true

Cause: Accessing a node that has been removed from the scene tree or calling a scene-tree method too early.

Solution:

  1. Check that the node is still in the tree: if is_inside_tree():.
  2. Use await ready or call_deferred() for initialization that depends on the tree.
  3. Avoid using queue_free() on a node and then accessing it in the same frame.

Error: Invalid operands for operator

Cause: Type mismatch in GDScript operations (e.g., multiplying a String by an int).

Solution:

  1. Use typed GDScript to catch these at parse time.
  2. Cast explicitly: float(my_int), str(my_value).

Error: Null instance or Invalid get index on base Nil

Cause: Accessing a property or method on a null reference, often from $NodeName where the node does not exist.

Solution:

  1. Verify the node path: has_node("NodeName").
  2. Use @onready for references that must wait for tree entry.
  3. Use null checks: if node != null: node.do_thing().
  4. Double-check node names for typos (case-sensitive).

Error: Area3D does not detect body_entered on StaticBody3D

Cause: A known collision detection issue (GitHub #74300, 32+ comments) where Area3D nodes fail to detect entered/exited signals for certain body types.

Solution:

  1. Ensure collision layers and masks are correctly configured.
  2. Set monitoring = true and monitorable = true on the Area3D.
  3. On the StaticBody3D, enable input_ray_pickable if applicable.
  4. Try adding a small impulse to "wake" static bodies.
  5. Check that collision shapes are not zero-sized.

Error: Voxel GI darkens when 32+ lights in area

Cause: Voxel GI light count limit (GitHub #117297). When more than approximately 32 lights overlap, the GI darkens instead of brightening.

Solution:

  1. Reduce overlapping light count to under 32 per area.
  2. Use baked lightmaps instead of Voxel GI for scenes with many lights.
  3. Merge small lights into fewer, larger-area lights.

Error: Push error: body_entered signal unexpected re-entry (Jolt Physics)

Cause: Jolt physics module can emit duplicate enter/exit events in specific collision configurations (GitHub #118714).

Solution:

  1. Add deduplication logic in your signal handler:
var tracked_bodies: Dictionary = {}

func _on_area_body_entered(body):
    if body in tracked_bodies:
        return  # Duplicate — ignore
    tracked_bodies[body] = true
    # Handle actual enter

func _on_area_body_exited(body):
    if body not in tracked_bodies:
        return
    tracked_bodies.erase(body)
    # Handle actual exit
  1. Switch to Godot Physics if Jolt duplicates are problematic for your use case.

Error: Reloading scene with separate game window doesn't reopen the window

Cause: Known issue (GitHub #111175, 25+ comments) where using "Play Edited Scene" with separate game window enabled, then reloading the scene in code, causes the game window to not reappear.

Solution:

  1. Use the main window instead of a separate game window during development.
  2. Avoid get_tree().reload_current_scene() with separate game windows.
  3. Manually close and reopen the game window via OS window management calls.

Error: Find/Replace in Files cannot search built-in scripts

Cause: The editor's Find in Files feature does not search scripts embedded in .tscn files (GitHub #74145).

Solution:

  1. Extract built-in scripts to external .gd files (right-click script in Inspector → Save As).
  2. Use external text search tools (grep, VS Code search) to find text in .tscn files.

Prevention: Always save scripts as external .gd files instead of embedding them in scenes.

Error: Script inherits from native type, but native type is not Node

Cause: Trying to attach a script that extends Resource (or another non-Node type) to a node in the scene tree.

Solution: Ensure your script's extends clause matches the node type: extends Node2D for a Node2D, extends Control for a Control, etc.

Error: Cyclic dependency detected

Cause: Two or more scripts reference each other at load time (via preload() or class_name).

Solution:

  1. Replace preload() with load() in one of the scripts (deferred loading breaks the cycle).
  2. Refactor to remove the circular dependency (extract a shared base or interface).

6.4 Export Errors

Error: Export template not found

Cause: No export template installed for the selected platform/version.

Solution:

  1. Go to Editor → Manage Export Templates.
  2. Download and install templates for your exact engine version.
  3. Verify the template directory contains files for your target platform.

Error: No export preset configured

Cause: No export preset exists for the target platform.

Solution:

  1. Go to Project → Export.
  2. Click Add and select your target platform.
  3. Configure the preset before running command-line exports.

Error: PCK file version mismatch

Cause: The .pck file was exported with a different engine version than the one running it.

Solution: Re-export the .pck with the same engine version you intend to run it with.

Error: Android export fails — keystore not found

Cause: The debug or release keystore path is incorrect.

Solution:

# Generate a debug keystore
keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android \
  -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" \
  -validity 9999

# Set environment variables
export GODOT_ANDROID_SIGN_KEYSTORE="/path/to/debug.keystore"
export GODOT_ANDROID_KEYSTORE_ALIAS="androiddebugkey"
export GODOT_ANDROID_SIGN_PASSWORD="android"

Error: iOS export requires macOS

Cause: iOS exports can only be performed on macOS with Xcode installed.

Solution: Use a Mac (physical or CI with macOS runners) for iOS export. Cross-compiling iOS from Linux/Windows is not supported.

Error: Web export shows blank page or shader errors

Cause: Using Forward+ or Mobile renderer for web export, or browser lacks WebGL 2.0 support.

Solution:

  1. Switch the project to the Compatibility rendering method.
  2. Test in a browser with WebGL 2.0 support.
  3. Serve the exported files from an HTTPS server (required by some browsers for SharedArrayBuffer).
  4. Ensure Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers are set on the server.

Error: Web export has no audio on first interaction

Cause: Browsers require user interaction (click/tap) before allowing audio playback (autoplay policy).

Solution: Design your game so the first action is a user click (e.g., a "Play" button on a title screen). Audio will work after the first interaction.

6.5 Performance Issues

Issue: Low FPS in 3D scenes

Cause: Too many draw calls, unoptimized meshes, excessive lighting, or insufficient GPU.

Solution:

  1. Check draw calls in the debugger (Monitors tab).
  2. Enable occlusion culling and LOD.
  3. Reduce shadow-casting lights.
  4. Use mesh LOD (Level of Detail) for distant objects.
  5. Profile with --gpu-profile to identify GPU bottlenecks.

Issue: High memory usage

Cause: Uncompressed textures, large scenes kept in memory, resource leaks.

Solution:

  1. Use compressed textures (VRAM compression in import settings).
  2. Unload unused scenes: get_tree().change_scene_to_file() frees the old scene.
  3. Watch the Object Count monitor for leaks.
  4. Use queue_free() on nodes you no longer need.

Issue: Stuttering during gameplay

Cause: Shader compilation (first use), resource loading on the main thread, or GC pauses (C#).

Solution:

  1. Use shader precompilation or a loading screen that renders all materials.
  2. Use ResourceLoader.load_threaded_request() for background loading.
  3. For C#, minimize allocations in hot paths.

Issue: Audio crackling or latency

Cause: Audio buffer too small for the system, or driver issues.

Solution:

# Increase audio latency (reduces crackling, adds slight delay)
godot --path /path/to/project --audio-output-latency 30

# Try a different audio driver (Linux)
godot --path /path/to/project --audio-driver ALSA
# or
godot --path /path/to/project --audio-driver PulseAudio

Issue: Physics jitter

Cause: Physics running at a different rate than rendering, or variable frame rate causing instability.

Solution:

  1. Use _physics_process() for all physics-related code (runs at fixed 60 Hz by default).
  2. Enable physics interpolation in Project Settings → Physics → Common → Physics Interpolation.
  3. Avoid setting position directly on physics bodies — use velocity or forces.

Issue: Long import times on project open

Cause: Many large assets being reimported (textures, models, audio).

Solution:

  1. Use .import files to pre-configure import settings.
  2. Avoid storing the .godot/ folder in version control — but do not delete it unnecessarily.
  3. Use compressed formats (WebP instead of PNG for large textures).

7. FAQ

Q: Is Godot really free? What's the catch? Godot is released under the MIT license. There are no royalties, no per-seat licensing fees, no revenue share, and no restrictions on commercial use. You own everything you create with it.

Q: Can I use Godot for commercial games? Yes. The MIT license permits unrestricted commercial use. You are not required to credit Godot (though it is appreciated). You do not need to open-source your game.

Q: Should I use GDScript or C#? GDScript is recommended for most users. It is tightly integrated with the editor, has better auto-completion, and most community resources use it. Use C# if your team already has .NET experience or you need access to .NET libraries. Both languages have equivalent capabilities for game logic.

Q: Can I mix GDScript and C# in the same project? Yes. You can have GDScript nodes and C# nodes in the same scene tree. They can call each other's methods and connect to each other's signals, though the interop requires using Godot's type system (Variant) at the boundary.

Q: How do I install Godot? Is there an installer? There is no installer. Godot is a single executable file. Download, extract, and run. On macOS, move the .app to Applications. On Linux, chmod +x the binary.

Q: What is the difference between Forward+, Mobile, and Compatibility renderers? Forward+ (Vulkan) is the most feature-rich — it supports SDFGI, volumetric fog, and advanced effects. Mobile (Vulkan) is a subset optimized for mobile GPUs. Compatibility (OpenGL ES 3.0) runs on the widest range of hardware and is required for web exports.

Q: Can I switch renderers mid-project? Yes, via Project Settings → Rendering → Renderer. However, some features (SDFGI, volumetric fog) only exist in Forward+. Switching to Compatibility may disable those features.

Q: What are the system requirements for Godot? The editor runs on Windows 7+, macOS 10.13+, and Linux with X11 or Wayland. GPU requirements depend on the renderer: Vulkan requires a Vulkan 1.0-capable GPU; Compatibility requires OpenGL ES 3.0 / OpenGL 3.3.

Q: How do I export for the web? Use the Compatibility renderer, set up a Web export preset, install web export templates, and export. Serve the output from a web server with proper CORS headers.

Q: Why does my web export show a blank page? The web export requires: (1) Compatibility renderer, (2) an HTTPS server (for SharedArrayBuffer), (3) proper Cross-Origin headers, and (4) a browser supporting WebGL 2.0.

Q: How do I target mobile (Android/iOS)? For Android: install the Android SDK, set ANDROID_HOME, create a debug keystore, and add an Android export preset. For iOS: you must use a Mac with Xcode. Create an iOS export preset and configure your provisioning profile.

Q: What 3D model formats does Godot support? glTF 2.0 (.gltf/.glb) is the recommended and best-supported format. FBX is supported via a built-in module. OBJ works for static meshes. Blender .blend files can be imported directly if Blender is installed on your system.

Q: How do I handle screen resolution and aspect ratios? Configure stretch mode and aspect in Project Settings → Display → Window → Stretch. Common setups: viewport stretch mode with expand aspect for pixel-art games; canvas_items stretch mode with keep aspect for UI-heavy games.

Q: What is the user:// path? user:// maps to a platform-specific user data directory: %APPDATA%\Godot\app_userdata\<project> (Windows), ~/Library/Application Support/Godot/app_userdata/<project> (macOS), ~/.local/share/godot/app_userdata/<project> (Linux). Use it for save files and settings.

Q: What is the res:// path? res:// is the project root directory (where project.godot lives). All project resources are referenced relative to res://.

Q: How do I make a dedicated server build? Use --headless to run without rendering. Build a template with scons platform=linuxbsd target=template_release. Script your server logic and run with godot --headless --path /project --script server.gd.

Q: How do I use version control with Godot? Use Git. Add .godot/ to .gitignore. Use text-based scene format (.tscn) for meaningful diffs. Avoid binary .scn format for files that change frequently.

Q: Why is the .godot/ folder so large? The .godot/ folder contains imported/cached resources. It is fully regenerated from source assets and should not be committed to version control. Delete it to force a clean reimport.

Q: Can I run Godot from the command line without a GUI? Yes. Use --headless for fully headless operation. This is useful for CI/CD, dedicated servers, and batch processing.

Q: How do I pass arguments to my game? Use -- or ++ as a separator. Everything after the separator is available via OS.get_cmdline_user_args(). Example: godot --path . -- --level=5 --debug.

Q: What is recovery mode? Launch with --recovery-mode to start the editor without loading tool scripts, editor plugins, or GDExtensions. Use this when a broken addon prevents the editor from starting.

Q: How do I build Godot from source? Install Python 3.6+, SCons, and a C++ compiler. Clone the repo. Run scons platform=<your_platform> target=editor. Do NOT use CMake — the CMakeLists.txt is not for building the engine.

Q: Can I reduce the Godot binary size? Yes. Disable unused modules during compilation: scons module_<name>_enabled=no. For example, scons module_webrtc_enabled=no module_websocket_enabled=no module_mono_enabled=no.

Q: How do I update from Godot 3.x to 4.x? Use the built-in converter: godot --convert-3to4 --path /project. Preview changes first with --validate-conversion-3to4. The converter handles API renames but manual work is still required.

Q: What physics engine should I use? Godot Physics (built-in) is the default and works well for most cases. Jolt Physics (module) offers higher accuracy for complex 3D simulations. Both work with the same node types (RigidBody3D, CharacterBody3D, etc.).

Q: How do I profile my game's performance? Use the built-in Profiler in the Debugger tab while the game runs. For GPU profiling, launch with --gpu-profile. For validation, use --gpu-validation. Monitor draw calls, frame time, and memory in the Monitors tab.

Q: How do I use multiple monitors? Use the --screen <N> flag to select a display. In the editor, configure run settings in Editor → Editor Settings → Run → Window Placement.

Q: What audio formats should I use? OGG Vorbis (.ogg) for music and longer sounds (compressed, loopable). WAV (.wav) for short sound effects (uncompressed, low latency). MP3 is supported but OGG is preferred.

Q: How do I create a splash screen? Configure in Project Settings → Application → Boot Splash. Set a custom image and background color. The splash screen appears while the engine initializes.

Q: Can I use Godot for non-game applications? Yes. Godot's UI system (Control nodes), theming, and scripting make it capable of building tools, visualizations, simulations, and other interactive applications.

Q: How do I handle localization/internationalization? Use the TranslationServer with CSV or PO translation files. Wrap user-facing strings with tr(). Set locale with TranslationServer.set_locale("es") or the --language CLI flag.

Q: What is GDExtension? GDExtension is the system for writing native C/C++ plugins that integrate with Godot at runtime. It replaces the older GDNative system. Extensions are compiled as shared libraries and loaded via .gdextension configuration files.

Q: How do I record gameplay video? Use --write-movie <file> to record to AVI or PNG sequence. Combine with --fixed-fps 60 for deterministic frame capture.

Q: Where are Godot's configuration files stored? Editor settings: %APPDATA%\Godot\ (Windows), ~/Library/Application Support/Godot/ (macOS), ~/.config/godot/ (Linux). Project settings: project.godot in the project root.

Q: What is the default window size? 1152x648 pixels. Override in Project Settings or with the --resolution CLI flag.

Q: How do I enable VR/AR support? Godot supports OpenXR. Enable it in Project Settings → XR. Run with --xr-mode on from the command line.

Q: Can I use Godot on visionOS (Apple Vision Pro)? Yes. Godot supports visionOS as an export target. You need Xcode with the visionOS SDK to build and deploy.