Dev Talk #2 - Procedural Environments - Layout
We're very busy here at ChaosForge preparing for the upcoming Kickstarter! Expect to hear more details really soon, but in the meantime, we invite you to another Dev Talk. This time, we'll be discussing procedural environments.
ASCII TRIGGER WARNING!
At it's core, Jupiter Hell's procedural environments share a common root with AliensRL. When developing AliensRL, I ditched the screen-sized 78x19 levels of DoomRL, and wanted to go for levels that more believably would look like real world space bases. I quickly figured out that I will need to take a top-down approach, setting first the layout, then the rooms themselves.
I didn't obviously want to have premade levels, so some sort of procedural system needed to be implemented. I came with the idea of layouts -- ASCII receipts of the general layout of the level.
These layouts are stored along with a meta-code that handles their expansion into full-level sized fills. These then are passed towards further algorithms that handle the smaller elements -- rooms, corridors and the like. The process is composed of optional mirroring (on one or two axes), followed by expansion controlled by the meta-code.
The meta-code is composed of numbers and placeholder signs (0, or *, as you prefer) -- the numbers tell us by how much to expand the given row, while the placeholder shows us where variable expansion may take place. We can then expand the level as much as we want, by varying the placeholder expansion.
This in turn is followed by passing the resultant empty level to lower level algorithms that handle filling of the smaller rooms. Of course, to prevent repetitiveness a large amount of such layouts should be prepared, however, if the lower-level algorithm is good, a layout algorithm provides a very good substitute for just starting with a empty grid.
To provide a complete example, we'll fill the level with the simplest algorithm possible - with randomly picked "room-blocks" from a given set.
For this algorithm to give nice results, three things have to be taken into account:
- the passages between the blocks need to be in symmetrically fitting positions -- these are great positions to place doors. Depending on if you want to have mirroring or also rotations, the tiles should always fit together when rotated and/or mirrored.
- we make sure that we can overlap blocks with the edge rows
- the space to be filled must be of a proper size a*(x-1)+1 width (where a is the amount of tiles, x their width), and conversely b*(y-1)+1 height
Additionally, after placement, you can remove the dead end corridors, and doors leading nowhere.
The result could look something like this:
For anyone interested in this method, there's a more advanced version, called Herringbone Wang Tiles, with some nice documentation on the nothings.org site.
By using both algorithms together, we can create complex, yet structured levels:
Using layouts gives a much more ordered structure to your levels, which goes well with the idea of space bases, but might also work with castles, or any man-made structures. Layouts can also take care of reasonably placed inter-level connections (like elevators, or corridors to other sections).
To finish up, a zoomed out section of the graphical version:
Expect to hear from us soon, Kickstarter is coming!