Godot is free, open-source, and genuinely fun to learn. This guide walks you through every essential concept — nodes, scenes, GDScript, physics, and exporting your first real game.
In This Guide
- What is Godot?
- The Editor Interface
- Nodes & Scenes
- GDScript Basics
- Physics System
- Input Handling
- Animation
- User Interface
- Signals
- Exporting Your Gam
01. Introduction
What is Godot Engine?
Godot is a free, open-source game engine that lets you build both 2D and 3D games and publish them to Windows, macOS, Linux, Android, iOS, and the Web — all without paying a single licensing fee or royalty.
Originally created by Juan Linietsky and Ariel Manzur, Godot went public in 2014 and has since grown into one of the most loved engines in the indie game world. The community is enormous, the documentation is excellent, and the engine itself weighs in at a remarkably lean 50–160 MB.
🆓
Truly Free
No royalties, no subscriptions, no catch. MIT license — use it for anything.
⚡
Lightweight
Download, extract, run. No installer. The editor is a single executable.
🎮
2D & 3D
Fully independent 2D and 3D engines — both production-ready out of the box.
🌍
Cross-Platform
Export to 6+ platforms from the same project with minimal configuration.
Godot 4.6 — What’s New?
The current stable version, Godot 4.6 (released January 2026), ships with Jolt Physics as the default 3D engine, a fully redesigned Modern editor theme, and a unified docking system that supports multi-monitor workflows. Godot 4.0 was the landmark release that introduced Vulkan rendering, a rewritten GDScript, and a complete physics overhaul.
📌 Hardware Note
Godot 4.x uses Vulkan by default. If you have older hardware, switch to Compatibility (OpenGL) mode during project creation to keep things running smoothly.
02. Tools
Getting to Know the Editor
When you open a project, Godot’s editor greets you with a well-organized workspace. Once you know what each panel does, navigating it feels completely natural.
The Five Areas You’ll Use Every Day
- Scene Dock (top-left) — the tree of every node in the current scene. Add, remove, rename, and rearrange nodes here.
- FileSystem Dock (bottom-left) — all your project files. Drag images, audio, and scenes directly into your viewport from here.
- Viewport (center) — the visual canvas. In 2D mode it’s a flat canvas; in 3D, a full perspective view. Transform nodes by clicking and dragging.
- Inspector (right) — every property of the selected node. Change position, add a texture, assign a script — all from here.
- Output / Debugger (bottom) — see print() output, click on errors to jump straight to the offending line in your code.
Editor Modes
The toolbar at the top switches between 2D, 3D, Script (full code editor), and AssetLib (community plugins). You’ll jump between 2D/3D and Script constantly as you develop.
💡 Tip
In Godot 4.6, every panel can be floated as its own window — perfect if you’re working across two monitors. Just drag any dock header to undock it.
03 — Core Concept
Nodes & Scenes — The Big Idea
Everything in Godot revolves around nodes and scenes. If you understand this one concept deeply, everything else clicks into place.
What’s a Node?
A node is the most basic unit in Godot. Every visible object, sound, camera, physics body, and UI element is a node. Each node type has its own purpose and its own properties in the Inspector. Nodes can be parented to other nodes, creating a hierarchy.
| Node | What it does |
Node2D | Base for all 2D objects — has position, rotation, scale |
| Sprite2D | Displays a 2D image in the scene |
| Character Body2D | Physics body for player-controlled movement |
| RigidBody2D | Fully physics-simulated object (gravity, forces) |
| StaticBody2D | Immovable walls, floors, and platforms |
| Area2D | Trigger zone — detects overlapping bodies |
| Camera2D | Defines what the player sees |
| Timer | Fires a signal after a set duration |
| AudioStreamPlayer | Plays sound effects or music |
What’s a Scene?
A scene is a saved group of nodes in a tree, stored as a .tscn file. Think of it as a reusable template — a Player scene, an Enemy scene, a Level scene. You build it once and instance it anywhere.
Instancing a Scene in Code
var enemy_scene = preload("res://scenes/Enemy.tscn")var enemy = enemy_scene.instantiate()add_child(enemy)
Changes to the original Enemy .tscn automatically propagate to every level that uses it. That’s the power of scenes — true modularity with zero duplication.
04 — Scripting
GDScript — Write Game Logic Fast
GDScript is Godot’s own scripting language. It looks a lot like Python — indentation-based, dynamically typed by default, easy to read. It’s purpose-built for Godot, so it integrates with nodes and the engine with zero friction.
The Callback Functions
These special functions are automatically called by the engine at specific moments. You don’t call them yourself — Godot does.
func _ready():
# Runs once when the node enters the scene tree
print("Node is ready!")
func _process(delta):
# Runs every frame — use for non-physics logic
position.x += 100 * delta
# moves 100 px/sec
func_physics_process(delta):
# Runs every physics tick (default 60/sec)
# Use this for movement and physics
Variables, Types, and @export
var player_name = "Hero" # dynamic variablevar health: int = 100 # typed — better performanceconst MAX_HEALTH: int = 100 # constant, can never change@export var speed: float = 300.0 # editable in Inspector!
The @export annotation is one of GDScript’s most useful features. It makes a variable show up directly in the Inspector, so designers can tweak values without ever touching the code.
Node References
# Dollar shorthand — clean and readablevar sprite = $Sprite2D# @onready — resolves after _ready runs, avoids null errors@onready var label: Label = $UI/ScoreLabel
Best Practice
Always use @onready for node references. It prevents null errors and makes your intent crystal clear.
05 — Physics
Physics System
Godot’s physics system is powerful and beginner-friendly. For 2D, Godot uses its own engine. For 3D, Godot 4.6 ships Jolt Physics as the default — it’s fast, accurate, and stable.
The Right Body for the Job
| 🧍 CharacterBody2D For players and enemies you control with code. Use move_and_slide(). |
| 🎱 RigidBody2D For crates, balls, and projectiles. The physics engine drives it. |
| 🧱 StaticBody2D For floors, walls, and platforms that never move. |
| 🔔 Area2D For trigger zones, collectibles, and damage areas. Doesn’t block movement. |
Player Movement — move_and_slide()
func _physics_process(delta): var direction = Input.get_axis("move_left", "move_right") velocity.x = direction * speed velocity.y += gravity * delta # apply gravity manually move_and_slide() # handles slopes, walls, floors
move_and_slide() is the workhorse of 2D platformers. It handles slope detection, stair-stepping, and wall sliding automatically — one function call replaces hundreds of lines of manual collision math.
Collision Layers & Masks
Godot uses a 32-layer system to control which objects interact. The layer is where an object lives; the mask is what it detects. Set bullets to only check the enemy layer and they’ll never accidentally trigger on each other.
06 — Input
Handling Player Input
Godot separates input actions from physical keys. You define logical names like jump or fire in the Input Map, then your code checks those names — not specific keys. This means remapping controls requires zero code changes.
Setting Up the Input Map
Go to Project → Project Settings → Input Map. Add actions like move_left, jump, fire and bind keyboard keys, mouse buttons, or gamepad buttons to each.
Checking Input in a Script
# Is the key held down right now?if Input.is_action_pressed("move_right"): velocity.x = speed# Was it pressed just this frame?if Input.is_action_just_pressed("jump"): velocity.y = -jump_force# Smooth axis (-1 to 1) — great for movementvar dir = Input.get_axis("move_left", "move_right")
📱
Mobile Tip
Godot automatically maps touch events to mouse events on mobile. Simple games often work without any extra touch-specific code at all.
07 — Animation
Bringing Your Game to Life
Godot offers three main animation tools, each suited to a different job.
01. AnimationPlayer — Keyframe Anything
AnimationPlayer is the most powerful option. It can keyframe any property of any node — position, color, shader parameters, even custom variables. Perfect for moving platforms, UI fades, and attack animations.
$AnimationPlayer.play("walk")$AnimationPlayer.play_backwards("walk")$AnimationPlayer.stop()
02. AnimatedSprite2D — Frame-by-Frame Sprites
Import a sprite sheet, define named frame sequences in the SpriteFrames resource, then play them with a single call. Great for pixel art characters.
$AnimatedSprite2D.play("run")
03. Tweens — Animation in Pure Code
Tweens animate values over time without any keyframes at all. Perfect for UI animations and one-off effects.
var tween = create_tween()tween.tween_property(self, "position", Vector2(300, 0), 1.0)# Moves this node to (300, 0) over exactly 1 second
08 — Interface
Building Your Game’s UI
Godot’s UI system is built on Control nodes. Every button, label, health bar, and menu is a Control node. The root of any UI scene is typically a Control or CanvasLayer node.
Essential Control Nodes
| NODE | Purpose |
| Label | Display static or dynamic text |
| Button | Pressable button — connect its pressed signal |
| ProgressBar | Health bars, loading bars, fill-based indicators |
| VBoxContainer | Stacks children vertically with automatic spacing |
| HBoxContainer | Stacks children horizontally |
| TextureRect | Display an image inside a UI rectangle |
| CanvasLayer | Fixed-screen HUD that doesn’t move with the camera |
The CanvasLayer Trick
Add your HUD (health bar, score, minimap) as children of a CanvasLayer at layer 1. It renders independently from the game camera, so it stays pinned to the screen no matter where the player moves.
09 — Communication
Signals — How Nodes Talk to Each Other
Signals are Godot’s event system. A node emits a signal when something happens; other nodes can listen for it. The emitter doesn’t need to know who’s listening — they’re completely decoupled.
Connecting a Built-in Signal
Select a node → open the Node dock (next to Inspector) → double-click a signal → choose the target function. Godot writes the connection for you. This is how you wire up a button press in under 10 seconds.
Custom Signals with Arguments
# Define the signal at the top of your scriptsignal health_changed(new_health: int)func take_damage(amount: int): health -= amount health_changed.emit(health) # fire the signal# In another node — listen for itfunc _ready(): player.health_changed.connect(_on_health_changed)func _on_health_changed(new_health: int): health_label.text = str(new_health)
Awaiting a Signal (Coroutines)
func _ready(): await get_tree().create_timer(2.0).timeout print("2 seconds have passed")
The await keyword pauses a function until the signal fires, then resumes it — without blocking the rest of the game. It’s one of GDScript’s most elegant features.
10 — Ship It
Exporting Your Game
When your game is ready, Godot can package it for Windows, macOS, Linux, Android, iOS, and Web — all from the same project. Here’s the process:
- Go toEditor Manage Export Templates → and download templates for your engine version (~500 MB). You only need to do this once
- Go to Project Export →and click Add to create an export preset for your target platform.
- Set your output path, application name, icons, and any platform-specific options (keystore for Android, etc.).
- In the Export dialog, click “Export Project” for your final build — not “Export With Debug”. The debug version includes extra data for testing and is larger. The clean export is smaller and optimized for players.
- Click Export and you’re projects done.
Web Export
Exporting to HTML5 generates an index.html, a .wasm file, and a .pck resource pack. Upload the entire folder to a web host or itch.io — players can run your game without downloading anything. Godot 4.3 added single-threaded web export for better browser compatibility without special server headers.
📦 PCK Files
The .pck file contains all your game resources. Enable Embed PCK in export settings to bundle everything into a single standalone executable for the cleanest distribution.
Quick Reference
GDScript Cheat Sheet
| TASK | CODE |
| Get child node | $NodeName or get_node(“Name”) |
| Delete a node | queue_free() |
| Change scene | get_tree().change_scene_to_file(“res://…”) |
| Quit the game | get_tree().quit() |
| Pause the game | get_tree().paused = true |
| Wait N seconds | await get_tree().create_timer(N).timeout |
| Random number | randf_range(0.0, 1.0) |
| Play sound | $AudioStreamPlayer.play() |
| Check group | body.is_in_group(“enemies”) |
| Instance a scene | scene.instantiate() |