Godot 4 is one of the most capable free game engines available today — and a 2D platformer is the ideal first project. It exercises every core system: physics, input, animation, level design, and scene management. By the end of this guide you will have a playable game with a moving character, tile-based levels, and collectibles, all built using Godot’s node system and GDScript.
Table of Contents
Godot 4 (current stable release: 4.6.3 as of mid-2026) is a single executable you download from godotengine.org — no installer, no subscription, no royalties. Its scripting language, GDScript, reads like Python and is designed specifically for game logic. If you have never opened a game engine before, this guide starts at zero.
Quick Answer
Download Godot 4 free from godotengine.org, create a 2D project, build a Player scene rooted on CharacterBody2D (with CollisionShape2D and AnimatedSprite2D as children), write a GDScript that applies gravity and calls move_and_slide() each physics frame, then paint your levels using TileMapLayer. A basic playable prototype takes 2–4 hours.
Step 1 — Download, Install, and Configure Your Project
Go to godotengine.org/download and grab the Standard build for your platform (Windows, macOS, or Linux). Godot 4.6.3 is a self-contained executable — just extract and run it. You do not need to install anything. On first launch you will see the Project Manager. Click New Project, give it a name, pick a folder, and choose the Forward+ renderer for desktop games (or Mobile for cross-platform support). Click Create & Edit.
Before touching any nodes, open Project > Project Settings and make two changes that matter enormously for 2D games. First, go to Rendering > Textures and set Default Texture Filter to Nearest — this prevents pixel art from looking blurry. Second, go to Display > Window > Stretch and set Mode to canvas_items so the game scales correctly at any resolution. In the FileSystem panel at the bottom left, create three folders: scenes/, scripts/, and assets/. Drag your sprite sheets and tile images into assets/.
Step 2 — Build the Player Scene
Go to Scene > New Scene and click Other Node. Search for and select CharacterBody2D — this is the node Godot provides for characters that move and collide with the world. Rename it Player and save the scene as scenes/player.tscn. Now add two child nodes by right-clicking Player in the Scene dock: first add a CollisionShape2D, then add an AnimatedSprite2D.
Select the CollisionShape2D in the Scene dock and look at the Inspector on the right. Click the Shape dropdown and choose New CapsuleShape2D or New RectangleShape2D — pick whichever matches your character sprite. Use the resize handles in the 2D viewport to fit it snugly around the character. For the AnimatedSprite2D, click the Sprite Frames property in the Inspector, choose New SpriteFrames, then click Edit to open the SpriteFrames editor. Create three animations named idle, run, and jump, and populate each with the appropriate frames from your sprite sheet.
With the Player node selected, click Attach Script in the Inspector toolbar (the scroll icon) and choose GDScript. Check the Template checkbox and select CharacterBody2D: Basic Movement from the dropdown before confirming — this gives you a working movement scaffold to build on. Save the script as scripts/player.gd.
Step 3 — Write Movement Logic in GDScript
The template Godot generates already contains the essentials. At the top it pulls the gravity value from Project Settings using ProjectSettings.get_setting(“physics/2d/default_gravity”) — leave that line as-is. Add two exported variables below it: @export var speed: float = 200.0 and @export var jump_velocity: float = -400.0. The negative sign on jump_velocity is intentional: in Godot’s 2D coordinate system, Y increases downward, so negative Y moves the character upward.
The _physics_process(delta) function runs every physics frame (60 times per second by default). The logic flows in this order: first, add gravity to velocity.y when the character is not on the floor (if not is_on_floor(): velocity.y += gravity * delta). Next, detect jump input — if Input.is_action_just_pressed(“ui_accept”) and is_on_floor(): velocity.y = jump_velocity. Then read horizontal input with Input.get_axis(“ui_left”, “ui_right”) and multiply by speed to set velocity.x. Finally, call move_and_slide() — this one function applies the velocity, handles all collision responses, and refreshes is_on_floor() for the next frame. After move_and_slide(), call a small helper function that switches the AnimatedSprite2D animation based on the current velocity and floor state.
Step 4 — Paint Levels with TileMapLayer
Since Godot 4.3, the older TileMap node has been replaced by TileMapLayer. Each TileMapLayer is its own independent node, making it easy to separate collision tiles from decorative background tiles. In your main scene (scenes/main.tscn), add a TileMapLayer node as a child of the root. In the Inspector, click the TileSet property and choose New TileSet, then click Edit to open the TileSet editor. Drag your tile spritesheet into the panel and use the automatic tile detection wizard to slice it into individual tiles.
To make tiles solid, you must first add a physics layer to the TileSet itself: with the TileSet selected in the Inspector, scroll down to Physics Layers and click Add Element — this creates Physics Layer 0. Without this step, tiles have nowhere to store collision data. Once a physics layer exists, select a solid tile in the TileSet editor, go to its Physics tab, and draw a collision polygon over the tile’s area. Any tile without a drawn polygon is purely visual and has no physical presence. Add a second TileMapLayer with no physics shapes for background decoration. Add your Player scene to the main scene by dragging scenes/player.tscn into the viewport — keep it as a sibling of TileMapLayer, not a child of it.
Step 5 — Add Collectibles with Area2D
Create a new scene for a coin: Scene > New Scene, root node Area2D, with CollisionShape2D and AnimatedSprite2D as children. Set up the sprite animation and collision shape the same way you did for the player. Attach a GDScript to the Area2D. In the script, declare a signal at the top: signal collected(value). In the Node panel on the right, connect the Area2D’s body_entered signal to a function in the same script. That function should emit the collected signal and call queue_free() to remove the coin from the scene when the player touches it.
Back in your main scene, place several instances of the coin scene by dragging scenes/coin.tscn into the viewport. Select each instance and connect its collected signal to a function on the main scene’s root node that increments a score variable. Display the score using a Label node placed inside a CanvasLayer — the CanvasLayer ensures the UI stays fixed on screen regardless of where the camera moves.
Tips and Common Mistakes
Do not parent the Player node inside the TileMapLayer hierarchy — they must be siblings under the main scene root. If the player is a child of TileMapLayer, it inherits the layer’s transform and collisions behave unexpectedly. For TileMapLayer tiles to have any physical presence, two things must both be true: the TileSet resource must have at least one physics layer added (Inspector > Physics Layers > Add Element), and each solid tile must have a collision polygon drawn on that layer in the TileSet editor. A TileSet with a physics layer but no polygons, or polygons on a TileSet with no physics layer, produces zero collision. Enable Debug > Visible Collision Shapes while running to confirm shapes are actually there.
GDScript is indentation-sensitive like Python — mixing tabs and spaces causes syntax errors that are hard to spot. Godot’s built-in script editor defaults to tabs, so stick with that throughout. Another common stumble: forgetting that custom input actions must be registered before you can use them. The default actions ui_left, ui_right, and ui_accept exist out of the box, but if you want named actions like move_left or jump you must add them first in Project > Project Settings > Input Map. Finally, save your scenes manually with Ctrl+S after each meaningful change — Godot auto-saves scripts but not scene files.
Explore more: Game Development guides and tutorials.
Godot 4 2D platformer FAQs
Is Godot 4 completely free to use?
Yes. Godot 4 is free and open-source under the MIT license. There is no subscription, no revenue share, and no royalties — you keep 100% of what your game earns.
What replaced TileMap in Godot 4?
Since Godot 4.3, TileMap was deprecated and replaced by TileMapLayer. Each layer is now its own independent node in the scene tree, making it easier to manage collision tiles and decorative tiles as separate layers without complex sub-layer configuration.
Do I need prior coding experience to build a platformer in Godot 4?
Basic familiarity with coding concepts helps, but GDScript is intentionally beginner-friendly — it reads like Python and Godot provides built-in script templates for common node types like CharacterBody2D. Most beginners have working movement code within their first session.
Build It With GTStudios
Need help shipping your app, game, or small-business tech? GTStudios builds web, apps, and games. See how GTStudios can help.
Photo: Gflare / CC0, via Wikimedia Commons.