Hello, Delvers! Get ready for a massive and exciting End-of-July Update. Over the last month, we have made an epic hoard of programming progress, which is demolishing our previous level design roadblocks and bottlenecks. The game is now able to generate full rooms on the fly, completely via programming algorithms.
What are the benefits of full procedural generation?
As mentioned in previous updates, we’ve been moving toward this higher degree of procedural generation as opposed to by-hand design. The old level generation system, while it did have some fun rooms/levels, wasn’t scalable. Designers had to put together every single room by hand, and hope that the game could effectively combine random elements, which were quite difficult to plan. This limited the random possibilities, limited the size of the rooms, and generally was not sustainable to build out the full game simply due to the hours necessary to create the desired amount of variety.
We will still have certain aspects designed by hand (story areas, puzzles, special rooms, bosses), but the results of the full procedural generation are much faster, more flexible, and just as unique. Our algorithm also follows similar rules (probably even better rules!) compared to our previous best-practices for by-hand room design and creation. In other words, our design sensibilities are being implemented directly into the procedural generation code, in detail. Good game design is still the driving force, rather than relying on the crutch of a basic RNG (random number generator).
It’s all still in process, but the exciting news is that as of now, we are confident that our procedural rooms will be at least as interesting and aesthetically pleasing as our previous hand-designs… if not more. And now the possibilities of room size/shape/gameplay variation are countless.
So how does it work?
In order to achieve these goals, the algorithm goes through several phases of generation, as listed below. The first three of these steps are programmatically complete (short of some bug fixes), with steps four and above still early in development or in the planning stages. Steps do not necessarily represent the final generation order via the algorithm:
• Build the Basic Floor Space / Wall Structure — define the floor layout of the room itself, where the player can walk.
• “Enhance” the Walls — make the walls feel more organic (less strictly grid-based), and make hallways feel more winding rather than straight and boring.
• Auto-tile the floors with a random assortment of basic tiles (later to be improved with overlaid decorative tiles).
• Make a “Critical Path” — a.k.a. the “planned” or intended primary pathway of the player through the room.• Create Fixed Barriers to block off portions of the room, which enforces portions of the critical path and adds exploration interest. These fixed barriers will include sub-walls, chains, pits, etc.
• Generate Soft Barriers and Obstacles, including switch-operated gates, bomb-able barricades, and traps, in order to add challenge.
• Add interest areas by placing breakable reward objects (such as crates, pots, treasure chests) and aesthetic or narrative objects (tables, chairs, statues) to complete the dungeon experience.
• And obviously, add enemies!
Notes about screenshots below:
All images use placeholder art to some degree, so floors may appear flat and un-textured. Please also know that the images below are completely generated by the game — we’ve edited the contrast and colors a little bit so it’s easier to see the important details, but the room sizes, shapes, etc. and the screenshots themselves are all directly from the game’s normal render mode. Many are simply zoomed out via our debug controls, but they are still in-game shots.
Creating Room Spaces
The first step in making this new system was to create a room entirely via code. This first picture shows room generation at its most basic: the game simply creates a grid, marks sections of that grid as “free” (in other words, “traversable” areas where the player can walk), and places walls around those areas to enclose them. The bronze-gold “pillar” placement and wall-tiling are also automatic:
Even this early on, the system was capable of making rooms several times larger and vastly more complex than any of our previous room shapes, which were tediously created/scripted by hand, and were often limited to simple geometric shapes like Tetris-pieces. Now we can procedurally generate a room thousands of tiles in size, in a fraction of a second:
The above image is an actual in-game render, just zoomed out to about 3%. If you look very closely on the left side of the image, you can see the tiny pink speck. This is your character, the Rogue, which was rendered at a size of a 4 pixel square due to the zoom level.
What you’re seeing is not even a “level” made of multiple rooms — it is a single room.
This means our possibilities have increased by several orders of magnitude. But with great procedural power comes great developer responsibility — we will be restricting such generation to ensure that the game is interesting and goal-driven, rather than completely rambling, exploratory, and uninteresting. In other words, we are still generally aiming for a tightly-designed Link to the Past feel, rather than a Skyrim-esque sprawl.
The next step was to make the room layouts more unique, and less strictly grid-based. So the original basic grid upon which the room is generated is “enhanced,” by choosing spaces where the walls are pushed inward or outward to create more variety. This can create rooms that feel architecturally geometric (grid-based), organic (more random / cave-like), claustrophobic, or exposed. The rate at which walls are altered is easily modifiable via our CSV data (modders ahoy!), meaning each zone can have a slightly different feel to its “architecture”. An example room, where the walls were pulled in or pushed out as often as possible (maximum “organic” feel), is shown below:
The third step in the new room generation system is tiling the floor. In the old system, all of the tiles had to be placed by hand. But now that the rooms are procedural, it means that the floors have to be generated as well. So based on our previous tilesets, we created a modified system, featuring several different sizes of totally randomizable tiles. This random flooring will be the “base layer” of the visual tiles (like a concrete or wood sub-floor), upon which other decorative tiles will later be dynamically placed. There are mini tiles, wide tiles, tall tiles, and double-sized tiles for visual variety — and the game can mirror and rotate them to make them look even more natural and non-repetitive.
The examples below (using an obviously placeholder floor texture with letters), shows how some zones can have very gridded tiles:
...and others can have a random assortment of different sizes and shapes, with maximum randomization of mirroring / rotation:
You may notice that currently some tiles are repeating near themselves, but we are working to ensure sure that the same tile is never repeated in immediate proximity.
Developing the Critical Path
So now the room layouts, walls, and floors have the maximum amount of variety and flexibility that we can create, within our given perspective and the constraints of our grid-based world. However, a well-designed room or level requires much more than that. Instead of randomly creating a room by just opening up chunks of floor here and there and putting walls around them, the generation algorithm needs to create a directed experience. Fundamentally, we need to generate a particular path with a beginning and an end, and interesting events along the way.
This is where we began our most recent step — generating the “Critical Path,” or the intended minimum pathway through the room.
NOTE: Those savvy in game design are probably asking “why is this step last? Shouldn’t the critical path be most important?” And you would be right! This step will actually occur first in the final algorithm — we just happened to work on this system most recently.
Our Critical Path is not necessarily the 100% most efficient beeline from beginning point to endpoint — but rather a diverse “gameplay path” that requires the player to complete certain objectives in order. Those objectives might include walking from point A to point B, flipping a switch at point C and then back-tracking to B (or looping back to A) in order to proceed to D. It allows us to procedurally create challenges that must be passed in a certain order, as well as creating detours that are necessary for the completion of a room (or level).
So for example, the system we are working toward will be able to create a room where the Drop Portal (the exit down to the next level) is generated behind a locked gate. The player can’t go through this gate without first flipping a switch elsewhere in the room — and importantly, this switch must somewhere along the critical path before the locked gate. (Otherwise the player will get stuck).
This piece of the code is still very early in the making, but the following screenshot shows a debug view of the world, with a (rather complex but linear) critical path highlighted in blue:
Note that this room is 1) currently only generated immediately around the critical path, with no extra space or off-shoots, and 2) has not been “enhanced” with more random walls. These features will be grafted into the Critical Path system as it is finished. The algorithm will also need to erect barriers within the room in order to prevent the player from taking shortcuts. And as always, the length of the path, degree of path complexity (twists and turns), and the number of straights versus diagonals will all tweakable on a level-by-level and room-type basis, and able to be modded. This gives our designers/scripters the ability to create lots of variety, and avoid both overly-complex and overly-simple structures… as well as increase complexity as the player progresses.
That’s all for our End-of-July Update! We hope that you’re as excited about the recent progress as we are. It’s difficult to express, but we’re sure most of you understand how huge of a leap these improvements are, compared to the previous versions of the game. We now have a truly randomized room structure, which further allows levels to be even more interesting and challenging.
Please let us know what you think! We know that many of you are awaiting a new build, but please know that when it comes, all of the above features will be there — and Delver’s Drop will have gone from a game with limited variety (as in the previous builds), to a game with huge amounts of replay.
Thanks as always for sticking with us!