I write this post as I am sitting in hospital being administered my second cycle of chemotherapy, which means I’ll probably be quite fatigued over the next few weeks and you might not see as much progress.
But let’s get into the meat of today’s post; procedurally generating interesting levels.
I’m going to skip through a lot of the boring / tedious generation things since I forgot to take screenshots and it has all been covered before.
What you’re seeing is a prototype for the “canyon” levels / areas. The idea is to have the player progress through a bunch of procedurally generated environments which vary as you progress. You might start in a forest, then head to a derelict city, accidentally head into the sewers, and end up in the ruins of an ancient alien civilization or something.
This game is largely impromptu - everything I implement is either by request or whatever I feel like at the time, and I hope it ends up as something glorious. I’ve got notes and plans laying around, but nothing is concrete at this moment.
The first part of making a level is to… make the level. For the canyon, I wanted it to feel fairly open and organic, but also have some smaller paths and variation around edges. A forest would have a more open layout with lots of trees and things, and caves or dungeons would probably be a bit more twisted and enclosed - you get the idea.
In order to generate the level areas, I started out with a random walker, a really simple and quick approach to caves.
Whenever the walker gets trapped and can’t move anywhere, it teleports randomly to an area that hasn’t been dug out yet. It’s not ideal, the clusters aren’t necessarily connected, and the long tunnels on the side aren’t great for a top down game; too much walking for very little action.
I decided this wasn’t getting good results even with some tweaking. My next approach was to just create a bunch of randomly sized circles and try to connect the areas up at the end. Also a super quick way to generate a map . My hope was that it would result in some more open areas.
It’s a little bit messy due to the aliased circle edges, and not completely connected. Cellular-automa cleaned it somewhat, but some levels were definitely uglier than others:
I went back and forth for a while trying to discover any other quick methods of creating a nice “canyoney” area. Cellular-automa also helped a bit with the random walks, but ultimately they were still too scraggly.
Both of the methods had their own problems, but they were unique to the generation method I was using, so I combined them.
First, the level will generate some crazy paths with the random walk. I tuned the values so that it tries to slowly curve around, and avoids heading completely straight or turning too quickly. From here, I attempt to generate around 300 random circles of varying sizes in any spaces that haven’t been dug out. The only criteria for a circle to spawn is that the single tile in the center is still black, it doesn’t matter if it destroys too many other walls.
From here, I decided to place a bunch of POIs (points of interest). The idea is that eventually each of these will have a chance of being used to generate structures or enemy spawns, and also provide some quick path-ing if I connect them together and use something like djisktras to generate some nice paths.
They’re randomly placed in the level, but only if they have enough space around them, to avoid ugly clustering. In this time I also quickly coded a flood-fill to remove any floaty level bits and rogue circles which weren’t accessible.
Some density tweaks and you get an alright looking canyon. The difference between the pink and white POIs is that the pinks have enough space around them for structures, whereas the white ones are deemed too close to the wall.
From here I added in the cave walls and generate a really simple starting structure from which the player spawns. The cyan dots indicate that they’re hidden from the player spawn line-of-sight, I figure I can use this for some variation in spawn chances.
The hard to see blue dot in the bottom right is the “treasure” spawn. Each level is going to have an optional treasure spawn with extra difficult enemies and extra valuable loot, and it will usually be a bit more hidden from the player.
A few more changes and I’ve got the basic layout of the level planned, as well as plenty of nodes for enemies / structures / loot / rocks and whatever else you can imagine.
I’m yet to implement any enemies or loot, so those will have to wait. You might see some cool weapon designs coming soon though - I have plenty in store.
Hopefully this was somewhat helpful in explaining some of my process of generating levels. I guarantee that this code will be tweaked hundreds of times before you see a playable version, and hopefully it looks a little less sparse, but I’m quite happy with it for now.