Mikhail Dragovalovskiy from Banzai Games explained how the AI in Shadow Fight 3 functions and how it was developed.
Game designers regularly face the challenge of creating a credible AI. This process can be either relatively simple or extremely complex, depending on the requirements of the project and the goals that you pursue. Banzai Games’ Senior Game Designer Mikhail Dragovalovskiy wrote about his experiences in creating the AI for the popular mobile fighting game Shadow Fight 3.
The Shadow Fight series was designed with a number of unique features that distinguish it from many other fighting games:
We already used AI logic to control the opponents in our previous fighting game Shadow Fight 2. But due to the transition to 3D graphics, the use of real character collisions and the introduction of the shadow form, we could only reuse a part of the existing AI logic. The rest had to be reinvented from scratch.
If you don’t want to use a bot that is powered by machine learning algorithms, there are two main other approaches:
The second option sounds very attractive: you create a cool AI that beats the players first, and then you mercifully reduce the difficulty of the bot. From the developers' point of view, this may be more convenient, because you can pre-design all the features of the bot’s behavior and have a full idea of its final performance in the fights.
Of course, we chose this option first, although we later realized that it wasn’t so simple: with our balance of animations, automatic blocks and the variety of special skills, a highly skilled player can almost always find out the necessary tactics and tricks that allow him to defeat the AI. We did not understand this right away, but after measuring the winrate of the players at different stages of the game it became obvious. This, by the way, contradicted the fact that for many people, judging by their feedback on the game, the bot was almost invincible.
Triggers or rules of conduct
The system of rules under which the bot performs random actions is called triggers.
Here is an example of this set of rules:
If you release such a bot against a beginner of an equal level, the result will depend on the armed weapons of the opponents. The one with the faster animation will win. Because, in fact, both just hectically push all buttons, except that the bot does it in a more meaningful way.
Decision-making
The logical step to improve the AI is to reduce this randomness and add a decision-making system that will guide the bot to victory. To do this, you need to understand which decisions are right in which situation. For fighting games there are two situations that happen all the time:
There are two solutions, too:
It turns out that for victory, the AI must interrupt enemy attacks with its counterattacks, or block if it cannot interrupt them.
We distinguish two groups of decisions that the bot has to make: first - when the player is standing, and second - when the player is attacking. In order for the AI to know exactly how to counter, we came up with collision tables.
Collision Tables
Remember how Doctor Strange looked through all the possible outcomes of the battle with Thanos? The collision tables work similarly: a computer calculates the outcomes for each attacking animation at every possible distance in advance.
In more detail: we simulate a strike with a sword and at the same time a strike with a katana, and then we look who will hit whom. We do this procedure for all attacks in the game, at all distances and with delays of a different number of frames.
(Example: “I launch a blow with a sword, and my opponent starts a katana strike after N frames”).
All results are recorded in tables. We repeat this elaborate procedure before each game update and store the resulting tables in compressed format inside the game build, so the calculations don’t eat up the device’s resources in runtime. This way the player’s client already has a complete list of all the outcomes for any possible attack combination. The AI can see in these tables which action can counter any attack of the player at a specific distance, or understand that it’s best to block the attack.
As a result, the AI effectively responds to the player’s actions with the optimal counterattacks. Next, we need to teach the bot to attack in the optimal way, rather than using only random strikes.
The choice of distance and the right strike
An attentive and intelligent reader could say: “Stop! Why even attack by yourself if the enemy is in the autoblock mode most of the time? We simply have to wait for the player’s action and punish him with a quick blow that will interrupt his attack! ”
Yes, this is true, but a bot that does not move and does not attack without the player taking the initiative looks at least strange. A credible AI must also be able to choose effective attacks, even if the optimal strategy is to play just with counterattacks. To do this, we have developed a system for choosing the best distance and strikes.
We know that most players have a repertoire of several favorite punches. For us, this means that our bot should specifically choose such attacks that cannot be interrupted by these typical player punches (at a given distance). To do this, we...
In theory, it sounds cool, but in practice, it has proved to be unsuitable: players rarely stand idle - they almost always press buttons and attack the bot. Too often, the bot was busy only reacting to the player's actions, instead of taking the initiative. So, the choice of the right strike only works against passive players. But at least the choice of the right distance improved the effectivity of our counterattacks - they’ve become more diverse because the bot has more choices.
At this stage, the bot is already quite effective: it recognizes the best moment for an attack, it knows when to counterattack and when to block. Next, we will talk about the systems that allowed us to set the required level of complexity and weaken or strengthen the bot.
Resentment and forgiveness
This is an interesting concept in our balance system. Through this, we create a sufficient level of complexity for beginners and professionals, as well as motivate the player to use different strikes, which increases the interest and fun of the game.
The essence of this concept already lies in the name: the bot takes offense at the player’s attacks if the player uses the same ones too often. Resentment is an internal variable in the game that reduces the AI’s chance of making a bad decision and increases the chance that the AI will conduct a perfect counterattack.
On the other side of the scale lies forgiveness. This variable increases the bot’s chance of choosing non-optimal solutions and reduces the chance of a counterattack, when the player stops spamming and switches to using different attacks more often.
If we want to have a challenging bot, we reduce the speed of forgiveness and also set a high starting level of resentment. If we want to make a weak bot, the opposite is true.
Delay
Every bot in SF3 has a delay in making a decision. This parameter causes the bot to pause N frames before choosing an action option. It’s useful because it creates an illusion that the bot is thinking. The simpler the bot we want to make, the higher the delay we set for it.
Checking conditions
In order to make some parts of the game more vivid, more emotional, we are constantly monitoring the states and relations of various game variables.
For example, we can force the bot not to use throwing weapons at certain distances. We can reduce the speed of forgiveness if a player has more hit points than a bot, or make the AI more aggressive if the player has fewer hit points.
In general, this is an add-on that we use to generate situations in which the bot dramatically changes its behavior and effectiveness. If necessary, we restrict some actions of the bot in certain situations. For example, we made it more difficult for a bot to make a throw than for a player. Otherwise, the player would never be able to throw a bot. Since the distances for a throw are the same for both fighters, the bot would always be the first to start the throwing animation.
Based on all of the mechanisms described above, we have created 9 basic AI presets that we use in different situations and sections of the game. This approach allows us to change the balance step by step and track the effecting changes.
The process of developing our bot tactics was a long one. We introduced these features gradually, so sometimes our players suffered, and then we suffered reading their complaints and curses. When we released the latest iterations of AI modifications, the flow of negative reviews regarding the behavior of opponents stopped, which made us proud of our work.
Our latest experience shows that the current approach to bot improvements will not give a noticeable further increase in quality. Therefore, we started working on a neural network that will simulate the actions of a player.
There are several reasons for this decision: