Zum Inhalt springen

Godot Cheat Sheet

Overview

Godot is a free, open-source game engine that provides a comprehensive set of tools for 2D and 3D game development. It features its own scripting language (GDScript) designed specifically for game development, along with support for C#, C++, and community-maintained language bindings. Godot’s unique scene system treats every game element as a composable scene made of nodes, enabling a modular and reusable design approach that scales from simple prototypes to complex productions.

The engine includes a full-featured editor with visual scripting, animation tools, physics engines for both 2D and 3D, a particle system, shader editor, and tilemap tools. Godot 4.x introduced a Vulkan-based renderer with global illumination, signed distance field effects, and volumetric fog. The engine exports to Windows, macOS, Linux, Android, iOS, and HTML5, with console exports available through third-party providers. Its permissive MIT license means no royalties or subscription fees.

Installation

# Download from official site
# https://godotengine.org/download

# Linux (Flatpak)
flatpak install flathub org.godotengine.Godot

# Linux (Snap)
sudo snap install godot-4

# macOS (Homebrew)
brew install --cask godot

# Steam
# Available free on Steam store

# .NET version (for C# support)
# Download "Godot Engine - .NET" variant

# Command-line export (headless)
# Download Godot Server/Headless for CI/CD
./Godot_v4.3-stable_linux.x86_64 --headless --export-release "Linux" build/game.x86_64

# Verify
godot --version

GDScript Basics

# Variables and types
var health: int = 100
var speed: float = 5.0
var player_name: String = "Hero"
var position: Vector2 = Vector2(0, 0)
var is_alive: bool = true
var items: Array = ["sword", "shield"]
var stats: Dictionary = {"str": 10, "dex": 8}

# Constants
const MAX_SPEED: float = 10.0
const GRAVITY: float = 980.0

# Enums
enum State { IDLE, RUNNING, JUMPING, FALLING }
var current_state: State = State.IDLE

# Functions
func take_damage(amount: int) -> void:
    health -= amount
    if health <= 0:
        die()

func get_damage_multiplier() -> float:
    return 1.0 + (stats["str"] * 0.1)

# Signals (event system)
signal health_changed(new_health: int)
signal player_died

func _ready() -> void:
    health_changed.connect(_on_health_changed)

func _on_health_changed(new_health: int) -> void:
    print("Health: ", new_health)

Node Lifecycle

extends Node2D

# Called when node enters the scene tree
func _ready() -> void:
    print("Node is ready!")

# Called every frame
func _process(delta: float) -> void:
    # Game logic, UI updates
    position.x += speed * delta

# Called at fixed intervals (physics)
func _physics_process(delta: float) -> void:
    # Physics calculations
    velocity += gravity * delta

# Called for input events
func _input(event: InputEvent) -> void:
    if event.is_action_pressed("jump"):
        jump()

# Called for unhandled input
func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventKey and event.pressed:
        if event.keycode == KEY_ESCAPE:
            get_tree().quit()

# Called when node exits scene tree
func _exit_tree() -> void:
    print("Node removed")

Common Node Types

NodePurpose
Node2DBase for 2D game objects
Node3DBase for 3D game objects
CharacterBody2D2D physics character
CharacterBody3D3D physics character
RigidBody2D/3DPhysics-driven body
StaticBody2D/3DNon-moving collision body
Area2D/3DDetection zone (triggers)
Sprite2D2D image display
AnimatedSprite2DSprite with animations
Camera2D/3DViewport camera
TileMapLayerTile-based level
CanvasLayerUI layer
AudioStreamPlayerSound playback
TimerCountdown timer
RayCast2D/3DLine-of-sight detection
NavigationAgent2D/3DPathfinding agent

2D Character Controller

extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0
const GRAVITY = 980.0

@onready var animated_sprite = $AnimatedSprite2D

func _physics_process(delta: float) -> void:
    # Gravity
    if not is_on_floor():
        velocity.y += GRAVITY * delta
    
    # Jump
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY
    
    # Horizontal movement
    var direction = Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
        animated_sprite.flip_h = direction < 0
        animated_sprite.play("run")
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)
        animated_sprite.play("idle")
    
    move_and_slide()

3D Character Controller

extends CharacterBody3D

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

var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")

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

func _ready() -> void:
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventMouseMotion:
        rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
        camera_pivot.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
        camera_pivot.rotation.x = clamp(camera_pivot.rotation.x, -PI/3, PI/3)

func _physics_process(delta: float) -> void:
    if not is_on_floor():
        velocity.y -= 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()

Scene Management

# Change scene
get_tree().change_scene_to_file("res://scenes/level2.tscn")

# Preload scene
var enemy_scene = preload("res://scenes/enemy.tscn")

# Instance scene
var enemy = enemy_scene.instantiate()
enemy.position = Vector2(400, 300)
add_child(enemy)

