Author Topic: Damage reduction algorithm - looking for advice  (Read 30030 times)

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Damage reduction algorithm - looking for advice
« on: October 01, 2014, 07:41:00 PM »
In a nutshell, I am looking for a way to have unbounded integer values representing armor mean something without having damage get ridiculously high for attackers simply for them to actually damage the player - any advice?


More detailed description: My game has a value representing armor as an integer. There are around 6 armor slot and a potential shield, so the absolute lowest value a player can have with a full set of the worst armor is 7. As armor quality improves, this value gets higher...and higher...and higher. I can reduce it somewhat by saying a "better" piece of armor has other positive values, such as lower weight or lower evasion penalty, but these are marginal improvements. Ultimately, unless I have just 3 classes of armor (for example), I end up with armor values 30, 40,...etc....

(Just a note: armor in my game is purely damage reduction - there is a separate evade stat that is negatively impacted by armor, but only affects a hit landing, not how much damage it does.)

Well, you say, just make higher level creatures do more damage increasing at a rate somewhat relative to the expected armor at said level. This is fine...IF you are wearing lots of armor. If I increase damage to give creatures a chance to do damage to a heavily armored character (I don't want the player to be 100% invulnerable), then this makes low-armor characters die ridiculously easy.


I have tried several approaches, but none are satisfactory:

1) Armor reduces damage by its flat value, or a percentage of its value (still results in a linear growth in damage to keep up with increasing armor).

2) Armor reduces damage by a relative percentage (damage is reduced by something like damage/armor, which obviously is a problem with damage > armor, resulting in multiple case-specific damage calculations...ugh).

3) The CURRENT choice is a hybrid - armor reduces damage on a 1 to 1 basis, up to half of the incoming damage. I have toyed with it reducing the remaining damage by a random amount up to total armor.

4) I supposed I could change armor value to a single precision number, but it's still a linear growth progression, and ugly in terms of player presentation (Of course I can present it as other than a fractional number, but the point still stands about linear growth.)

5) A poly function might work for damage reduction, but what kind? Parabolic or logarithmic seems the natural fit, as the value of armor decreases the more you have, but where to place the limits?

Playtesting has shown none of these approaches to be exactly what I want.

Does anyone have a suggestion for such a problem? I only have 2 requirements 1) I don't want an arbitrary armor limit imposed, because it limits the differentiation of armor pieces (or at least makes the differences almost superficial.) 2) I don't want to simply increase damage to create a creature capable of hitting a high armor character,  due to the existence of low armor characters, and their resulting 1 hit deaths.

Any advice from anyone who has balanced a roguelike around a similar idea?
« Last Edit: October 01, 2014, 07:46:54 PM by Brigand »

mushroom patch

  • Rogueliker
  • ***
  • Posts: 554
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #1 on: October 01, 2014, 08:23:58 PM »
Have you looked at the way crawl handles this? How is their approach unsatisfactory to you? I wouldn't say they solve exactly the same problem or that their approach is very elegant, but they certainly solve a related problem in a way that's reasonably balanced. Some discussion of what, if anything, you don't like about how crawl does it might suggest a way forward.

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #2 on: October 01, 2014, 08:30:53 PM »
I have not looked at Crawl's implementation - I will download their source tonight and take a look, but do you know in broad terms how they do it?

mushroom patch

  • Rogueliker
  • ***
  • Posts: 554
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #3 on: October 01, 2014, 09:09:03 PM »
In broad terms, it's complicated -- lots of step down functions, special rules, and so on. The crawl wiki outlines some of the details. Check the pages on armor class, guaranteed damage reduction, shields, and evasion to get a feel for the whole picture.

Bear

  • Rogueliker
  • ***
  • Posts: 308
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #4 on: October 01, 2014, 10:24:42 PM »
Sure.  Start the user with something like a damage resistance of 5, just standing there naked.  That means whatever damage he gets, divide it by 5 before applying it.   Then just add to the damage divisor per armor class.  If he has 5 armor, he's taking half the damage he otherwise would.  If he has 10 armor, he's taking a third of the damage he otherwise would.  If he has 15 armor, he's taking a quarter of the damage he normally would.  And so on.  If you wanna be nice, you can add a rule that the same number (or half of it) is also subtracted from whatever damage remains, meaning that a well armored character is actually immune to weak attacks. 

