Create a procedurally generated 2D Roguelike in Godot 4
Create a procedurally generated 2D Roguelike in Godot 4
In this course you will learn how to create a procedurally generated 2D Roguelike similar to games like Nuclear Throne or Enter the gungeon.
Enroll Now
Creating a procedurally generated 2D roguelike in Godot 4 involves several key steps, including setting up the project, creating the player character, generating the game world procedurally, and adding enemies and items. Below, I'll guide you through these steps in detail to help you build a basic roguelike game.
Step 1: Setting Up the Project
Install Godot 4: Ensure you have Godot 4 installed on your machine. You can download it from the official Godot website.
Create a New Project: Open Godot and create a new project. Name it "ProceduralRoguelike" or something similar. Choose a suitable directory for your project and click "Create & Edit".
Project Structure:
- Create the following directories in your project:
Scenes
: For storing all the scene files.Scripts
: For storing all the GDScript files.Assets
: For storing sprites and other assets.
- Create the following directories in your project:
Step 2: Creating the Player Character
Player Scene: Create a new scene for the player character.
- Right-click on the
Scenes
folder, selectNew Scene
. - Add a
KinematicBody2D
node as the root and name it "Player". - Add a
Sprite
node as a child of thePlayer
node to represent the player visually. - Add a
CollisionShape2D
node as a child of thePlayer
node for collision detection. Choose a shape that fits your sprite.
- Right-click on the
Player Script: Attach a script to the
Player
node.Right-click the
Player
node, selectAttach Script
, save it in theScripts
folder, and name itPlayer.gd
.Write the following script to handle player movement:
gdscriptextends KinematicBody2D @export var speed = 200 func _physics_process(delta): var velocity = Vector2.ZERO if Input.is_action_pressed("ui_right"): velocity.x += 1 if Input.is_action_pressed("ui_left"): velocity.x -= 1 if Input.is_action_pressed("ui_down"): velocity.y += 1 if Input.is_action_pressed("ui_up"): velocity.y -= 1 velocity = velocity.normalized() * speed move_and_slide(velocity)
Input Map: Define the input actions in the project settings.
- Go to
Project
->Project Settings
->Input Map
. - Add actions
ui_up
,ui_down
,ui_left
, andui_right
and assign the corresponding arrow keys or WASD keys.
- Go to
Step 3: Procedural Generation
Dungeon Scene: Create a new scene for the dungeon.
- Create a new scene with a
Node2D
root and name it "Dungeon". - Save this scene in the
Scenes
folder.
- Create a new scene with a
Dungeon Script: Attach a script to the
Dungeon
node.Save the script as
Dungeon.gd
in theScripts
folder.Write the following script to generate a simple grid-based dungeon:
gdscriptextends Node2D @export var width = 10 @export var height = 10 @export var tile_size = 32 var tiles = [] var player func _ready(): generate_dungeon() place_player() func generate_dungeon(): # Clear any existing tiles for tile in tiles: tile.queue_free() tiles.clear() for y in range(height): for x in range(width): var tile = create_tile(x, y) tiles.append(tile) func create_tile(x, y): var tile = Tile.new() add_child(tile) tile.position = Vector2(x, y) * tile_size return tile func place_player(): player = Player.new() add_child(player) player.position = Vector2(width / 2, height / 2) * tile_size
Tile Scene: Create a tile scene for the dungeon floor.
- Create a new scene with a
Node2D
root and name it "Tile". - Add a
Sprite
node to represent the floor tile. - Save the scene in the
Scenes
folder. - In the
Dungeon.gd
script, replaceTile.new()
withload("res://Scenes/Tile.tscn").instance()
to instantiate the tile.
- Create a new scene with a
Step 4: Adding Enemies and Items
Enemy Scene: Create an enemy scene.
- Create a new scene with a
KinematicBody2D
root and name it "Enemy". - Add a
Sprite
andCollisionShape2D
node. - Save the scene in the
Scenes
folder.
- Create a new scene with a
Enemy Script: Attach a script to the
Enemy
node.Save it as
Enemy.gd
in theScripts
folder.Write basic enemy behavior, such as moving towards the player:
gdscriptextends KinematicBody2D @export var speed = 100 var player func _ready(): player = get_parent().get_node("Player") func _physics_process(delta): if player: var direction = (player.position - position).normalized() move_and_slide(direction * speed)
Spawn Enemies: Modify the
Dungeon.gd
script to spawn enemies.Add an export variable for the number of enemies:
gdscript@export var num_enemies = 5
Add a function to spawn enemies randomly in the dungeon:
gdscriptfunc spawn_enemies(): for i in range(num_enemies): var enemy = load("res://Scenes/Enemy.tscn").instance() add_child(enemy) enemy.position = Vector2(randi() % width, randi() % height) * tile_size
Call
spawn_enemies()
in the_ready()
function.
Item Scene: Create an item scene.
- Create a new scene with a
Area2D
root and name it "Item". - Add a
Sprite
andCollisionShape2D
node. - Save the scene in the
Scenes
folder.
- Create a new scene with a
Item Script: Attach a script to the
Item
node.Save it as
Item.gd
in theScripts
folder.Write the script to handle item pickup:
gdscriptextends Area2D func _on_Item_body_entered(body): if body is Player: body.collect_item(self) queue_free() func _ready(): connect("body_entered", self, "_on_Item_body_entered")
Player Item Collection: Modify the
Player.gd
script to handle item collection.Add a function to collect items:
gdscriptfunc collect_item(item): print("Collected item:", item)
Step 5: Final Touches
Main Scene: Create a main scene to bring everything together.
- Create a new scene with a
Node2D
root and name it "Main". - Instance the
Dungeon
scene into the main scene. - Save the scene and set it as the main scene in
Project
->Project Settings
->Run
.
- Create a new scene with a
Testing: Run the game to test the procedural generation, player movement, enemy behavior, and item collection.
Conclusion
This basic outline covers the fundamental steps to create a procedurally generated 2D roguelike game in Godot 4. From setting up the player character and dungeon generation to adding enemies and items, each component plays a crucial role in creating a dynamic and engaging roguelike experience. Experiment with different procedural generation techniques, enemy behaviors, and item mechanics to expand and enhance your game further.