7
\$\begingroup\$

I'm developing an RPG and I want to do the damage calculation in my game.

I have for example the following situation:

Player 1 Stats:

{
    "hp": 160,
    "attack": 22,
    "defense": 27,
    "speed": 19,
    "luck": 11
}

Player 2 Stats:

{
    "hp": 160,
    "attack": 16,
    "defense": 23,
    "speed": 17,
    "luck": 14
}
  1. Let's assume that Player 1 will give a physical attack. What calculation would I use to get the attack value?

  2. Let's assume that Player 1 will use a skill that has an attack strength of 70, that is, how would I calculate it based on attack + skill?

  3. Using the attribute "luck", how could I also calculate a probability of giving +5% attack depending on "luck"?

\$\endgroup\$
5
  • 27
    \$\begingroup\$ It all boils down how you want your game to work. There is no universal formular that applies to all games. What is attack of 22 in your game? What is defense? How should your defense work? Is it just reducing a flat attack value? Or just a percent of the attack? Is there a cap? Luck of what limit? If 100 is always applied, 11 luck could just be 11% chance. If 50 is the limit, it would be 22%. If you tell us more about how your combat is supposed to work, we might be able to help you \$\endgroup\$
    – Zibelas
    Commented Jan 8, 2022 at 12:06
  • \$\begingroup\$ Also keep in mind that "the formula" will need to work for every the whole range of values those stats can have. \$\endgroup\$
    – Vaillancourt
    Commented Jan 8, 2022 at 13:40
  • 1
    \$\begingroup\$ Does this answer your question? How to develop RPG Damage Formulas? \$\endgroup\$ Commented Jan 10, 2022 at 1:08
  • \$\begingroup\$ @BlueRaja-DannyPflughoeft funnily enough the comments on that one say the opposite of the consensus here - design stats first and then work the math to make them work \$\endgroup\$ Commented Jan 10, 2022 at 10:29
  • \$\begingroup\$ @Vaillancourt within reasonable limits, things need to work. I think most games have limits on these things. In Final Fantasy as a popular example, damage is capped at 9999 so no matter what combination or absurd thing a player comes up with (or just naturally reaches a high level), a single hit cannot deal more than that. \$\endgroup\$
    – user985366
    Commented Jan 12, 2022 at 0:23

2 Answers 2

2
\$\begingroup\$

Very close to be "more suited for a forum" but still answerable.

When designing damage formulas and related mechanics, there are well tested approaches. As we have now an entire universe of games to analyze.

First: I have seen Attack + Skill but mostly on RTE games or top down action RPGs. While Character.Strength + Weapon.Attack is more common for RPGs/JRPGs. We are still missing target's defenses/resistances/armors.

It is better to multiply/scale Character.Attack/Strength rather than add Skill.Power to it. Otherwise your skill will became obsolete in late game, and you will need a growth system that gives your Character more powerful skills with time, so player stop using obsolete skill in favor of the newer ones.

And this damage skills going obsolete is very common in JRPGs. They do this to give the player a sense of progression. In those games, you need the leveling, but also the skills. Raw stats alone won't be enough. You need both.

A notable example of this are most 2D Final Fantasy titles.

Add the weapon power to the Character attack/strength is more acceptable, as weapons are OK to became obsolete in late game, forcing the playing to buy more expensive weapons.

Western RPGs are more tactical, in average. A damage skill may have a stronger version, but this doesn't have to mean the previous one is obsolete. It may still be useful because it costs less MP or whatever.

There is also the possibility of leveling skills rather than learning new ones. The idea here is that different skills must do different things. If you just want more damage, but same effect, then just level the same skill, don't learn new ones. Think Diablo/Torchlight.


This is what happens when you use the + operator.

Skill:

{
  Name: "Slash",
  Power: 10,
  Stat: "Attack",
  DamageType: "Physical",
  Cost: 32
}

Damage Formula:

if DamageType == "Physical":
   Damage = Character.Attack + Skill.Power - Target.Defense
else if DamateType == "Magical":
   Damage = Skill.Power - Target.MDefense

Leveling Formula: final_stat = base_stat * level

HP also levels by this formula.

Note: this is for simplicity. But nobody does this kind of leveling. Notes on this at the end.

Let's take some time to wonder why magical damage is raw. Because we don't have a stat for magic casting. In our worldbuilding, magic doesn't depend on a Character' stat. Who knows the most powerful spells wins. And yes, this was done before, in Earthbound, PSI (magic) abilities do raw damage, with a random variance between a minimum and a maximum, and magic defense doesn't exist.

We will introduce variance based on Character.Luck latter.

