Hello! My name is Anton, and I am a game designer and match3 level designer. I've been working on match3 games for over 15 years (am I considered a veteran yet? :)), participated in the creation of new games, and joined projects at various stages of their life cycle. I've accumulated a lot of experience and have some free time, so I want to start a series of articles where I will share useful information.
The first topic I'd like to cover is the use of automatic difficulty adjustment in match3 levels.
When we play cool (successful) match3 projects, we often encounter a situation where you can't pass a certain level for a long time — everyone remembers level 65 in Candy Crush, right? But after a few days, or sessions, for example, you spent 5 lives, closed the game, and came back the next day, the level is passed on the first try. Wow! How did that happen?!
You immediately start thinking and analyzing how other levels were passed. Is this not a pattern? And it seems there's something to it. Developers have come up with some algorithm that makes the game easier or harder, depending on certain conditions. Of course, we cannot claim that these algorithms definitely exist in any specific game, and I certainly won't claim how it worked in Candy Crush back then and now, but let's imagine that such algorithms exist and delve into them a bit.
There are many ways to change level difficulty, which can be divided into types — Unnoticeable to the player and Noticeable. Noticeable changes include altering the number of colors or even reducing the number of obstacles; you can even change the level topology. Thus, with each level launch, we would give the player a "different" level. Let's agree right away that this is bad, disrespectful to the player, and generally not our choice. But with unnoticeable methods, things are much more interesting:
- Changing the chance of a certain color dropping on a certain move
- Giving out pre-made combinations or auto-matching bonuses
- Using pre-calculated level generations by fixing the seed
It's important to note that each of these approaches can become noticeable in unskilled hands.
Changing the Chance of a Color Dropping
The generation of new tiles on the level uses drop chances for a specific color. For example, we have 3 colors on the level: blue 100%, yellow 100%, and red 50%. Thus, there will be approximately half as many red tiles as others. With these settings, an observant player might notice that there are fewer red tiles, but if we are working with 4 or even 5 colors, or changing the chance by 20–30%, the player will never notice this. Why reduce the drop of one or two colors? This is one of the most important tools for a level designer; this approach allows you to reduce the difficulty of the level, increase the number of bonuses collected, without fundamentally dropping the difficulty.
We've covered the theory of how we can use this for automatic difficulty adjustment. We can come up with an algorithm that will dynamically change the drop chance of one color, depending on the conditions. For example, if we have a hard level, the player has already spent 15 out of 25 moves, and the percentage of completed goals is less than half, we can change the drop chance for one color from 100 to 50, thereby increasing the probability of creating a bonus and winning the level. Yes, this does not guarantee the result; the impact will be minimal on some levels, but it increases our chances.
Giving Out Pre-made Combinations or Auto-matching Bonuses
With this, there seem to be the fewest questions. Under certain conditions, we can provide chips such that when they fall onto the field, they automatically form bonuses, or conversely, provide chips that only form a match of 3 chips. It sounds very simple and not complicated, but the result is not always predictable. In this case, we get more control over the situation and can come up with rules under which combinations should be generated and what bonuses will result.
Both of these approaches have significant drawbacks: no guarantee of the result, and they are difficult to configure. Each of these approaches does not guarantee the result. We can give the player bonuses, create automatic matches, but the impact will vary on each level, and we simply increase or decrease the chance of winning or losing. Furthermore, the impact will be unique for each level (the state of the level at the moment the algorithm started to interfere).
Okay, we've come up with some system of automatic assistance for the player. How do we now evaluate its results? The only way is to conduct an A/B test. We divided players into groups and look at our key metrics: ARPU, revenue, churn. If it got better — you are great, nothing changed? Think and adjust further. Or move on to other algorithms.
Generating Chips Using Seeds
The principle of operation is very simple. We take a number (this is our seed), and based on it, we generate the initial chips on the level and all the chips that will appear on the level. Thus, if we restart the level and make the same moves, the result will always be the same. It's important to note: if your team didn't plan for determinism in the project's code architecture beforehand, I have bad news for you.
Okay, we've taught our game to work with seeds. How do we now achieve the desired difficulty? You need an algorithm (bot) that will play your level. There are several options here:
- Calculate all possible moves on the selected level and count how many solutions lead to a win and how many to a loss — you will get the level difficulty. Sounds cool, but it's very time-consuming.
- Random approach — making random moves on the level. This is bad; it's suitable for finding bugs, but very far from the true state of affairs regarding level characteristics.
- Empirical approach — analyze all available moves on the level and assign a weight to each move. One move will use 3 chips, another move will use 4 chips, and another move will remove 5 goals of the level. This move for 5 goals seems the most correct. We make moves according to the evaluation of the current state of the field, do 50–100–200–1k iterations, evaluate the level difficulty.
We need to teach our algorithm to play like our player plays. The empirical approach won't give precise results; you'll get something like an "average temperature across the hospital". What to do if we are just developing the game and want to predict level difficulty? I have bad news for you — you won't be able to accurately configure your algorithm with certainty. Approximately? Yes, that's possible. We need data from our audience, but there's a level designer who created the level, isn't their data suitable? No, because their skill differs from your players. I'll surprise you even more: if you drastically change your user acquisition approach, for example, start buying misleading advertising, you again need to make an adjustment in the algorithm's operation.
How much data is needed? From my experience, 1k level completions were enough for us to consider the difficulty reliably and base the algorithm configuration on it (in fact, 1k is the minimum threshold, but at 100k, the results are quite accurate). And then we can delve into mathematics: Monte Carlo, reinforcement learning, and other scary words.
Can you limit yourself to manually adjusting weights? Yes, if you have enough statistics from players, you can predict the difficulty of levels quite accurately, with an error of approximately ~10% on difficult levels and almost no errors on easy ones.
Let's assume that we have learned to predict the difficulty of a level. The levels were random, meaning each level launch was unique. Now we make a difficult level, fix the seed, and check its difficulty 1k times. We repeat this until the resulting difficulty matches our planned difficulty, as well as several seeds that will be easier. We check the result obtained on real players and see that the level is indeed difficult, and easier seeds give the expected difficulty result.
We've come a long way. We can fix seeds and get a predetermined difficulty for a level. Moreover, we've come up with an algorithm for when to give the player a difficult seed and when to give an easy one. It's time to launch an A/B test and check our work.
And some levels show great results, while others don't. Let's figure this out in Part 2.

