Let’s prepare the dungeon generator’s main scene to focus on the algorithm in the next lesson.
Create a new scene. Select 2D Scene from the Scene docker and rename the Node2D to MSTDungeon. Add the following child nodes:
Vector2(8, 8)
so we have enough room on the screen for the dungeon.Your scene tree should look like the following.
With the Level node selected, assign tileset-prototype.tres
to the Tile Set
property in the Inspector. Also set Cell > Size to Vector2(60, 60)
as this is our tiles’ size.
Attach a script to your MSTDungeon node and remove its contents. We’ll start fresh with the following code:
extends Node2D # Emitted when all the rooms stabilized. signal rooms_placed const Room := preload("Room.tscn") # Maximum number of generated rooms. export var max_rooms := 60 # Controls the number of paths we add to the dungeon after generating it, # limiting player backtracking. export var reconnection_factor := 0.025 var _rng := RandomNumberGenerator.new() var _data := {} var _path: AStar2D = null var _sleeping_rooms := 0 var _mean_room_size := Vector2.ZERO onready var rooms: Node2D = $Rooms onready var level: TileMap = $Level
Since we can’t predict when the physics simulation stabilizes, we need signals to coordinate our actions. For this, we introduce the rooms_placed
signal, which we emit after all the rooms stabilized and aren’t colliding any longer. We do so to know when to begin the next phase.
Next, we load the Room
scene because we want to instantiate it from code as we require many rooms.
We then have a block of exported variables that appear in the Inspector as properties for easier manipulation. We define max_rooms
to play with the number of rooms we want. reconnection_factor
will make sense when we go over the algorithm. In short, we use it to bring back some edge connections after calculating the MST graph. This means more connections between rooms, which improves gameplay as the player doesn’t always have to backtrack.
Since this is a PCG lesson, we have to deal with random numbers, so we define _rng
as our RandomNumberGenerator
. Then we define _data
as a dictionary since it’s faster than arrays at inserting and deleting operations. We use the AStar2D
_path
variable to store and manipulate the Minimum Spanning Tree graph. We use the variable _sleeping_rooms
to keep track of how many rooms entered the sleep state. We use _main_room_size
to store the mean size of the rooms. Our algorithm will select “main” rooms that are close to this size. We’ll see how this works in the next part.
Finally, we store references to the relevant nodes.