Godot Version
4.5.1
Question
Hello.
I am trying to make a procedurally generated dungeon. I made the graph generation and room rendering based on the generated graph (2D array of symbols), but im stuck on how to approach the moving between the rooms through doors. I am also new to those stuff in godot so that also doesn’t help.
Here is the code if it helps somehow. The generation and door bitmasking are based on 2 parts of video: https://www.youtube.com/watch?v=yl4YrFRXNpk
I would really apprecitate if i got some push in the right direction ![]()
enum Cell {
EMPTY = 0,
START = 1,
CRITICAL = 2,
BRANCH = 3,
END = 4
}
enum Doors {
RIGHT = 1,
UP = 2,
LEFT = 4,
DOWN = 8
}
const DIR_TO_DOOR := {
Vector2i.RIGHT: Doors.RIGHT,
Vector2i.UP: Doors.UP,
Vector2i.LEFT: Doors.LEFT,
Vector2i.DOWN: Doors.DOWN
}
const OPPOSITE_DOOR := {
Doors.RIGHT: Doors.LEFT,
Doors.LEFT: Doors.RIGHT,
Doors.UP: Doors.DOWN,
Doors.DOWN: Doors.UP
}
func generate_path(from : Vector2i, length : int, marker : Cell) -> bool:
if length == 0:
return true
var current_position : Vector2i = from
var previous_position : Vector2i
var directions : Array[Vector2i] = [
Vector2i.UP,
Vector2i.RIGHT,
Vector2i.DOWN,
Vector2i.LEFT
]
directions.shuffle()
for direction in directions:
if(current_position.x + direction.x >= 0 and current_position.x + direction.x < dungeon_dimensions.x
and current_position.y + direction.y >= 0 and current_position.y + direction.y < dungeon_dimensions.y
and dungeon[current_position.x + direction.x][current_position.y + direction.y] == Cell.EMPTY):
previous_position = current_position
doors[previous_position.x][previous_position.y] |= DIR_TO_DOOR[direction]
current_position += direction
doors[current_position.x][current_position.y] |= OPPOSITE_DOOR[DIR_TO_DOOR[direction]]
dungeon[current_position.x][current_position.y] = marker
if length > 1:
branch_candidates.append(current_position)
if generate_path(current_position, length - 1, marker):
return true
else:
branch_candidates.erase(current_position)
dungeon[current_position.x][current_position.y] = Cell.EMPTY
doors[current_position.x][current_position.y] &= ~OPPOSITE_DOOR[DIR_TO_DOOR[direction]]
doors[previous_position.x][previous_position.y] &= ~DIR_TO_DOOR[direction]
current_position = previous_position
return false
func generate_branches() -> void:
var generated_branches : int = 0
var candidate : Vector2i
while generated_branches < max_branch_amount and branch_candidates.size():
candidate = branch_candidates[randi_range(0, branch_candidates.size() - 1)]
if generate_path(candidate, randi_range(branch_length.x, branch_length.y), Cell.BRANCH):
generated_branches += 1
else:
branch_candidates.erase(candidate)
func place_start() -> void:
dungeon[start_pos.x][start_pos.y] = Cell.START
func spawn_test_rooms() -> void:
for x in dungeon_dimensions.x:
for y in dungeon_dimensions.y:
if dungeon[x][y] != Cell.EMPTY:
var room := room_scene.instantiate()
room.position = Vector2(x, y) * CELL_SIZE + CELL_SIZE * 0.5
add_child(room)