Hey friends! i was following a zenva course on youtube on how to do roguelike dungeon generation, and nearing the end of the video he was showing how to instantiate the rooms, but im getting an error.
The error reads: “Invalid access of index ‘7’ on a base object of: ‘Array’”
how can i solve this and make the code work as intended?
Heres the code, and yes it is EXACT to the tutorial.
var map_width : int = 7
var map_height : int = 7
func instantiate_rooms() -> void:
if rooms_instantiated:
return
rooms_instantiated = true
for x in range(map_width):
for y in range(map_height):
if map[x][y] == false:
continue
var room = room_scene.instantiate()
room.position = Vector2(x, y) * 816
if y > 0 and map[x][y - 1] == true:
room.north()
if y < map_height and map[x][y + 1] == true:
room.south()
if x > 0 and map[x - 1][y] == true:
room.west()
if x < map_width and map[x + 1][y] == true:
room.east()
if(first_room_pos != Vector2(x, y)):
room.Generation = self
$"..".call_deferred("add_child", room)
room_nodes.append(room)
get_tree().create_timer(1)
calculate_key_and_exit()
In an array, the numbers start at slot 0, which would mean that access to array[7] will lead to an error if the array.size() is just 7.
I would set a breakpoint inside your for loop and then go through each line until the error appears. This is where you’ll need to see if map[?][?] is not somehow out of bound.
the error occurs on the second if statement, and to be honest i have no idea what im looking at in the output console. im gonna post the entire script, to see if someone else can see what i cant.
extends Node
@onready var room_scene : PackedScene = load("res://Scenes/Nodes/room.tscn")
var map_width : int = 7
var map_height : int = 7
var rooms_to_generate : int = 12
var room_count : int = 0
var rooms_instantiated : int
var first_room_pos : Vector2
var map : Array
var room_nodes : Array
# Spawn Chance
@export var enemy_spawn_chance : float
@export var coin_spawn_chance : float
@export var heart_spawn_chance : float
@export var max_enemies_per_room : int
@export var max_hearts_per_room : int
@export var max_coins_per_room : int
func _ready() -> void:
for i in range(map_width):
map.append([])
for j in range(map_height):
map[i].append(false)
seed(3141592)
generate()
func generate() -> void:
check_room(3, 3, 0, Vector2.ZERO, true)
instantiate_rooms()
$"../Player".global_position = (first_room_pos * 816) + Vector2(262, 262)
func check_room(x : int, y : int, remaining : int, general_direction : Vector2, first_room : bool = false) -> void:
if room_count >= rooms_to_generate:
return
if x < 0 or x > map_width - 1 or y < 0 or y> map_height - 1:
return
if first_room == false and remaining <= 0:
return
if map[x][y] == true:
return
if first_room:
first_room_pos = Vector2(x, y)
room_count += 1
map[x][y] = true
var north : bool = randf() > (0.2 if general_direction == Vector2.UP else 0.8)
var south : bool = randf() > (0.2 if general_direction == Vector2.DOWN else 0.8)
var east : bool = randf() > (0.2 if general_direction == Vector2.RIGHT else 0.8)
var west : bool = randf() > (0.2 if general_direction == Vector2.LEFT else 0.8)
var max_remaining : int = rooms_to_generate / 4
if north or first_room:
check_room(x, y + 1, max_remaining if first_room else remaining - 1, Vector2.UP if first_room else general_direction)
if south or first_room:
check_room(x, y - 1, max_remaining if first_room else remaining - 1, Vector2.DOWN if first_room else general_direction)
if east or first_room:
check_room(x + 1, y, max_remaining if first_room else remaining - 1, Vector2.LEFT if first_room else general_direction)
if west or first_room:
check_room(x - 1, y, max_remaining if first_room else remaining - 1, Vector2.RIGHT if first_room else general_direction)
func instantiate_rooms() -> void:
if rooms_instantiated:
return
rooms_instantiated = true
for x in range(map_width):
for y in range(map_height):
if map[x][y] == false:
continue
var room = room_scene.instantiate()
room.position = Vector2(x, y) * 816
if y > 0 and map[x][y - 1] == true:
room.north()
print(map[x][y])
if y < map_height and map[x][y + 1] == true:
room.south()
if x > 0 and map[x - 1][y] == true:
room.west()
if x < map_width and map[x + 1][y] == true:
room.east()
if(first_room_pos != Vector2(x, y)):
room.Generation = self
$"..".call_deferred("add_child", room)
room_nodes.append(room)
get_tree().create_timer(1)
calculate_key_and_exit()
func calculate_key_and_exit() -> void:
pass
please help me out, what statement do you refer to when you say
the error occurs on the second if statement
right now I will just assume it’s the second if-statement inside of your instantiate_rooms() method.
That would be:
if map[x][y] == false:
continue
I can already see the error inside because this will lead to an error if either x or y is higher than the array size. I am not sure how large your map array is because you are appending a lot of things into it.
For now, I would print out your map at that point and see how it looks.
At your breakpoint you are also able to see your current x and y values and also what map[y] is.