How are stats generally handled?

This is a question for RPGs, but if you know other genres which use stats, you can include them.

Basically, I’d like to know how exactly games use stats when calculating things like damage dealt and damage taken. Because if you think about it, it’s not as simple as adding “Damage” of a weapon to your character’s damage and using that as the amount you will deal.

This is especially clear in MMOs. If you have a total of 100 damage, but the enemy has 100 defence, you’ll still do damage.

And if you have 100 damage, you won’t do 100 every single time.

So, how do games calculate these stats in order to give random results, and how do they make two stats like “Damage” and “Strength” work together, while also taking into account the enemy’s stats?

I understand that every company and game has their own way of doing it, but I’m asking in general. How do stats work, if not literally (100 damage stat dealing 100 damage to an enemy)?

You could look at how games like Dungeons and Dragons handle this.
A great sword will do 2d6 damage, while a long sword will do 1d8. You then look at the player’s strength and add a modifier to the damage roll.
You can show the player the average damage, this is how the monsters in the D&D Monster Manual are handled–you see the average damage for an attack, and then the dice used to calculate that.

The only real damage reduction in D&D is resistance, which just halves the amount of damage taken, but depending on what kind of game you’re making, you could have armor work as anti-weapons. So plate armor might negate 2d6 damage, and leather armor may negate 1d4.

Basically, just make “damage” a range, and add (or subtract) the relevant stat.

2 Likes

Oh boy! I just pushed an asset that handles Stats (in review). It doesn’t do rng bits but it wouldn’t be terribly complicated to add forumlas that do manage rng even based on stats.

It first depends on your structural implementation of the stat system, formulas and calculation. It’s much more straightforward to hardcode all of your stats because you can just pass an interface with all of the variables guaranteed. However if you want to use a generic approach it makes the code a little harder to read and a tad bit weirder to write.

When passing damage and such I chose to push ‘done’ values through the pipe then the recipient does all the calculations to consider that flat number. The idea applied to everything, each phase or target is responsible for handling the incoming data based on it’s own local stats.

This makes it easy to modularize the formulas/calcs. Every probability just runs through a check like for ‘Miss’ before sending damage it would roll a number against a stat on the shooter to see if its over a threshold and if so then its not a ‘Miss’. If it doesn’t Miss then it passes the flat ‘damage’ over to the recipient where that guy runs some calcs to see if his own stats cause a ‘Miss’, then calcs damage (the flat value against his own stats) for a final damage application value.

It’s all about good structure and systematically evaluating numbers against each other - static calls for forumlas where you can just pass in numbers and get a result back will help make things consistent when you can use them.

The other tricky part is when you want to scale stats. Making sure you level up and access stat values correctly without corrupting them. Live, runtime Stat Modifiers are fun too, they throw a new wrench in the mix :wink:

1 Like

Games which don’t use RPG elements these days are rare :stuck_out_tongue:

Resistances are the most common thing to add for variation now, generally percentage-based. To complicate matters they often have the concept of damage types. This is a benefit with computers - you’re able to make really complicated combat calculations because players don’t have to roll the bucket of dice. None of that boring D&D crap.

Some systems would use the resistance as simply damage reduction. 5% fire protection subtracts 5% off flame damage, but if it’s a fire sword the target would still take 100% of the edged damage while wearing wizard two-ply (which in some systems offer no physical protection and only exists to enchant and avoid nudity).

But the second use seen in some games is a flat out chance of immunity. This means the game first does a d100 roll against 5 in the fire protection example above, and if it’s 6+ the target takes fire damage minus 5%, but 1-5 reduces the damage 100%. It’s a simple way to add a bit of random luck to a heroic game.

I guess the most popular and simplest is to add strength to any melee weapon’s damage. If you’re simulating a die system you could make each point of strength add another die (lots of inspiration to take from pen & paper RPGs or board/card games).

Target protection could be calculated as a total number, or totals per damage type, based on constitution/toughness plus resistances plus armour. Chance to hit could be attacker skill minus defender skill, or both could be a roll and the defender gets a damage reduction number from that. Lots of possibilities.

