Logan Foster developer of WaveLand is working hard on his latest game, Seals of the Bygone. He has put together the following blog on how he is handling random level generation and he wants to share it with the GameMaker Community.
Diversity in experience is one of the pillars of Rogue-lite games. Having every playthrough exist in a unique environment is an exciting proposition, but algorithmically generated levels pose a lot of challenge for the platformer perspective. The commonly used middle ground is stitching together levels from premade sections. Here’s how I used GameMaker's layer system for quick and easy level randomization in Seals of the Bygone.
In essence, we’re going to build our levels in different “sections”. Each “section” contains “subsections” which contain our assets! By dynamically toggling subsections “on” and “off” with code, we can randomize our levels.
Instead of storing level sections in code or outside resources we store them in layers and build them using the room editor, just like any other level. This was the primary reason I created this system. I wanted to keep my existing design process, which was based in the room editor.
Step 1: Create Parent Sections
To start we’re going to want to create blank asset layers for each major division. There is no limit to how many sections you can have so get creative! This level has three, named “
Section2”, and “
Section3”. These asset layers essentially act as a folder for easy organization that can also be referenced in code.
Step 2: Create Subsections
Now as a child to these asset layers we want to create additional blank asset layers. These layers will hold the tiles and objects that make up our level! Here I’ve gone with the naming scheme of “
Step 3: Parent Layers to the Subsections
Lastly, we parent our tile, asset, and object layers that make up our level to those subsections (making sure to follow our naming scheme!). As you can see above, subsection “
Sub2_1” is open and layers like “
Collision2_1” and “
Tiles2_1” are present. These are the layers where you build your level.
It’s worth noting you don’t have to build levels in rigid divisions like this. You could even have a section that has some blank subsections making it only spawns sometimes!
Now that you’re done setting everything up, you can toggle visibility on the parent groups to easily see what different combinations of subsections would look like! I recommend using the handy lock feature once you’re done designing a subsection to make sure you don't accidentally edit it.
So now that we’ve built our level in sections and have them sorted into different layers, let's randomize which layers get chosen when the level starts! I have the following code in the Room Start event if the level is to be randomized.
First, we define the prefix we’re using for our sections and subsections. We’re going to find our layers using their names so make sure this is the same as what you used in the room editor. We then loop through looking to see how many different sections there are.
Now that we know how many sections there are we loop through each section and look to see how many subsections there are. Then we pick a random subsection to use.
After deciding what subsection to use we loop through and destroy all other subsections (within that section) so only the subsection we chose remains. Lastly, we clean up by setting the visibility of our layers just to make sure everything is correct. As you can see the layer names here are “hardcoded” so you’ll need to change them to whatever your sections contain. It is possible to do this dynamically but it wasn’t necessary here.
And that’s it! A very simple solution for adding a bit of randomization to your levels. I found that even this simple system made the game feel a lot more dynamic. I wonder what other games could benefit from a bit of randomness? If you wanted to make something a little more powerful, you could expand upon this system by using
layer_y to move stuff around!
If you end up using this or have any questions feel free to get up with me @rologfos. Thanks for reading!