Using RNG for scene loading with an array, crashing on last element

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By SnapCracklins

Alright, Godot wizards. I am working on a semi-random level loader for a game I am working on, using arrays to store level paths and then using a RandomNumberGenerator to pick one from the array, load that scene, and then remove it from the array and adjust the numbers to dodge errors.

Here’s what I can’t figure out - every time it loads the last item in the array (item with value equal to the array’s size) the program crashes. (Example: if the array size is 6 and it loads level 6, it bugs out.) What am I missing?

Single global function, called on each scene.
(I understand this is not terribly efficient coding, appreciate any feedback there.)

extends Node

var nextScene
var removeTag
var levelKeyMax
var levelKeys = [
	"res://Level_1.tscn",
	"res://Level_2.tscn",
	"res://Level_3.tscn",
	"res://Level_4.tscn",
	"res://Level_5.tscn",
	"res://Level_6.tscn",
	"res://Level_7.tscn",
	"res://Level_8.tscn",
	"res://Level_9.tscn",
	"res://Level_10.tscn",
	"res://Level_11.tscn",
	"res://Level_12.tscn",
	"res://Level_13.tscn",
	"res://Level_14.tscn",
	"res://Level_15.tscn",
	"res://Level_16.tscn",
	"res://Level_17.tscn",
	"res://Level_18.tscn",
	"res://Level_19.tscn",
	"res://Level_20.tscn"
]


func _ready():
	levelKeyMax = levelKeys.size()
	get_tree().change_scene("res://Level_0.tscn")


func levelSelect():
	levelKeyMax = levelKeys.size()
	if levelKeys.empty() == false:
		var rng = RandomNumberGenerator.new()
		rng.randomize()
		var num = rng.randi_range(0,(levelKeyMax))
		nextScene = (levelKeys[num])
		removeTag = num
		print("Loading " + str(nextScene))
		get_tree().change_scene(nextScene)
		call_deferred(nextScene)
		levelKeys.remove(removeTag)
	

	if levelKeys.empty() == true:
		get_tree().change_scene("res://EndLevel.tscn")
:bust_in_silhouette: Reply From: SnapCracklins

SOLVED. I figured it out.

While the array has a size, the size is not the same size as the end of the index.
While the array has 20 elements, you don’t call on the 20th element with array[20] - you call on it with array[19] because the first element is zero! D’oh!

A simple -1 to the levelKeys.size() and solved. Leaving it here for whoever else gets perplexed on this tiny detail.

func levelSelect():
     levelKeyMax = levelKeys.size() -1

HOORAY FOR LEARNING INTRICACIES! HUZZAH!

Rats, and I was just going to suggest that part. :-/ Glad you found it.

BTW, may I suggest reusing the RandomNumberGenerator object instead of creating a new one each time.

Ertain | 2022-04-04 02:20

Ah! That’s a good point. I’ll substantiate that it outside the function/in a separate function next time. Good call!

SnapCracklins | 2022-04-04 09:04