Generating a Level
I've been working on a jumper game in which players run along a strip of land, dodging obstacles like water pits and spinning blades and avoiding traps such as flipping spike panels. So far all of the maps the player has seen has been hand crafted by me and our producer, doing our best to make levels feel interesting and challenging. The problem with this method is it takes a good while to create, test, modify, and input all of these levels, so a level generation system seems like a logical next step.
Generating a landscape, albeit a thin one for our game, is always a daunting task. You can’t just randomize all of your options or it would look like madness haphazardly crammed together. You do need a little madness though, that’s the point of generation. Something that is predictable enough, but still presents you with fun, new, and interesting layouts. So I will be walking through how I handled my first pass at world generation.
First and foremost I started with the basics: water and grass. I generate each row at a time of 7 bricks wide randomly. This produced what I said before, just a crazy madness of water chunks and grass that the player couldn’t progress through. To fix this, I added a “fixer” function to each row. It looks at the row that spawned before it and matches up the water and grass blocks, also creating pathways the player needs if none existed. This made a nice flat land with pools here and there. There was more complexity to how I fixed the land, but that’s the basics of it.
Now I wanted to clean up some of the awkward shaped lakes and pave way for rivers. There are logs in the game that flow down streams, but for that to work, I needed to generate stretches of water that go across the whole row. I told the game to increase the chance of spawning water bricks until a river is made, and then tone it down for a little so there’s a chunk of land after it. This made crossing rivers at regular intervals.
Next was obstacles the player has to face. Again, randomly throwing them into the world would look sloppy. So what I did is made a list of each possible trap and gave each one a spawning chance between 0 and 32. I chose this, because if it randomly chooses over 20, I tell it not to spawn at all. This makes it so the level can possibly have every kind of trap, or only a few kinds.
I then spawn the traps on a case by case basis. Guns should spawn on the edge of a row, flipper spikes only spawn on ground, spinner blades spawn symmetrically to each other and enemies spawn wherever. Each time it spawns a trap, it decides how soon the next trap should spawn, and each trap changes this value. For example, flippers and guns are less of a hassle than spinners and enemies, so if I spawn one of those, there’s a chance another trap could spawn directly next to it. Enemies have the largest wait time, making sure they are spaced out at least 4 units per baddie.
I turn down the chance of spawning a particular trap after it’s used, and then turn it up when another type is spawned. To make sure the game doesn’t favor which it chooses first, I made a list of all available traps to spawn and randomly picked from it, not factoring in it’s spawn chance. Then it uses the spawn chance for what it handles next. I do the same thing with everything else I spawn: I create a chance of it spawning and then modify it after it spawns. I even have a random chance to increase or decrease that chance afterwards, so maybe there will be 5 guns in a row, or a clean slate of air with 2 traps in it.
There's still plenty more to be worked on here and it’s far from perfect, but for a start, it’s a good baseline. The player always has a chance to beat the level and get by the traps. It’s really interesting seeing what combinations can pop out or what ways it can generate a chunk of land. The important thing to keep in mind is to always give everything a chance. Don’t just favor one brick over another all the time. Give each one their own spot to shine in and don’t overload the player with objects; make sure there is a fair amount of open space for them to breathe in.
it will be awhile before the procedurally generated maps feel as good as the human designed ones but I hope to share our progress with anyone that’s interested. Our team loves to to get feedback and make improvements to the game then post a build online. Follow my game and let us know what you think.