Then let's look how the damage becomes obsolete with leveling. Assuming same Character and Enemy level. Let's look at the turns requiring to kill a foe. Note: if your game is real time, it's possible to extrapolate damage per turn to damage per second.

simpler damage formula

The same foe, as long as levels match, takes more turns to be killed by the same skill in late game.

Your game may or may not be OK with this.

If not OK, then you have some options: allow skills to gain levels too. There are real world examples of this system. Think in Skill Trees of most MMORPGs out there, where you can expend skill points in skills you already learned, to make them stronger.

Doing this you can compensate for the numeric effect shown in the graph.


Now let's hack the damage formula. We can make Defense a division, but for simplicity, let's change one thing at a time.

Damage Formula:

if DamageType == "Physical":
   Damage = Character.Attack * Skill.Power - Target.Defense

multiply power

Ignore that a level 1 it takes 4 turns to kill the foe. That's a rounding artifact. I forced all damages to round down, and all turns to round up.

What that graph shows is that, as long as there aren't other factors like equipment (armor/weapons) at play, the same foe, as long as levels match, will die in the same amount of turns.

I think that is a lot more "elegant" from a mathematical point of view. I like more this damage formula.

There are room for improvement. Try this: do your spreadsheet, but use this damage formula: Character.Attack * Skill.Power / Target.Defense

Also watch for the negative damage artifact. With the subtract defense formula, you may heal the target, in place of damaging it, if defense is too high. In this case, just code an extra if at the end of damage calculation, and round to 0 if value is negative.

While a division will never change the sign of damage. But watch for other parts of your final damage formula that may.

You still may add skill leveling to your design, but it will be to match lore, or because you think it gives player something extra to do. But not because you need to fight your math.


Damage formula expanded

There is room for improvement.

Most games also have the concepts of elemental attacks. Imbue weapons. Etc.


Variance

In PokeMon there isn't variance in damage calculation except a move has a unique mechanic. There are such moves.

But in most RPGs out there there is variance as a way to add uncertainty to action outcomes.

Example: Damage = Damage + Damage * Math.random(-0.10, 0.10)

Where Math.random is your favorite runtime random function. And Damage is a variable already containing a value as result of your damage formula.

Pay attention to operator priority. Multiplication solves first.

In words: damage plus a random value that goes from -10% of damage to +10% of damage.

This is a good place to give that Luck stat a reason to exists.

You can make luck affect the variance somehow.

Example: Damage = Damage + Damage * Math.random(-0.10 + 0.10 * (LUCK/MAX_POSSIBLE_LUCK), 0.10)

In this case, we use Luck to shift the lower limit of variance to the right. You may do the same for the upper limit, if you want.

MAX_POSSIBLE_LUCK is a constant. And is must be set to the max allowed LUCK, for a legal, non hacked, character in your game. And here is our first problem. This requires you to know your max allowed legal LUCK in advance.


Mechanic has implied narrative or must be coherent with lore

This is an open debate. Some say yes, some say no. I say yes.

What exactly is Luck?

Because I understand Strength. It implies the Character has big muscles.

And I also may understand Attack. It is more general, for better or worse. It implies the Character does more damage with physical attacks but it doesn't tell us exactly how. It may have big muscles, or it may use its martial arts knowledge to compensate the lack of muscles/size and hit as hard as a very tall person.

Now, while I don't really get Luck, its use is common. Truth be said.

