Original Author: Daniel Achterman
My previous articles were about system design at a conceptual level, focusing on goals and best practices for system designers. This article gives an example of how to put those principles into practice. To demonstrate, I’ll walk through the character stat systems for one of the games I did system design for: Dungeon Siege 2. I’ll describe how its systems work, why we set things up the way we did, and how we did the math to translate our goals into content.
I’ve posted the part of our system spreadsheets where we tracked and compared these values. As you read, follow along with the numbers here:
Dungeon Siege 2 Character Statistic Progressions
As an RPG, characters in Dungeon Siege 2 increase in power as they level up. Their stats increase, they get more health, and they get better weapons and armor. In order to make content that is appropriately challenging for characters throughout the game, we needed to be able to predict how strong characters would be at each level. We decided that characters’ attributes and the base statistics of their weapons and armor would form their “base power level”, so we started by defining those values and progressions. This base power level would later be increased by additional factors like skills, powers, and random loot modifiers to give their total overall power.
All of these formulas have “Level” as a parameter. In the case of characters, this is their character level. In the case of items, it’s the level we expect characters to be when they are using the item. Item level restricts when the random treasure generator can drop it.
Damage per Second
We had a couple simple goals for base character damage per second:
- The base damage per second formula should be the same for all classes. Dungeon Siege 2’s classes have different strengths and weaknesses, but they all start with the same DPS. This changes as players start specializing their roles by spending skill points, but it’s nice to have one base formula for everyone.
- The base damage per second formula should be stupidly simple. It appears in countless other tuning calculations, like monster health and item bonus values, so it should be an easy formula to work with.
To keep the DPS formula simple, we made it increase linearly with level, the simplest kind of progression rate. It’s just this:
Base Damage Per Second = 8 + 2 * Level
You can see it is identical for all classes in rows 6, 16, and 27 of the spreadsheet. The “8” term represents how much damage a character does at the start of the game. The “2” term represents the rate his base DPS changes with each level.
To find a weapon or spell’s damage, we multiplied the expected base damage per second from the spreadsheet by the weapon’s time between attacks to get its damage per attack. For melee and ranged weapons, we then subtracted the expected damage bonus characters would get from statistics like Strength or Dexterity. Here’s an example of a level 10 two handed sword that swings once every 1.5 seconds:
Level 10 Sword Damage = Base DPS at Level 10 * Time per Swing – Strength Bonus
Level 10 Sword Damage = (8 + 2 * 10) * 1.5 – (0.2 * (10 + 3 * 10))
Level 10 Sword Damage = 34
So, a level 10 fighter wielding a sword that deals 34 damage per swing will deal the desired base DPS. Here’s a visual of how much of a fighter’s damage comes from his weapon vs. his strength at different weapon speeds:
If I had to do it again, I’d make the formula coefficients higher. Sometimes at low levels a player got a weapon or piece of armor that was one or two points better than his previous item, which just didn’t feel very good. There was nothing to stop us from making all the numbers in the game bigger, so we should have done it to make those early upgrades feel more exciting.
The armor value progression is related to the game’s damage calculation formula. There are a so complicated no one understands how they work. Dungeon Siege 2’s is pretty simple by industry standards:
Actual Damage = Attack Damage * (Expected Attacker DPS / Armor)
Actual Damage = Attack Damage * ((8 + 2 * Attacker Level) / Armor)
The “((8 + 2 * Attacker Level) / Armor)” term is essentially the percentage of attack damage the victim takes. We wanted that percentage to stay roughly constant throughout the game, and 50% sounded like a good target for durable fighter characters. Keeping the percentage constant allowed us to tweak difficulty by just changing monster health and damage, without having to factor in changing damage reduction.
In order to get the 50% ratio, base armor for fighters and monsters must be double base damage per second (see row 7 of the spreadsheet):
Armor = 2 * (8 + 2 * Level) = 16 + 4 * Level
Ranger and Mage Armor
Say that a ranger has X% as much armor as a fighter. Our simple damage formula makes it easy to determine that he’ll take 1/X times as much damage from attacks as the fighter, so he’ll be able to withstand X% as much punishment before dying.
The defense values on ranger and mage armor were noticeably lower than the values of fighter armor so players could see the distinction between gear for different classes. We ended up making ranger armor defense values 70% of fighter armor and mage armor 55% of fighter armor. You can see these formulas in rows 17 and 28 of the spreadsheet.
To figure out how much health characters have, we thought in terms of how long it would take to kill a character. Since base damage per second increases linearly with level, base health should also increase linearly with level, so that it takes about equally as long to kill a character at low and high levels.
Fighter health is the baseline that ranger and mage health were compared to, so we started with it. We started by multiplying the damage per second formula by different numbers to get a progression that looked right:
Health = 42.4 + 10.6 * Level
After playtesting a bit, we realized that low levels were pretty lethal, we increased the starting health value a bit to give low level players more durability:
Health = 56 + 10.6 * Level
You can see the values in row 8 of the spreadsheet follow this progression, but the formula for it looks very different. One of the things Dungeon Siege 2 carried over from the first Dungeon Siege is that character health and mana are a function of their attributes – Strength, Dexterity, and Intelligence. Strength has the biggest impact on health, then Dexterity, then Intelligence. The health formula has this format:
Health = A * Strength + B * Dexterity + C * Intelligence
To find the actual values of A, B, and C, we needed to also consider ranger and mage health.
Ranger and Mage Health
We knew we wanted rangers and mages to have less health than fighters. As with armor, we decided to make their health a percentage of fighter health. Rangers should have 90% as much health as fighters of the same level, and mages should have 75% as much health.
This would have been easy if different classes had different health formulas, as they do in games like Diablo 2. But in Dungeon Siege 2, every class uses the same health formula. Character health is based on attributes, which grow at different rates for different classes. We had to derive health formula coefficients that would multiply their different attribute values to result in the expected health percentage for each class. Time for some math!
Here’s the health formula again:
Health = A * Strength + B * Dexterity + C * Intelligence
Rows 3-5, 13-15, and 24-26 of the spreadsheet show how attributes progress for each class. Replacing Strength, Dexterity, and Intelligence with their expected values for each class, we get the following three formulas:
Fighter Health = A * (10 + 3 * Level) + B * (10 + Level) + C * (10 + Level)
Ranger Health = A * (10 + Level) + B * (10 + 3 * Level) + C * (10 + Level)
Mage Health = A * (10 + Level) + B * (10 + Level) + C * (10 + 3 * Level)
Replacing “Fighter Health” with the desired health progression and replacing “Ranger Health” and “Mage Health” with the desired ratios of Fighter Health gives us the following:
56 + 10.6 * Level = A * (10 + 3 * Level) + B * (10 + Level) + C * (10 + Level)
0.9 * (56 + 10.6 * Level) = A * (10 + Level) + B * (10 + 3 * Level) + C * (10 + Level)
0.75 * (56 + 10.6 * Level) = A * (10 + Level) + B * (10 + Level) + C * (10 + 3 * Level)
In Dungeon Siege 2, all characters start at level 0 with the same amount of health. We can’t give fighters, rangers, and mages different health at level 0. The best we can do is give their rates of change the desired ratios. To focus on that, we can throw out all the constants in the formulas:
10.6 * Level = 3A * Level + B * Level + C * Level
9.5 * Level = A * Level + 3B * Level + C * Level
8.0 * Level = A * Level + B * Level + 3C * Level
Then divide both sides of the equations by “Level” to clean up the formulas:
10.6 = 3A + B + C
9.5 = A + 3B + C
8.0 = A + B + 3C
This is a system of simultaneous equations. This wikipedia page explains how to solve for values of A, B, and C, resulting in this final health formula:
Health = 2.5 * Strength + 1.95 * Dexterity + 1.15 * Intelligence
That’s the formula that appears in lines 8, 18, and 29 in the spreadsheet. Lines 20 and 31 and the chart show that ranger and mage health settle into the expected ratios of fighter health, so we know our math is right.
That works, but getting there was really complicated. This design also doubles up the functionality of attributes. We couldn’t increase a fighter’s strength to increase his melee damage without significantly increasing his health as well. If I were designing a game from scratch, I would have done something like derive health directly from class levels, without involving attributes at all.
A Word on Math
Applying math to system design can take some practice. It can be difficult to look at some formulas and figure out how they behave in different situations, or how to get the result you want, especially if you’re just starting to do this kind of quantitative design work. Here are some tips for game system math:
- Focus on setting up equations correctly. It doesn’t matter if your math is simple or complex, but it does need to be right. If I started with my intended base DPS progression but messed up the math to solve for a weapon’s damage value, then the reality of the game wouldn’t match my intended progression at all, and I’d get unexpected results and make bad conclusions.
- The hardest part is keeping your units straight. If you know a value is “damage per second”, then multiplying by a time value will result in a damage value. Keep track of your units and don’t mix up inverses. For instance, frequency is not the same as time between attacks.
- Don’t try to be too precise. Math in games is like math in physics – it’s a broad-strokes tool for approximating a complex system. I wasn’t able to get exactly the result I wanted with the ranger and mage health formulas, but I got close enough for my purposes. So long as your progressions are set up correctly, it’s okay if the reality of your game doesn’t match your ideal version completely.
- Test your results by graphing them. If you’re not sure your math is right, check your work by graphing your result. Erroneous results will often be apparent, letting you know that you need to review your math to see what went wrong.
- Practice, practice, practice. Look up formulas that other games use and try to determine why the designers set them up that way.
The Final Word: The First System Doesn’t Really Matter (Yet)
In the grand scheme of making a game, all of the above work on the first game system – every formula and value chosen – is completely arbitrary and doesn’t matter very much. Don’t obsess over it. Write some formulas down, plug some numbers in, and move on.
There are two reasons not to worry too much about the details for the first system in your game:
- None of this is “tuning” yet. Making armor and weapon damage progression values isn’t tuning until you make the content that intersects them, such as monster health and damage. You can make that stuff match whatever you choose to do here.
- There’s a huge range of values for game content that players will perceive as balanced. The vast majority of PvE players don’t engage with numbers in game systems in a deep way. So long as there aren’t obvious anomalies in your game, players are inclined to perceive a game as balanced.
The first system is often the hardest to design. There are so many ways you could set up your game content and make your rules work, and it’s easy to over-think it. The most important thing is for your systems to be comprehensible and workable so that you can avoid or fix any big irregularities in your content. Just choose simple rules and progressions and don’t worry about making every number perfect.