Divisors are reasonably self-scaling.  Each point of armor with this system is then worth less than the previous one.

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #5 on: October 01, 2014, 10:31:52 PM »
Sure.  Start the user with something like a damage resistance of 5, just standing there naked.  That means whatever damage he gets, divide it by 5 before applying it.   Then just add to the damage divisor per armor class.  If he has 5 armor, he's taking half the damage he otherwise would.  If he has 10 armor, he's taking a third of the damage he otherwise would.  If he has 15 armor, he's taking a quarter of the damage he normally would.  And so on.  If you wanna be nice, you can add a rule that the same number (or half of it) is also subtracted from whatever damage remains, meaning that a well armored character is actually immune to weak attacks. 

Divisors are reasonably self-scaling.  Each point of armor with this system is then worth less than the previous one.

Oooooh, I like that, thank you. That's worth some play testing.

Worthless_Bums

  • Newcomer
  • Posts: 44
  • Karma: +0/-0
    • View Profile
    • Steam Marines - squad based roguelike
    • Email
Re: Damage reduction algorithm - looking for advice
« Reply #6 on: October 02, 2014, 01:51:38 AM »
In Steam Marines I keep overall armor and damage values low. Armor works as flat mitigation and a unit's armor degrades when that unit gets hit. Because you have multiple pieces of gear that grant armor (Steam Marines does not) you could random which piece of armor gets degraded on a hit, or implement some targeted hit system.

You might consider an armor penetration (ignore) stat for higher level creatures to tailor damage/armor scaling.

Paul Jeffries

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 257
  • Karma: +1/-0
    • View Profile
    • Vitruality.com
Re: Damage reduction algorithm - looking for advice
« Reply #7 on: October 03, 2014, 07:27:02 PM »
The way that some games (I think POWDER, maybe some others) deal with this is to display your total cumulative armour score but when you get hit the game randomly determines which part of your body was struck and then uses only the armour value of the item you are wearing in the relevant slot.  This keeps damage reduction within a manageable range and if you think about it makes a lot more sense than the alternative; if somebody stabs you in the chest it's not going to make the slightest bit of difference that you're wearing a helmet as well as a breast plate.  The downside is that the AC rating shown to the player is a bit of an abstraction but higher numbers are still always better, so it's not super misleading.

BtS

  • Newcomer
  • Posts: 24
  • Karma: +0/-0
    • View Profile
    • The Ground Gives Way
Re: Damage reduction algorithm - looking for advice
« Reply #8 on: October 06, 2014, 09:58:47 PM »
Actually, the basic idea of Crawl is really simple (if we disregardguaranteed damage reduction and special cases): on a hit reduce damage by a random number between 0 and AC.

koiwai

  • Rogueliker
  • ***
  • Posts: 99
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #9 on: October 06, 2014, 10:03:46 PM »
I like Bear's Armor Class = divisor, it's intuitivly clear.

Let me describe one more approach, I use it in Wanderers. Each piece of armor has the property D = the probability to block an attack.
Let's say you can wear a chain mail (50%), a shield (20%), and a saber that also gives you small defense (10%).

When you equip multiple items, the combined probability is not simply added up (otherwise you could easily get >100% probability).  We add the probabilities assuming that all items block as independent events:

When two items are equipped:
50% and 20% = 50% + 20% - 50%*20% = 50% + 20% - 10% = 60%.

When three items are equipped:
50% and 20% and 10% = (50% and 20%) and 10% = 60% and 10% = 60% + 10% - 6% = 64%.

And so on, you can continue for multiple items. In general, this is called inclusion-exclusion principle, and the probability can be computed iteratively the way I just showed.

This resulting probability can be interpreted both as a chance to block, or as a factor to damage, so 60% block reduces the damage by 60%. With this approach its difficult to get very high defense, and it's impossible to become 100% immune to damage, unless you put on a 100%-blocking armor. And it fits better those games where your strength does not grow exponentially.

Xecutor

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 263
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #10 on: October 08, 2014, 04:34:23 AM »
I beg you - do NOT do damage reduction like in Crawl. It's the worst idea.
Some kind of diminishing return might be a good idea.
One possible way:
armor from 0 to 10 blocks damage in 1:1 proportion.
armor from 11 to 20 blocks damage in 1.25:1 proportion. i.e. 16 armor blocks 10+6/1.25=15 damage.
armor from 21 to 30 blocks damage in 1.5:1 proportion. i.e. 28 armor blocks 10+10/1.25+8/1.5=23 damage.
etc

