The Combat System is one of the main gameplay element in a game. Of course there are a lot of games without “combat”: puzzles, simulation games, driving games and so on. However (and you know this in the depths of your soul) that your game must have an amazing combat system because we LOVE beating the crap out of our enemies! Other games mechanics are good, but a good fight can be AMAZING.
There are several ways to implement a combat system but, at the end of the day, we can divide the heterogeneous world of combat systems into two big clusters: real time combat systems and turn-based combat systems. The first are exciting but they rapidly becomes hard to implement. We will need to do a lot of animations, tuning collision boxes and tons of graphical stuff. If you are a poor programmer like me, you cannot do that (sad face :<).
With turn-based combat system, instead, you can do the most complex things you can image! You can take into account hundreds of variables and statistics, create complex strategic combinations, evocations, magic, everything. You can use dice, cards, tokens, everything in order to emulate an epic combat between a dragon and drunk dwarf with a wooden leg. Because turn based combat systems are an explicit abstraction of a real combat, the player can absorb without complaining a bigger level abstraction. The same cannot be said for a real-time combat system in which just an ugly animation can be labeled as “ugly designed and sluggish combat” and provide frustration to the player.
So we are going to implement a turn-based combat system! But how? Well, this obviously depends on which type of turn-based combat system you want to do. For now, we will try to do a replica of the first turn-based game I’ve ever played: the Pokemon Combat System!
This is a nice combat system to replicate as a tutorial because is not too complex (especially in Gen. 1 or 2), but contains several tricky points that we need to handle! We will explore the design and the implementation of this combat system in details. We will see how to design the combat system, how to do a first balancing and test on paper, and every implementation step! So let’s start!
Chapter 1 – Writing down the basic design
First of all we need to start with a good design. We need to point out the main elements of our combat system. Not everything, this would be impossible! we just need to sketch up the main points. In this tutorial we are cloning an existing combat system, so this is definitely easy! But if we want to create a new combat system from scratch we need to carefully plan the input and output of the combat.
To help us in the design process, we can try to answer the following questions:
1. How do the rounds work?
Each turn is usually divided in different phases. If your combat system is a card game, you need to specify every single phase: drawing of cards, when to play a card, how the combat is resolved and so on. If your combat system is based on dice, then you have to decide if dice are thrown simultaneously or not, when the damage is computed, what to do next, and so on. This will becomes extremely useful during the implementation when we will be forced to explicitly enumerate every single step of every single turn.
In our case the combat system is quite easy. Two phases: in the first one each player select a move, in the second one the combat is resolved applying each move according some priority rule (example: the Pokemon with higher velocity attack first, some moves can be top priority). Obviously there are other small phases, for instance when we decide to apply the poison or burn damage but for now, for simplicity sake, we just forgot about that.
2. What is the damage formula?
The second step is to find a good damage formula. Damage is the core element of your combat system and it is a good starting point. Note that if your combat system is more complex than just “chose an action -> apply damage” you can replace this step with “find whatever the main element of your combat system is”. For instance if you have a combat system based on wounds (in place of traditional HP) you have to define a formula to compute the wound entity, the position and the effects on the players.
Be clear! This is not the only way to proced! Some people prefers the other way round: they start from the bottom, defining stats (strength, attack, defense) up to the damage formula. I prefer starting from the damage formula instead. Your call.
But how to define a damage formula? Write it in simple algebra. It is not difficult, most damage formula are just a bunch of sums, subtractions, products and divisions. There is no fancy stuff at this level. After all, you have to consider that the basic idea of RPG starts on “paper and pen” RPGs in which damage should be computed by hand! You have to think at the 4 basic operation as primary colors: you have to mix them to obtain your perfect picture, step after step.
We are in the Pokemon world and suppose we don’t know the exact formula. Let’s start with the basics: we have an attack with a certain amount of strength. The main idea is very simple: we want to do more damage the more is our attack. Easy.
Then, we want that the damage is reduced by the defender defense. Think to something that can reduce the damage value. Subtraction could be a solution but note that if “defense” is higher than “attack” then you can have negative damage! Do you want this? Maybe yes, it may be a cool game indeed. But maybe no. We stick to the classics for now. Without subtraction we have only division remaining on the table.
That’s better. Defense directly reduce the effect of Attack, the value is always positive and this is good. Now we want to spice things up: critical strike! If there is a critical strike we want to do 2-times, 3-times, whatever-times more damage. It is clear that we need a product.
Where multiplier can be 1 if there is no critical strike, or 2 if there is. Now let’s add a bit of randomness.
In interval notation, this mean that we multiply everything for a random variable between 0.85 and 1. Do not exceed with randomness in your damage formula! Randomness is good to make the whole combat less deterministic but if you exceed that… well… your combat becomes in practice a “toss a coin” combat. You don’t want that!
That’s it! You have a very basic damage formula for a game defined by the attack and defense. You can tune this formula in any way you want. You can add more properties of the player such as “precision”, the “anatomy skill”, the armor value and so on. For us, the official Pokemon formula is this one:
Where the modifier is just the product of every “multiplicative terms” such as CritMultiplier and the random variable. The pokemon formula also include STAB (Same Type Attack Bonus) and Type Multiplier to the modifier. We will talk about these other variables during the implementation.
3. Use the formula to sketch Character Sheets and Attacks Sheets
Just looking at the formula we can see that there are some necessary parameters for the player. Attack, Level and Defense are something that must belong to the fighting characters. BaseAttack it is something that is in the attack. Write this down and look at the others parameters. There are other elements in the formula that do not belong nor to the character nor to the attack. STAB, TypeMultiplier, CritMultiplier are parameters that can be computed starting from the elements of the characters and the attack. Try to decompose these values. Write their dependencies in terms of something that belongs to the character or to the attack. It is not important HOW they are calculated, it is important to know what parameters you need.
For instance, TypeMultiplier depends on: the attack type and the type of the receiver character. Write this in this way:
Do the same thing for STAB and CritMultiplier. The STAB value is a small bonus to the attack if the attack and the character share the same type. So, STAB obviously depends on the AttackType and the Character Type. The critical multiplier can be computed knowing the critical chance probability of the specific attack.
STAB(AttackType, CharacterType) CritMultiplier(CritProbability)
Now highlight in blue all the elements that belong to the player and in red all the elements who belong to the Attack. At the end you should have something like this.
CHARACTER: Attack, Defense, Level, CharacterType ATTACK: BaseDamage, CritProbability, AttackType
Obviously in our game we can have elements who came from other objects in game (items, environment, and so on). But now we stick on Pokemon! (I will stop to say that! But it is always true: you can add everything you want!)
This elements we have identified are a subset of the variable we have to use in the character sheet and in the attack. They are not everything we want, but they are a necessary subset!
4. Add the other variables!
Attack, Defense, Level and Type are not the only variables we need to attach to the player. Look at the small description of the combat turns and try to understand what is missing. Obviously we need to add HitPoints (after all, we are using a numerical damage). There is also the Speed variable we will use for the priority rule!
At the end our character has the following properties:
Cool! This seems a real character sheet! Real Pokemon game split attack and defense into physical attack/defense and special attack/defense, so we will add them.
We do the same thing for the attack.
- CRIT PROBABILITY
We added the precision parameter. Our attacks can miss and we need to add this.
Now we have all we need to start! The initial sketch of the combat system is ready. It is time to test it. Testing a combat system is a good way to see if the combat system works, if it is fun, strategic and balanced.
We will talk of this on the next chapter!