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
- 2. Installation
- 3. Configuration
- 4. Core Usage
- 5. Common Tasks
- 6. Troubleshooting
- 7. FAQ
1. Quick Start
1.1 Your First Project in 5 Minutes
- Download the Godot editor from godotengine.org for your platform (Windows, macOS, or Linux).
- Run the executable — no installer required. Godot is a single self-contained binary.
- The Project Manager opens. Click New Project, choose a folder, name your project, and select a rendering method.
- Click Create & Edit to enter the editor.
- 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
- 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
- Download the Windows ZIP from godotengine.org/download.
- Extract to any folder (e.g.,
C:\Godot\). - Run
Godot_v4.x-stable_win64.exe.
For C# support, download the .NET build instead of the standard build.
macOS
- Download the macOS ZIP.
- Extract and move
Godot.appto/Applications/. - On first launch, right-click → Open to bypass Gatekeeper.
Linux
- Download the Linux x86_64 binary.
- 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
cmakeon the Godot source tree will not build the engine. Always usescons.
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:
- Open the editor.
- Go to Editor → Manage Export Templates.
- Click Download and Install for the matching engine version.
Installing manually:
- Download from godotengine.org/download.
- 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>/
- Windows:
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.godotby 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:
- Write your extension using the godot-cpp bindings.
- Compile to a shared library (
.dll,.so,.dylib). - Register via a
.gdextensionfile 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:
- Add an AnimationPlayer node to your scene.
- Create a new animation in the Animation panel.
- Add tracks for any property (position, scale, color, custom variables).
- 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:
- Open the Script editor.
- Click in the gutter (left of line numbers) to set a breakpoint.
- Run the project with F5 — it pauses at breakpoints.
- 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
- Go to Project → Export.
- Click Add and choose a platform.
- Configure settings (icon, permissions, signing, etc.).
- 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
- Create a TileMap node.
- In the Inspector, create a new TileSet.
- Add a tile atlas from a spritesheet.
- 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
Main Menu Example
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:
- Create an AudioStreamInteractive resource.
- Define clips and transitions between them.
- 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:
- Add a NavigationRegion2D (or 3D).
- Assign a NavigationMesh and bake it.
- 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-fpswith--write-moviefor 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:
- Go to Project → Project Settings → Autoload.
- Add a script and give it a name (e.g.,
GameManager). - 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:
- Create mesh items in a MeshLibrary.
- Add a GridMap node.
- 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
--testflag 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:
- Check your internet connection and firewall settings.
- Try downloading templates manually from godotengine.org/download.
- Extract the
.tpzfile (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>/
- Windows:
- 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:
- Open the
.tscnfile in a text editor and checkext_resourcepaths. - Fix broken paths or remove stale references.
- 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:
- Verify the file exists at the referenced path.
- If moved manually, update references or move it back.
- Try reimporting: right-click the file → Reimport.
- 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:
- Update your GPU drivers to the latest version.
- On Linux, install the Vulkan loader:
sudo apt install libvulkan1 vulkan-tools. - Verify Vulkan support:
vulkaninfo(Linux/macOS). - 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:
- Update GPU drivers.
- Check if your GPU supports OpenGL 3.3 or newer.
- On Linux, verify with
glxinfo | grep "OpenGL version". - 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:
- Save your work before adding the node.
- If the error occurs, try switching to a different rendering method temporarily.
- 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:
- Close the editor.
- Delete
.godot/uid_cache.bin. - 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:
- Save frequently (Ctrl+S).
- Restart the editor periodically for long sessions.
- Try using a different window compositor (X11 vs Wayland).
- Check system logs (
journalctl) for GPU-related errors. - 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:
- Simplify shaders that use advanced features.
- Test in multiple browsers (Chrome, Firefox, Safari).
- Use the Compatibility renderer for web exports.
- 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:
- Use
Color.FromHsv()as an alternative. - Check the issue tracker for the fix in newer versions.
- Manually compute OkHSL values if precision is critical.
Error: macOS Gatekeeper blocks Godot
Cause: The downloaded binary is not code-signed by Apple.
Solution:
- Right-click the app → Open (bypasses Gatekeeper on first launch).
- 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:
- Go to Editor → Editor Settings → Interface → Editor → Display Scale.
- Set a custom scale (e.g., 150% or 200%).
- 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(orgcc+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:
- Ensure your compiler meets minimum requirements (GCC 9+, Clang 6+, MSVC 2019+).
- Install all platform dependencies (X11/Wayland dev packages on Linux).
- Pull the latest source:
git pull && git submodule update --init. - Clean the build:
scons --cleanthen 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
Error: Link error: undefined reference when building with modules
Cause: Module dependencies are missing or incompatible.
Solution:
- Clean the build completely:
scons --clean. - Rebuild from scratch:
scons -j$(nproc) platform=linuxbsd target=editor. - 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:
- Check that the node is still in the tree:
if is_inside_tree():. - Use
await readyorcall_deferred()for initialization that depends on the tree. - 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:
- Use typed GDScript to catch these at parse time.
- 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:
- Verify the node path:
has_node("NodeName"). - Use
@onreadyfor references that must wait for tree entry. - Use null checks:
if node != null: node.do_thing(). - 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:
- Ensure collision layers and masks are correctly configured.
- Set
monitoring = trueandmonitorable = trueon the Area3D. - On the StaticBody3D, enable
input_ray_pickableif applicable. - Try adding a small impulse to "wake" static bodies.
- 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:
- Reduce overlapping light count to under 32 per area.
- Use baked lightmaps instead of Voxel GI for scenes with many lights.
- 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:
- 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
- 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:
- Use the main window instead of a separate game window during development.
- Avoid
get_tree().reload_current_scene()with separate game windows. - 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:
- Extract built-in scripts to external
.gdfiles (right-click script in Inspector → Save As). - Use external text search tools (
grep, VS Code search) to find text in.tscnfiles.
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:
- Replace
preload()withload()in one of the scripts (deferred loading breaks the cycle). - 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:
- Go to Editor → Manage Export Templates.
- Download and install templates for your exact engine version.
- 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:
- Go to Project → Export.
- Click Add and select your target platform.
- 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:
- Switch the project to the Compatibility rendering method.
- Test in a browser with WebGL 2.0 support.
- Serve the exported files from an HTTPS server (required by some browsers for SharedArrayBuffer).
- Ensure
Cross-Origin-Opener-PolicyandCross-Origin-Embedder-Policyheaders 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:
- Check draw calls in the debugger (Monitors tab).
- Enable occlusion culling and LOD.
- Reduce shadow-casting lights.
- Use mesh LOD (Level of Detail) for distant objects.
- Profile with
--gpu-profileto identify GPU bottlenecks.
Issue: High memory usage
Cause: Uncompressed textures, large scenes kept in memory, resource leaks.
Solution:
- Use compressed textures (VRAM compression in import settings).
- Unload unused scenes:
get_tree().change_scene_to_file()frees the old scene. - Watch the Object Count monitor for leaks.
- 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:
- Use shader precompilation or a loading screen that renders all materials.
- Use
ResourceLoader.load_threaded_request()for background loading. - 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:
- Use
_physics_process()for all physics-related code (runs at fixed 60 Hz by default). - Enable physics interpolation in Project Settings → Physics → Common → Physics Interpolation.
- Avoid setting
positiondirectly on physics bodies — usevelocityor forces.
Issue: Long import times on project open
Cause: Many large assets being reimported (textures, models, audio).
Solution:
- Use
.importfiles to pre-configure import settings. - Avoid storing the
.godot/folder in version control — but do not delete it unnecessarily. - 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.