The project is creating rooms with doors. Any door that does’t have something the way can be used to generate another room. There are 4 main blueprints in play here.
“Rooms” - The main actor that spawns everything else. My level has one “Rooms” actor in it at 0,0,0 and everything is generated from that. Contains an array of “Room” actors.
“Room” - A single rectangular room with an array of “Door” actors. Also has “Wall” actors, but they’re not stored.
“Door” - A 200x300 wall with an opening for a player to walk through
“Wall” - A 200x300 solid wall.
A room is built wall-by-wall using either a Door or a Wall (Currently, every segment has a 10% chance to be a door).
Here’s the basic logic:
- Create Start room. Small room with 4 doorways. Add the Start room to the array
I apologize for the images. Posting at work and all I have available is MSPaint - For each room in the room array…
- For each door in the door array of the current room…
- Use the door’s location to determine the amount of space available outside the doorway for another room
- If there is space, randomize the dimensions within the space available and spawn a new Room actor
- Add the room actor to the room array
- Build the room based on the dimensions passed in. If a door segment is placed, add the door to the “Doors” array.
From here, the logic passes back to step 3. There are 3 more doors in the array still, each creating their own room. Then the logic passes back to step 2 where the 4 new rooms are processed. I have a “Max Rooms” variable which I use to break the loop
The problem I have is with step 4, determining the amount of space I have available.
At first, I grabbed the location just outside the door and ran 5 single line traces (Up, Down, Left, Right, Forward) to see what was out there.
Side Note: I say “Left”, “Right” and “Straight” because I am doing everything 100% relative to the door being processed. In doing everything relative to the door, I can build a room in any direction without needing a separate routine for each direction I would build in.
I thought this was working for a while until I finally realized these traces wouldn’t find rooms that were built on a diagonal from the doorway
So my next thought was … if 5 traces isn’t enough… I need more. (including both top-down and perspective views for this to improve clarity).
-
See how much room I have Up and Down
I took the results of this trace and divided it by 300 (the height of a door/wall) to see how many doors/walls I could fit in the space available. -
For every vertical I had available, I ran traces left and right as well. In this picture I show that the prior step determined I could go both up a floor and down a floor. Save the values of each left/right trace into their own array.
-
For every horizontal “segment” found in step 2, run a forward (away from the door) trace. Save the values into an array.
-
Compile the results. For every left/right/forward trace, go through the array and get the lowest value in the array. The room can only be as big in that direction as the lowest trace will allow.
-
Use the up/down/values from step 4 to build the room.
This worked … OK. Overall it seems much more intensive than I had planned, but it kind of worked. As I was roaming about my game though, I found instances where rooms were being created inside other rooms. The reason this happens is because two or more doorways were leading into the same area. Both doorways get “processed” and build a room on top of each other. I thought I had taken steps to prevent this. I have a system in place that, when placing a door or wall, it checks to see if it is up against another door. If it is, remove that door from the array of doors to be processed so that it doesn’t try to make another room. But it seems that’s not working.
In this example, both room 1 and room 3 have doorways leading into the same area. Example isn’t truly accurate, the rooms would never be the same exact size, but you get the idea.
So room 1 processed the eastern door and created room 4. Room 3 will later process the southern door and run the traces INSIDE room 4 and build another room inside it.
After all this, I decided to add another layer of checks to the process. I created a 100x100 collision box actor. When my traces are done, I spawn the collision box scaled to the room’s proposed dimensions and check to see if it’s overlapping any actors. If it is, I bail out of the whole thing. But then I started thinking… if I’m doing that, why bother with the trace at all? Toyed with the idea of just generating collision boxes of random sizes and seeing if they overlap. Maybe try 5-10 times with random boxes. If it still overlaps after all that, just remove the doorway and decide there’s not enough room. Seems messy though.
So I’m looking for new/creative ways to solve this problem. Maybe one without so many steps. Debugging random generation is insanely difficult and I spend most of my time reading log files to determine what got spawned where and why.
Anyways, thanks for reading.