# Remove node
enemy.queue_free()

# Pause/unpause
get_tree().paused = true
# Nodes with process_mode = PROCESS_MODE_ALWAYS still run when paused

# Groups
add_to_group("enemies")
get_tree().get_nodes_in_group("enemies")
get_tree().call_group("enemies", "take_damage", 10)

Signals and Communication

# Define custom signal
signal coin_collected(value: int)
signal game_over

# Emit signal
coin_collected.emit(10)

# Connect in code
func _ready():
    var player = get_node("Player")
    player.health_changed.connect(_on_player_health_changed)
    
    # Lambda connection
    player.coin_collected.connect(func(value):
        score += value
        update_score_display()
    )

# Disconnect
player.health_changed.disconnect(_on_player_health_changed)

# Autoload (global) signals
# In an autoload script "Events.gd":
signal score_updated(new_score: int)

# Any script can emit/connect:
Events.score_updated.emit(100)
Events.score_updated.connect(_on_score_updated)

Animation

# AnimationPlayer
@onready var anim_player = $AnimationPlayer
anim_player.play("walk")
anim_player.play_backwards("walk")
anim_player.stop()
anim_player.queue("idle")

# Tweens (programmatic animation)
var tween = create_tween()
tween.tween_property(self, "position", Vector2(500, 300), 1.0)
tween.tween_property(self, "modulate:a", 0.0, 0.5)
tween.tween_callback(queue_free)

# Chained tweens
var tween = create_tween().set_trans(Tween.TRANS_BOUNCE)
tween.tween_property($Sprite, "position:y", 0.0, 0.5)
tween.tween_interval(0.2)  # Wait
tween.tween_property($Sprite, "scale", Vector2(1.2, 1.2), 0.1)
tween.tween_property($Sprite, "scale", Vector2(1.0, 1.0), 0.1)

# Parallel tweens
tween.set_parallel(true)
tween.tween_property(self, "position:x", 100, 1.0)
tween.tween_property(self, "rotation", TAU, 1.0)

Configuration

; project.godot (key settings)
[application]
config/name="My Game"
run/main_scene="res://scenes/main.tscn"

[display]
window/size/viewport_width=1920
window/size/viewport_height=1080
window/stretch/mode="viewport"
window/stretch/aspect="keep"

[input]
move_left={ "deadzone": 0.5, "events": [InputEventKey(keycode=KEY_A)] }
move_right={ "deadzone": 0.5, "events": [InputEventKey(keycode=KEY_D)] }

[physics]
2d/default_gravity=980.0
3d/default_gravity=9.8

[rendering]
renderer/rendering_method="forward_plus"

Advanced Usage

# Shaders (visual shader or code)
# Save as .gdshader
shader_type canvas_item;
uniform vec4 flash_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform float flash_amount : hint_range(0.0, 1.0) = 0.0;

void fragment() {
    vec4 tex = texture(TEXTURE, UV);
    COLOR = mix(tex, flash_color, flash_amount);
    COLOR.a = tex.a;
}

# Resources and save/load
var save_data = {
    "health": health,
    "position": {"x": position.x, "y": position.y},
    "inventory": inventory
}
var json = JSON.stringify(save_data)
var file = FileAccess.open("user://save.json", FileAccess.WRITE)
file.store_string(json)
file.close()

# State machine pattern
class_name StateMachine extends Node

var current_state: State
var states: Dictionary = {}

func _ready():
    for child in get_children():
        if child is State:
            states[child.name.to_lower()] = child
            child.transitioned.connect(_on_child_transition)

func _on_child_transition(new_state_name: StringName):
    var new_state = states.get(new_state_name.to_lower())
    if new_state and new_state != current_state:
        current_state.exit()
        current_state = new_state
        current_state.enter()

Export and Build

# Export presets must be configured in Editor > Export
# Then use CLI:
godot --headless --export-release "Windows Desktop" builds/game.exe
godot --headless --export-release "Linux" builds/game.x86_64
godot --headless --export-release "macOS" builds/game.dmg
godot --headless --export-release "Android" builds/game.apk
godot --headless --export-release "Web" builds/index.html

Troubleshooting

IssueSolution
Node not found (null)Use @onready or access in _ready(); check node path
Physics not workingEnsure correct body type; check collision layers/masks
Exported game crashesCheck debug export first; verify export templates installed
Import errors with assetsReimport in editor; check .import folder
GDScript errors on loadCheck autoload order; avoid circular dependencies
Performance issuesUse _physics_process for physics only; profile with built-in profiler
Signals not connectingVerify signal name spelling; check node is in scene tree
Animation not playingCheck AnimationPlayer has the animation; verify autoplay settings
Tilemap collision wrongRe-setup collision polygons on tile set
3D lighting looks flatAdd environment/sky; configure DirectionalLight3D shadows