







The tileset was purchased from https://pita.itch.io/rpg-dungeon-tileset and is a lot better than what I'm showcasing here in these early prototypes. Though it could use a bit more rubble methinks.

This post will outline an approach to making a dungeon generator mixing pre-made rooms and procedural rooms, which will allow arbitrary sizes and shapes of rooms. Better than telling is showing, so just look at the beautiful animation below!The basic part of the algorithm was kind of explained in the previous post , but let me go over it again in a bit more detail now that I have actually made it. Most of the rooms seen in the above are designed by hand. An algorithm is then able to look at the rooms and "cut them out" - specifically, a grid data structure is made which holds a common index for each designed room. When a new room is to be generated, it then chooses a random index and then copies each tile and doodad of the predesigned room into the new map.Linked to this are two complexities. The first is that the position of the tiles in the generated world should be different than in the designed world, so that a room can be created at any arbitrary position. To this end, each designed room holds information about the coordinates of its corners, and thus also where its centre is. Further, this allows one to rotate or mirror the rooms. In the above example, rooms can be mirrored horizontally or flipped vertically - due to limits of the tileset, rotations are off the table. Still, this (somewhat) quadruples the amount of rooms the generator can pull from.The next is that the rooms should not connect to each-other arbitrarily. Each designed room holds a list of potential doors. I decided to go for a limited amount of door-spaces rather than allowing any non-obstructed wall to make a door - this gives some extra design possibilities when it comes to symmetric rooms, etc. Anyway, when a new room is added, it finds an old, unused door-space to connect one of its own doors to. This is how the position offset described above is found - the place where the two potential doors overlap. Before the room is brought into the world, every single tile has to be checked for overlap with other rooms.However, apart from the predesigned rooms, the generator also sports two wholly procedural room types.Hallways, here highlighted within the grey rings, are generated procedurally to connect potential doors between rooms that would be difficult to make connect otherwise. There are basically three types - straight corridors, three part corridors (as shown) and corner corridors. The two first connect doors that face each-other, while the corner corridor connects perpendicular doors.The hallways are pretty simple, but have an important purpose. The generation algorithm starts with a seed room in the middle and then generates rooms in random directions. This, however, tends to lead to radial arms that stretch in different directions and never touch. In that way, the whole dungeon would be a linear tree where all rooms have just a single path to one another. The hallways, with their unending flexibility, make sure that there are circular paths through the dungeon.Last, corridors also create potential door spaces, and are thus able to connect with one another, as seen in the above example. I have spent quite a bit of time tuning the chance of creating hallways so that gigantic cities of interconnected hallways do not spawn.Finally, caves are completely procedurally generated rooms that spawn almost the same way as predesigned rooms. They can be seen in the rightmost half of the above picture, with the brown walls. Their shape is determined by Perlin noise, specifically a contour map with the value at the origin door as comparison value. Some extra stuff is done to make sure that no unreachable islands are included. This same algorithm also finds out the dimensions of the room and where to place potential doors. Finally, the room is filled with random decals.And I guess, the more I look these rooms over, the more I see how much work there still is to do. The bottom-most cave is kind of okay, but the top one, which just randomly happened to only have one sort of floor tile, looks unfinished. The decals also seem strewn about haphazardly, and tile repetitions really ruin the atmosphere. I think I ought to look them over again, perhaps replacing random chance with Perlin noise, and expand the available decals quite a bit, too. Unfortunately, the tileset I am using does not have a lot to offer when it comes to rubble.However, I think the cave bits offer a fine amount of diversity as long as they are kept rare and small. It mostly seems to be a problem when they are big and all over the place.Two last things I want to mention. First, adding dynamic lighting really made the dungeons feel a lot more unique. However, I think I could still work on some faint light-sources in the darker areas so that they do not end up completely uniformly dark. Currently only torches act as light, which are all equally luminant.Second, if you look at the above picture, you might notice that the different parts of the dungeon are coloured differently. The original tileset offered a single colour swap, but when working with procgen, colour swap is pretty straightforward to implement on a larger scale. Thus, each new room deviates slightly in colour from the previous, meaning that as you explore one arm of the dungeon, the walls might become green, and in another, red. A lot of tuning went into making this difference noticeable yet not too strong. Perhaps I am not quite done, either.If you're curious how the designed rooms were made, well, mostly with a lot of auto-tiling! I designed one gigantic dungeon, then had an algorithm cut out individual rooms. I also use noise as inspiration for this design, as described in the previous post . The default dungeon looks like this:All of this is WIP, but you can expect further updates in not too long - though about a topic a bit different than dungeon generation. What is a dungeon without a thousand hapless adventurers running around, steered by neural networks, most often to their demise by slime?