Skip to main content
Back to module
Game Prototyping & Systems · Engines and Tools

First scene in Godot

Reading1h 20mLesson 2 of 3 in this module

Install Godot, build a 2D scene from nodes, and attach a GDScript that moves a character with gravity and input.

Why this matters

Your canvas prototypes taught you the moving parts of a game: a loop, state, input, collision and gravity. An engine packages those parts so you can spend your time on design. Godot is a good first engine for a designer: it is free and open source, the download is small, it runs on modest laptops, and its language, GDScript, reads like Python. In this lesson you will map what you already know onto Godot's concepts and build a playable scene.

Getting Godot

Download the standard build of Godot 4 from godotengine.org/download (the ".NET" build is only needed for C#). On Windows and Linux it is a single executable you can run without installing; on macOS it is an app bundle. Steam and itch.io also distribute it. Use the latest stable 4.x release. Checked on 2026-10-23.

Nodes and scenes

Everything in Godot is a node: a sprite, a camera, a sound, a collision shape, a timer. Nodes form a tree. A saved tree is a scene (.tscn file). A scene can be a whole level, or a single reusable thing like a player or a coin, and scenes can be placed inside other scenes (called instancing). This replaces most of the hand-rolled structure you wrote in JavaScript.

A typical 2D player scene:

Player (CharacterBody2D)      <- moves and collides; holds the script
├── Sprite2D                  <- the picture
└── CollisionShape2D          <- the hitbox (a RectangleShape2D or CapsuleShape2D)

A floor:

Floor (StaticBody2D)          <- does not move, but others collide with it
├── Sprite2D (or ColorRect)
└── CollisionShape2D

Mapping to what you know:

your canvas codeGodot
player = { x, y, w, h }a CharacterBody2D with position and a CollisionShape2D
update(dt)_physics_process(delta) (called at a fixed 60 Hz by default)
draw()automatic: nodes draw themselves
keys.ArrowLeftInput.is_action_pressed("ui_left") or Input.get_axis(...)
AABB + landing codemove_and_slide() and is_on_floor()

Your first script

Select the Player node and click the Attach Script button. Godot creates a file starting with extends CharacterBody2D. Replace its contents with:

extends CharacterBody2D

const SPEED := 220.0
const JUMP_SPEED := 450.0
const GRAVITY := 1200.0

func _physics_process(delta: float) -> void:
	if not is_on_floor():
		velocity.y += GRAVITY * delta

	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = -JUMP_SPEED

	var direction := Input.get_axis("ui_left", "ui_right")
	velocity.x = direction * SPEED

	move_and_slide()

Read it next to your JavaScript from module 2. velocity is a built-in Vector2 on CharacterBody2D. Gravity is added only in the air. ui_accept is a built-in input action (Enter and Space by default). Input.get_axis returns -1, 0 or 1 from two actions, so opposite keys cancel exactly as yours did. move_and_slide() moves the body by velocity, handles collisions with the floor, and updates is_on_floor(). GDScript uses tabs for indentation, like Python uses indentation for blocks.

Input actions

Hard-coding keys is the mistake you avoided in the input lesson. Godot builds that idea in: Project > Project Settings > Input Map lets you define actions such as jump and bind several keys and gamepad buttons to each. Your code then asks for "jump", and players or designers can remap without code changes.

Running and iterating

  • F5 runs the main scene (Godot asks you to choose one the first time). F6 runs the scene you are editing.
  • Change SPEED while the game runs and save: many changes apply live. Even better, mark tuning values with @export var speed := 220.0 and they appear in the Inspector, where a designer can tweak them without opening the script.
  • Use print() for quick debugging; output appears in the bottom panel.

Common mistakes

  • Forgetting the CollisionShape2D (Godot shows a yellow warning triangle on the node). Without it, the player falls through the floor.
  • Moving a CharacterBody2D by setting position instead of using velocity and move_and_slide(), which skips collision.
  • Mixing tabs and spaces in GDScript.
  • Writing physics in _process instead of _physics_process.
  • Not setting a main scene, so F5 asks every time.

Quick recap

  • Godot organises everything as nodes in trees saved as scenes.
  • CharacterBody2D + CollisionShape2D + Sprite2D is a typical player.
  • _physics_process(delta) is your update; move_and_slide() does movement and collision.
  • Use the Input Map and @export variables to keep controls and tuning editable.

Try it

Open the Do tab and build the scene step by step. It takes about 30 minutes with the editor open.

Also in this lesson: