A Protection Paladin Blog

# Revenge Combinatorics

Posted on January 18, 2013 by

Since January is apparently “Warrior Month” here at Sacred Duty, I figured I’d share a little side project I’ve been working on. Omega (of DBM fame) and I were having a conversation about warriors on Lei Shi, and what effect the lack of melee attacks did to your rage generation through Revenge. He mentioned that he’d love to see the calculation, and I said those famous last words, “Oh, that should be easy…”

Several hours later….
Several days later….

OK, to be fair, it didn’t actually take days. It was maybe 8 or 9 hours spread over 3 or 4 days, in bits and pieces. And the vast majority of that time was spent trying to get two different expressions to agree with one another. I worked up a haphazard solution for one limit (boss swing timer longer than the GCD) and then a separate but similar solution for short swing timers, and then found out they didn’t agree with one another. So most of that time was spent hunting down the error causing the inconsistency. Eventually I decided that it would be easier to put together a completely general derivation, and about an hour later had the correct solution. But since I wasted about 8 hours on this, we’ll pretend it took 9 hours just to make me feel better. It can be our little secret.

What follows is the full derivation of the average cooldown.

Derivation

The diagram below illustrates the situation. We consider a string of n GCDs, each having a duration G seconds. During that time, we have a boss attacking us with a swing timer of S seconds. It will be useful to define the maximum number of swings we’ll take during those nG seconds, so we’ll call that N.

Figure 1: Mathematical model for Revenge cooldown calculations. We’re interested in calculating the probability of avoiding a boss attack during the nth GCD (blue) given a boss swing timer S.

It’s fairly easy to find a mathematical expression for N. We note that the elapsed time from t=0 to the time at which attack N lands is $(N-1)S$, and since this must be less time than nG (otherwise attack N would happen after the nth GCD), we can write:

$\large (N-1)S\leq nG$
$\large N-1 \leq nG/S$
$\large N \leq 1 + nG/S$

Since we want to stipulate that N is the very last attack that falls within the window, we apply a floor() function and turn the $\leq$ into an equals sign:

$\large N = 1 + {\rm floor} \left ( \frac{nG}{S} \right)$

To try and put that another way, N is 1 plus the largest integer number of times you can fit S into nG. The 1 is due to the first attack at t=0, which we include in the tally.

Of course, the boss isn’t always going to attack at the very start of the first GCD. It could happen half a second into the GCD, or a full second into the GCD, or anything up to S seconds into the GCD (but not larger than S, because at that point there’ll be a new swing happening at t=0). To see what this looks like, all we need to do is shift the green boxes to the right by some amount $\tau$:

Figure 2: Shifting the time of the first attack causes the total number of attacks occurring between t=0 and t=nG to change.

Note that the amount of shifting we do has a significant effect on the math. In the figure above, we’ve shifted the green boxes over enough that the Nth attack crosses over t=nG and no longer falls within the nth GCD. Now we’re no longer taking N attacks in n GCDs, we’re taking N-1 attacks in that period of time. That changes the statistics slightly, giving us a different probability for refreshing Revenge early due to an avoid.

In the diagram above, I’m using a swing timer that’s exactly 1/3 of a GCD. But if G isn’t evenly divisible by S, we get another complication, which is that the number of attacks that occur during the nth GCD changes as $\tau$ changes. If S were just a bit bigger (see Figure 3) we would push the Nth attack “off” of the blue section before attack N-m-1 gets pushed “on” to the blue section. In that case, we’d only get two attacks during the blue GCD instead of three, as in the lower part of Figure 3.

We have to account for this variation somehow. In practice, the time that elapses between t=0 and the first incoming boss attack is essentially random, can be modeled as a uniform probability distribution. That’s good, because it makes the math pretty easy. We want to perform a weighted average of the three possible situations we can run into, which will end up being an integral. A uniform probability distribution makes that integral easier to evaluate.

Let’s set up that expression now. We’ll consider the nth GCD, which spans the period of time from t=(n-1)G to t=nG. The period of time between the start of the nth GCD and the first boss attack that occurs during that GCD will be important, so we’ll call that x. To be even more specific, x is a function of $\tau$, so let’s define $x_0$ as the value of x when $\tau=0$. In other words, for $x(\tau)$, $x_0=x(\tau=0)$.

In performing our integral, we’re going to need to consider one full period of the swing timer. That means we’ll need to integrate from $\tau=0$ to $\tau=S$, or equivalently from $x=x_0$ to $x=x_0+S$. However, due to the periodicity, we’re not bound to those exact values. We’ll get exactly the same answer if we integrate from $x=0$ to $x=S$, for example – in other words, starting in the condition where a boss attack occurs immediately upon the start of the nth GCD and ending when that boss attack has been shifted by S seconds. It turns out that it’s easier to perform this integration from $x=0$ to $x=S$, so we’ll do that instead. The situation is depicted graphically in Figure 3, where I’ve also increased the swing timer by 20% so that G is no longer evenly divisible by S:

Figure 3: Model for the development of the analytical expressions we need to calculate the average Revenge cooldown. The top panel shows the system near the lower limit of integration (x=0) and the lower panel shows the system near the upper limit of integration (x=S).

The top half of Figure 3 shows the case where x is near zero. We get three attacks within the nth GCD in this case. The lower half of the figure shows the system when x is almost at the upper limit of integration, x=S. There are only two attacks occurring during G in that case. However, we want a more general expression. It will be useful to define a value m to represent the minimum number of attacks we will take during G seconds – in other words, the number of attacks we’re guaranteed to have. We can define this mathematically in a very similar fashion to the way we defined N, giving us

$\large m={\rm floor}\left ( \frac{G}{S} \right )$

For our case, it’s easy to see that m=2. It should also be clear that we’ll only ever have m or m+1 attacks during G as a result of our definition.

Now let’s look at what happens as we increase x from 0 (i.e. slide the green boxes to the right). At a certain value of x we push attack N “off” of the blue box, meaning it no longer occurs during the nth GCD. When this happens, the sum $x+S+S$ must be equal to G (if you’re having trouble seeing that, try and draw it out on paper, it’s somewhere between the top and bottom halves of Figure 3). In the general case, the sum is actually $x+mS$ because there are $m$ full green boxes that fit inside the blue box. Setting those two equal to one another, we have an expression for this value of $x$:

$\large x = G-mS$.

Between $x=0$ and $x=G-ms$, we always have $m+1$ attacks occurring during the nth GCD. Then, from $x=G-mS$ to $x=S$, we have $m$ attacks occurring during the nth GCD. Why is this important, you ask? Well, our chance to reset the cooldown of Revenge during the nth GCD depends on how many attacks occur during that GCD. In fact, let’s figure out what that probability is now.

Assume that we have decimal avoidance $a$, such that 20% avoidance gives us $a=0.20$. It will be more convenient to use the chance that we don’t avoid, so we’ll define that as $q = 1-a$. If we take $y$ swings during a particular GCD, the probability $\rho$ that we avoid at least one of them is:

$\large \rho \left ( y \right) =1-q^y$

This should look familiar if you’ve got a bit of background in statistics, but basically it’s just saying that the probability we avoid at least one attack is 100% minus the probability that we don’t avoid any of them. For a proof, feel free to consult any introductory statistics textbook.

So far, we’ve figured out everything we need to know about what’s happening during the nth GCD. There’s one more piece to the puzzle that we haven’t dealt with yet, and it’s the one that throws the largest wrench into the works. See, we only care about the chance that we avoid an attack during the nth GCD if we didn’t already avoid one in all of the previous GCDs – if we avoided an attack in the 2nd GCD since our last Revenge cast, then we stop counting and the whole thing starts over at 0 again. We only ever get to the 3rd GCD if we didn’t avoid anything during GCDs 1 and 2, and similarly we only ever get to the nth GCD if we don’t avoid anything during the previous (n-1) GCDs.

So we need to know how many attacks occurred during the previous (n-1) GCDs. You might look at Figure 3 and guess that this is just $N-m-1$. It’s not though. This is trickier than it sounds because of the limits of integration we chose. We decided that we’d shift the entire attack stream to the left by $x_0$ so that we could consider the range $x=0$ to $x=S$. But in doing so, we pushed attack #1 to the left as well, so that it no longer occurs during the first GCD. So in fact, we have $N-m-2$ attacks occurring during the first $(n-1)$ GCDs.

However, at some value of $x$ that first attack is going to cross $t=0$ and rejoin the group, which will change the number of attacks occurring between $t=0$ and $t=(n-1)G$. That will bring us back up to $N-m-1$ attacks, and change all of our formulas. Oops.

Luckily, we know what value of $x$ this happens at – it’s easy to see from Figure 1 that it happens at $x=x_0$. And, also using Figure 1, we can write out a pretty simple definition of $x_0$ with a simple geometric argument. $N-m-1$ green blocks is the same length as the orange block, which is $(n-1)G$, plus $x_0$. Rearranging we get:

$\large x_0 = (N-m-1)S-(n-1)G$

This bifurcates our first situation (m+1 attacks during the nth GCD) into two different sections, as illustrated in Figure 4. If attack #1 crosses $t=0$ before we push attack #N out of the nth GCD, then we have to split the term where we have m+1 attacks during the nth GCD into two parts: one with N-m-1 attacks preceding the nth GCD and one with N-m-2 attacks preceding the nth GCD.

Figure 4: Diagram illustrating the four possible probability combinations for GCD #n.

We don’t know the value of $x_0$ until we chose values for G and S, of course, but we do know it occurs between $x=0$ and $x=G-mS$. It can’t happen later than $x=G-mS$, though the reason may not be obvious at first. Looking back at Figure 1, remember that $x_0$ is the value of $x$ if we line up the very first attack that occurs with $t=0$. But $G-mS$ is the value of $x$ where the Nth attack gets pushed out of the nth GCD. For $x_0$ to be greater than $G-mS$, it would mean that the Nth attack occurred after $t=nG$, which can’t happen – remember, we defined attack #N as occurring before $t=nG$ when $x=x_0$.

At this point, we have enough information to write out the expression for the probability that we reset the Revenge cooldown during the nth GCD. To see how this works, let’s write the first integral out and analyze it. From $x=0$ to $x=x_0$, we have $m+1$ attacks during the nth GCD and $N-m-2$ attacks preceding the nth GCD. We can write an integral representing the probability contribution of this first component as follows:

$\Large \displaystyle P_1(n)=\left ( \int_0^{x_0}\frac{dx}{S}\right ) \left ( 1-q^{m+1} \right ) q^{N-m-2}$

Let’s go through that piece by piece. The first part is an integral of $dx/S$, which gives us the portion of our sweep from 0 to $S$ during which the above conditions are true. If we hadn’t used a uniform probability distribution, the arguments of the integrals would have been $p(x)dx$, where $p(x)$ was the probability distribution for the incoming attack time. However, the assumption of uniformity vastly simplifies things, because $p(x)=1/S$ which is independent of $x$.

The second factor is the probability that we avoid at least one of the $m+1$ attacks that occur during the nth GCD. And the third is the probability that we didn’t avoid any of the $N-m-2$ attacks that occurred during the previous $n-1$ GCDs. So this term in its entirety gives us the probability of resetting the cooldown of Revenge between $x=0$ and $x=x_0$.

We can write similar expressions for the other two situations. If we do, we get an expression that looks like this:

$\large \displaystyle P(n)=\left (\int_0^{x_0} \frac{dx}{S}\right )\left (1-q^{m+1}\right )q^{N-m-2} + \left(\int_{x_0}^{G-mS} \frac{dx}{S}\right )\left (1-q^{m+1}\right )q^{N-m-1} \\+ \left(\int_{G-mS}^S\frac{dx}{S}\right )\left(1-q^m\right )q^{N-m-1}$

$P(n)$ is the complete probability that we reset Revenge during GCD #n. I’ve written this as if $P$ was a function of $n$ even though $n$ doesn’t’ show up on the right hand side explicitly because $N$ is a function of $n$. In general, we have all three terms. When $x_0$ is equal to zero or $G-mS$, then one of the integrals has the same upper and lower limits, which makes it identically zero, eliminating one of the first two terms.

