How to Create an RPG in Godot – Part 1

Introduction

Welcome, everyone!  Even after all the years games have existed, RPGs are still one of the most popular genres that aspiring developers want to learn how to make.  However, given how feature-rich RPGs can be, it can be hard to know where to start.  Thankfully, though, with Godot and some programming knowledge at hand, you will have all the tools you need to start on your very own dream RPG!

In this RPG tutorial series, we’ll be creating a 2D RPG inside of the Godot game engine together. It will feature a top-down player controller, enemies, combat, loot, and even a leveling system.  For Part 1, though, we will be covering a number of new systems inside of Godot as we start to build our RPG, including tilemaps, sprite animations, and raycasting.  This course will require a basic understanding of the Godot game engine and the GDScript scripting language. If you’re new to Godot, you can view our introductory tutorial here.

Otherwise, though, we hope you strap in and are ready to learn how to make 2D RPGs with Godot.

If you’d like to jump straight in making enemies and loot, check out Part 2 instead!

ezgif 3 8c32af3c74f4

Project Files

For this project, we’ll be needing some assets such as sprites and a font. These will be sourced from kenney.nl and Google Fonts. You can, of course, choose to use your own assets, but for this course we’ll be using these.

  • Download the sprite and font assets here.
  • Download the complete Godot project here.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.

Setting Up The Project

To begin, let’s create a new Godot project. Inside of the editor, let’s then import the assets we’ll be needing.

Godot RPG Assets added to Godot FileSystem

Once we have the assets, let’s create our first scene by selecting 2D Scene in the scene panel. Rename this node to MainScene, then save the scene to the file system.

Godot with MainScene Node created

Creating the Player

Now that we have the main scene, let’s create a new scene (Scene > New Scene) of type KinematicBody2D.

  • Rename the node to Player
  • Save the scene to the file system

As a child of this node, we want to…

  • Drag in the player_s_0.png sprite in to create a new sprite node
  • Set the position to 0, 0
  • Create a child node of type CollisionShape2D
  • Set the Shape to Capsule
  • Resize it to fit the sprite

Right now, we’re using just a sprite node to allow us to see the player. Later on, we’ll be replacing this with an AnimatedSprite node.

Player Character sprite with 2D collision shape

Finally, for our player, let’s create a RayCast2D node. You’ll see that in the scene view, an arrow will appear to come out of the player. This is a raycast, which is a concept in game development that is used in many different cases. You give a raycast an origin position and a direction. Then it will shoot a point from that origin in the given direction. If that point ever hits a collider it will return that object and some other information.

In our case, the raycast has a max distance and this will be used to detect interactable objects and enemies.

  • Make sure to enable Enabled

2D character sprite in Godot with RayCast2D

Scripting the Player Movement

Now that we have the player scene, let’s create a new script attached to the kinematic body node called Player. We can start with our variables.

var curHp : int = 10
var maxHp : int = 10
var moveSpeed : int = 250
var damage : int = 1

var gold : int = 0

var curLevel : int = 0
var curXp : int = 0
var xpToNextLevel : int = 50
var xpToLevelIncreaseRate : float = 1.2

var interactDist : int = 70

var vel = Vector2()
var facingDir = Vector2()

onready var rayCast = $RayCast2D

Later on, we’ll be adding in a couple more variables, but for most of our systems, this will do. Now, in order to move the player around, we’ll need to know which buttons do what. Go to the Project Settings window (Project > Project Settings…) and click on the Input Map tab. Here, we want to create 5 new actions and assign a keyboard key to each of them.

  • move_left – left arrow key
  • move_right – right arrow key
  • move_up – up arrow key
  • move_down – down arrow key
  • interact – space

Godot Project Settings window with movement options

Back in the script, we can create the _physics_process function. A built-in function which runs at 60 FPS (good for physics). What we want to do here, is a few things.

  1. Reset vel (vector containing our velocity)
  2. Detect the 4 direction keys to change the velocity and facing direction (used for animations later)
  3. Normalize the velocity vector to prevent faster diagonal movement
  4. Move the player based on the velocity using the KinematicBody2D node function
func _physics_process (delta):
	
    vel = Vector2()
	
    # inputs
    if Input.is_action_pressed("move_up"):
        vel.y -= 1
        facingDir = Vector2(0, -1)
    if Input.is_action_pressed("move_down"):
        vel.y += 1
        facingDir = Vector2(0, 1)
    if Input.is_action_pressed("move_left"):
        vel.x -= 1
        facingDir = Vector2(-1, 0)
    if Input.is_action_pressed("move_right"):
        vel.x += 1
        facingDir = Vector2(1, 0)
	
    # normalize the velocity to prevent faster diagonal movement
    vel = vel.normalized()
	
    # move the player
    move_and_slide(vel * moveSpeed, Vector2.ZERO)

