Video summary

Create a 2D RPG in Godot 4 | Step-by-Step

Main summary

Key takeaways

Technology

Overview

This video is the first episode in a short series that shows how to build a 2D RPG player controller in Godot 4 “from scratch” over five videos. Episode 1 focuses on the core player systems, including:

  • Player scene setup
  • Movement
  • Animations
  • Animation State Machine
  • Attack logic

1) Player scene setup (Godot nodes + visuals)

  • Creates a new 2D scene
  • Replaces the default node with CharacterBody2D (to use built-in physics/movement)
  • Adds a Sprite2D using a free sprite sheet (e.g., warrior_blue.png) that contains animations arranged in a grid:
    • 6 frames horizontally
    • 8 frames vertically
  • Configures the Sprite2D frame region to match the sprite sheet layout (initially via the Inspector)

2) Correct positioning for depth sorting with TileMaps

  • Ensures the player’s feet sit on the world baseline:
    • The sprite is transformed so the feet align with y = 0
  • This is explicitly intended for depth ordering / Y-sorting later with TileMaps, so the player can appear in front of or behind tiles.

3) Physics collision shape and camera

  • Adds a CollisionShape2D (required for CharacterBody2D)
  • Uses a circle collision shape, positioned to “bump” around the feet area
  • Adds a Camera2D
    • The script relies on the camera being active at game start

4) Input mapping (WASD-style)

  • Configures Project Settings → Input Map with actions:
    • left/right/up/down
  • Binds them to:
    • A/D/W/S respectively
  • Movement direction is later computed from input values, e.g.:
    • right - left
    • down - up

5) Scripted movement (physics loop, velocity)

  • Saves the scene first as player.tscn, then creates/attaches the script (to keep paths organized)
  • Uses _physics_process (running ~60 times/second by default)
  • Implements movement by:
    • Computing direction on X and Y
    • Normalizing the direction vector
    • Setting velocity
    • Calling move_and_slide()
  • Design note:
    • If opposing inputs are pressed together (e.g., A + D), they cancel out due to subtraction logic (right - left, same idea for up/down)

6) Creating animations with AnimationPlayer

  • Adds an AnimationPlayer node
  • Uses property tracks to animate Sprite2D.frame
  • Creates animations:
    • idle (looping)
    • run (looping)
  • Timeline notes:
    • Animation duration is set to 6 seconds for each animation segment (based on chosen frame grouping)
    • Looping is enabled for idle/run
    • Timeline snapping is adjusted so keyframes align cleanly with sprite sheet frame indices

7) AnimationTree + state machine (idle/run/attack/death structure)

  • Adds an AnimationTree and uses it as a “golden standard” approach
  • Sets:
    • the tree root / state machine requirement
    • assigns the AnimationPlayer to the AnimationTree
  • Builds an AnimationNodeStateMachine with states:
    • idle
    • run (and later attack)
  • Connector behavior:
    • idle → run switches immediately when movement starts
    • run → idle is enabled (movement code decides when to travel), rather than using only automatic expression conditions on connectors

8) Driving animations from code (state + travel)

  • Defines:
    • enums for animation states (idle, run, attack, death)
    • a current state variable (default: idle)
  • On each physics tick, an “update animation” function:
    • checks whether input produces non-zero motion
    • if moving while in idle → travel to run
    • if not moving while in run → travel back to idle
  • Uses AnimationTree playback:
    • animation_playback.travel("stateName")

9) Sprite flipping optimization (left vs right)

  • The sprite sheet stores right-facing animations only to save space
  • Left-facing versions are produced via flipping:
    • Uses Sprite2D.flip_h
  • Flip logic includes a small guard band:
    • if in idle/run and move_direction.x < -0.01 → flip
    • if in idle/run and move_direction.x > 0.01 → don’t flip
  • Important:
    • Flipping is not applied during attack states, so attack animations remain consistent with their intended direction.

10) Attack animations (right/down/up) and BlendSpace setup

  • Creates attack animations in AnimationPlayer:
    • attack_right
    • attack_down
    • attack_up
  • Each attack animation is a non-looping “oneshot”
  • AnimationTree attack structure:
    • Uses a nested BlendSpace2D instead of separate direction nodes
    • BlendSpace expects a normalized Vector2 in [-1, 1] for both axes
    • Set to discrete mode (not continuous), since sprite flipbooks don’t blend well
  • Direction mapping:
    • attack direction selects the nearest node in the graph
    • left attacks are handled via sprite flipping in code (left frames are not stored)
  • Time scaling for RPG feel:
    • attack output is passed through a TimeScale node
    • intended to enable RPG mechanics like speeding/slowing attacks (debuffs/buffs, gear effects, level-up sync)

11) Attack gameplay logic (input event → state lock → timed return)

  • Adds _unhandled_input(event) to detect player actions
  • Uses InputEventMouseButton:
    • on left-click pressed → triggers attack()
  • attack() behavior:
    • if already in attack, immediately returns (prevents repeated triggering)
    • sets state to attack to lock out movement
    • creates a temporary Timer and waits for attack_speed
    • when timer ends → returns state back to idle
  • While attacking:
    • physics movement is skipped (if state != attack then move)
  • Attack direction:
    • computes vector from player position → mouse position
    • normalizes it
    • feeds it into AnimationTree attack BlendSpace2D parameters

12) Attack flipping based on blend space selection logic

  • When attack direction points to the left side of the blend graph, code sets:
    • Sprite2D.flip_h = true
  • The decision uses comparisons involving component magnitudes (using abs to determine dominance between X and Y) to infer whether the blend logic would select the “left” side.

Outcome / result

The character controller supports:

  • WASD movement
  • Switching between idle/run based on movement input
  • Smooth left/right direction flipping
  • Directional mouse-click attacks using:
    • BlendSpace2D
    • timed attack lockout
  • Compatibility with upcoming systems (e.g., TileMaps next episode)

Main speakers / sources

  • Primary speaker: the tutorial creator (narrator of the step-by-step Godot 4 RPG series)
  • Project assets / references:
    • free starter kit and sprite assets referenced via links in the video description:
      • GitHub “starter kit”
      • assets from H.io (as stated in subtitles)
  • Engine documentation implied by usage:
    • Godot 4 systems such as:
      • CharacterBody2D
      • AnimationPlayer
      • AnimationTree
      • AnimationNodeStateMachine
      • BlendSpace2D

Rate this summary

Your feedback will help improve summaries.

Improve this summary

Reprocess with a stronger model when the summary feels incomplete or inaccurate.

Pro

Translate summary in another language

Pro

Ask questions to this video

Chat for follow-up questions, clarifications, and source-backed answers.

Coming soon

Share this summary

Original video