We can simplify this a little further by evaluating the integrals. Doing so gives us our final expression for $P(n)$:

$\large \displaystyle P(n) = \left ( \frac{x_0}{S} \right ) \left (1-q^{m+1}\right )q^{N-m-2} + \left (\frac{G-mS-x_0}{S}\right )\left ( 1-q^{m+1}\right )q^{N-m-1} \\+\left (\frac{(m+1)S-G}{S}\right )\left (1-q^m\right )q^{N-m-1}$

Now that we have the probability that we’ll reset Revenge’s cooldown during the nth GCD, there’s just one more thing we need to do to finish our calculation. We want to know the average number of GCDs it takes to reset the cooldown. The average of a discrete random variable is defined to be $\bar{X}=\sum X p(X)$, where $p(X)$ is the normalized probability density function for $X$. In our case, we want $\bar{n}$, which is

$\large \displaystyle \bar{n}=\left (\sum_{n=1}^{\infty} nP(n)\right )$.

However, there’s one other detail we need to fix. The sum in the above equation should be carried out over all values of $n$ from 1 to $\infty$. However, that’s now how our system works. Revenge’s cooldown isn’t infinite, it’s 6 GCDs. So we need to truncate our sum at $n=6$, and somehow account for all of the probability we’re throwing away when we do that.