Let’s hop over to the MainScene and test the movement out. In the file system, drag the player scene into the scene window to create a new instance of it. Then click the Play button, choose the main scene to be the base scene and see if the movement works.

Player node added to MainScene in Godot 2D RPG project

Animating the Player

You’ll see that we can move around, but it’s pretty bland. Let’s now implement sprite animations. In the Player scene, delete the Sprite node and replace it with an AnimatedSprite node.

AnimatedSprite added to Player node in Godot

In the inspector, create a new sprite frames resource. The SpriteFrames window will then pop-up.

Godot with Frames resources

In the animations list there will be an animation called default. Double click on it and rename it to IdleDown. For this animation, we’re going to drag in the player_s_0 sprite.

Godot Animations windows with IdleDown sprite added

From here, we can create the rest of the animations. These will be:

  • IdleDown (already created)
  • IdleUp
  • IdleLeft
  • IdleRight
  • MoveDown
  • MoveUp
  • MoveLeft
  • MoveRight

Here’s what the MoveDown animation will look like. Click on the New Animation button to create a new animation.

Godot Animations window with MoveDown sprite added for 2D character

Go through now and create all of the idle and move animations. Once that’s done, select the AnimatedSprite node and…

  • Set the Animation to IdleDown
  • Enable Playing

Godot Inspector with AnimatedSprite properties open

Back in the Player script, let’s create a new variable to reference the animated sprite node.

onready var anim = $AnimatedSprite

Then we can create the manage_animations function which will check the velocity and facing directions to determine which animation to play.

func manage_animations ():
	
    if vel.x > 0:
        play_animation("MoveRight")
    elif vel.x < 0:
        play_animation("MoveLeft")
    elif vel.y < 0:
        play_animation("MoveUp")
    elif vel.y > 0:
        play_animation("MoveDown")
    elif facingDir.x == 1:
        play_animation("IdleRight")
    elif facingDir.x == -1:
        play_animation("IdleLeft")
    elif facingDir.y == -1:
        play_animation("IdleUp")
    elif facingDir.y == 1:
        play_animation("IdleDown")

The play_animation function will take in an animation name and play that.

func play_animation (anim_name):
	
    if anim.animation != anim_name:
        anim.play(anim_name)

We can call the manage_animations function every frame at the end of the _physics_process function.

manage_animations()

Now when we press play, you should see that the animations play when we move around.

Creating the Tilemap

Now that we’ve got a player who can walk around, let’s create our world.

In the MainScene, create a new child node of type TileMap. Then in the inspector, create a new tileset.

TileMap Node added to MainScene in Godot

These tile sets require tiles, so to do this, we need to create a new scene with all the available tiles in it.

RPG tileset for Godot 2D RPG

Once all the tiles are in the new scene, go to Scene > Convert To… > Tile Set and save it as tileset.tres.

Back in the MainScene, select the TileMap node and in the inspector, select the tileset property and choose load. Select the resource we just made and the tiles should appear in the panel to the right.

Godot Inspector with TileMap Tile Set being loaded

We can now select a tile and paint it in the scene view. Here are some keys for building your tilemap:

  • Place tile – Left Mouse
  • Delete tile – Right Mouse
  • Draw line – Shift + Left Mouse
  • Draw rectangle – Shift + Ctrl + Left Mouse
  • Delete line and delete rectangle are the same but with right mouse

Godot 2D RPG project with Tilemap painted on

Now if we try to place a tree, you’ll see that it replaces the tile rather than placing it on top. To fix this, we can create a second tilemap.

  • Call the existing tilemap TileMap_Ground
  • Create a new tilemap called TileMap_Above
  • Set that tileset to the same tileset
  • We can now draw tiles on-top of the existing tilemap

Godot Tilemap with extra layer added for objects above the ground

Something you might also want is a collision with some tiles. To implement this, select the tilemap in the file system and the TileSet panel should pop up.

  • Select a tile
  • Click on the sprite that pops up (a bunch of settings should then appear)
  • Select Collision
  • Select the Rectangle tool
  • Draw the collider on the sprite

Godot Tileset with collision being added to tile

Let’s now create a larger scene with our two tilemaps.

Godot 2D RPG project with player and completed tilemap

Continued in Part 2

With the tilemap created and player set up, we now have the basis for a spectacular 2D RPG in Godot!  Over the course of part 1, we’ve covered not only setting up sprite animations for your player character in Godot, but also setting up raycasts and tilemaps with appropriate collisions.  Fortunately, with just these foundations, you can expand into other games as well, or create even more complicated RPG maps.

Nevertheless, our RPG certainly isn’t complete!  In Part 2, we’ll cover the rest of our RPG creation process with enemies, loot, UI systems, and more!  Hope to see you then!