Random dungeon generation occasionally has rooms missing

I am making a device that generates a dungeon, and every few generations, one or more rooms will not be teleported to the locations even though the output log says what room is supposed to be there.

The red line represents the path that was generated, according to the output log. Here is the code for the device, all three arrays have 5 props in each of them:

using { /Fortnite.com/Devices }
using { /Verse.org/Native }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath}
using { /Verse.org/Simulation }
using { /Verse.org/Random }

# A Verse-authored creative device that can be placed in a level
dungeon_device := class(creative_device):
    
    @editable
    var FloorNumber : int = 1
    @editable
    var UpRooms : []creative_prop = array{}
    @editable
    var RightRooms : []creative_prop = array{}
    @editable
    var LeftRooms : []creative_prop = array{}
    @editable
    var MaxRoomNumber : int = 10
    var RoomNumber : int = 1
    var LastRoomDirection : int = 1
    #1 = Up, 2 = Right, 3 = Left
    var RoomLeftRightPosition : float = 0.0
    var RoomForwardPosition : float = 0.0
    var RoomAngle : float = 0.0

    
    # Runs when the device is started in a running game
    OnBegin<override>()<suspends>:void=
        GenerateDungeon()

    GenerateDungeon()<suspends>:void=
        loop:
            RoomDirection : int = GetRandomInt(1, 3) 
            if (RoomDirection = 1):
                GenerateUpRoom()
            if (RoomDirection = 2 and RoomAngle < 90.0):
                RandomRoom : int = GetRandomInt(0, RightRooms.Length)
                if(RoomToMove := RightRooms[RandomRoom]):
                    RoomPosition := vector3{X:=0.0 + (2500.0 * RoomForwardPosition), Y:=0.0 + (2500.0 * RoomLeftRightPosition), Z:=0.0 + (5000.0 * FloorNumber)}
                    RoomRotation := MakeRotationFromYawPitchRollDegrees(RoomAngle, 0.0, 0.0)
                    if (RoomToMove.TeleportTo[RoomPosition, RoomRotation]):
                        if (ChangeArray := RightRooms.RemoveElement[RandomRoom - 1]):
                            set RightRooms = ChangeArray
                        set RoomAngle += 90.0
                        set RoomNumber += 1
                        Print("Right room made")
                        if (RoomAngle = 0.0):
                            set RoomForwardPosition += 1.0
                        else if (RoomAngle = 90.0):
                            set RoomLeftRightPosition += 1.0
                        else:
                            set RoomLeftRightPosition += -1.0
                else:
                    GenerateUpRoom()
            if (RoomDirection = 3 and RoomAngle > -90.0):
                RandomRoom : int = GetRandomInt(0, LeftRooms.Length)
                if(RoomToMove := LeftRooms[RandomRoom]):
                    RoomPosition := vector3{X:=0.0 + (2500.0 * RoomForwardPosition), Y:=0.0 + (2500.0 * RoomLeftRightPosition), Z:=0.0 + (5000.0 * FloorNumber)}
                    RoomRotation := MakeRotationFromYawPitchRollDegrees(RoomAngle, 0.0, 0.0)
                    if (RoomToMove.TeleportTo[RoomPosition, RoomRotation]):
                        if (ChangeArray := LeftRooms.RemoveElement[RandomRoom - 1]):
                            set LeftRooms = ChangeArray
                        set RoomAngle += -90.0
                        set RoomNumber += 1
                        Print("Left room made")
                        if (RoomAngle = 0.0):
                            set RoomForwardPosition += 1.0
                        else if (RoomAngle = 90.0):
                            set RoomLeftRightPosition += 1.0
                        else:
                            set RoomLeftRightPosition += -1.0
                else:
                    GenerateUpRoom()
            if (RoomNumber > MaxRoomNumber):
                break

    GenerateUpRoom()<suspends>:void=
        RandomRoom : int = GetRandomInt(0, UpRooms.Length)
        if(RoomToMove := UpRooms[RandomRoom]):
            RoomPosition := vector3{X:=0.0 + (2500.0 * RoomForwardPosition), Y:=0.0 + (2500.0 * RoomLeftRightPosition), Z:=0.0 + (5000.0 * FloorNumber)}
            RoomRotation := MakeRotationFromYawPitchRollDegrees(RoomAngle, 0.0, 0.0)
            if (RoomToMove.TeleportTo[RoomPosition, RoomRotation]):
                if (ChangeArray := UpRooms.RemoveElement[RandomRoom - 1]):
                    set UpRooms = ChangeArray
                set RoomNumber += 1
                Print("Up room made")
                if (RoomAngle = 0.0):
                    set RoomForwardPosition += 1.0
                else if (RoomAngle = 90.0):
                    set RoomLeftRightPosition += 1.0
                else:
                    set RoomLeftRightPosition += -1.0

I suspect that it is an issue with TeleportTo, but I am most likely wrong. Does anyone know what the issue is?

I figured it out, I had accidentally left the subtraction in the RemoveElement lines from before I changed the GetRandomInt minimum values :sweat_smile:

Edit: Nevermind, that was part of the issue but it still is not entirely gone.

The code is picking a random room from the list each time. Is it possible that you’re picking the same room from the same list twice, sometimes? Resulting in it being teleported twice, once to the first location, then again to the second location?

I believe that what you’re saying is the problem, I just don’t know how to fix it. It only ever happens with the UpRooms array.

Maybe you should spawn the rooms instead of moving them :thinking:

I thought about that, but I can’t do that because I need to put devices in the rooms such as guard spawners and item spawners.

Only other way to do it is with a logic array. Set it up to be the length of the number of rooms, when a corresponding room gets selected, set the array entry to true and in your random number generator, have it check the array before moving the room. If it has already been used, just rerun the random number generator.

From your code:

RandomRoom : int = GetRandomInt(0, RightRooms.Length)
...
RandomRoom : int = GetRandomInt(0, LeftRooms.Length)

GetRandomInt (API page) “Returns a random int between Low and High, inclusive.”
Could it be that you overshoot the Rooms array, hence failing and not executing the subsequent code?

No, that isn’t the issue, I’ve found that the problem is that one room is being used twice. For example, it gets teleported to the room 2 position, and a few loops later it gets teleported to room 5 even though it was already used.