Luckily this last part is easy. We just need to express the probability that we didn’t avoid any attacks during all 6 GCDs. Looking back to Figures 1 and 2, we see that at some value of $\tau$, the Nth attack lines up with the end of the nth GCD (i.e. attack #N occurs at $t=nG$). For smaller values of $\tau$, we have $N$ attacks in n GCDs; for higher values, we have $N-1$ attacks. Geometrically we see that this value of $\tau$ is $nG-(N-1)S$. So for $\tau$ seconds out of our $S$-second period, we have $N$ attacks that weren’t avoided, which happens with a probability of $q^N$. For the other $S-\tau$ seconds, we have $N-1$ attacks that weren’t avoided, with a probability of $q^{N-1}$. If we let $n=6$, these two probabilities are

$\large Q(6,N)=\left (\frac{6G-(N-1)S}{S}\right )q^N$
$\large Q(6,N-1)=\left (\frac{NS-6G}{S}\right )q^{N-1}$

I’ve used $Q(6,x)$ to represent this, because it’s the probability that we have not reset Revenge after 6 GCDs given $x$ attacks occurring during that time. The contribution to $\bar{n}$ from both of these terms is going to be $6\cdot Q(6,x)$, because when these events occur the cooldown is the full 6 GCDs. Thus, our final expression for $\bar{n}$ is

$\large \displaystyle \bar{n}=\left (\sum_{n=1}^{6} nP(n)\right )+6\left ( \frac{6G-(N-1)S}{S} \right )q^N + 6\left (\frac{NS-6G}{S}\right ) q^{N-1}$.

And of course, the average revenge cooldown is just $\bar{n}G$.

Special Case

In testing this expression to make sure it was correct for all values of $S$ and $G$, I ran into a curious special case. Let’s let $S=2$ and $G=1.5$ and consider the first GCD $(n=1)$. Then our equations tell us that $N=1$ and $m=0$. And the expression for $x_0$ gives us $x_0=(1-0-1)S-(1-1)G=0$, which means that $x_1=0$ and $x_2=G$ (if you didn’t follow that, go back up to the expressions and plug in $N=1$ and $m=0$). Then the first term in our expression for $P(1)$ is

$\large P_1(1) = \frac{x_1}{S}\left (1-q^{m+1}\right )q^{N-m-2} = \frac{0}{S}(1-q)\frac{1}{q}$

OK, so no problem, the first term is zero, right? For most cases, that’s true. But let’s consider the special case of 100% avoidance. While it’s not realistic in-game, it’s a good extreme limit to test to make sure our equation is working properly. 100% avoidance is equivalent to $a=1$, which means $q=1-a=0$. Which is a problem – if we plug this into a computer, it sees that we’re trying to divide by zero and tells us that the result is invalid (MATLAB spits out “NaN” for “not a number” any time you divide by zero).

Before we fix this, let’s think about what the math means. We’re considering the very first GCD, with a swing timer $S$ that’s longer than the GCD. That $q^{N-m-2}$ term is accounting for the $N-m-2$ attacks that we didn’t avoid during the previous GCDs. Except wait a minute… we’re in the very first GCD! There were no earlier GCDs! So that should be identically $q^0$ whenever $n=1$.

This isn’t an issue for the other two terms because $N-m-1$ is identically 0 when $n=1$. But it leads to a weird result for this first term. There’s probably an alternative way we could write $N-m-2$ in terms of $n$, $G$, and $S$ that would fix this problem. However, it would almost certainly not be pretty. Instead of trying to spend a lot of time finding that expression, I’ve implemented a slightly easier fix: I’ve constrained the exponent $N-m-2$ to be greater or equal to zero with a max() function. Thus, if we ever get into that $N=1$, $m=0$ situation, $q^{N-m-2}$ becomes $q^0$ and no longer causes problems. This will be strictly correct for our situation as well, because we know that we can’t have a negative number of attacks preceding a GCD.

Just to check, let’s finish that example with 100% avoidance. The first term now goes to zero because $x_0=0$. The second term is simply

$\large P_2(1)=\left ( \frac{G}{S}\right )$

or the probability that the attack falls within the first GCD. The last term is also zero:

$\large P_3(1)=\left ( \frac{S-G}{S}\right ) \left (1-q^0\right )q^0 =\left (\frac{S-G}{S}\right ) (1-1)\cdot 1 = 0$

Thus, the probability of resetting Revenge’s cooldown within one GCD is just the probability that an attack happens in that GCD. It’s straightforward to show that for $n=2$, $N=2$ and $x_0=S-G$, giving just

$\large P(2)=P_1(2) = \left ( \frac{S-G}{S}\right )\left (1-q\right )$.

Or, in other words, just $1-P(1)$. Thus, as long as we have 100% avoidance, we’re guaranteed to reset the cooldown of Revenge within two GCDs if we’re getting attacked every two seconds, just as one would expect. Every other term becomes zero since $q=0$. So the result is exactly what we expect for this simple special case. If we plug in $S=2$ and $G=1.5$, we find that the result is

$\bar{n}G = 1.5 \left [1\cdot \left ( \frac{1.5}{2} \right ) + 2 \cdot \left ( \frac{2-1.5}{2} \right ) \right ]= 1.5\cdot 0.75 + 3 \cdot 0.25 = 1.875$

or 1.875 seconds.

Numerical Solutions

Now that we have the proper expressions, we can start cranking out some more general results. For all of these cases we’ll choose a GCD length of $G=1.5$, as warriors have no mechanism for haste scaling. The first thing we might want to know is how the average Revenge cooldown scales with avoidance. We’ll assume a swing timer of $S=2$ seconds and let $a$ vary from 0 to 1. Doing so gives us this plot:

Average Revenge cooldown as a function of avoidance for a swing timer of S=2 seconds.

As expected, this function seems continuous and slowly decreases to the minimum of just under 2 seconds. At around 20% avoidance, which seems like a reasonable guess for a well-geared warrior, the average cooldown is 6.2 seconds, or about a 31% reduction. The reduction very sharp between 0% and 50% and becomes shallower above 50%. This steepness at low avoidance is part of the reason dodge and parry perform as well as they do for warriors as compared to paladins. You get a pretty significant resource increase at low levels of avoidance.

This also lets us answer the original question that sent us down this path in the first place. For an average tank with ~20% avoidance, Revenge is available every 6.2 seconds. If we’re generous and say that they get lucky, we could say that they cast it every ~6 seconds instead since that’s a GCD multiple. Thus, they’d be gaining 15 rage from Revenge every 6 seconds, for a net rage generation rate of 2.5 RPS. With 0% avoidance (equivalent to a boss that doesn’t melee, like Lei Shi), you get that 15 rage every 9 seconds, for 1.67 RPS. So the net loss is about 0.83 RPS, which is pretty large (over 10% of your rage generation).

However, that’s assuming Revenge is your highest priority. In practice, it isn’t, so it will get pushed back sometimes for Shield Slam. As such it might be a better estimate to round up in GCDs, turning that 6.2 seconds into 7.5 seconds. And 15 rage every 7.5 seconds is an even 2 RPS. In that case, the loss in rage generation by not being meleed drops to 0.33 RPS. That’s only about 4% of your total rage generation. Though we should note that as we saw in the last round of Monte-Carlo simulations, even that small amount makes a significant difference in damage patterns, especially in queues that involve Shield Barrier (which Lei Shi obviously would).

We could also ask how the average cooldown varies with boss swing timer. Keeping avoidance fixed at 20% and letting $S$ vary from 1.5 to 2.5 seconds gives us the following plot:

Average Revenge cooldown as a function of boss swing timer for 20% avoidance.

This plot has some interesting features. The cooldown isn’t a continuous function of boss swing timer, which seems strange. What we’re seeing here is similar to a Moiré pattern, caused by the interference of two periodic effects at different frequencies. Whenever we hit a point at which an integral number of swing timers is divisible by an integer number of GCDs (i.e. $bS=cG$, for arbitrary integers $b$ and $c$), we get a discontinuity. So, for example, at $S=2$ (3S=2G), or $S=1.8$ (5S=6G). These variations aren’t very large, and there’s really nothing we can do about them anyway, so it’s not worth worrying about. It’s just an interesting quirk of the combinatorics.

And that quirk gets even more noticeable for swing timers shorter than 1.5 seconds. Let’s extend that plot all the way down to $S=0$:

Average Revenge cooldown vs. swing timer for 20% avoidance, now with illogically small swing timers included!

As you can see from the plot, there are lots of discontinuities occurring below $S=1.5$ because we’re rapidly scanning through different integer multiple conditions. Since few bosses (if any, nowadays) have swing timers as short as even one second, these features aren’t likely to manifest themselves in game. In cases where you have multiple mobs attacking you, such that the average swing timer is less than one second, there’s an inherent randomness that breaks the periodicity and averages out these discontinuities. If we ran a simulation instead of an analytical model, we could perform that averaging and see that it just smooths this curve out a bit. Since the variations aren’t that great to begin with, it’s not worth doing that, because this plot is good enough to give us good ballpark estimates of what we expect in those situations.

Since it’s not always easy to read off of the graph that accurately, in closing I want to provide a table you can use to look up the average Revenge cooldown given a certain amount of avoidance and swing timer. The table below contains calculated values for avoidance ranging from 0% to 30% and swing timers from 0.5s to 2.5s in steps of 0.25s.

```       -----------------------------------S-----------------------------------
|  A  | 0.50s | 0.75s | 1.00s | 1.25s | 1.50s | 1.75s | 2.00s | 2.25s | 2.50s |
|  0% | 9.000 | 9.000 | 9.000 | 9.000 | 9.000 | 9.000 | 9.000 | 9.000 | 9.000 |
|  1% | 8.358 | 8.564 | 8.670 | 8.734 | 8.778 | 8.809 | 8.833 | 8.851 | 8.866 |
|  2% | 7.776 | 8.155 | 8.355 | 8.476 | 8.562 | 8.623 | 8.669 | 8.705 | 8.733 |
|  3% | 7.249 | 7.770 | 8.053 | 8.225 | 8.351 | 8.440 | 8.507 | 8.560 | 8.602 |
|  4% | 6.772 | 7.410 | 7.766 | 7.982 | 8.147 | 8.262 | 8.349 | 8.418 | 8.472 |
|  5% | 6.340 | 7.071 | 7.491 | 7.747 | 7.947 | 8.088 | 8.194 | 8.278 | 8.344 |
|  6% | 5.947 | 6.754 | 7.228 | 7.518 | 7.753 | 7.917 | 8.041 | 8.141 | 8.218 |
|  7% | 5.591 | 6.455 | 6.977 | 7.296 | 7.564 | 7.751 | 7.892 | 8.005 | 8.092 |
|  8% | 5.267 | 6.175 | 6.737 | 7.080 | 7.381 | 7.588 | 7.745 | 7.872 | 7.969 |
|  9% | 4.972 | 5.912 | 6.508 | 6.871 | 7.202 | 7.429 | 7.601 | 7.740 | 7.847 |
| 10% | 4.704 | 5.665 | 6.290 | 6.669 | 7.028 | 7.273 | 7.460 | 7.611 | 7.726 |
| 11% | 4.460 | 5.433 | 6.081 | 6.472 | 6.859 | 7.121 | 7.321 | 7.484 | 7.607 |
| 12% | 4.237 | 5.215 | 5.881 | 6.281 | 6.695 | 6.973 | 7.185 | 7.359 | 7.489 |
| 13% | 4.034 | 5.010 | 5.691 | 6.096 | 6.535 | 6.828 | 7.052 | 7.236 | 7.372 |
| 14% | 3.849 | 4.818 | 5.509 | 5.916 | 6.380 | 6.686 | 6.921 | 7.115 | 7.257 |
| 15% | 3.679 | 4.637 | 5.335 | 5.742 | 6.229 | 6.548 | 6.792 | 6.996 | 7.143 |
| 16% | 3.523 | 4.466 | 5.169 | 5.573 | 6.082 | 6.413 | 6.667 | 6.878 | 7.031 |
| 17% | 3.381 | 4.306 | 5.011 | 5.409 | 5.939 | 6.281 | 6.543 | 6.763 | 6.920 |
| 18% | 3.250 | 4.156 | 4.860 | 5.250 | 5.800 | 6.152 | 6.422 | 6.650 | 6.810 |
| 19% | 3.129 | 4.014 | 4.715 | 5.096 | 5.665 | 6.026 | 6.304 | 6.538 | 6.702 |
| 20% | 3.018 | 3.880 | 4.577 | 4.947 | 5.534 | 5.903 | 6.188 | 6.429 | 6.595 |
| 21% | 2.916 | 3.755 | 4.445 | 4.802 | 5.407 | 5.783 | 6.074 | 6.321 | 6.490 |
| 22% | 2.822 | 3.636 | 4.320 | 4.661 | 5.283 | 5.666 | 5.962 | 6.215 | 6.385 |
| 23% | 2.735 | 3.525 | 4.199 | 4.525 | 5.162 | 5.552 | 5.853 | 6.111 | 6.282 |
| 24% | 2.655 | 3.419 | 4.084 | 4.392 | 5.046 | 5.440 | 5.746 | 6.009 | 6.180 |
| 25% | 2.580 | 3.320 | 3.975 | 4.264 | 4.932 | 5.332 | 5.641 | 5.908 | 6.080 |
| 26% | 2.511 | 3.226 | 3.870 | 4.140 | 4.822 | 5.225 | 5.538 | 5.809 | 5.980 |
| 27% | 2.447 | 3.138 | 3.770 | 4.019 | 4.715 | 5.122 | 5.438 | 5.712 | 5.882 |
| 28% | 2.387 | 3.054 | 3.674 | 3.903 | 4.611 | 5.021 | 5.339 | 5.617 | 5.785 |
| 29% | 2.331 | 2.975 | 3.582 | 3.789 | 4.510 | 4.922 | 5.243 | 5.523 | 5.690 |
| 30% | 2.279 | 2.900 | 3.495 | 3.680 | 4.412 | 4.826 | 5.148 | 5.431 | 5.595 |```

As a final note, I want to apologize for the formatting in this post. I’ve used LaTeX fairly inconsistently because the WordPress plugin for latex is ugly as hell for inline equations (you might note that it “sinks” the letters with respect to the baseline of text). It was much prettier to just use italicized letters (i.e. N, S, G, instead of $N$, $S$, $G$), but for some of the equations and symbols it was just easier to use TeX. Sorry for the ugly, if anyone knows of a good/better LaTeX plugin for WordPress, I’d love to know about it.

### Share this:

This entry was posted in Tanking, Theck's Pounding Headaches, Theorycrafting and tagged LaTeX, Raid Bosses, Scaling, tank, tanking, theck, Theorycraft, theorycrafting, warcraft, warriors, WoW. Bookmark the permalink.

### 7 Responses to Revenge Combinatorics

1. bryjoered says:

Honestly, I don’t think regular people will have any idea what most of these equations actually mean. The amount of math that you do for this game is astounding, what would we do without you? I mean I get the gist, I think, you are trying to develop (or already have) a reliable way to measure revenge procs.

2. bryjoered says:

Also, I’m not positive on this, but isn’t revenge a priority when AOE tanking? Maybe it doesn’t surpass shield slam in pure rage generation, but it sure as hell helps you keep aggro better. I normally hit thunderclap, shockwave, revenge when available, then continue my normal rotation, of course always keeping shield block up which is clearly better unless they are caster mobs.

• Sly says:

I think Shield Slam almost always hits harder than Revenge (at least since they nerfed it to do reduced damage to the second and third targets). So you’re better off keeping Shield Slam as your highest priority and tab targeting rather than moving Revenge up. This also results in better rage generation.

Furthermore, there’s really only one situation I can think of where AoE aggro is really a concern: two-tanking Windlord and trying to keep a somewhat even distribution of adds (note I haven’t completed all Heroic bosses).

My usual AoE queue is: Shield Slam > Revenge > Shout > Shockwave/Dragon Roar > Thunderclap > Devastate. Thunderclap doesn’t even beat Devastate until you get to three or four targets, either.

3. Pantherj says:

As a math major in Applied Stats 2 and Probability, this was amazing to look at. I can’t wait to open more posts to see what other satisfying concepts to observe in (mostly) real life.

4. Pingback: The Care and Feeding of Warriors: Tanking stats and design | Mass-Dispel

5. Pingback: Splashgame.Community » The Care and Feeding of Warriors: Tanking stats and design

6. Pingback: The Care and Feeding of Warriors: Tanking stats and design

• ### Theck’s Twitter

• @Slootbag I could maybe see an efficiency argument though. Large DPS gain for small relative HPG impact due to proc 1 day ago
• @Slootbag it is a sizable damage increase though, but so would just prioritizing AS with or w/o proc 1 day ago
• @Slootbag it's actually an HPG loss though. The probability of wasting a proc is very small, so the loss incurred by CS pushback is greater 1 day ago
• @Slootbag @ConverttoRaid TLDR rarely worth separating AS from ASGC, and none of the edge cases boost one over CS/J but not the other 1 day ago
• @Slootbag @ConverttoRaid or you want max DPS, in which case AS> all regardless of proc status. 1 day ago
• ### Ana’s Twitter

• Third time I've heard Clarity in the last hour. Good thing I still love this track! 5 hours ago
• Hey @riftmaker I made you assist again- I might be late and miss the start! Getting in the car soon, 2.5 hrs away 7 hours ago
• My grandfathers old friend, taking a photo of me, my two sisters and my mom, calls out: "OK ladies, tits up!" ......... What. 22 hours ago
• Turned my radio back on at the awesome \$25/6mo deal. Live EDC NYC playing!! Oh my xm, I missed you! 1 day ago
• Only 30 min into this car trip and already I desperately miss my satellite radio. I wonder how fast it would be active if I called to resub. 1 day ago
• ### Mel’s Twitter

• @Esoth @KihraOfTemerity @Kerriodos @methodtreckie @Anafielle Say what now? That sounds almost exactly like my philosophy. 4 days ago
• @SerrinneWoW Co-incidence, or the start of a pattern? :P 1 month ago
• @Rhidach @_vidyala @SerrinneWoW Clearly Sara isn't a foodie. Anyone who knows me knows how I go out of my way to avoid a good meal. 1 month ago
• @SerrinneWoW Are you stalking me? 1 month ago
• @_vidyala @SerrinneWoW @Jasyla_ @Kaleri_ @Chronis_ Liekwise! Sorry I had to miss dinner yesterday. 1 month ago

Cancel
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 190, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "github"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.9383133053779602, "perplexity_flag": "middle"}