How a Programmer Tried to Design Levels for a Game
An article about a Level Design process that we went through during the development of our game in Unity engine and the mistakes that we made.
Our team consists of four developers, one graphic designer and one musician. Unfortunately, none of us had any experience with level design so we had to pick one of the developers (me) to take the job of a level designer. This article covers all the ideas that we came with to maintain difficulty progression in the levels.
Before we start, I have to say a little bit about our game, because some of the points that are written later in the article might be very specific to the type of the game that we work on. Our game is a 2D maze-like game for mobile devices with a focus on fast level walkthrough. The levels are pretty short, it usually takes about 15 to 30 seconds to complete a single level once the player master the way through the level. There is no narrative in the game. The core of the gameplay is its unique controls and the way that player moves through the level. So to teach players the controls and the movement that the players have probably never seen before is one of the biggest challenges that we face.
Step 1 — Progression Structure Definition
As a programmer, I always want to have some kind of structure in anything that I work on. So as a level designer I immediately started to look for answers to questions like :
- How to define player’s skill progression in the game?
- What is the optimal learning curve?
- How to teach the player the gaming mechanics?
- How to ensure that the player keeps improving his skills in certain mechanics?
- etc.
I was looking for a “framework” or a “method” to put everything that I need to do in the levels on a “paper”, then give it some structure and later follow the structure to place walls, obstacles, monsters, collectibles etc in the level scenes.
One of my colleagues told me about a framework that is mainly used for narrative development. The framework is called Kishōtenketsu. I will not cover the details of the process here, but after spending a few hours trying to define my levels using Kishōtenketsu I decided to continue with its principles.
So I finally had the framework chosen, so I could start with the level definition.
Step 2 — Define Core Game Mechanics and Features
Please keep in mind that this has nothing to do with the actual graphic design of your game. The Step2 and Step3 can be done completely independently of your graphic design.
In this step, I tried to put together the complete list of all game mechanics and features that we implemented or that were supposed to be implemented later. The list included things like:
- Movement
- Speed changes — Time goals
- Collectibles
- Moving obstacles
- etc.
I put all these game mechanics and features into a spreadsheet document, so I could work with it later. In this step it looked like this:
The other columns of the table are prepared for later stages.
Step 3 — Identify Skills or Split Complex Mechanics Into Smaller Features
The goal of this step is to split everything into smaller portions that can be introduced to the player gradually.
With all the core game mechanics defined, my next step was to define “skills” that we need to develop in players to master a certain game mechanic. For example, considering the most basic one of them called “Movement”, I defined the following skillset:
- Basic controls — Player is able to move
- Ability to avoid obstacles that are placed in the middle of the player’s path
- Ability to avoid obstacles that are placed on top/bottom of the map — This might sound strange, but our game does not allow the player to move freely. The player is limited to move in certain directions and with a limited ability to change it, so placing obstacles outside of the middle part of the map makes it harder to avoid the obstacles.
- Precision — The game often requires that the player is able to navigate through narrow aisles or through sections that are full of small obstacles.
- Quick reactions — Sometimes the player is forced to quickly change the movement direction even multiple times in a row.
Sometimes instead of defining the skills, I ended up with a list of smaller and simpler features that certain mechanics/features can be split into. This ensures that the player is not overwhelmed with complex features, but the features are introduced step by step and give the player a chance to improve his skills gradually. For example, considering the “Moving obstacles”, I created a list of features that I wanted to introduce to the player:
- Verticle moving obstacle — The obstacle movement doest not cover the full map height
- Horizontal moving obstacle
- Obstacles moving in any angle
- Verticle obstacle that can move through entire map height
- Rotating obstacles
- Combination of multiple moving obstacles — max 2
- Combination of multiple moving obstacles — max 4
- Combination of multiple moving obstacles — more than 4
Similarly to all the points mentioned above, I split everything that was defined in the second step. Some of the points might have only one skill/feature needed others can have even 10 depending on the complexity.
I ended up with a table that looked like this:
Step 4 — Difficulty Definition
Ok, so after the third step I knew all the features that I needed to introduce to the players during the campaign, but the question was what should be the order of these features to ensure that the players are gradually improving. To be able to do this, I came up with an idea to define the difficulty of each feature on a scale from 1 to 6 with 6 being the most difficult one. The scale range can be anything you need. I choose 1–6 just because it perfectly fits my needs.
To be able to define the difficulty level you either have to:
- Choose it yourself in case it is obvious — Some of them might be dependent on each other. For example, you can not teach the players how to sprint before you teach them how to walk
- Create some test levels and let other players to give you difficulty feedback. Something that might seem pretty easy for you as a developer of the game might actually be very difficult for a new player.
In our case, I used both steps. First, I tried to define the difficulty myself and then I created sample levels (about 10) and sent it to some friends to give me feedback on the difficulty of the levels. Based on the feedback, I found out that some of the features are more difficult than I expected. The collection of the feedback was done using a simple Google form and questionnaire.
My table with the difficulties filled in looked like this:
Step 5 — Kishōtenketsu stages
In this step, I wanted to link each skill/subfeature to the Kishōtenketsu principles.
The Kishōtenketsu principles define 4 stages of each core game mechanic/feature. The stages are:
- Introduction
- Development
- Twist
- Conclusion
If you want to learn more details about each stage follow this link.
The idea here is that these stages are very similar to the difficulty levels that I had defined in the previous step. The only difference is that we only have four stages instead of 6 difficulty levels, but that just means that each stage can contain more features of different difficulty levels.
Here is an example of how I defined the stages for the basic Movement including my notes on how it should be implemented in the levels.
Introduction
Contains following skills/subfeatures:
- Basic controls — Of course our game has a tutorial level that shows the players how to control the game, but this is something different, I need the players to play around a little bit and try the controls in an actual level. In the first level, I wanted to create a section, that has no obstacles, no collectibles, nothing. Just a clear section of the level where the players can try the controls to understand the sensitivity, to understand the ranges how the players can change the directions, etc. This does not mean that the entire level should be like this. I think it is a good idea to mix the Introduction with the Development stage so it will not be a boring level.
Development
Contains following skills/subfeatures:
- Avoid Obstacles in the middle of the path — In our game, obstacles that are placed vertically in the middle of the level are the easiest ones to avoid. The reason is that the players can slow down and choose which way to avoid the obstacles. So my idea was to place obstacles of different sizes in the middle of the level with the gap between each large enough so the players can focus on the single obstacle and can not get distracted by the next obstacle.
- Avoid Obstacles placed anywhere in the level — With this one, I wanted to introduce it the same way as the ones in the middle except that this one is a little more difficult for the player, so I decided to introduce these in later levels.
Twist
Contains following skills/subfeatures:
- Quick Reactions — Based on the Kishōtenketsu principles I wanted this to be something unexpected, something that the player is not used to from the previous levels. So in the previous levels, the players learned how to avoid obstacles of different sizes placed in any random position, but the players still had enough time to consider their movement and choose the right path. So in this stage, I wanted to put the players under some stress. Every time the players choose a certain way to avoid an obstacle, there is always another obstacle in their new direction that they need to quickly avoid.
Conclusion
Contains following skills/subfeatures:
- Precision — This phase just sums it all up. I wanted the players to prove that they can master the controls with a very precise navigation through narrow aisles combining everything the players learned in the previous levels. This is supposed to be very difficult.
Following the same principles mentioned above, I was able to link together all my features and game mechanics with the stages of Kishōtenketsu. And because I had already created some notes describing how I wanted to implement it in the levels, I was ready to start defining the levels.
Step 6 — Levels Metadata Definition
Before starting to put some game objects into actual game scenes I wanted to first define all metadata describing the levels. This metadata table can be used as a “guideline” for other level designers when creating levels. The benefit of this is that more people can work on different levels without breaking the defined progression. You can even work on the levels in any particular order without being worried that you could create something that would not fit into the entire game.
While defining the levels I followed these simple rules (the rules are probably specific for our type of game):
- Introduce only one new mechanic/feature in a single level — the reason is that our levels are 15 to 30 seconds long so I had a very limited space to introduce the new feature without overwhelming or distracting the player. I wanted the player to be able to focus on the new stuff.
- Keep Twist stages alone in the level without any other Twist or Conclusion — I only combined Twist stages with Development stages of another feature.
- Keep Conclusion stages alone in the level without any other Twist or Conclusion — I only combined Conclusions stages with Development stages of another feature.
- Don’t wait for Conclusion before introducing new Features — I wanted to keep the players motivated to play the game and continue with the campaign by introducing new features. Sometimes it can take several levels to get to a conclusion phase of a certain feature, so it could get a little boring for the players without showing them more features of the game.
Applying these rules I created a metadata table that looked like this:
There are a few things to discuss in the table:
- I had much more columns in the table than you can see in the screenshot. For example: collectibles count, more details about the placement of obstacles, etc.
- Some of the Development stages (Movement — Obstacles everywhere) are listed multiple times — This is something that I did wrong in the first iteration of the levels which will be discussed later in the article. Basically, because our levels are so short, it is sometimes impossible for the players to actually develop the skill in a single level, so they could not improve the skill enough and they got stuck in the next levels.
Step 7 — Definition of Chapters/Episodes
Our graphic designer came with an idea that the game should be utilizing four different visual styles in the levels, so we decided to split the large chunk of levels into chapters with different visual styles. We split it all equally with every chapter having the same number of levels (this was the initial idea although it ended up that the last chapter contains fewer levels).
In our game, the players can reach up to 3 points in each level. The first point is for reaching the end of the level, the second one for completing the level in a certain time and the third one for collecting all collectibles in the level.
The question was, how the players should unlock the new chapters. Honestly, I really had no idea so I decided to download a few successful games of the same genre and follow the same pattern.
I didn’t want to be so strict to force the players to reach as many points in the level as possible. My goal was to give an opportunity even for average players to unlock all four chapters without completing final levels in each chapter. This ensures that most of the players can at least see the entire game with all its features and graphics. Fortunately, I found out that the most common practice is to unlock new content by reaching half of the maximum points yet available, which exactly fit my needs.
Except for the fresh design I decided to use every new chapter as an introduction to a new gaming mechanic. I choose gaming mechanics that drastically change the gameplay and introduced these in every new chapter. This practice helps to keep the players playing the game by gradually introducing new content and giving them more possibilities in the game.
Step 8 — Levels Creation #1
With all the metadata defined I was ready to start creating the first set of the levels to validate the metadata table. But before creating a full list of the levels (I had 24 levels defined), I created only half of the levels for the testing purpose to validate the whole process and levels definition before spending much more time on creating a full set of the levels.
In this step, I still worked only with “placeholder” graphical assets. The assets had the right shape or very similar shape, but had basically no detail. The reason is that during the next steps we wanted to test the difficulty progression during the campaign which is mostly independent of the graphic design. And honestly, we didn’t have the assets ready yet so I wanted to save some time of our graphic designer so he could focus on finishing the designs.
This is an example of the low detail assets that we used for an obstacle:
Setting the time goal
Every level in our game has a time goal. The players have to finish the level in a certain time to complete the goal.
I set the time goal based on the best possible time that I could reach. Anyway, I knew I would have to update the times based on the results of the testing.
One of my colleagues even tried to develop an artificial intelligence that could play the game trying to reach the best possible time. It worked somehow, but the times the AI could reach were much worse than mine so we decided to play this simple and use my times.
Colliders
In the first iterations of the levels, my colliders were exactly the same size as the graphical assets. The result was, that sometimes the detected collisions were too precise especially in case the players were just passing by the obstacle and “touched” the surface. It was rather annoying even though the detected collision was absolutely correct. Based on that, I decided to make all obstacles a little more “forgiving” by making the colliders smaller than the actual asset size. The result is that the game is less frustrating and it gives the players a much better feeling from closely passing by obstacles.
Step 9 — Internal Testing
This is very important even though it can be misleading. The reason why this testing can be misleading is that members of our team had already played the game before so they were familiar with the controls and the gaming mechanics. You can not test the progression in first levels with your internal team.
But the reason why I included this internal testing was to avoid any obvious bugs in the levels like :
- Incorrectly placed colliders
- Too difficult sections even for our internal team
- Misleading level sections
- Time goals set incorrectly
Step 10 — Evaluation of the Testing
Except for some bugs, we found one mistake in the level design that we decided to change. It was the length of the levels.
The length was defined by the width of the level (the players constantly move forward and only the speed of the movement can be changed). Basically, the more complex the level is, the more time it takes to finish the level even though the length of the level is the same as other levels. Our game is a simple arcade game and our goal is to allow the players to play the game anytime they have some spare time and that means we need short levels. We wanted the levels to take 30 seconds max so we decided to shorten the complex levels.
Step 11 — Iteration
This step is very simple. We just fixed all the bugs and re-implemented the findings from the testing. After fixing everything we went back to Step 7 and repeated the testing and evaluation until we were ready to send the game to the first set of testers.
Step 12 — Friends and Family Testing
Our friends and family testing followed the same pattern of testing->evaluation->iteration multiple times. I will not go into the details of each step, I just want to discuss the mistakes we wade and the tools we used. During the iterations, we were improving the graphics of the game and adding more levels to keep the testers interested.
Based on our first testing done in Step 4, I knew that the way we want to collect the data from players has to be something more robust than just a simple Google form. The reasons are:
- Most of the testers will not have time to fill the form completely
- Most of the testers will play the entire game and later they will try to fill the form, but they will already forget the detail about the skill progression and what difficulties they had so the collected data will be inaccurate
- The more levels you have the less likely it is that someone will fill it all
So based on that, we decided to collect as much data as possible without any user interaction. We still kept the Google form, but only with a single field for general feedback in case anyone would like to fill it. We also invited the testers to our Discord so we could discuss the issues directly.
The data we decided to collect in the background were :
- How many times a player run a certain level
- How many tries it took to finish the level for the first time
- How many tries it took to finish each of the level goals
- What was the player’s best time
- Where the players die, the exact location of the death where they hit an obstacle
All the data were sent to our server for further analysis.
Here are some examples of the charts that we were able to create with such data.
This chart gave us feedback on the difficulty of each goal and the progression. You can clearly see that only half of the players were able to make it to the final levels, which is something we wanted to change. For example, the difficulty of the level L08 is strange. All players were able to complete the level, almost all of them also completed the Collectible goal, but very few testers could complete the time goal. This had to be changed.
This chart shows exactly how wrong I was with my levels. L06 was too easy compared to the surrounding levels. L09, L10, and L11 were too difficult and on the other hand, the final level is too easy compared to the previous ones. I knew I needed to change that, but I was not sure how and what was the issue until I moved to the next data analysis. The Death Heatmaps.
We implemented a Unity editor extensions that allowed us to display each death location in the scene in Unity. The results of the testing were amazing.
Using these heatmaps I was able to identify the most difficult parts of each level and fix these. Fixing the levels usually meant reducing the number of obstacles in a certain location or changing their placement so the player is less likely to turn incorrect way.
During the testing, we already started to implement more detailed graphics for the levels. It ended up that my initial assumption that the level difficulty is independent of the graphic design was incorrect. During the analysis of the heatmaps, I started to see a similar pattern.
The pattern is that players are more likely to hit the obstacle in the dark part of the obstacle. The reason is that the background of the level can be also dark in some parts of the level and that makes it almost impossible for the player to spot the edge of the obstacle. So we decided to make it a little brighter like this:
This was not the only thing related to the graphics that we needed to improve. Our game is based on speed, fast reactions, and precision. I found out that using visually complex assets, even though the outline shape is simple, it can distract the players and they are more likely to make a mistake. Based on that we decided to change the complexity of some assets, for example:
We also reduced the number of background assets to make it look visually more simple.
The last interesting finding from the heatmaps was that some testers tried to “cheat” the levels by trying to go through little gaps between two obstacles. Unfornutenetly, it took them many tries before realizing it is not possible because it was designed to stop them. This was clearly my mistake. It either has to be obvious to the players that this path is blocked, or they should be allowed to go through. Here is an example of such spot.
Certainly the death heatmaps helped us the most. If you are interested how we implemented the server-side and the Unity extension feel free to subscribe to any of our social media accounts at the bottom of the article, because my colleague will write an article about the implementation of the heatmaps soon.
One more thing that we wanted to get from the data was to identify the most active player and work with them closely in the later stages. We were able to do that easily from the data we collected.
One advice for this step. Try to put something challenging into the game, so the testers would play the game as much as possible just because they want to and not because you asked them to do so. In our case, we knew that some of the testers knew each other and we knew that they would love to challenge each other, so we implemented leaderboards in the game where they could see the best times of their friends and compete with them.
Things that we did wrong before and during the friends and family testing
- Not focusing on testing the graphics from the initial test and slow iteration of graphical improvements
- Inviting all the testers to the first iteration of the testing — The reason is that once you sent the game to the testers they learn how to play the game and they improve their skills, so when you need to iterate some of the first levels you will not get a relevant feedback from the testers because their skill is far beyond the skill level needed for the first levels. That means we needed to look for more new testers with every iteration.
- Collecting only the death location instead of the full walkthrough — Sometimes it took me a long time to figure out how the testers could die in a certain location.
- No proper user interface testing before the level design testing — For example, We had no in-game notification system implemented, so the testers were not notified in case they unlocked new content, thus some of the testers had not realized they had already unlocked more chapters. They did not play the newly unlocked levels just because they did not know about them.
- I was ignoring the warning signs that the levels might be too difficult — I knew this from the internal testing, but I was ignoring this because I thought that my team is not a relevant test group. It ended up that they were right and the levels were too difficult. It was so difficult that most of the testers were able to complete only 6 levels. Because of that failed first testing, we lost a lot of time and even some testers because they just did not want to play the game again.
- I thought that every defined skill/subfeature can be developed in a single level — this happened to be one of the biggest problems. Because of our short levels the player doesn’t have enough time and opportunities to improve his skills in certain topics. So after the first iteration of the testing, I was forced to completely re-do my levels metadata table to define much more levels. From 24 levels I ended up with 36 levels that still covered the same content just with more gradual progress.
Step 13 — Public Testing
This is the phase that is still ahead of us, but we are sure that it will follow the same structure as all the testings done before and hopefully we learned from our mistakes.
We are looking for open beta testers (iOS in the first iteration, Android later) so if you are interested in testing our game, please follow the links at the bottom of the article to subscribe to our social media or just send us a direct message. We would be more than happy to include you in the testers list.
Conclusion
Our current state of the levels is that we have 36 levels in which we try to introduce new gaming mechanics and gradually improve the skills of the players. These 36 levels are split into 3 chapters. The levels are challenging enough so the players probably don’t even realize that the whole campaign is one long tutorial. There is also the fourth chapter that currently contains only 6 levels that does not bring anything new to the game, the levels just make everything more difficult and challenging even for the best players, I think of this as a “boss fight”.
The testing we have done so far proves that we are moving the right direction, but unfortunately, I can not tell whether this is a good or the fastest way to design levels. It is kind of a time-consuming and very painful process. I would be more than happy for any ideas to improve our process.
We are Lonely Vertex, a small indie game studio located in Prague, Czech Republic. Currently getting ready to release our first game, Sine. You can subscribe for newsletter, read our development blog posts or follow our progress on Twitter, Instagram or Facebook.