The pieces every Godot game is built out of. Learn these first, because every lesson assumes them.
One piece of your game: a player, a wall, a coin, a label. Every node is one kind of thing, and that kind decides what it can do. Nodes are the smallest thing Godot works with.
A group of nodes saved together in one .tscn file. A scene can be a whole level, or one small thing like a coin that you use over and over.
The list of nodes in the Scene dock, drawn as a family tree. Nodes indented under another node are its children, and children move with their parent.
The node at the very top of a scene. Its type is what the whole scene counts as, so a scene whose root is a CharacterBody2D can be dropped into a level and it moves.
The plain 2D node. It has a position and a rotation and draws nothing on its own, so it is what you reach for when you just need something to hold other nodes.
extends Node2D
# draws nothing, but it has a position
position = Vector2(100, 50)A body you drive yourself with code. It is the node for anything that walks, runs, or jumps: the player, and usually the enemies. You set velocity, call move_and_slide(), and Godot stops it at walls.
extends CharacterBody2D
func _physics_process(delta):
velocity = Vector2(200, 0)
move_and_slide()A solid thing that never moves: walls, floors, platforms. It blocks bodies that run into it and needs no code at all.
A shape that notices a touch but does not block it. Coins, spikes, checkpoints, bullets. It tells you something arrived by sending the body_entered signal.
extends Area2D
func _on_body_entered(body):
queue_free() # noticed the touch, did not block itThe invisible shape that says which part of a node counts as solid. A body or an area with no CollisionShape2D child touches nothing, which is the most common reason a coin does nothing when you walk over it.
The node that draws a picture. Drag an image into its Texture slot and it shows up. The picture is only how the thing looks, never how it collides.
$Sprite2D.texture = load("res://art/coin.png")
$Sprite2D.flip_h = trueA node that counts down and sends timeout when it reaches zero. Use it for a shot cooldown, a countdown clock, or a spawner that fires every two seconds.
$Timer.wait_time = 2.0
$Timer.start() # sends timeout in 2 secondsDecides which part of the world is on screen. Make it a child of the player and the view follows the player for free.
A layer that stays put on screen even when the camera moves. Your score, your hearts, and your menus go in here so they do not slide away with the world.
Draws text on screen. Set its text from code to show a score, a countdown, or the words GAME OVER.
%ScoreLabel.text = "Score: " + str(score)A thing the player can click. It sends the pressed signal, which is how a Play button starts the game.
%PlayButton.pressed.connect(_on_play_pressed)
func _on_play_pressed():
get_tree().change_scene_to_file("res://level1.tscn")The node that plays a sound. Put the sound file in its Stream slot, then call .play() when the coin is picked up.
$PickupSound.play()Changes a value over time and can loop it: a coin that spins, a door that slides open, a sprite that flashes red when it is hit. One of them holds several named animations and plays one at a time.
$AnimationPlayer.play("spin")
$AnimationPlayer.play("hit_flash")An invisible node used only to mark a spot. Ours sits at the tip of the gun, so bullets start there instead of in the middle of the player.
var bullet = BULLET_SCENE.instantiate()
bullet.global_position = $Muzzle.global_positionA saved scene file sitting ready to be copied, like a cookie cutter. It is not in the game yet.
@export var enemy_scene: PackedScene
# the cookie cutter, not a cookie yetOne real copy of a scene, alive in the game. instantiate() makes the copy and add_child() puts it in, which is how one bullet scene becomes fifty bullets.
var enemy = enemy_scene.instantiate() # one real copy
add_child(enemy) # now it is in the game