Today I would like to write about a simple but very important game design concept that is to ensure there is always a way or path.
In arcade games, one of the challenges when generating random levels is to get the right difficulty without risking impossible situations (or “No-exit” situation). Let’s imagine the game is about a rocket that flies with a constant speed and needs to dodge circles that appear as he moves.
Ok, now that we have an idea about the amazing visuals of the game, these are our requirements:
- Random levels
- Difficulty progression with time
- The game must be fair so there must always be a path (no blockades where the player will die for sure)
Requirements 1. and 2. are easy to implement. In this case, for example, it would be enough to create new circles on a random Y at a right-offscreen position every X seconds. To make the difficulty progression, X would decrease with time. The problem with this approach is that as X gets smaller and the number of circles starts to get larger, the probabilities of a no-exit situation increase.
How to solve this problem? Well, there are different possible approaches depending on the complexity of the game and some design choices, I’ll show you 2, the “Workaround way” and the “Pregenerated Path” way:
The Workaround way
A classic trick to solve this problem is to change the problem itself. Predetermine some hardcoded safe values (frequency in the example) to generate obstacles that for sure will not cause a non-exit situation. This frequency will remain constant through the game. Now, to increase the difficulty, instead of increasing the frequency generating more and more obstacles, just progressively increase the rocket speed. This moves the challenge from geometry path-finding to reaction time.
The Pregenerated Path way
If the first way is not an option, we need to make sure when creating the obstacles that there will be a path. To do that we need 3 things.
- Generate a random path for the rocket. You don’t need to care about any obstacle, just make sure it moves randomly up and down as the rocket would do. We’ll call this the Safety Path.
- Define the size for a bounding box for the rocket that we’ll call Safety Area. Imagine the Safety Area follows the safety path. If you were playing the game you should be able to keep the rocket inside the Safety Area.
- Finally, when generating the obstacles, make sure they will not overlap the Safety Area on the future time T when the obstacle is at the same x position than the rocket. It may be necessary to make multiple checks (on an interval around T) depending on factors such as the width of the obstacles, Safety Path changes of direction, etc…
Here you can see a couple of examples to illustrate the way we’ve implemented it:
1. This level is about dodging bouncing circles
This one is about dodging shrinking circles
And a bit messier with rotating rectangles…
- Blue Rectangle is the Safety Area
- White dots on first screenshot and grey rectangles center point is the Safety Path
- Yellow shapes are the exact position and shape of the obstacles on T (plus extra checks)
- Light Blue circle is the main character
- Black shapes with white glow is the current position an shape of the obstacles
Even if it took some time to create the foundations for this checks, once done it allows us to add any amount and type of objects with randomly generated speed, shape, angular velocity, etc… to our levels without needing to worry about “no-exit” situations.