There’s also the dice pool system: Each point of damage for a weapon indicates a die, each point of the relevant stat another. Damage has a static difficulty to roll against, and each success gives you a point of damage. The defender’s constitution roll could increase the difficulty required to do damage per roll, or each success could eliminate an attacker’s successful damage die. Different damage types could be “unsoakable”, where no defensive roll would be allowed.

Each point of a weapon skill would give you a die to try against a target difficulty to hit, and each point of success from the target’s defensive roll would increase the difficulty or again eliminate a die.

The World of Darkness games (O.G. Vampire the Masquerade and so on) used only ten-sided dice, and each roll of a natural 10 let you roll again and add the number to that die-roll. Crazy numbers are rare, but possible. The snowballing reroll on tens is again inherited from Ars Magica. (Rolling a 1 is just an automatic failure no matter how many bonuses, so no snowballing failures.)

Then there are the Chaosium games - Call of Cthulhu, RuneQuest and ElfQuest. All skills are percentage-based. You roll a d100 to see if you hit, the defender rolls to avoid it if applicable. You roll some damage and apply it, with damage location systems to complicate matters in some of those games.

The Chaosium system is great for tabletop games where you need the story flowing. Dice pool games are great for heroic games with epic amounts of damage. Percentage protection and separate damage types are good additions to either.

Online and offline RPGs from EverQuest (which I’ve, uh, done extensive research on) to Elder Scrolls (also personally well-researched) sometimes have a level-limited armour skill for each type, which increases through taking damage. It can automatically ensure that high-level gear isn’t too overpowered if a low-level character gets their filthy hands on them, and some games make it so bonuses on gear also scale with the skill up to a maximum.

1 Like

I actually never got into d&d (mainly due to the lack of friends who know how to play it, or want to). So all I understood from your reply is “show the player an average of the damage, and use random values from that average”.

Hopefully that’s sort of what you were pointing at.

For example, if a weapon can deal between 2 and 12 damage (2d6), show the average of those numbers (which is what the player sees as the Damage stat), and use those numbers at random when dealing damage.

And it could be also affected by other stats, which might decrease that average’s possibilities in order to guarantee a higher damage dealt (like 6-12 instead of 2-12).

The most important thing to remember is that it’s a game. You’re not trying to simulate fully realistic damage modelling - we don’t have enough data on dragons and goblins to do it well anyway.

3 Likes

This is probably the most used base algorithm in Rpg’s for damage calculation. It’s probably a the core of like half the mmo’s out there.

(100 * attack) / (100 + defense)

1 Like

Here is a course on the matter

And here is a talk about the matter

1 Like

This. Just about every RPG video game is a more sophisticated version of pen and paper RPGs. So grab a players handbook for dungeons and dragons, path finder, advanced fighting fantasy, war hammer, or whatever the kids are playing these days.

1 Like

On the other hand, THAC0 is better to avoid like the plague.

2 Likes

I agree, these kinds of stats are something you want to avoid. Unless you want to spends ages digging into a rabbit hole of stat calculation formulas for your game then you want to keep it down to less than a dozen real stats (including lvl and xp) and avoid having niche cases where you have to evaluate stat pairs in a non-standard way.

For example, it may be very simple and okay for you to have only multiply and divide methods and always lock the integral at a value of 10.

        /// <summary>
        /// Divide some value by a Stat. For example when applying damage, divide the incoming damage by the Endurance stat.
        /// </summary>
        public static float ValueDivByStat(float inValue, Stat stat, StatProperty property)
        {
            return inValue / Mathf.Clamp(stat.Get(property) / 10, 1, 99999);
        }

        /// <summary>
        /// Multiply some value by a Stat. For example when applying damage, multiply the base damage by the caster's Strength stat.
        /// </summary>
        public static float ValueMultByStat(float inValue, Stat stat, StatProperty property)
        {
            return inValue * Mathf.Clamp(stat.Get(property) / 10, 1, 99999);
        }

I’d definitely opt for making things as generic as possible and separating the generic formulas from the ‘calculator’ methods that use those generic formula calls.

1 Like