For Fire Emblem (I don't sure if all of them, but at least the 2D ones). Luck is used in Critical Hit Chance calculation:

Unit's skill/2 + the weapon critical chance + the support bonus (if any) + the class critical bonus (if any) + character's skills (if any) - the enemy's Luck

Source

I think it comes from Tolkien's: "Luck is also an skill". He didn't invented it, its common belief, but I'm sure it got to gamedevs thanks to him.

But... What exactly it is telling us? That universe is more on the side of that character than on the side of others?


Be digital, not analog

Specially true for Luck.

In my experience, players don't notice oscillating values. Think in analog radio signals. They won't notice a stat is affecting something analog. The only way they will notice is if you tell them with a help text in your game gui.

Global variance is OK. But nobody will notice if a stat affect it.

Making luck oscillate between -10% and +10%, or between 0% and +5%, is no good.

The mechanic of Critical hits comes to the rescue.

Refer to the Fire Emblem formula once more. The analog part is hidden in the game code. The player will get a digital, binary, experience. It's critical or not critical. But they will notice that more Luck affect the frequency of critical hits.

Said all that, all game is unique. Just do what you feel.


Notes on leveling

base_stat * level isn't good. Nobody does that.

You start with very small numbers at level 1 and you end with very big ones at level 100.

Take inspiration from PokeMon, again.

You can define your character structures as a set of initial and maximum stats. The advantage of this, is that you know, and control, the final shape of your characters. Then level will change a stat from minimum to maximum in steps of 1/100. This, assuming you want to cap at level 100.

In JavaScript:

var UniqueCharacterDatabase = {
  Hero: {
     BaseStatsMin: {
       hp: 50,
       mp: 25,
       attack: 21,
       defense: 18,
       luck: 8
     },
     BaseStatsMax: {
       hp: 2000,
       mp: 800,
       attack: 243,
       defense: 204,
       luck: 97
     }
   }
}

Formula to calculate current stats:

var level_cap = 100;

var any_stat = Math.floor(any_stat_min + (any_stat_max - any_stat_min) / level_cap * (current_level - 1));

Example, at level 50, attack would be 129. And that is a nice number for level 50.

You can tune the "growth formula" to include some form of easing. But I think it's not needed.

Note: It's not a good idea redo the numeric simulations shown in graphs with this new proposed leveling system. Because with the simpler stat * level formula, a characters is, to other characters, always the same as long as levels match.

But with the new leveling system, depending of how you shape two characters final shape, the distance between them may get smaller or bigger, as they approach to their final shape. This would introduce "noise" in the graphs if we only want to analyze the damage formulae.

\$\endgroup\$
38
\$\begingroup\$

It appears that you came up with an array of stats first, and now try to figure out what those stats could be doing.

I think you might be approaching this problem from the wrong direction.

The way I would approach the design of an RPG combat system is:

  1. How do I want the core gameplay loop to feel? Do characters attack each other? How many hits does it take to take one down?
  2. How varied do I want the experience to be? Should different opponent feel different to fight? Should I perhaps allow the player to use different playstyles to get a different combat experience? What should enemies and players be able to do during combat to provide such a variety?
  3. What bells and whistles could I add to that core gameplay loop? A leveling system perhaps? How do I want the core gameplay loop to turn out when two characters with different levels fight each other? Or perhaps some additional mechanics which make the game more interesting by forcing strategic decisions?
  4. What formulas do I need to create such a game experience?
  5. What stats do I need to feed into those algorithms?

That way I would not end up with the question "I got that luck stat, what could it do?". When I don't have a use-case in mind, then I would not create such a stat in the first place (more ranting from me about the uselessness of a luck stat here).

When you never designed an RPG combat system before, then I would recommend you to start with the most simple possible system and iterate from there:

  • Every character got exactly one stat: HP
  • Characters take alternating turns
  • Characters can do exactly one thing: Attack, which takes away 1 HP from the opponent
  • First one with 0 HP loses

When you implement this and try it out, you will realize that it's not a particularly interesting system (although in some cases where the main appeal of the game lies elsewhere, it might actually be enough). Especially because the result is a foregone conclusion: The one with more HP wins, when it's a tie the winner is the one who moves first. How could you iterate on the idea to make it more interesting?

For example:

  • You could give the characters another stat: Attack, which starts out as simply the number of HP their attacks take. The battle is still a foregone conclusion, but it's not that obvious at first glance who will win (now you at least need to perform a division to predict the winner).
  • You could add some randomness to the equation so battles are no longer deterministic. For example:
    • Randomize the damage.
    • Randomize the turn order, so characters might move twice before the opponent gets a chance to act. This might work well with a "speed" stat which decides how often characters get turns.
    • Add a hit/dodge mechanic which creates a random chance to negate attacks (which might or might not warrant a new "dexterity" or "agility" stat)
  • You could add different forms of attacks which do different amounts of damage. But in order to prevent players from always using their strongest attack, you might also want to add some kind of a resource mechanic.
  • You could add a defense mechanic, which could start out as a simple subtraction (damage = damage - defense), but could get more complicated when you realize flaws in it. The main reason for this stat is to shift which attacks are cost-effective against which enemies (high-def opponents might only be beatable with costly attacks, while low-def opponents could be beat with less resource-intense attacks).
  • You could add support for parties of multiple combatants. Now it becomes a strategic decision which enemies to take out first.
  • Perhaps attacks with damage types and characters with resistances or vulnerabilities to certain attacks could make the game more interesting?
  • You could add a progression system which allows characters to increase their stats. But how stronger do you want characters to get as the game progresses, and how much do you want the gameplay to change through that progression? This is a decision you have to make for your game.

When you go through this iterative process until you have a fun combat system, you are going to end up with more or less stats, but you will have a reason for each one to exist and you will know what it does.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .