Procedural generation: a primer for game devs
This article is is a high level summary of what procedural generation (or procgen) is and how it works, using our game Rogue Singularity as an example of application and management.
What is procedural generation?
In general computing terms, procedural generation is any technique that creates data algorithmically as opposed to manually. It may also be called random generation, but this is an over-simplification: although procedural algorithms incorporate random numbers, they are never truly random, or at least not as random as that term implies.
This article is is a high level summary of what procedural generation (or procgen) is and how it works, using our game Rogue Singularity as an example of application and management. It is suitable reading for a beginner programmer, though creating your own procedurally generated content will require intermediate coding skills.
Procgen can be used by game developers in a number of ways. For graphics, it can be used to automate the creation of textures and 3D models, instead of having to draw or build everything by hand. There are some amazing tools that artists can use to create procedural art, like Substance Designer for textures or Houdini for 3D models. Currently, procgen in video games is most commonly used for level generation, to automatically create large amounts of content in a game. Rogue Singularity is a great example of using procgen for level generation, and other popular examples include Spelunky and The Binding of Isaac.
An example level being generated for Zone 4 in Rogue Singularity
Rogue Singularity uses procgen to create all of its levels. Greatly simplified, our system takes these steps to generate a level:
Our code generates a spline through 3D space that forms the basic shape of the level. Depending on the difficulty level and thematic feel we want it to have, this spline shape could be a simple straight line, a snake-like shape that weaves left and right as the level progresses, or even an upward spiral.
An offshoot spline is then generated that branches out of the main spline; this forms a dead end that will ultimately hold a bonus such as a life, an unlockable, or a large cache of coins.
Randomly selected blocks of level architecture are then placed in chains along these splines, from a level start block at the player spawn point, to a level end block at the far end of the spline. Each base level block has a number of connecting points defined by our level designer that constrain where, and how each level block can be joined to others along the spline.
With a rough level now populated with base level blocks, the algorithm does another pass over the entire level, placing obstacles and enemies at a sub-selection of predetermined obstacle locations. Like the connection points, potential obstacle locations are defined on each block by our level designer.
Finally, collectables are generated along the level and the player is spawned, ready to play.
Some example levels being generated with straight splines
Rogue Singularity’s main campaign is made up of five different zones, with around three levels each. Each zone has a different set of possible spline shapes, base level pieces, and obstacles, giving each of them a distinct character. When starting the generation of a level, a random subset of the possible base level pieces and obstacles is made available to be used in the current level. This then gives each level in the zone its own unique feel, which isn’t possible if you give the generator complete freedom all the time.
If you are considering a similar system, we suggest difficulty weightings for each base level piece and obstacle. We also make sure our procgen system supports different possible placements and rotations, as well as diverse colouring themes. These simple constraints give the Rogue Singularity level system huge variation while also allowing each zone to feel cohesive and distinct.
Some example levels being generated with slightly curved splines
The Rogue Singularity procgen structure outlined above has evolved over the past few years of development in a number of steps. The first iteration was created for a previous game called Postman’s Odyssey that has been shelved for now. Postman’s Odyssey used procgen for parts of level design at the level build time, rather than runtime.
We created giant towers out of modular blocks that would all fit together on a proscribed strict grid. During the level design process, we would continually generate procedural towers until we found one we liked. We would then use this as a base and tweak it by hand. This was a great time-saver for our level designer, but we ultimately decided that the project was too large in scope and the towers were too enclosed to make vertical climbing easy and fun. Even so, we learned a great deal and brought all of those lessons forward to Rogue Singularity.
A screenshot of Postman’s Odyssey, showing the procedurally generated buildings
When starting work on Rogue Singularity we knew we wanted to use procgen at runtime rather than build time, and we wanted to focus more on open horizontal platforming instead of the cramped vertical platforming of Postman’s Odyssey. Our first iteration of the Rogue Singularity algorithm was on a very strict grid again, and the underlying spline varied a huge amount. This was good as a starting point, but wasn’t very interesting and levels were not particularly distinguishable from each other. It took us a few more iterations of the algorithm and the art style before we arrived at what we have today.
A screenshot from an early version of Rogue Singularity
A screenshot of the same zone from the current Early Access version of Rogue Singularity
The many applications of procedural generation
Procgen is an incredibly powerful tool, and when it is implemented well on an appropriate project it can significantly improve a game and extend its lifespan by greatly increasing its replayability. This is the most obvious way that procgen can improve your game, as it can facilitate near-infinite ways to generate content for players. Procedural content can help to retain player engagement for much longer, since they aren’t being made to replay exactly the same content over and over again. Just look at the longevity of Spelunky and some other titles that use procedural level generation effectively.
Level generation is probably the first thing that game developers think of when they hear the words “procedural generation”, but it’s important to remember that the sheer amount of work involved in making a procgen level system do what you want may be greater than building levels by hand. Developers considering procgen for the first time should consider starting with smaller systems to build up their skill set. The procedural gun generation system in the Borderlands series is a great example of an effective small-scale application, with the unlimited variety keeping players coming back to find the next best gun. This enhanced the replayability of Borderlands despite it having only hand-made levels.
Even if a developer has no plans to include procgen elements in a shipped game, it can be an extremely useful tool during the design stage. Tools to create procedural trees, houses, or roads for example can be relatively easy to create or buy, and can drastically speed up your workflow in the long term if a game’s design calls for a lot of similar but unique elements. Other tools, like the great Bfxr for sound effects, can be used to create quick prototype or placeholder assets so that you can quickly test out ideas and see if you want to continue with them. You should always be looking for, or creating tools that speed up the development time of your current project—efficiency and effectiveness are vital, and time is always precious.
In saying all this, I want to emphasize that procgen is not a silver bullet. It is very tempting to think things like “If I procedurally generate my levels, I won’t need a level designer!” but that is a dangerous road to go down. Procedural level generation still requires a designer to fine tune the constraints and parameters of game level building blocks, and a great deal of the workload traditionally placed on a level designer will instead be shifted to a programmer.
It may or may not save your team time in the long term to use procgen, as there will be trade-offs and unforeseen complications. Learning more about how procgen works (reading this article is a good start!) allows developers to make an informed decision as to whether it will work for any given project.
Evaluating whether procedural generation is right for your game
When thinking about whether you want to use procedural level generation in your game, there are a number of considerations that you need to account for. For example, is your game focused heavily on the gameplay or on story? Are you building an atmosphere, or do you want to give the player a very specific experience? If the latter, hand crafted levels might be the better route. Also, as touched on above, consider whether your players will want to play through your game multiple times, or if just one playthrough is what you are aiming for.
When considering using another form of procgen other than level generation, the main things to consider are your team's experience with procgen and how programmer-heavy your team is. Will procgen speed up your development time, or add something to your game that players actually want? Unless your project is purely a learning exercise, always have a reason for adding procgen to your game; don't add it as a buzzword for increasing sales!
There are downsides to using procedural level generation that need to be thought about and planned around as well. When first starting out, your procedural levels will probably feel very samey and it will take a lot of work and some creative thinking to refine your systems to counteract that. Also, tweaking the generation values during level design can be an annoying process because you don’t get immediate, direct visual feedback like you do when designing a level manually. You will often have to tweak values, then start the game to see what gets generated, decide if you like the result, then go back and adjust. This can be quite time-consuming.
Another potential problem is creating a good difficulty curve. Completely random levels placed back-to-back will have a difficulty curve that jumps all over the place, which obviously isn’t a good player experience. The methods for combating this issue will depend on your game, and will require some careful thinking.
Finally, procedural levels can be hard to test—when you have a near-infinite number of possible levels, quality assurance is guaranteed to be challenging! You’ll need the basics of a seed system that you can use to input a seed and get back the exact same level each time so that when you see a bug you can save the seed, try to fix the bug, then play the same seed again to see if it is fixed. Of course, then you will have to work out if you fixed the problem globally rather than simply preventing it from showing up on this particular seed.
The easiest part of the procgen in Rogue Singularity was getting the basic algorithm up and running with a spline and simple cubes as the base level pieces. This first iteration where everything was in a grid had very simple logic to program, so I was able to get visual feedback from my work very quickly, which always makes the work more rewarding. Once we moved to base level pieces that could be any shape or size, things got immediately more difficult and complicated!
The hardest element, which is always a problem to try and overcome with procgen, was creating levels that feel unique instead of samey. We’ve had to implement a number of features in our algorithms to try overcome this problem. A procedurally generated level can reach a really high quality bar, equal to the best in hand-crafted level design, but it requires careful risk management.
A level generation bug in Rogue Singularity
Setting yourself up for success when implementing procedural generation
Give yourselves plenty of time to get it right. Setting up procgen is not a shortcut for getting rid of the time you would usually spend on level design and creation. You save time in some places, but need to spend a lot of time in others, so make sure to take that into account.
Test with other people often, ideally both developers and non-developers. What feels samey for you might not for them, and vice versa. If something is not working or is too complicated for either the development team or the players, don't be afraid to completely rework your algorithms.
Some great examples of procedural generation in games
Three of my favourite examples of procgen in other games are Spelunky, Spore, and the two Left 4 Dead games.
The level generation in Spelunky is so well designed and implemented that it still keeps a large number of players coming back, eight years after release. Derek Yu, the creator of Spelunky, has even written a book about the game’s design that goes into depth about how its level generation works, and I would highly recommend it to anyone interested in procgen.
The creature creator in Spore is very impressive technology, and a great use of procgen. It allows players to create truly weird and strange creatures, and then uses procedural animation to bring them to life in a natural way. The rest of the game might not have lived up to expectations, but many gamers played with the creature creator for hours, and some still do to this day, pushing it to its limits.
The AI Director in the Left 4 Dead games is a very smart use of procgen. The AI Director is in charge of placing enemies and player loot and recombines what, where, and how much of each should be placed in each level. The result varies the gameplay between play sessions, and mixes things up depending on how well the players are doing at any given time. As Michael Booth of Valve says in the above linked presentation, “static placement of enemies and loot hinders replayability” and by moving to procedural placement of enemies and loot, the “game session is viewed as a skill challenge instead of a memorization exercise