(Written by our developer, Yellowfive)
The first version of this was posted on Nov 16, 2016 for feedback. Based on some good conversations with the community, we have updated the metric and this post to reflect those changes. (Dec 1, 2016). The main updates are related to self-healing and stamina.
NPS
NoPeS. That’s what tanks do: they nope you. Want to hurt me? Nope. Need some healing to stay alive? Nope, I got this. Can I hit you for 2 million damage please? Nope, let’s make that 1 million.
In a sentence: “NPS” measures how good you are at reducing the size of each incoming hit, and reduces your chance to die.
For the sake of ease, let’s say the “N” stands for “negation” in this discussion.
Motivation
The goal of NPS is to create a metric that is easy to understand and meaningfully quantifies the value of disparate sources of toughness. A secondary goal is to create a metric that can be used to generate reports that clearly show how much all of your different actions are contributing to your toughness relative to each other — data that has been sorely missing for tanks since… forever.
How is it calculated?
First, we calculate your chance to live through any given fight without dying. This is pretty easy with our simulator — just keep track of whether you die or not! The AMR simulator is the only tanking tool created thus far that can actually calculate a meaningful chance to die — more on this in the simulator section below.
Second, we calculate the percent of raw incoming damage that you negate. There are many ways to negate damage: reduce it via armor or versatility, avoid it, absorb it, or heal it back up. A few sources of negation need some extra explanation.
Self Healing
We only consider effective healing — all overhealing is ignored. In addition, we subtract any overhealing that you cause your tank healers to do. This only applies to direct heals that the tank healers have decided to cast on you because your health dropped down for a long enough period of time for them to see it.
The healer overheal adjustment turns out to be extremely minor, but it is useful to ensure that poorly timed heals don’t seem to give more value than they actually are. If you consistently heal yourself just as or after your tank healer decides to start casting on you and thus cause your healer to waste heals, your self-heals have very little value. The opposite is true as well: if you consistently decide to heal just as or after your tank healers heal you, you will tend to overheal. We don’t want total negation to see these situations as fundamentally different — both represent situations where you are healing in a suboptimal way.
Stagger
Brewmaster’s Stagger deserves some special mention. We handle this in a very straightforward manner: self-damage is treated as negative negation. Thus if you never purified any of your stagger, you would gain exactly zero negation. The fact that spread-out damage is far less threatening than spike damage is irrelevant — chance to live will tell us all we need to know about that.
Max Health
Increasing your maximum health does nothing to negate damage. Max health’s main benefit is increasing your chance to live, which we account for directly. There are some indirect benefits such as making some abilities or heals larger, but those will all be accounted for by the impacted abilities. Though we don’t have a direct adjustment for max health, don’t be fooled — it is the single most important stat for all tank specs (along with armor). Chance to live is highly dependent on it.
Final Calculation
Now we have two numbers between 0 and 1 (or 0 and 100%, but we use the decimal form internally): chance to live, and percent of raw damage negated. We give those equal weight and combine them, with a small adjustment for edge cases: it is extremely rare to have below 50% negation. You more or less have to take off all your gear to get that low. So negation below 50% is only given 5% of the total score (so that if you are testing edge cases we can distinguish between them, and so that changes in negation within reasonable ranges have a bigger impact on score), and the remaining 95% of total score is split equally between negation from 50-100% and chance to live from 0-100%.
As an example, say you have 85% negation and 95% chance to live (pretty realistic numbers if you are appropriately geared for a fight).
Your “low” negation (below 50%) would be 1.
Your “high” negation (above 50%) would be (0.85 – 0.5) / 0.5 = 0.7.
Your chance to live would be 0.95.
Total = (1 * 0.05) + (0.7 * 0.475) + (0.95 * 0.475) = 0.83375
We then multiply by 500,000. This number is arbitrary and doesn’t really matter — we just use a number to get into the ballpark of DPS and HPS numbers for this expansion. It helps make things like stat weights into easier-to-use numbers that don’t run into precision issues.
NPS = 0.83375 * 500,000 = 416,875
Simulator Details
It is worth noting a few details about how the AMR tank simulator works because it will have a huge impact on NPS.
Incoming Damage
Incoming damage is scripted using a simple boss script mechanism based on real abilities used by real bosses. Most tank damage is very regular in boss fights. A great example is our Ursoc script — it matches the actual log for an Ursoc fight very closely without being overly complex. When damage is dealt to the tank, we replicate the actual game mechanics exactly as the game would do it — same as you would expect from a DPS or HPS simulation.
Incoming Heals
We simulate heals coming in on the tank from external healers using a simplified set of rules that realistically approximate generic healer behavior. We consider a 20-man raiding scenario with 4 healers for some scripts, and a 5-man scenario with one healer for others. In the 20-man scenario, we assume all 4 healers keep a single HoT on the tank, one healer is giving specific attention to the tank, and two healers will respond in “emergencies”.
The size of heals scales with the tank’s average item level, the idea being that well-geared tanks are getting healed by well-geared healers. The rules for when healers cast are relatively simple (and subject to further tweaking), but generally follow patterns like “cast a direct heal if the tank’s health drops below X%” or “use my instant/big heal if the tank drops really low below Y%”, or “add another HoT on the tank if health is going down but still pretty high.”
We used combat logs as a baseline to determine the actual amount of HPS being done to tanks in real fights, and split it between passive healing (HoTs, beacon, atonement, etc.) and direct healing/attention. The goal was to have realistic but not overly-aggressive tank healing. Too much tank healing makes it hard to value things like self-healing. Not enough causes too many unrealistic deaths.
Rotations
Tank rotations have all the flexibility available to DPS rotations, and a set of tank-specific functions that allow rotations to respond to predictable “big damage” events. For example, on Ursoc it is extremely predictable when Overwhelm or Rend Flesh will hit. A good tank will time up active mitigation and cooldowns with these kinds of damage spikes. Our simulator allows you to make these kinds of decisions with relative ease, resulting in very realistic and efficient ability usage.
The AMR simulator also has very advanced off-GCD rotation checking, allowing smart and efficient cooldown usage in parallel with the main GCD-locked rotation.
Death
When you die in the simulation, you stay dead for 3 seconds and then get resurrected to 60% of your maximum health, like most battle resurrection spells. Ending the simulation on death and starting again results in far too much volatility — it would take forever to get meaningful results from the simulator. This approach works well in most realistic cases where chance to die is very low. By staying dead for a few seconds and getting resurrected to a reasonable level of health, we prevent most of the bad things that death can do to a simulator: triggering “below X% health” effects too much or not at all, dying repeatedly and using instant resurrection as a great way to get infinite heals, really bizarre results due to health going negative, etc.
Reporting
A major goal of the NPS metric is to produce a report that shows a meaningful breakdown of how much each source of negation is contributing to keeping you alive. The by-spell breakdown that you see on the simulation result report is total negation contributed by each ability. A few decisions had to be made about how to divide up the value between simultaneously active sources of negation — this has no impact on the final total value (and thus no impact on any gearing strategies or conclusions drawn from the metric value itself). It simply changes the by-spell breakdown, and thus might impact how you think about the relative worth of certain abilities when viewing the report.
How the Combat Log Works
The way we end up reporting is significantly different than the in-game combat log, or what you might see on a combat logging website, particularly with regards to things like Block and auto-attack reductions like Blessed Hammer. The way that the combat log reports these abilities significantly undervalues them. This is best understood by example:
Say a boss melee attack hits you for 1m raw damage. You have 50% damage reduction from armor, you block 40% of the damage, and your Blessed Hammer adds another 15% damage reduction. Your final damage taken is calculated by multiplying all these reductions together:
1m * 0.5 * 0.6 * 0.85 = 255k
The way that the game reports this in the combat log is by applying these reductions in a very specific order:
1m * 0.5 = 500k base hit after armor
500k * 0.6 = 300k, 200k blocked
300k * 0.85 = 255k, 45k absorbed by Blessed Hammer
Thus in the combat log you will see 200k blocked, and the Blessed Hammer line under healing done will say 45k absorbed.
This “accounting” significantly undervalues both the block and the absorb. These are all just damage reduction multipliers that multiply together. Multiplication is commutative, meaning you can do it in any order and get the same result. Let’s say that the game decided to apply Blessed Hammer first, then block, then armor, just for kicks:
1m * 0.85 = 850k, 150k absorbed by Blessed Hammer
850k * 0.6 = 510k, 340k blocked
510k * 0.5 = 255k after armor
We end up with the same 255k damage taken, but now we are reporting Blessed Hammer as 3x as much absorption, and that you blocked 75% more damage!
The point is this: it doesn’t matter what order the game actually applies the modifiers — they could have chosen any order they felt like and got the same result, but the order has a huge impact on how we perceive each source of reduction. We might look at a combat log and say “Blessed Hammer? Meh.” But if it were reported 3x larger… there would probably be 20 theorycrafters saying “lol ur bad if you take any other talent.” And nothing changed about how much damage you actually take… just how we report it.
How AMR Works
So how do we take that previous example and give an “unbiased” report of the value of Armor, Block, and Blessed Hammer?
In general, we first figure out the total damage prevented: in this case 1m – 255k = 745k. Then, we split that proportionally between all active damage reductions. In this case we have 0.5, 0.4, and 0.15. Just total those up to 1.05, and split it:
745k * (0.5 / 1.05) = 354.8k to armor
745k * (0.4 / 1.05) = 283.8k to block
745k * (0.15 / 1.05) = 106.4k to blessed hammer
That’s pretty close to the final values we report, and looks a lot more “fair” to the true power of each ability. But there’s one more piece…
Avoidance
Parry, Dodge, and Block require some further special handling to give each a fair share. Let’s create a new example and say that we have Armor that reduces damage by 50%, and 50% chance to dodge. And let’s say that we take 10 hits for 1m damage each. It’s pretty straightforward to figure out the final damage that we will take: every hit will land for only 500k, and only half (5) of those will connect at all, for 5 * 500k = 2.5m total damage, or 7.5m total damage prevented.
So how should that 7.5m damage be split? For Dodge (and Parry): a 50% chance to Dodge essentially acts like a 50% damage reduction, so both the Armor and Dodge in this scenario are of equal value. 3.75m goes to each. The way this is calculated on a per-attack basis is similar to our first example, we add your dodge chance to the list of sources of damage reduction on each attack that can be dodged, whether you dodge it or not:
Total reductions: 0.5 (armor) + 0.5 (dodge) = 1
Dodged Attack:
1m hit, does 0 damage because dodged it: 1m total damage prevented
1m * (0.5 / 1) = 500k to armor
1m * (0.5 / 1) = 500k to dodge
Not-Dodged Attack:
1m hit, does 500k damage after armor, didn’t dodge it: 500k total damage prevented
500k * (0.5 / 1) = 250k to armor
500k * (0.5 / 1) = 250k to dodge
This gives us the 50/50 split between Armor and Dodge that makes sense for this scenario.
Going back to our first example with Block, we need to apply this same principle to blocking, which essentially acts like a “partial dodge”. Every hit that can be blocked, we add the current block chance * block amount (* 1 + crit block chance for warriors) to the list of things that the final prevented damage is split between, whether we block it or not. This might seem a little “weird”, but doing it any other way will short-change block. Here is another simplified example to demonstrate:
Say you take 10 hits for 1m raw damage each.
Scenario 1:
Armor: 50% DR
Total damage prevented: 10 * 500k = 5m (prevent half the damage on all hits)
Scenario 2:
Block: 50% chance to block 50% damage
Total damage prevented: 5 * 500k = 2.5m (block half the damage on half the hits)
Scenario 3:
Armor: 50% DR
Block: 50% chance to block 50% damage
- 5 hits land for 1m * 0.5 = 500k, 500k prevented
- 5 hits land for 1m * 0.5 * 0.5 = 250k, 750k prevented
- Total damage prevented: 5 * 500k + 5 * 750k = 6.25m
We can use these 3 simplified scenarios to eyeball the relationship between these two sources of damage, then verify that our math will give the expected result. The Armor is twice as good as the Block, which makes sense: the Block only happens half as often for the same amount. The block is essentially acting like a 0.25 damage reduction, since it only happens half the time, or 0.5 * 0.5.
When the two are combined, the final damage taken acts like you multiplied a 0.5 and 0.25 damage reduction together: 0.5 * 0.75 = 0.375 multiplier on damage taken.
So on our final NPS report for this case, we want to see Armor as worth 2x Block. To get this result, we need to use the method described for Avoidance: on every single hit that can be blocked, whether it is blocked or not, add in block chance * block amount when portioning out the total damage prevented.
Total reductions: 0.5 (armor) + 0.5 * 0.5 (bock) = 0.75
Blocked Attack:
1m hit, does 250k damage after 0.5 * 0.5 reduction, 750k total damage prevented
750k * (0.5 / 0.75) = 500k to armor
750k * ((0.5 * 0.5) / 0.75) = 250k to block
Not-Blocked Attack:
1m hit, does 500k damage after armor, didn’t block it: 500k total damage prevented
500k * (0.5 / 0.75) = 333.3k to armor
500k * ((0.5 * 0.5) / 0.75) = 166.6k to block
This gives us the 2 to 1 split between Armor and Block that we desire.
Summary
The tanking community has had plenty of good theorycrafters over the years, but has lacked a comprehensive tool akin to a DPS simulator. Mainly this is because it’s a lot harder to simulate a tanking situation than a DPS situation. With NPS and the AMR simulator, we finally have a “complete” tool for evaluating tanks. The NPS metric works very well for generating gearing strategies and useful reports about various sources of negation. The AMR simulator allows scripting realistic incoming damage and has realistic incoming healing. Rotations can be written that respond intelligently to predictable boss attacks. And most importantly, the AMR simulator can calculate a realistic chance to die on any given fight, thus doing away with a lot of guesswork about tank gearing. We encourage you to try it out, customize it, and give us your feedback.
Appendix: Other Metrics
There are several other metrics that have been used for tanking. Here we compare them to NPS.
DTPS
Damage taken per second is the simplest measure for a tank, and often seen in logs. It is of limited use though. Some tank specs just take more damage and rely on self-healing. Its main use is as a relative measure when comparing two players of the same spec. If one player is able to take less damage, it might be interesting to figure out why. But it’s still only sort of interesting… maybe one guy takes more total damage but dies less because his timing is better, or he heals himself back up between hits better.
HRPS
Healing required per second is a metric that we showed on our logs in WoD, and has been used in various forms elsewhere. It measures how much external healing people had to do to keep you alive. This is better than DTPS in many cases because it doesn’t ignore self-healing. It can be interesting to know how much work it takes your healing team to keep you alive. It has one major limitation though (which is also a limitation of DTPS): it can’t value max health increases. If you have a huge health pool but require more healing, you might actually be a lot tougher (die less), but that won’t be reflected at all.
TMI
The “Theck-Meloree Index” was created by a couple good theorycrafters a few years ago, full details here: http://www.sacredduty.net/theck-meloree-index-standard-reference-document
The short version is this: it keeps a 6-second moving average of the damage that you take minus the healing and absorption that you do to yourself. This is normalized to your max health at any given moment. Then some fancy math is done to the results that spit out a lower number if that total in any 6-second window is less than your max health and happens infrequently. It spits out a higher number if you take more than your max health in any 6-second window and it happens frequently. In other words: smaller and less frequent spikes in damage is the best scenario, lower is better.
TMI is a great concept and caught on in the community, to a degree. We calculate it in the AMR simulator and show it on the report pages, or you can generate batch simulations to compare it. Though it is interesting, it is largely unnecessary if you can calculate a realistic chance to die — that is ultimately what TMI is trying to measure. The more complete model in the AMR simulator can measure your death chance directly, so there isn’t a need for this layer of indirection anymore. Also, as your chance to die approaches zero, TMI becomes less interesting. The spikes you are taking are no longer threatening, so trying to reduce healer burden through total negation is a more valuable toughness goal.
NPS
NPS attempts to address all of the weaknesses of these three older metrics. It factors in healing required (negation is essentially the “inverse” of healing required), thus handling the biggest limitation of DTPS. It factors in max health via measuring death chance, thus handling the biggest weakness of HREQ/S. It simulates real tanking situations with incoming heals, realistic damage patterns, and actual tank death. This removes the necessity for a layer of indirection on top of the simulation results which is TMI’s biggest weakness: complexity and extra assumptions.
So is NPS perfect? Nope! But it is a big step forward. Directly measuring death chance is a huge win for evaluating truly threatening tank scenarios and valuing things like max health. For non-threatening fights where your death chance is zero, total negation is the only thing that moves your score — a better goal if you want to pile on the toughness and bring one less healer to your raids.