Procedural Room Generation Tool
Technical Design Project - Spring 2020
Engine: Unreal Engine 4
Project Type: Blueprint
Since I used Unity for nearly all of my previous projects, I wanted to learn more about Unreal Engine’s Blueprint system during my final class to complete my Game Programming minor. As a developer who wants to specialize in either level design or technical design, I decided to create a tool that allowed level designers to procedurally generate rooms based on the dimensions of a single cube. This would allow the designer to create a basic outline for the area, and allow them to make small adjustments to the room after it was generated to better fit their vision.
Since my class lasted for four months, I wanted to focus on making sure the algorithm and the spawning of each room was perfected. For the first two months, I focused on creating the algorithm for a Ballroom, in which it would spawn a floor, ceiling, walls, and holes for doorways. Once I was satisfied with being able to create the ballroom, I then started creating the courtyard and hallway sections. The courtyard would spawn with an open roof, while the hallway piece would create vases in the corners of the room. Once all three generation algorithms were complete, I worked on creating a user-friendly interface for designers using Unreal Engine’s Editor Utility Widget, as seen above. A designer can select their desired piece by hitting the respective button, and once all of the generation blueprints are scaled and moved to the designer’s content, they can hit generate to spawn to procedurally generate each room. Once a designer is finished using the generation blueprints, they can hit the destroy button to remove remaining blueprints from the scene.
The floor spawning portion of the algorithm. It spawns pieces row by row.
The algorithm for all three rooms can be broken down into four major parts: The floor, walls, ceiling, and extra props. For the sake of keeping it simple, I will be going through the process of generation for the ballroom section, and explain the key differences between different room sections. Starting with the floor generation, the algorithm starts by determining the scale of the cube placed in the world, and then determines how many pieces are needed for the floor section. Once the blueprint stores those numbers, the loop then starts spawning pieces along the positive z axis. Once the loop completes the row, it shifts over in the positive x direction, resets its z value, and begins the next row. This loop continues until it spawns the maximum amount of pieces for the floor.
Spawning a piece of the wall on the x axis. Once one side is completed, it then determines
the proper direction to start moving in next. There is a similar setup for the y axis spawning.
The wall spawning was the hardest part of the algorithm to figure out. For this section, the loop starts by going up the positive X side of the room, then across the positive Y side, then down the negative X, and finishing with the negative Y. The function would then go up the height of the wall, and continue spawning the walls until we hit the upper bounds of the box.
A sample of the math done to determine where doorways should be placed. When the loop reaches the point
that a doorway should be spawned, it will instead bypass spawning the section and move onto the next piece.
Once I figured out how to generate the walls, I needed a way to prevent walls from spawning to allow a doorway on each side of the cube. To do this, I ended up using four different equations depending on the number of pieces on each side. If a side had an even amount of pieces, I would need two walls to not spawn in order for the doorway to be centered. A side with an odd number of pieces would need a single wall removed. Finally, I needed the wall levels above the doorway to spawn normally so that a tall room wouldn’t have a doorway that stretched all the way to the ceiling.
The algorithm for spawning lights in each of the corners of the ballroom and hallway sections.
The vases spawned by the hallway section follows a similar structure.
The ceiling spawning copies the algorithm for the floor spawning, just at the top of the box’s bounds. For the courtyard section however, the ceiling section imitates the wall spawning algorithm to leave an open ceiling. Once the three major sections of each blueprint were spawned, the room specific algorithms are run. As pictured above, the light spawning is used to place four lights in the top corners of the room. A similar method is used for placing vases inside the hallway sections.