you can choose ranges and proportions to your liking.


BtS

  • Newcomer
  • Posts: 24
  • Karma: +0/-0
    • View Profile
    • The Ground Gives Way
Re: Damage reduction algorithm - looking for advice
« Reply #11 on: October 08, 2014, 12:14:16 PM »
I beg you - do NOT do damage reduction like in Crawl. It's the worst idea.

Could you elaborate why it's such a bad idea? I thought it was a really good way of solving it. What are the main drawbacks with this method?

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #12 on: October 08, 2014, 02:10:49 PM »
These are some great ideas - thank you guys. I have ended up settling on something pretty simple:

damage reduction = armor / (armor + modifier)

where the modifier is just an arbitrary number which produces results that work well for the armor levels in question - the bigger the number, the less effect each point of armor has. This is a slightly modified version of what Bear was talking about. It provides a bounded number from 0 to 1 (simple ratio), and lets me explicitly adjust the effect of each point of armor. Why I just didn't consider this from the start, I have no idea, considering I was headed down a much more complicated path using logs and parabolas adjusted to an arbitrary range.

I am considering combining this formula with what Paul Jeffries was talking about as far as discrete armor slots being hit, but if I do, I will need to consider what the effect on the game is if your hand gets hit, as opposed to an arm or leg. This would require a good bit of refactoring, and a lot of thought before I implement it.

I may also modify this damage reduction to not be guaranteed, but a random value bounded by the calculated damage reduction - again, play testing will bear out any good ideas.

Bottom line, thanks everyone - very constructive responses.

mushroom patch

  • Rogueliker
  • ***
  • Posts: 554
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #13 on: October 08, 2014, 04:25:55 PM »
The way that some games (I think POWDER, maybe some others) deal with this is to display your total cumulative armour score but when you get hit the game randomly determines which part of your body was struck and then uses only the armour value of the item you are wearing in the relevant slot.  This keeps damage reduction within a manageable range and if you think about it makes a lot more sense than the alternative; if somebody stabs you in the chest it's not going to make the slightest bit of difference that you're wearing a helmet as well as a breast plate.  The downside is that the AC rating shown to the player is a bit of an abstraction but higher numbers are still always better, so it's not super misleading.

I just want to put in a word against this interpretation of AC. AC is an average value which reflects overall difficulty of landing a damaging blow. The point is not that if someone tries to stab you in the heart when you're wearing a breastplate, they won't be able to stab your heart as hard once they've gotten through. The point is that stabbing through a breastplate is not a viable option in an active combat situation and an opponent must seek less straightforward alternatives, reducing their odds of landing a good hit, making it easier for you to avoid such hits, and on average reducing their deadliness. It is in this sense that wearing a helmet and a breastplate gives you a cumulative advantage.

The rock'em sock'em robot-like combat mechanics of D&D and roguelikes seems to encourage thinking that AC and HP are supposed to model combatants taking turns randomly flailing and pounding on each other with whatever's in their right hand until one's head comes off, but this isn't the right picture to have in mind.

jlund3

  • Newcomer
  • Posts: 33
  • Karma: +0/-0
    • View Profile
Re: Damage reduction algorithm - looking for advice
« Reply #14 on: October 08, 2014, 05:26:26 PM »
Just throwing out another possibility:

Damage Reduction Factor = Armor / (Armor + Modifier * Damage)

I think it is easiest to see what this does with a picture:



This plot was done with the modifier set to 1. Playing with that modifier changes the slope of the surface, but not the overall trends. As you can see, when the amount of damage is low relative to the armor, the percent reduction is high, though damage is never completely eliminated. Imagine throwing rocks at a guy in full plate armor - its not gonna do that much, although if it hits it will probably do something. On the other hand, if you use a firearm or something on our armored opponent to do a large amount of damage, the armor does a lot of damage reduction, but it has a lower damage reduction factor. In this way more armor always helps damage reduction, but you get some diminishing returns on the damage reduction factor, meaning that you don't have to increase the damage to extraordinary amounts in order to hurt heavily armored opponents.