With this project I wanted to experiment with generating a dungeon out of premade pieces and create a system that made it easy to make any new room I wanted. The goal was to create a proof of concept that would not set strict rules for the user.
I also decided to add my Stargate project to the dungeon generator in order to showcase the flexibility of the stargate system. If you have not read about it yet, you can do that here.
The player character I something I made for a previous assignment. I used free assets from the marketplace to create the animation blueprint. I scripted the rest of the character myself.
Deciding an Approach
There are many ways to randomly generate a dungeon. I had some criteria for the kind of generator I wanted;
The dungeon is NOT generated on a grid
The rooms can be any shape or size
The rooms can have any number of connections above 0.
The rooms must be premade blueprints so that they support scalable scripting
Not using a grid and using any shape I want goes hand in hand. It does make the idea of a goal a bit harder to achieve since I must make sure that the end room is reachable from the start room.
The best approach I could think of was a snake-like system. I would place a start room, and then place rooms one after the other creating a long chain of rooms. This would create a long chain of rooms that had a start and end room.
Then I would take each room that had an empty connection and make another snake from that starting point.
For the first iteration I decided it would be easier to try the system out on a grid and a fixed square size on the rooms. That way I could quickly make some rooms and place them without worrying if they would fit next to each other.
The system looked promising, but one thing I overlooked was that I would not be able to have any rooms looping back after I moved away from the square rooms and grid. The loops in this iteration was not intended anyway so I decided to accept that my generator would not create any loops.
The second iteration required me to set up the system I would use to build the rooms and then how they would connect to each other. I could no longer rely on the convenience of the grid.
Creating the Rooms
Unreal has a nice pre-made system for creating instances of levels that you can move around and rotate. I would make each room as its own level, then create an instance and move it to the correct location. However, there is no way to access actors per level, so rotating the levels and offsetting them to the correct piece would be almost impossible without some very extensive and ugly scripting.
I needed the component system of a blueprint, but it did not want to build the rooms inside of a blueprint because that would be very slow and tedious.
I took a lesson out of the object-oriented programming book and made a parent master room that would contain all the necessary code to find offsets and connections. When I wanted to create a new room all I would need to do build it as a regular level then convert all the actors into a blueprint class that inherited from that master room.
The master room has info on all the connections points and if they are occupied or not. The generator would only have to ask for a free connection and pass the location and rotation of said connection to the newly created room and the master room handles the alignment process
The anchor component is a custom component I use to tell the master room where the connections are. It has a world transform and a boolean that keeps track if it is connected or not.
Since I used the same doorway-mesh for all the connections I set-up two sockets I could snap my anchors to. This will ensure that my connections are always perfectly aligned every time.
A limitation with this is that I can only use one doorway, but I feel like it is a nice compromise for having such an easy set-up.
I place anchors after the rooms have been converted to a child of the master room.
Result of replacing the temporary tiles with rooms
When the generator places a room, it checks if that room can fit by doing a box trace on the desired location, if there is anything in the way I tried to place another room until it either succeeds or runs out of rooms. This often leads to awkward dead-ends and not very satisfying gameplay.
I tried to fix it by creating a very small room that could fit almost anywhere that would serve as a small reward for the player.
The process of creating blueprints from rooms is in its current state very prone to user error and could be improved on a lot, but it serves its pupose as a proof of concept.
The generator itself is very basic and not very customizable in turns of what parameters you can tweak. Unfortunately, implementing things like, room sizes, multiple floors and loops was not in the scope of this project.
I am however very pleased with the anchor and room system. It feels very robust and expandable, which is what I strive for with my creations.