Random Dungeon Generator (Minecraft Forge Mod)

Thijs Adema

Contents

  1. Intoduction
  2. Minecraft modding
  3. Dungeon generation
  4. Rooms
  5. Corridors
  6. Connected rooms
  7. Conclusion
  8. Future references
  9. Sources

1.    Introduction

One of the goals I have for my career is to create a 2D Role Playing Game. I have spent a lot of time during my years studying game development trying to come up with ways to make my future game unique. This research is a great opportunity to try something with procedurally generated content. That way I may learn something that will help me reach this goal.

I chose to research how to make a randomly generated dungeon inside the game Minecraft. This is possible by modding the game using Java code.

Minecraft itself is a game in which everything is randomly generated. The world, structures and placement of resources is completely randomized.

2.    Minecraft modding

In order to make a Minecraft mod I will need to download and install multiple programs. I followed a youtube tutorial that explained exactly how to download and install these programs correctly (TechnoVision, Minecraft 1.15.2: Forge Modding Tutorial – Workspace Setup (#1), 2020). I chose this video as the creator made a full tutorial series on Minecraft modding in the past as well as a complete new one following this video.

I then followed the next video to get a better understanding of the way Minecraft mods are made (TechnoVision, 2020). I made a custom item which I then connected with a ‘jump event’ that called my dungeon generation code.

3.    Dungeon Generation

Minecraft is a voxel engine, so my dungeon will consist of cubes. I found the method setBlockState in the Forge docs which allowed me to change the blocks on specific positions (Forge, z.j.). This method also allows me to delete blocks by placing air on their position. This way my dungeon will also be able to be generated underground.

I will first have to create rooms and then connect these rooms with corridors. This way I will have a dungeon that the player can traverse through and that has different areas that can be filled with obstacles, treasure and traps.

4.    Rooms

In order to make a room I would have to make a method that could spawn multiple blocks right next to each other. Each block that gets placed needs a position coordinate for the x, y and z axis. I used three nested for loops to do this. This way I can give the method a starting position and a size for each axis. The following method creates a cube consisting of blocks in any size that is given as an argument.

I used this method to create a cube with golden blocks that I will use as a test site. Here I will spawn dungeons/rooms during the development of my project/research. This will show the improvements from the first blocks I spawned to the final dungeon after the four weeks of research.

Sadly, not all versions were saved as they sometimes had disappeared after reloading the world. There was also a problem with data corruption when I had two windows open in the same world and then saved them both.

To make the rooms I took the spawnBlock method and modified it a bit. It now checks whether one of the coordinates is the first or the last of that same coordinate. It then places a ‘stoneBricks’ block or changes the block to ‘air’ respectively.

This is what the rooms that are spawned with this method look like. (removed part of the wall for demonstration)

5.    Corridors

Now that rooms can be generated, I will generate the corridors that can connect these rooms. To spawn the corridors, I will need to gather information inside the code. Like the axis the corridor will be placed towards and the position and size of the room the corridor starts from. This will help me calculate the starting point of the corridor.

I did this by giving the DungeonCorridor class the room it will connect to as a parameter in its constructor. Then calculating a starting position in a random axis.

In order to calculate the starting position of the corridor I had to use the position and size of the room the corridor connects to. The next example is the calculation for the X axis.

Here I first calculate a random Z value between zero and the size of the room. This makes each corridor spawn on a different spot of the room. Then a new position is calculated made with the length of the room and the random Z value. This position is then added to the position of the room the corridor connects to.

The corridor is placed one block into the room so the corridor can cut a hole in the wall of the room making it possible for players to walk into the corridor.

I made the same calculation for the Y and Z axis. These calculations look a bit different but work the same way. The Y axis is a bit special as the X and Z axis are both randomized as the corridor should be able to spawn anywhere on the ceiling.

The next step was to generate the corridors. This is done with almost the same method as the spawnRoom method, but with walls missing on one of the axes. I did this by excluding that axis from the if statement which checks if a block should be placed.

These are my some of my tries of spawning a corridor (the smaller rooms/blocks) on the correct position.

Here I had succeeded with spawning my first corridors (the rooms on the right) and some tries of spawning the corridor in a random Z position (the rooms on the left).

This picture shows the corridors I could spawn at this point. The upper room has a corridor in the Z axis. The middle room has a corridor in the X and Z axis. The lowest of the three rooms has a corridor in the Y axis.

The next step is to make the corridors in the X, Y and Z axis but in the other direction. This meant that I had to expand each method to be able to calculate all the necessary values for these directions. I did this by copying the code I already had and modifying it slightly.

I tested each axis by placing multiple corridors on one room and checking if they were placed correctly.

In the picture on the right was one of the test rooms as there is still a problem with the spawning. The corridor should be spawned one block inside the room so there is an opening.

6.    Connected Rooms

For the connection of rooms, I want to place a starting room then add a corridor (or multiple corridors) to it and then place a new room at the end of it. This way I know all my rooms are connected with each other.

The only thing I need is the ending point/position of the corridor I want to connect the new room to. I made a method that returns this position for any corridor that is given as an argument to the method. It also needs the size of the new room for the corridors in the negative direction.

Using this method, I can now spawn rooms that connect to other rooms. But there is a problem with the order in which the rooms and corridors are now spawned.

Because the corridor is spawned before the second room there is no opening to go through. That is why I changed to code to first spawn all the rooms and collect all data for the corridors and then spawn in all the corridors.

The following code shows how a dungeon with three rooms and two corridors can be spawned.

These are two dungeons generated with the code above.
This is inside one the top dungeon of the previous picture. (torches added manually)

7.    Conclusion

The dungeon generator that I made during this research serves as a foundation for the dungeon I had in mind. I am happy with the result of my research and can say that I enjoyed the process of making the generator. It was also interesting to write code that works in a game that I have played a lot.

I am still unsure if I will use procedurally generated content in my future games. The amount of edge cases a system like this has makes it prone to bugs. However, it does make the gameplay more interesting. The pros and cons of using procedurally generated content that I have found during this research are as follows.

Pros:

+Interesting randomization options.

+Fun to develop.

+Improves replayability.

Cons:

-Many edge cases to consider.

-Prone to bugs.

-Needs a lot of testing.

This knowledge will help me make the decision whether to use procedurally generated content in the future easier.

8.    Future references

If I could continue my research, I would first make sure no rooms could overlap. This could be done by making a grid of cells. Then use those cells to spawn rooms in so they can’t overlap.

Then I would make a middle room with a constant size that takes up eight of these cells. From here I would branch out to the X and Z axis to make different ways for the player to go.

This is a visual representation of this idea. The red blocks indicate the cells, the stone bricks the rooms and the cobblestone the corridors. The branches can also branch out in the Y axis and there would be many more rooms.

After this whole dungeon is generated some rooms and corridors would get special properties. They would be added semi randomly as follows.

Boss room: The room that is furthes away from the middle room, counting the amount of rooms and corridors between the two. (A locked corridor will be added to the branch to the boss room)

Treasure room: This room will be the deepest of the dungeon and will contain the key to the locked corridor to the boss room and random weapons and armour. (When the boss room is the deepest room the treasure room will be the second deepest room)

Enemy room: Every room that is attached to a non-enemy room has a 50% to 70% chance to become an enemy room. These rooms will contain a random minecraft mob spawner block.

Trapped corridor: Every corridor has a 10% to 30% chance to become a trapped room. This could for instance be a corridor filled with dirt that the player has to dig through.

These changes would bring structure to the dungeon and would give players a clear goal. I wish I could have made this version of the dungeon but am happy with progress I have made during my research.

9.    Sources

Forge. (n.d.). Block States. Retrieved 7, 2020, from mcforge: https://mcforge.readthedocs.io/en/latest/blocks/states/

TechnoVision. (2020, march 18). Minecraft 1.15.2: Forge Modding Tutorial – Custom Items (#2). Retrieved october 5, 2020, from Youtube: https://www.youtube.com/watch?v=qX-nyprSDAM&list=PLDhiRTZ_vnoUI3-9z0Zg-I8tTSp3EfOia&index=2

TechnoVision. (2020, march 13). Minecraft 1.15.2: Forge Modding Tutorial – Workspace Setup (#1). Retrieved october 5, 2020, from Youtube: https://www.youtube.com/watch?v=JOTH1eDP99Y&t=434s

Related Posts