## The Making of a Metric: Part 1

Simulationcraft now has full support for protection paladin mechanics, and hopefully in a week or two I’ll get around to writing a how-to blog post on using it and interpreting the data.  Once I write a few batch files, it should produce all of the DPS results I could generate from the MATLAB FSM code and more.

What it doesn’t have yet is a good smoothness metric with which we can assess our survivability. Of course, that’s not really Simcraft’s fault, because a good smoothness metric doesn’t exist yet.

So if we want a metric, we have to build it ourselves.

Up until now, we’ve looked at data and made qualitative assessments about the results to come up with statements like “X smooths better than Y.”  But now we want to  quantify that thought, which is a lot more difficult.  We want a numerical estimate of how much better X is than Y.  And to do that, we need to get a little introspective and think about what we’re doing when we make those qualitative assessments.  We need to analyze our process and figure out how to translate it into numbers.

Data

So let’s start with some data.  Below are the results of a 10k-minute sim like I usually show on the blog.  We’ll use this sample data set for all of the following analysis. The gear sets are variants on the Control/Haste setup – the first is just C/Ha, followed by sets where I add 1000 of a given stat.  In the case of hit and expertise, I subtract 1000 since we start at the cap. We’ll use a boss that swings for 350k after mitigation every 1.5 seconds, the standard SH1 finisher priority, back-calculated Seal of Insight with no overhealing apart from inherent, and Sacred Shield enabled.

Here are the gear sets:

|    Set: |  C/Ha |  Stam |   Hit |   Exp | Haste |  Mast | Dodge | Parry |
|     Str | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 |
|     Sta | 28000 | 29000 | 28000 | 28000 | 28000 | 28000 | 28000 | 28000 |
|   Parry |  1500 |  1500 |  1500 |  1500 |  1500 |  1500 |  1500 |  2500 |
|   Dodge |  1500 |  1500 |  1500 |  1500 |  1500 |  1500 |  2500 |  1500 |
| Mastery |  1500 |  1500 |  1500 |  1500 |  1500 |  2500 |  1500 |  1500 |
|     Hit |  2550 |  2550 |  1550 |  2550 |  2550 |  2550 |  2550 |  2550 |
|     Exp |  5100 |  5100 |  5100 |  4100 |  5100 |  5100 |  5100 |  5100 |
|   Haste | 12000 | 12000 | 12000 | 12000 | 13000 | 12000 | 12000 | 12000 |

And here are the simulation results:

Finisher = SH1, Boss Attack = 350k, SoI model=nooverheal data set metric-10000-3

| Set: |   C/Ha |   Stam |    Hit |    Exp |  Haste |   Mast |  Dodge |  Parry |
| mean |  0.261 |  0.261 |  0.270 |  0.269 |  0.255 |  0.255 |  0.255 |  0.255 |
|  std |  0.103 |  0.103 |  0.106 |  0.106 |  0.102 |  0.102 |  0.104 |  0.104 |
|   S% |  0.522 |  0.522 |  0.507 |  0.513 |  0.531 |  0.522 |  0.523 |  0.523 |
|   HP |   755k |   775k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  2.158 |  2.215 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ |
|  50% | 46.002 | 45.122 | 48.989 | 48.683 | 43.896 | 44.417 | 43.900 | 43.963 |
|  60% | 29.901 | 27.764 | 32.974 | 32.571 | 27.952 | 27.702 | 28.195 | 28.208 |
|  70% | 16.203 | 15.421 | 18.813 | 18.474 | 14.560 | 15.093 | 14.995 | 15.120 |
|  80% |  7.291 |  6.228 |  9.267 |  9.050 |  6.320 |  6.214 |  6.705 |  6.811 |
|  90% |  2.526 |  1.744 |  3.623 |  3.422 |  2.056 |  2.137 |  2.264 |  2.311 |
| 100% |  0.617 |  0.394 |  1.046 |  0.966 |  0.443 |  0.571 |  0.543 |  0.544 |
| 110% |  0.103 |  0.060 |  0.232 |  0.196 |  0.066 |  0.080 |  0.088 |  0.088 |
| 120% |  0.024 |  0.013 |  0.070 |  0.055 |  0.016 |  0.018 |  0.023 |  0.021 |
| 130% |  0.002 |  0.001 |  0.009 |  0.007 |  0.001 |  0.001 |  0.002 |  0.001 |
| 140% |  0.000 |  0.000 |  0.002 |  0.001 |  0.000 |  0.000 |  0.001 |  0.001 |

For now, I’ve narrowed our focus to 4-attack moving averages.  In theory this will be equally applicable to any string size, but there’s little point in providing data that we’re not going to use at the moment.  And for Simcraft, we’re going to have to choose a default time window for our moving average.  The 3- and 4-attack moving averages are the ones we focus on the most, and 4 attacks is closest to the time window I had in mind (5-6 seconds).

This is some Inception-level shit right here…

Now, let’s think about how we analyze this data.  Normally we look at the top few categories and draw qualitative conclusions from that. For example, adding 1000 haste vs. 1000 mastery, we see that haste comes in lower (or equal) in spike representation for all rows above 90% player health.  On the other hand, we pay less attention to rows that contain a large percentage of attacks across the board, because those are very likely to happen, and reducing the amount is rarely meaningful.  If something happens 8% of the time rather than 9%, that’s not a huge change because it’s still going to happen a lot during an encounter, so you need to plan for it happening anyway.

Within those top few categories that we consider, we tend to put heavier emphasis on the larger spikes than the smaller ones.  If we can significantly reduce spikes that are 130% of our health, then that’s perceived as a lot more important than an equal reduction in spikes that are 110% of our health, especially if there’s still a sizable percentage of those events.

So according to this data, we would conclude that haste is better than mastery, though not by a huge amount. Dodge and parry are both worse than haste, but stamina is a little better. It’s hard to say how hit/exp fare since we subtracted 1000 points instead of adding 1000 points, so ignore them for now.

Analyzing the analysis

Our qualitative assessment primarily looked at two factors:

Spike magnitude – A 130% spike is more important than a 120%, than a 110%, and so on. We mentally assigned more importance to the largest spikes than the smaller ones.  This has to be accounted for in our numerical analysis.

Spike frequency – This one is more complicated, because it’s not as straightforward as “bigger is worse.”  We care about how frequently things happen, and we care about changes in that frequency.  But not all changes are created equal.  Some examples:

• If we have 5%-10% representation in a category, those are going to happen unless we eliminate them. Going from 7% to 6% (as we do in the 80% spike category when we add 1000 stamina to C/Ha) isn’t really all that meaningful a change, and shouldn’t be worth a whole lot.
• But a representation of 0.002% isn’t that likely at all, and may not even be worth worrying about. Going from 0.002% to 0.001% is probably not that meaningful either even though you’re halving the number of spikes, because those spikes weren’t very likely in the first place.
• Reducing a 1% chance to 0.1% would be a meaningful change, because that’s a pretty noticeable reduction from a non-trivial amount.  You’re taking something that was very likely and making it fairly unlikely.  Similarly for 0.1% to 0.01% – something unlikely to something really unlikely.
• Going from 0.01% to 0.001% is the same change (a factor of 10), but maybe not as important because it wasn’t very likely to begin with.  Going from 0.001% to 0.0001% is almost irrelevant, because both are so unlikely.
• That said, there’s always some comfort in the certainty that an event can’t happen, so there’s almost always some (admittedly nebulous) value in reducing a representation to 0.000%.  But it’s obviously more valuable when you reduce a non-trivial chance into 0%.

It’s easier to describe how to do this with some pictures. Below is the overall spike histogram for the haste and mastery gear sets. This is exactly the same data that’s in the table, just in bar plot format, and instead of using bins that are 10% of your health wide, I’m using 2% wide bins.  The x-axis is the percentage of your health (expressed in decimal form, so 1.00 = 100%) and the y-axis is the number of events. The distribution is roughly centered around 50% health, with a large spike at 0% due to 4-attack avoidance or full absorb strings. This is pretty standard for these sorts of histograms.

Histogram of the 4-attack damage string data.

However, we don’t look at the whole histogram (in fact, the table only ever shows the top half of it). We look only at the highest-damage parts, which you can’t really see on that plot because the bars are tiny compared to the bulk of events in the middle. So in the plot below I’ve zoomed in on the very top end of the distribution. This figure shows the top 5% of all events – i.e., the 5% of events that have the highest damage value. Relating this to the table, it’s cutting off every row that has a number greater than 5.000 in the C/Ha column (around 82% player health is the cutoff).

A close-up of the top 5% of the data.

We see that haste and mastery are pretty similar here, which isn’t surprising since their data isn’t that different. Haste is a little better, but it’s easier to see that on the table than in this plot because the table uses a coarser binning. Nonetheless, we want to use this plot (or rather, the data it’s showing) to generate a quantitative metric.

The first thought is to subtract the two bar plots from one another. In other words, do something like this:

Histogram showing the difference of the haste and mastery histograms.

We could just sum all of the bins and get a number that represents the difference between haste and mastery. However, that’s ignoring the fact that these events are not equal: the events at 1.3 (130% of your health) are much, much worse than the ones at 0.85 (85% of your health). So what we really want to do is apply a weight function. Basically, we multiply each bar by a number representing how important that bin is, and then perform the sum. You may be familiar with the term “weighted average,” which is exactly the operation we’re performing.

For a simple example, consider the table below.  The first two data columns show the representations for the +1000 haste and +1000 mastery gear sets.  The third data column shows the difference between these values, just like we’re showing in the differential histogram above.  The next column is the weight factor, which represents how much we care about a certain category.  The final column is the product of the difference and the weight factor, which gives us a numerical representation of how much “value” we’ve gained or lost in that spike category.  And if we sum that column we get the weighted average, which is an overall “score” that tells us how much better or worse haste performs than mastery at smoothing.

Percentile
Haste Set
Mastery Set
Diff
Weight
Weighted
Value
80% 6.320 6.214 0.106 0.25 0.0265
90% 2.056 2.137 -0.081 0.5 -0.0405
100% 0.443 0.571 -0.128 1.0 -0.128
110% 0.066 0.08 -0.014 2.0 -0.028
120% 0.016 0.018 -0.002 4.0 -0.008
130% 0.001 0.001 0 8.0 0
140% 0.000 0.000 0 16.0 0
Sum: -0.178

In practice we’d do things slightly differently to get scale factors.  We would start the same way, by calculating the histograms for a baseline (C/Ha) and for new configurations with 1000 of each stat added.  But then we would subtract all of the +1000 sets from the baseline (rather than from each other), and then perform the same weighted average sum to get the scale factors describing how well each stat “smoothed” our damage intake.

Of course, we’ve glossed over the most important part of the problem: what weight function do we use?  This is a critical consideration, because the weight function is everything.  Get it right and you have a robust metric that works well; get it wrong and you have garbage.  This is where our breakdown of the factors we used in the qualitative assessment come into play.  We want to weight the higher spike categories more heavily than the lower spike categories, and we want larger changes to be more valuable than smaller changes.

There are lots of functions we could choose – a simple linear function, the Fermi function we explored when modeling Seal of Insight, and dozens of others. But what felt natural to me was an exponential function. For example, $w(x) = e^{a(x-1)}$, where $a$ is some constant that determines how quickly the function changes and $x$ is the spike size (again, in decimal form, so 100% of your health is 1.0, 90% of your health is 0.9, and so on). For those who aren’t familiar with what an exponential function looks like, here it is:

Exponential weight function with $a=10\ln(2)$.

So for example, the bin corresponding to 100% of your health is worth exactly $w(1)=e^{a(1-1)}=e^{0}=1$. The bin corresponding to 90% of your health is worth $w(0.9)=e^{a(-0.1)}=e^{-a/10}$. This form is a bit unwieldy because it’s hard to translate between the constant $a$ and the behavior of the function.  We know that a larger $a$ will make the function steeper and increase the value change between one bin and the next, and that a smaller $a$ will reduce that value change.  But it’s not obvious from looking at it what happens to the relative valuation of one spike size to another with an arbitrary change in $a$.

To make this more intuitive, let’s make a substitution.  Let $a=10 \ln(h)$. That makes the equation $w(x)=e^{10 \ln(h) (x-1)} = h^{10(x-1)}$. Why does this make it easier?  Well, consider what happens if we evaluate $w(x)$ for increments of 10% of your health, as I’ve done on the table below:

 50% 60% 70% 80% 90% 100% 110% 120% 130% 140% 1/32 1/16 1/8 1/4 1/2 1 2 4 8 16

In other words, for every 10% of your health you get a factor of $h$.  A spike that’s 10% larger is $h$ times more important, and a spike that’s 10% smaller is $1/h$ times as important.  The single variable $h$ controls how much weight a bin gains or loses if it’s one health decade away from 100% health. So we could call it the health decade factor, or HDF for short. If our top events are at 140% health and the smallest event we want to consider is at 90%, the top events will be approximately $h^5$ more valuable than the bottom ones.  Very straightforward.

The other reason this is good is that it works no matter where you are on the x-axis.  If our top events were between 50% and 100% of our health, each bin would get multiplied by a smaller factor, but you still have the same relative $h^5$ weight between the top and the bottom.  If we used a different function this might not be the case, and the metric wouldn’t work as well for an arbitrary distribution.

Of course, we still need a good value for $h$ that represents the effects we want.  There’s no obvious choice here, either.  It is, by its nature, sort of arbitrary.  We’re not attempting to model an exact number we can expect to see in game, like DPS or DTPS.  We’re trying to come up with a number that represents smoothness in damage intake, but the actual value isn’t that important.  What is important is that the value mimics a thorough qualitative assessment.  It doesn’t matter whether the value we get is 10 or 100 or 1000 as long as a similar amount of improvement from another stat gives a similar value and a larger or smaller amount of improvement gives a larger or smaller value, respectively.

Meloree and I discussed this at some length and guessed at a value of $h = 2$, which is also what I used for the weight function plot above. The idea here is that a 90% health spike is about half as important as a 100% spike, while a 110% spike is twice as important.  To see how this weight function affects the histogram, let’s multiply the entire histogram by the weight function.   That gives you the plot below.

Weighted histogram generated by multiplying the raw histogram data by an exponential weight function with $h=2$.

If you compare this to the un-weighted distribution provided earlier, you can clearly see that the weighted distribution gets shifted up by the nonlinear weighting function.  The events near 0 are practically worthless, while the events near the top get more valuable.  If we zoom in on the top 5% of events again, we get the following plot:

The top 5% of the raw histogram data after multiplication by the exponential weight function.

This has clearly increased the value of the higher-magnitude spikes compared to the lower-lying spikes. Mission accomplished, perhaps?

Well, no, not quite.  There are a few problems with this.

First, note that the few events occurring near 1.35 on the x-axis are still not worth very much – far less than the thousands of events that occur at ~0.85. Those events at 0.85 are going to happen, that’s around 1% of all events just in that bin. I’m not sure they should have so much more weight than the far more dangerous ones at the top.

Second, if you calculate the weighted average of the difference between the haste and mastery data, we get a number that suggests that mastery is better than haste. But our qualitative assessment gave us exactly the opposite answer!  What’s going on here? Did we screw something up?

The result seems paradoxical at first until you look a little deeper and realize what’s happening. With this value of $h$ we’re still very, very sensitive to “edge effects.” You get a different answer if you look at the top 5% of events than if you look at the top 4%, top 3%, top 7%, etc.  To illustrate that, here are the differential figures for the top 3%, 4%, 5%, and 7% of all events:

Differential histogram of the top 3% of the raw haste and mastery data.

Differential histogram of the top 4% of the raw haste and mastery data.

Differential histogram of the top 4% of the raw haste and mastery data.

Differential histogram of the top 7% of the raw haste and mastery data.

Differential histogram of the top 10% of the raw haste and mastery data.

You can see that the last bin on the left is generally the largest one, and while these plots are un-weighted, the problem is that the number of events in that last bin tends to increase in size faster than the weight function dies off.  To quantify that further, let’s actually calculate some stat weights.  Below is a table of the stat weights calculated this way for different cutoffs, starting from the top 1% and going to the top 10% most damaging attacks, along with a final row where we include 100% of attacks (i.e. all-inclusive) for a reference. Note that since we’re considering stat weights, a bigger number means it’s a better smoothing stat.  I’ve also properly adjusted for the fact that we’re subtracting hit and expertise instead of adding them, which just requires an inversion (e.g. -5922 becomes 5922).

hdf=2.00, N=200, vary pct

|   pct |  Stam |  Hit |  Exp | Haste |  Mast | Dodge | Parry |
| 0.010 |  1885 | 4481 | 3586 |  1507 |   712 |   688 |   680 |
| 0.020 |  3471 | 5448 | 4361 |  1986 |  2127 |   977 |   877 |
| 0.030 |  2947 | 5922 | 4710 |  2206 |  1724 |  1129 |   998 |
| 0.040 |  4013 | 6309 | 5070 |  2388 |  1547 |  1233 |  1034 |
| 0.050 |  4290 | 6652 | 5406 |  2597 |  2884 |  1358 |  1149 |
| 0.060 |  4290 | 6652 | 5406 |  2597 |  2884 |  1358 |  1149 |
| 0.070 |  3636 | 6843 | 5651 |  2715 |  2409 |  1427 |  1230 |
| 0.080 |  4907 | 6946 | 5643 |  2886 |  3173 |  1617 |  1433 |
| 0.090 |  4907 | 6946 | 5643 |  2886 |  3173 |  1617 |  1433 |
| 0.100 |  4814 | 7055 | 5740 |  2921 |  2188 |  1630 |  1436 |
| 1.000 |  4627 | 7309 | 6001 |  3257 |  2923 |  2096 |  1906 |

As you can see, the values fluctuate a lot as we change the percentage of attacks we consider.  If you go down the haste and mastery rows, you see that they’re swapping places depending on which row you look at.  That’s not good. Ideally they would be fairly consistent from row to row. Even if the values change (which is fine), the relative value of the two shouldn’t. But because that last bin is so important, our results depend heavily on what exactly we choose as a cutoff, even though the events near that cutoff are the least important!

Apart from the oddity with haste/mastery, the order is generally Hit>Exp>Stam>(Haste/Mast)>Dodge>Parry. This is about what we expected, so that part at least is good.  Dodge beats out parry because of diminishing returns, as in these gear sets dodge is diminished much less.  Hit and expertise are both very strong, just as we know they are.

The bottom row includes 100% of events, so it sums the entire histogram.  This tends to inflate the value of dodge and parry more. In general, the more exclusive you make the metric, the worse dodge and parry do because they trade the presence of worse spikes for lower average damage taken. Why? Well, when you restrict your view to just the top X% of events, those worse spikes really hurt dodge and parry.  As you increase the percentage of events being considered though, dodge and parry start to perform better because it starts adding value to the large mass of events in the middle of the unweighted distribution.

This all leads to the third problem: the choice of bin size matters. I’ve made the plots with 100 bins (between 0% and 200% health so bins of 2% health), but the data table above uses 200 (bins of 1% health). You get slightly different answers with the exclusive metrics because changing the number of bins sometimes shifts a chunk of events into or out of the part of the data you’re considering. That’s not good because again, the events near the bottom of the region we’re considering are supposed to be the least valuable ones, and thus have the smallest influence on the distribution.  Being so sensitive to edge effects introduces this artificial dependence on bin size.  And we don’t want to get significantly different results just because we altered the bin size slightly.

There are a few ways to try and fix this, but the most obvious to me was to increase the HDF.  That increases the weight discrepancy between lower-damage bins and higher-damage bins, making the lower bins less valuable and the higher bins more valuable. So I repeated the calculation for an HDF of 3:

hdf=3.00, N=200, vary pct

|   pct |  Stam |   Hit |  Exp | Haste |  Mast | Dodge | Parry |
| 0.010 |  3126 |  8488 | 6824 |  2259 |  1318 |   537 |   781 |
| 0.020 |  4320 |  9221 | 7414 |  2622 |  2383 |   752 |   926 |
| 0.030 |  3954 |  9529 | 7642 |  2762 |  2086 |   847 |  1001 |
| 0.040 |  4548 |  9747 | 7845 |  2864 |  1984 |   905 |  1021 |
| 0.050 |  4670 |  9919 | 8014 |  2970 |  2647 |   968 |  1080 |
| 0.060 |  4670 |  9919 | 8014 |  2970 |  2647 |   968 |  1080 |
| 0.070 |  4373 | 10006 | 8126 |  3024 |  2418 |   999 |  1117 |
| 0.080 |  4879 | 10048 | 8122 |  3094 |  2711 |  1077 |  1200 |
| 0.090 |  4879 | 10048 | 8122 |  3094 |  2711 |  1077 |  1200 |
| 0.100 |  4844 | 10091 | 8159 |  3108 |  2331 |  1082 |  1201 |
| 1.000 |  4772 | 10194 | 8260 |  3226 |  2590 |  1221 |  1342 |

Much better-looking. The variation with percentage is smaller, though we’re still seeing edge effects.  If you go down the haste and mastery rows you’ll see mastery jump around relative to haste a good bit. But the increased hdf has created a larger ramp on the weight function, making those edge effects smaller overall. The other interesting thing here is that the 100% (all-inclusive) version is a pretty good average – we’re still seeing the approximate 3-to-1 ratio of haste-to-avoidance value in the 100% row that we’re seeing in the 5% row. This all-inclusive version has another perk – it isn’t subject to edge effects at all, so it’s quite a bit more robust.

Just for completeness, here are the weighted histograms we get with $h=3$:

Weighted histogram with $h=3$.

The top 5% of the weighted histogram with $h=3$.

Of course, 2 and 3 are pretty arbitrary choices for the HDF.  To get the best metric, we really need to nail down the best value for $h$.  So the next step is to explore what happens when we change $h$ while keeping the percentage of events fixed. When we do this for the top 5%, 10%, and 100% of events, we get the results below:

pct=0.05, N=200, vary hdf

| hdf |  Stam |   Hit |   Exp | Haste |  Mast | Dodge | Parry |
| 1.5 |  4836 |  6256 |  5193 |  2735 |  3668 |  1566 |  1261 |
| 1.6 |  4660 |  6258 |  5170 |  2680 |  3443 |  1511 |  1227 |
| 1.7 |  4523 |  6301 |  5183 |  2640 |  3259 |  1465 |  1201 |
| 1.8 |  4419 |  6384 |  5228 |  2614 |  3108 |  1425 |  1179 |
| 1.9 |  4343 |  6501 |  5303 |  2600 |  2984 |  1390 |  1163 |
| 2.0 |  4290 |  6652 |  5406 |  2597 |  2884 |  1358 |  1149 |
| 2.1 |  4259 |  6836 |  5537 |  2602 |  2803 |  1328 |  1139 |
| 2.2 |  4247 |  7051 |  5695 |  2616 |  2738 |  1299 |  1130 |
| 2.3 |  4251 |  7297 |  5881 |  2637 |  2689 |  1270 |  1123 |
| 2.4 |  4271 |  7574 |  6094 |  2666 |  2652 |  1240 |  1118 |
| 2.5 |  4305 |  7883 |  6335 |  2701 |  2627 |  1207 |  1113 |
| 2.6 |  4353 |  8223 |  6607 |  2743 |  2613 |  1170 |  1108 |
| 2.7 |  4414 |  8596 |  6908 |  2790 |  2608 |  1130 |  1103 |
| 2.8 |  4488 |  9003 |  7242 |  2844 |  2613 |  1083 |  1097 |
| 2.9 |  4573 |  9443 |  7610 |  2904 |  2626 |  1030 |  1089 |
| 3.0 |  4670 |  9919 |  8014 |  2970 |  2647 |   968 |  1080 |
| 3.1 |  4779 | 10431 |  8455 |  3041 |  2676 |   897 |  1069 |
| 3.2 |  4900 | 10982 |  8936 |  3119 |  2713 |   815 |  1056 |
| 3.3 |  5032 | 11571 |  9460 |  3202 |  2757 |   720 |  1039 |
| 3.4 |  5177 | 12201 | 10029 |  3292 |  2809 |   611 |  1018 |
| 3.5 |  5333 | 12873 | 10645 |  3388 |  2868 |   486 |   994 |
| 3.6 |  5501 | 13588 | 11312 |  3490 |  2935 |   344 |   964 |
| 3.7 |  5681 | 14349 | 12033 |  3599 |  3009 |   182 |   929 |
| 3.8 |  5874 | 15157 | 12812 |  3715 |  3090 |    -2 |   887 |
| 3.9 |  6080 | 16014 | 13651 |  3837 |  3179 |  -210 |   839 |
| 4.0 |  6299 | 16922 | 14554 |  3967 |  3276 |  -444 |   783 |
| 4.1 |  6531 | 17883 | 15526 |  4105 |  3382 |  -707 |   719 |
| 4.2 |  6777 | 18899 | 16571 |  4251 |  3495 | -1002 |   646 |
| 4.3 |  7038 | 19971 | 17692 |  4404 |  3617 | -1331 |   562 |
| 4.4 |  7314 | 21103 | 18895 |  4566 |  3748 | -1698 |   468 |
| 4.5 |  7605 | 22295 | 20184 |  4737 |  3888 | -2105 |   362 |
pct=0.10, N=200, vary hdf

| hdf |  Stam |   Hit |   Exp | Haste |  Mast | Dodge | Parry |
| 1.5 |  5949 |  6996 |  5796 |  3333 |  2441 |  2068 |  1790 |
| 1.6 |  5601 |  6903 |  5698 |  3201 |  2363 |  1949 |  1689 |
| 1.7 |  5327 |  6869 |  5649 |  3098 |  2301 |  1849 |  1606 |
| 1.8 |  5111 |  6887 |  5642 |  3020 |  2252 |  1765 |  1538 |
| 1.9 |  4943 |  6950 |  5673 |  2962 |  2215 |  1693 |  1482 |
| 2.0 |  4814 |  7055 |  5740 |  2921 |  2188 |  1630 |  1436 |
| 2.1 |  4719 |  7199 |  5839 |  2895 |  2170 |  1573 |  1397 |
| 2.2 |  4653 |  7380 |  5969 |  2881 |  2161 |  1521 |  1364 |
| 2.3 |  4611 |  7597 |  6131 |  2879 |  2159 |  1472 |  1336 |
| 2.4 |  4592 |  7848 |  6323 |  2887 |  2165 |  1424 |  1312 |
| 2.5 |  4593 |  8134 |  6546 |  2904 |  2177 |  1375 |  1291 |
| 2.6 |  4611 |  8455 |  6801 |  2929 |  2195 |  1326 |  1272 |
| 2.7 |  4647 |  8810 |  7088 |  2963 |  2220 |  1273 |  1254 |
| 2.8 |  4698 |  9201 |  7409 |  3004 |  2251 |  1215 |  1236 |
| 2.9 |  4764 |  9627 |  7766 |  3052 |  2288 |  1152 |  1219 |
| 3.0 |  4844 | 10091 |  8159 |  3108 |  2331 |  1082 |  1201 |
| 3.1 |  4937 | 10592 |  8591 |  3170 |  2379 |  1003 |  1182 |
| 3.2 |  5045 | 11131 |  9064 |  3239 |  2433 |   914 |  1161 |
| 3.3 |  5165 | 11711 |  9580 |  3315 |  2494 |   813 |  1138 |
| 3.4 |  5298 | 12333 | 10141 |  3398 |  2560 |   699 |  1111 |
| 3.5 |  5444 | 12997 | 10751 |  3487 |  2633 |   569 |  1081 |
| 3.6 |  5604 | 13705 | 11412 |  3584 |  2711 |   422 |  1046 |
| 3.7 |  5776 | 14460 | 12128 |  3688 |  2797 |   255 |  1006 |
| 3.8 |  5962 | 15262 | 12901 |  3799 |  2889 |    67 |   961 |
| 3.9 |  6161 | 16114 | 13736 |  3917 |  2988 |  -144 |   908 |
| 4.0 |  6374 | 17016 | 14635 |  4043 |  3094 |  -382 |   849 |
| 4.1 |  6601 | 17972 | 15603 |  4177 |  3208 |  -648 |   781 |
| 4.2 |  6843 | 18984 | 16644 |  4319 |  3329 |  -946 |   705 |
| 4.3 |  7099 | 20052 | 17762 |  4469 |  3458 | -1278 |   619 |
| 4.4 |  7370 | 21180 | 18962 |  4628 |  3596 | -1647 |   522 |
| 4.5 |  7658 | 22369 | 20248 |  4796 |  3742 | -2056 |   413 |
pct=100.00, N=200, vary hdf

| hdf |  Stam |   Hit |   Exp | Haste |  Mast | Dodge | Parry |
| 1.5 |  5269 |  7122 |  6009 |  3834 |  3753 |  3033 |  2764 |
| 1.6 |  5122 |  7133 |  5982 |  3692 |  3552 |  2793 |  2538 |
| 1.7 |  4971 |  7139 |  5953 |  3557 |  3361 |  2578 |  2339 |
| 1.8 |  4834 |  7165 |  5941 |  3437 |  3191 |  2393 |  2169 |
| 1.9 |  4719 |  7220 |  5956 |  3337 |  3045 |  2233 |  2026 |
| 2.0 |  4627 |  7309 |  6001 |  3257 |  2923 |  2096 |  1906 |
| 2.1 |  4558 |  7434 |  6077 |  3194 |  2823 |  1978 |  1805 |
| 2.2 |  4511 |  7596 |  6186 |  3149 |  2742 |  1874 |  1720 |
| 2.3 |  4485 |  7793 |  6328 |  3118 |  2678 |  1781 |  1648 |
| 2.4 |  4478 |  8027 |  6501 |  3101 |  2630 |  1696 |  1587 |
| 2.5 |  4489 |  8297 |  6708 |  3097 |  2595 |  1616 |  1534 |
| 2.6 |  4516 |  8603 |  6948 |  3103 |  2573 |  1540 |  1488 |
| 2.7 |  4558 |  8946 |  7222 |  3120 |  2563 |  1464 |  1447 |
| 2.8 |  4616 |  9324 |  7531 |  3147 |  2562 |  1387 |  1410 |
| 2.9 |  4687 |  9740 |  7876 |  3182 |  2572 |  1307 |  1375 |
| 3.0 |  4772 | 10194 |  8260 |  3226 |  2590 |  1221 |  1342 |
| 3.1 |  4870 | 10686 |  8683 |  3278 |  2617 |  1130 |  1310 |
| 3.2 |  4981 | 11218 |  9148 |  3339 |  2652 |  1029 |  1277 |
| 3.3 |  5105 | 11791 |  9657 |  3406 |  2695 |   918 |  1243 |
| 3.4 |  5241 | 12406 | 10213 |  3482 |  2746 |   794 |  1208 |
| 3.5 |  5390 | 13065 | 10817 |  3565 |  2805 |   657 |  1169 |
| 3.6 |  5552 | 13768 | 11474 |  3656 |  2872 |   502 |  1128 |
| 3.7 |  5727 | 14518 | 12185 |  3754 |  2946 |   330 |  1081 |
| 3.8 |  5916 | 15316 | 12954 |  3861 |  3028 |   136 |  1030 |
| 3.9 |  6117 | 16164 | 13785 |  3975 |  3118 |   -81 |   973 |
| 4.0 |  6332 | 17064 | 14681 |  4097 |  3215 |  -323 |   909 |
| 4.1 |  6561 | 18017 | 15646 |  4227 |  3321 |  -593 |   837 |
| 4.2 |  6804 | 19025 | 16684 |  4366 |  3436 |  -895 |   757 |
| 4.3 |  7062 | 20091 | 17799 |  4513 |  3559 | -1230 |   667 |
| 4.4 |  7335 | 21216 | 18997 |  4670 |  3690 | -1602 |   567 |
| 4.5 |  7624 | 22403 | 20281 |  4835 |  3831 | -2014 |   455 |

There are a few effects happening here.

First, a small HDF tends to keep the scaling between stats small, which means they’re more vulnerable to edge effects.  We can see this from the first two tables, as haste and mastery swap positions from one table to the other. We already sort of knew that, but it’s good that the data reaffirms that expectation.

A really high HDF tends to increase that gap dramatically, which reduces edge noise.
On the other hand, a high HDF does something strange to dodge and parry. As you can see, the stat weight of dodge and parry both plummet, and the dodge value even becomes negative at one point.

Your first thought might be to rationalize these results.  For example, dodge and parry tend to give a wider distribution, allowing for larger spikes but reducing overall damage taken.  But remember, we’re not comparing a dodge/parry gear set to a control gear set here, we’re adding 1000 dodge or parry to it.  There should be absolutely no circumstance where adding 1000 dodge actually makes your smoothness metric worse!  It should always make it better, just not necessarily as good as other stats.

In fact, it’s a different issue entirely.  If you look at the source data, adding 1000 dodge reduces spike presence in every category except one: the very top one, 140%, where all of the sudden we have a 0.001 instead of a pure zero. This isn’t because adding dodge suddenly created higher-damage spikes; it’s simulation noise. That’s what’s causing the huge drop in dodge’s value here, and a similar (though less pronounced) effect is happening in the parry data. This is bad, it essentially means that our HDF is so large that it’s becoming super-sensitive to simulation noise.

So we’re stuck between a rock and a hard place.  If the HDF is too high it causes simulation noise problems, but reduces our edge-effect issues.  But if it’s too low we have the reverse: edge-effect noise problems, but low sensitivity to simulation noise in the higher categories. One solution is to just simulate longer and reduce the noise, but that’s not a great solution either. Ideally, we want to pick an HDF somewhere in the middle, so that we get good data fidelity and low sensitivity to noise so that we don’t have to simulate for hours at a time.

For the tables where we look at only the top 5% and 10% of spike events, it’s clear that $h=2$ is too low.  2.5 is on the border of what I’d deem acceptable, but even that is a little volatile.  On the high end, 3.5 is pretty good, but is right on the borderline of the region where simulation noise is a problem.  But probably our ideal value lies somewhere between 2.5 and 3.5.  Nominally, I’m going to say it’s around 3.0, because that data seems pretty consistent between both tables.  But I have to do a more detailed analysis of this range to really feel comfortable picking a final value.

However, there’s also another solution to consider.  The table that uses 100% of the data eliminates boundary issues entirely because it includes all of the data, and the weight function makes sure that each category is worth less as we work our way from higher to lower damage ranges.  That makes it more stable at low $h$-values than either of the percentile-based versions. I’d want an HDF larger than 2, because if it’s too low it risks watering down the strength of small changes near the top end and over-valuing avoidance.  But it’s even passable at $h=2$ in this table, unlike the percentile versions.

From considering all of this data, I’m leaning towards defining the metric using an all-inclusive histogram with a moderately high HDF, probably around $h=3$. However, we have a lot of further testing to do before we settle on final values.  And of course, we’ll want to implement some sort of normalization scheme such that the values are independent of the number of iterations we use.  I’ll detail all of that in the next two blog posts.

What’s in a name?

However, before we end, I want to offer a parting thought about the greater applicability of this metric, and suggest a name for it.  While I’ve framed this entire discussion in terms of subtracting histograms from one another, the way you would likely do this in a computer is a little different.  The distributive property tells us that $a(b-c) = ab – ac$. That means it doesn’t matter whether we subtract the two histograms first and multiply by the weight function afterwards or vice versa.

This is actually really good news, because it means you could multiply the weight function times the histogram for one experimental configuration (e.g. gear set, talent combination, glyphs, etc.) to get a single number. Then you could repeat that process for any other gear set or configuration you want and get a new number. And you’ll get a unique number for each configuration that describes the smoothness of your damage intake under those particular conditions.

There’s a bit of arbitrariness to this, in that the weight function is whatever we decided to come up with. However, that’s OK, since we’re not trying to give a measurable in-game number like DPS or DTPS. As an analogy, think about the stock market. The Dow Jones Industrial Average (DJIA) is a stock market index, which is just a weighted average of the stocks of 30 large companies. It’s used to reflect the performance of the entire stock market, but the companies chosen are pretty much arbitrary. Even if some sort of formula is used to choose them, that formula is essentially arbitrary, and there are other indexes that use different formulas (S&P 500, Russel 2000, etc.) and give slightly different impressions of the overall health of the market.

Another good analogy is your credit score.  Your credit score is calculated by an algorithm, which is somewhat arbitrary and chosen to model credit-worthiness.  But your credit score isn’t an estimate of some measurable value.  Having a credit score of 750 doesn’t tell you exactly what APR you’ll get on your mortgage or how large a loan you can take out, even though it affects those things.  But it’s also very clear that a score of 750 is better than a score of 600.  And there are multiple ways of calculating credit score with different ranges, all trying to convey the same rough information about your borrowing risk.

And that’s really what we’re doing if we come up with a unique number for each simulation configuration: producing an index.  You sim your gear set and you get a number out that tells you how smooth your damage intake is. You can re-sim with a different gear set to see if it improves.  In this case, that means the number goes down, because just like DTPS a lower number is better with this type of smoothness metric. And you can calculate scale factors, which is just a fancy way of saying “sim once with a baseline gear set, then sim again with +1000 haste, then with +1000 mast, etc., and subtract each of those indices from the baseline value.”

In short, it’s exactly what an index should be: a solid number with a very clearly-defined calculation method that you could compare to any other configuration that uses the same boss mechanics.  That’s really the only constraint here: the boss’ attacks need to be identical for two different indices to be comparable.  You can’t compare an index generated with Hogger to one generated by Lei Shen and expect to get anything useful out of it.  We’ll go into more detail on that point in the third post in this series, later this week.

But it will be clear that a result of 100 is a lot smoother than a result of 1000.  It may not be clear exactly why until you look at the details – maybe one boss was Hogger and the other was Lei Shen, or maybe it was a gearing difference, or who knows what.  Either way, it will be clear that the tank with the result of 100 wasn’t in much danger, while the tank clocking in at 1000 was.  If we choose our overall normalization factor properly, we’ll be able to do this very accurately.  For example, a smoothness value larger than 1000 would clearly be dangerous, while one below 500 wouldn’t be, or something like that.  Again, we’ll talk about the details of that normalization process later this week.

The concept of the DJIA came up while Mel and I were discussing this, so my first thought was that we should call this the Theck-Meloree Industrial Smoothness Average as a bit of a joke. However, it struck me that there was a much more natural name that was less of a mouthful: the Theck-Meloree Index.  Which, of course, would be abbreviated TMI. Which is not only amusing, but also eerily accurate based on the amount of background work we’re presenting here to develop it.

So yes, you heard it here first. We are going to get tanks to compare their TMIs. And it will be glorious.

## SotRdämmerung

As was pointed out in the comments on a previous blog post, the protection 2-piece-turned-4-piece that returns holy power when Bastion of Glory (BoG) stacks are consumed will allow us to keep SotR up 100% of the time.  That comes with a small disclaimer, namely that it takes about 40-45% haste to pull it off.  But many players are already at or above that threshold, and more of them will reach it with T16 gear.

The more I think about it the less I think it was intended.  To illustrate why, first let’s look at how the process works.  Let’s assume a player has T16 4-piece and barely enough haste to pull this trick off.  His finisher cast sequence looks something like this:

1: Build 3 HP, cast SotR, repeat 5 times to build 5 BoG stacks
2: Build 1 HP, cast WoG, cash in on 5 free Holy Power from set bonus
3: Cast SotR
4: Build 1 HP, cast SotR
5: Build 3 HP, cast SotR, repeat 3 more times to reach 5 BoG stacks
6: Build 1 HP, cast WoG, cash in on 5 free Holy Power from set bonus.  This takes you back to step 3.

The player then repeats 3-6 indefinitely since that forms a closed loop.  Let’s call a single traversal of that that loop a “cycle.”

For that cycle to maintain 100% SotR uptime, you need to generate 11 HP every 15 seconds.  There’s 16 HP total expenditure per cycle, but you get 5 back each cycle as well.  Eleven HP every 15 seconds is 0.733 HP/sec, which is easily achieved with ~40% haste and any of the T75 talents. Rather than re-do the math myself, I’ll just quote Thels, who worked it out:

Let’s take 2 minutes from a fight, so we can pop HA exactly once. We need 8 cycles of 15 seconds of SotR uptime, so 8 cycles of 11 HoPo, for a total of 88 HoPo every 2 minutes.

During 2 minutes, at 50% haste, we press CS/HotR exactly 40 times, and Judgment 26 times and a bit, for a total of 66 HoPo.

Our HA covers 6 CS/HotR presses and 4 Judgment presses, for a total of 20 extra HoPo, which brings us to 86 HoPo.

That would mean that we need 1 Grand Crusader proc per minute to indeed cap on SotR. Each additional proc allows us to underperform slightly.

The only thing I want to add is that each additional proc doesn’t just allow for under-performance, it also reduces the haste threshold.  My conservative estimate is between 40% and 45% haste, but it will vary a lot based on the number of mobs you’re tanking, the amount of time you spend tanking those mobs, and the average melee swing timer of the bosses (Ji-Kun, for example, spends so much time casting that his effective swing timer is absurdly long).  If you consider any real encounter with tank swaps, banking to 5 HP before starting the cycle essentially ensures 100% uptime while you’re tanking even at lower haste levels.

There are a few reasons I don’t think this was entirely intended.  The fist concern is the “block cap” issue, because that’s really the same problem being recreated by this effect.  We stack a particular stat (haste now, mastery in Cataclysm) so that we can reach a point where we take a lot less damage from physical attacks (>40% now, 30% in Cataclysm.  That certainly feels like it could be a balance problem on any hard-hitting boss, just like the Cataclysm-era block cap was.  How do you challenge all five different tanks when one takes almost half of the damage from the largest attacks?

In Dragon Soul, they simply made most attacks bypass block, but that solution doesn’t work with SotR.  And an entire tier of Lei Shi doesn’t sound appealing, nor is the next tier likely being designed with this in mind.  Block cap was a persistent problem the entire expansion, and they could (and did) plan for it when designing encounters. I doubt the same is true of this set bonus.

Second, the fact that they swapped the T16 set bonuses makes it clear that the developers thought the interaction between 2-piece tier 15 and this holy-power banking set bonus was a problem.  Maintaining a constant +40% block chance buff was bad enough to swap the set bonuses so that it couldn’t happen.  This effect is even worse, because it’s maintaining a constant 40% damage reduction.  We may have had a lot of that uptime already, but I’d argue it’s still a much stronger effect than an extra 40% block chance.

Third, there are some rotational concerns.  On these I’m a little more mixed.  The set bonus means that players will literally be able to macro SotR to every ability in their rotation and ignore it.  All they need to worry about is timing that single 1-holy-power WoG every ~15 seconds to keep their income level.  This bothers me from a skill standpoint, obviously, but also from an annoyance standpoint.  I don’t really want to write 7 or 8 new macros for my rotational abilities just so I can be lazy with SotR presses.  But I probably would, because not having to pay attention to SotR would open up some attention bandwidth that would probably be beneficial.

That said, to pull this trick off you give up WoG as your emergency button, so you are making a sacrifice.  Losing that big self-heal is certainly one fewer reactive tool we have at our disposal.  But it’s almost certainly a sacrifice worth making if you ensure that you never take a full-sized hit.  It’s sort of like giving up sunscreen to become immune to sunburn.

I’m also not certain that it was entirely intended that we could use a 1-holy-power WoG to return all five of our reserve holy power.  That’s the key to this trick, after all: use a 1-HP WoG to refund 5 Holy Power, netting you 4 HP.  If you can do that every 15 seconds, that’s 0.267 HP/sec.  For comparison, you get an equivalent HP generation rate from 67% haste, which is ludicrous.  The set bonus literally gives us about 67% haste worth of holy power generation, or about 28k haste rating.  Now admittedly, that’s assuming that you already have about 40% haste, and the overall value of the set bonus will reduce somewhat if you’re below that point already.  But no matter how you slice it, it’s absurdly good.

In fact, it feels a lot like using one-HP WoGs to game Divine Purpose back in Cataclysm.  When that trick became fairly widespread, the developers modified the proc chance so that it scaled with holy power spent.  The parallels between the two are somewhat uncanny, which leads me to believe that this bonus will be tweaked eventually as well.

I like the general idea of the set bonus, though.  Removing the opportunity cost of WoG is neat.  Having a Holy Power reserve is sort of neat as well.  I can see interesting situational uses for the bank, like getting into real danger and saving the day with a clutch sequence of SotR – WoG – SotR -SotR.  That would be pretty fun, and I feel like that’s the sort of thing the developers had in mind with this set bonus.

But I think I would like the “banking” idea a lot better if we were not able to use it to reach 100% uptime on SotR.  Being able to reach that threshold changes the entire feeling of the bonus.  It will feel not like a neat tool at our disposal, but like a maintenance buff.  And a cheesy maintenance buff at that – something we have to do because it’s just so broken that we’re at a disadvantage if we don’t.

The ability to reach 100% SotR uptime with this removes the interesting aspects of the banking, like being able to choose when you want to use that HP reserve, and replaces it with a rote, “macro SotR to everything” style that feels really bland and boring.  Instead of thinking about timing SotR on short time scales, we phone in our 1-HP WoG every 15 seconds and call it a day.

In more technical language, for the banking idea to be fun it needs to be more reactive than proactive.  Just as WoG is a tool you use to react to a big hit, this set bonus needs to be a tool we use primarily to react to a dangerous situation. There’s certainly still going to be proactive potential here, like using the bank to cram a few extra SotRs in during a period where you expect to be in danger.  But that’s still somewhere in the middle of the reactive-proactive continuum, because you’re reacting to a potential threat.  When it becomes purely proactive, as it does if we’re just withdrawing from the bank every 15 seconds for the steady-state HP gain, it stops being nearly as fun.

I do think that it’s possible to tweak the set bonus slightly to keep the interesting aspects while preventing abuse.  But to do that, the holy power refund we get needs to be scaled or limited somehow, either by the amount of HP spent (as Divine Purpose was) or by some other constraint.  I can think of a few fairly simple systems for this:

1) Return 1 holy power per stack of BoG consumed, capped by HP spent.
In other words, you can only get as much HP back as you spend.  That still removes the opportunity cost of WoG, but also removes the banking potential entirely. That’s a bit of a bummer, but at least it prevents abuse.

2) Let’s assume that solution is too severe.  Instead you could cap the returns by (HP spent + 1).  For example, with a 5-stack of BoG:

3 HP WoG grants 4 HP back
2 HP WoG grants 3 HP back
1 HP WoG grants 2 HP back

This has the downside of not being very intuitive.  It also encourages you to use WoG at less than 5 stacks of BoG to avoid “wasting” potential gains.  For example, the 1-HP WoG cycle would turn into two consecutive SotRs followed by a 1-HP WoG.  That requires 5 HP every 6 seconds if we’re aiming for 100% uptime on SotR, which is a higher threshold (0.8333 HP/sec), but probably still attainable with L75 talents and ~50% haste.

Another concern is that it doesn’t “fix” the problem, it simply raises the threshold.  And if one L75 talent turns out to be the best at HP generation (like the new version of Sanctified Wrath, or “Holy Judgment Spam” as I like to call it), it might be the only valid choice if it lets us reach that threshold.  That just ends up turning the set bonus into a constraint on talent choices, which isn’t much fun.

3) Internal cooldown. HP gains from the set bonus are limited to once every N seconds.  This doesn’t eliminate the banking feature, but does limits the maximum HP generation rate one can achieve by it.  For a few points of reference, here are the rates one would achieve for several different values of N assuming we use a 1-HP WoG at 5 stacks of BoG, which is a 4 HP gain:

N=30 gives 0.1333 HP/sec, or about 33% haste equivalent
N=45 gives 0.0889 HP/sec, or about 22% haste equivalent
N=60 gives 0.0667 HP/sec, or about 16.7% haste equivalent
N=75 gives 0.0533 HP/sec, or about 13.3% haste equivalent
N=90 gives 0.0444 HP/sec, or about 11.1% haste equivalent

Any longer N would probably be too weak, simply because we’re likely to give up about 10% haste just to wear 4-piece unless the itemization team starts embracing our new Mists mechanics.  So at that point it would be a wash in the HP generation department, and whether or not to use the set at all would become a question of whether it’s worth giving up the raw HP generation rate (and DPS!) we’d gain by using well-itemized off-set pieces to gain the short-term HP banking ability that the set bonus provides.

That may still be an interesting choice, but I think that a 1.5-minute or longer effective cooldown will turn players off.  I already heard complaints about the new version of Sacred Shield (30% absorb bubble every 2 minutes, triggered by low health) even though it’s rather powerful. The complaints were always, “meh, once every 2 minutes is so rare it might as well be never.”  I completely disagree, of course. How soon we forget the stupidly overpowered Wrath-era Ardent Defender talent.  But most players form their opinions based on gut feeling rather than rational analysis (you’d be surprised how many prot paladins still gear for dodge and parry!), so I think a long internal cooldown on the set bonus will be generally end up being viewed as not worth it.

And it’s worth noting that this version still only raises the threshold, it doesn’t eliminate it.  It raises it by a lot more than the other methods because it severely reduces the steady-state holy power generation rate that the set bonus provides.  So by the time we have enough haste to hit 100% uptime with this extra income, perhaps we’d already be well above 90% uptime anyway.

Still, I think the internal cooldown idea is probably the most even-handed.  And likely the easiest to implement as well, given that it doesn’t involve a significant change to how the HP returns are calculated.  A 60- to 75-second ICD would put a cap on how effective the set bonus is, and if chosen correctly might make sure that the 100%-uptime SotR panacea is out of reach.

Though I feel obligated to mention that I’ve ignored the potential interactions with the revised version of Selfless Healer, which would return 5 HP for zero HP cost via Flash of Light.  I’m ignoring that because the version of Selfless Healer on the Public Test Realm doesn’t grant the set bonus effect yet.  That may be intended, or it may be an oversight, it’s anyone’s guess as to which.  In fact, my guess is that it’s an oversight that will become intended once this blog post becomes common knowledge.

But more importantly, I don’t believe that the increase in effectiveness we would gain over the regular 1-HP WoG version is worth sacrificing Sacred Shield and tying yourself to the GCD with Flash of Light.  However, if the set bonus is “fixed” in a way that leaves the HP generation threshold in reach, it could become a concern, much like the level 75 talents might be.  It all depends on what, if anything, happens.  As much fun as it might be to be a stupidly-overpowered block-capped paladin tank, I hope something does.  If not for the sake of making the set bonus more interesting, than for the sake of the other tanks we’ll leave in the dust.

## Tiers Are The Silent Language Of Grief

As you may have noticed, the PTR went up recently.  And with it, we got some reveals of our set bonuses for T16.  Let’s take a brief look at them and ponder their usefulness.

2-piece bonus

The 2-piece bonus grants us one holy power for every stack of Bastion of Glory consumed.  This is a really interesting effect because it has a few potential uses.

First, it removes the opportunity cost of using Word of Glory as an emergency heal.  Using WoG means you’re giving up 3 seconds of Shield of the Righteous coverage, which can often mitigate more damage than WoG will heal.  Getting that balance point right can be tricky, and the set bonus makes that choice easier.  Since both WoG and SotR are off-GCD, you can WoG and SotR yourself in rapid succession during a danger period. This set bonus makes the WoG+SotR combination a very potent anti-spike technique, which should mean it’s a great damage-smoothing effect.  Once I have tank metrics properly implemented in SimC, we’ll be able to see exactly how effective it is for that purpose.

Second, and more subtly, it gives us a reserve bank of holy power.  Boundless Conviction already gives us a reserve of 2 holy power to work with, and smart paladins use that to great effectiveness.  This set bonus turns Bastion of Glory into a secondary reserve, such that if we’re in trouble we could fire off a WoG to gain up to 4 holy power instantly.  Pulling that off at max effectiveness will be a little tricky, as you’ll need to pick your order of operations properly to make sure you cast a 1-HP WoG.  But even if used inefficiently, this is a potent effect because it gives you extra SotR coverage whenever you deem it necessary.

But the third (and in my opinion game-breaking) use is the one that’s likely to get this set bonus nerfed.  And that’s the combination of 2-piece T15 and 2-piece T16.  The latter removes the opportunity cost of WoG, making it essentially free.  The former gives you 15 seconds of 40% block that isn’t affected by diminishing returns every time you cast WoG.  While HP generation rates are not quite to the point where we can keep that up 100% of the time, they’re not that far off.  You would need to generate 3 stacks of Bastion of Glory every 15 seconds, or one SotR every 5 seconds.  Right now, most players are casting SotR every 6-7 seconds.  As players approach the 50% melee haste soft-cap, 100% uptime of Shield of Glory should become a reality.

I think that this is probably an issue, because 40% block is almost certainly strong enough to sacrifice two slots of higher-ilvl T16 gear.  Especially if you can use two pieces of heroic, double-upgraded T15 tier.  I expect this interaction will trigger some sort of change as soon as Blizzard finds out it exists.  They could nerf this set bonus or swap it with the 4-piece to ensure that the 2T15+2T16 interaction is impossible.  They could also just nerf the T15 2-piece bonus and leave the T16 bonuses in-tact.  As we’ll see in a second, the 4-piece bonus is considerably weaker, so my vote would be to swap them.

4-piece bonus

The 4-piece bonus grants us a heal over time after Guardian of the Ancient Kings (GAnK) expires.  The amount of healing is determined by the damage we take during GAnK.  Blessing of the Guardians is the HoT spell, so we know that it ticks every second for 10 seconds.

Unfortunately, when I tested it on the PTR it seems the HoT amount isn’t being calculated, because the buff would appear and expire instantly.  In fact, the only reason I knew it was there (and could determine the spell name) was that it showed up in Recount/Skada as a heal that produced 0 healing.  So at this point, we don’t know what damage value it will use.  I’m assuming it will be post-mitigation (unlike Vengeance, which is pre-mitigation), but it’s anyone’s guess as to whether it will use damage done before or after absorb effects are taken into account.

That said, it may not matter that much.  This set bonus is incredibly weak, so as a 4-piece we may just skip it entirely.  You’re generally going to use GAnK in one of two situations.  The first is a predictable period of high damage, and it’s rare for that period to last the entire duration of GAnK.  The second is a situation where something goes wrong and you use GAnK to buy your healers time to recover.  In both of those cases, the HoT is showing up after the danger period is passed, so it’s not terribly effective.  Your healers may be able to ignore you more than usual after GAnK ends, but apart from that the set bonus probably just creates a bunch of unnecessary overhealing.

There’s also tank swaps to consider.  If you and your co-tank are taunting so that you can alternate cooldowns to survive an extended phase of intense damage, then it’s very likely that the HoT will end up ticking on you when you aren’t even tanking.  With some smart pre-planning you could arrange to chain GAnK and Divine Protection, and maybe the HoT will be enough of a buffer that DP will be a sufficient cooldown.  But that’s still a pretty niche application.  A set bonus that’s effective on only one or two fights in an entire raiding tier is a set bonus you’re probably safe skipping.

But the biggest Achilles heel of the 4-piece bonus isn’t the effect itself.  It’s what the effect has to compete with: the superior itemization of higher-ilvl thunderforged off-set pieces.  Which raises a more general point about paladin tier itemization.

Itemization

We don’t have any information about the itemization of tier 16 yet.  The T16 pieces have identical stat combinations to the T15 ones, so I’m assuming that they are all placeholders. That may be a good thing though – while it doesn’t give us any information, it means that maybe there’s still time to influence a change.

Our T15 set was a bit of a letdown for a few reasons, the first and most obvious of which is the set’s itemization.  It feels like a form of punishment to wear our tier gear, because we have to suffer a lot of dodge/parry itemization that we don’t want just in in order to have fun set bonuses.  The incredibly low value of dodge and parry for us also meant that those fun set bonuses weren’t terribly effective either; as we’ve shown, the bonuses don’t even make up for the loss of haste and mastery incurred by skipping thunderforged haste plate gear.

I know I found myself in the situation where I had heroic thunderforged off-set pieces before I had access to heroic tier, which made the decision to skip the set bonuses fairly easy.  And that was a little disappointing, because I would much rather be excited about tier items than feel ambivalent about them.

But an even more important effect is psychological – it feels like our tier set is not being designed for us anymore.  Either because the itemization team doesn’t know what paladins like, or because the developers themselves aren’t sure what we should be wearing.  The game is giving us conflicting messages.  The speed, fluidity, and fun of haste-stacking gameplay that Sanctity of Battle gives us make it clear we want to gear for haste.  But our tier itemization is the disapproving nanny “tsk tsk”-ing, wagging her finger, and suggesting that us naughty haste-stacking paladins should cut our hair, get a job, and go back to wearing respectable tanking stats like dodge and parry.

Since it’s “our” set, it should really feel like it’s made for us.  Obviously the itemization doesn’t have to be perfect.  I don’t expect gobs of haste on every piece.  But it should be on some of them, and for T16 maybe even most of them.

To be more explicit, what I’m suggesting is a paradigm shift in how paladin gear is itemized.  As an example of what I have in mind, let’s consider the other classes for a second.

• Warriors and DKs get combinations of hit/exp/mastery/dodge/parry, again because those are the core tanking stats the classes are designed to use.  DKs get a very small benefit from haste, and warriors get a small benefit from crit, but neither is large enough to warrant gearing for them.
• Monk and druid tier has combinations of hit/expertise/haste/mastery/crit, because those are the core tanking stats the classes are designed to use.  They can certainly wear dodge and parry gear, but the benefit they get is small compared to haste, mastery, and crit, so they don’t want them.

Paladins are somewhere in the middle now.  We get warrior/DK itemization even though we have little interest in dodge or parry. We’ve moved to a more monk- and druid-like active mitigation model, where dodge and parry give us much smaller benefits than haste and mastery.  In a sense, we’ve moved on to a WoW 5.0 active mitigation scheme, yet we’re still being itemized as if we were WoW 4.0.

What I would like to see is an acknowledgement by the developers that they understand we’ve evolved as well.  And that acknowledgement would come in the form of a paradigm shift in our tier itemization.  Rather than being stuck with warrior/DK itemization on our tier, I’d like to see us get combinations of hit/exp/mastery/haste/parry.

This itemization scheme has several advantages:

• It would shift our tier itemization to be more in-line with what we actually value
• It would eliminate dodge+parry combination pieces, which literally feel worthless to many paladins.  While we may suffer one or the other on a piece with another strong stat, like a hit/dodge or expertise/dodge item, double avoidance gear is the first thing we toss aside or disenchant.  A large part of the reason the T15 4-piece is not attractive is because we can replace a dodge/parry piece with well-itemized off-set, which provides a huge performance difference.
• It would send the message that Blizzard understands how prot paladins work
• More importantly, it also sends the message that Blizzard supports haste as a true tanking stat for us.
• Not only that, but putting haste on our tier does a much better job of informing the masses that “hey, haste-tanking is a thing” than any blog post or patch note ever will.  A large majority of players don’t do any research outside of the game, and may have literally no way of knowing that haste is a good stat for them.  Putting it on the tier will force them to consider that, and may even lead them to ask around to find out why.

Note that I’m only talking about our tier gear here.  I don’t think dodge/parry off-set items need to go away – in fact, I think off-set itemization can remain entirely unchanged.  Those pieces still have value for other tanks and can be gap-fillers for unlucky slots.  Though given that DKs don’t seem to care for dodge/parry either, it may be worth reconsidering dual-avoidance itemized pieces entirely.  However, that’s not a pressing issue.

It’s just the protection paladin tier itemization algorithm that really needs to be re-evaluated.  Otherwise we’re in for another tier of ambivalence towards (or outright avoidance of) set bonuses because they’re tied to gear that isn’t designed with a protection paladin in mind.  And I really hope that doesn’t happen, because I’m sort of tired of skipping set bonuses.  It takes a lot of fun out of the game to see all of your friends and teammates be excited about completing their 2- and 4-piece sets while you’re unable to muster up more than a “meh” because your spec’s bonuses just aren’t worth it.

TLDR

T16 2-piece bonus is very good, possibly to the point of being broken.
T16 4-piece bonus is very weak, probably to the point of being ignored.

Protection paladin tier itemization really needs to catch up with protection paladin gameplay, or else we’ll continue to ignore non-broken set bonuses in favor of gear that fits our play style.

## The Once And Future Sim

I hinted about a “secret project” in my last post, and promised I’d be more forthcoming this week.  It’s about time for the big reveal.  But first, let’s take a trip down memory lane.

In The Beginning, There Was Hit

I’ve been playing WoW since release, but I didn’t really get into theorycrafting until the early part of 2009.  At that time, protection paladin mechanics were pretty simple. Our rotation was so simple, in fact, that it was a true “rotation” that repeated and was 100% predictable.  If you ask paladins from this era, which was the beginning of Wrath of the Lich King, they’ll tell you all about the 969 rotation.  You’d alternate between a 9-second cooldown (one of Judgment, Consecration, and Holy Shield) and a 6-second cooldown (Hammer of the Righteous and Shield of Righteousness).  That X-Y-X-Y-X-Y casting sequence repeated itself every two cycles, or 18 seconds.

This was also back in the day when threat mattered, so people cared about tank DPS for reasons other than abusing Vengeance (which didn’t even exist yet!).  And even though theorycrafting at the time was miles ahead of what it was in previous expansions, it’s not even close to what we have today.  Not due to mind share, because there were some smart cookies working on this stuff back then too, but because the tools were much more limited.

We didn’t have AskMrRobot or Simulationcraft, and World of Logs was fresh on the scene.  The brains were available, but the modeling tools were mostly limited to hand-calculations and spreadsheets.  I think Rawr was the only software tool out there that truly did modeling, and it had limited support for most classes.

The tool that most influenced me at the time was Jonesey’s Prot DPS/TPS Spreadsheet (EJ link).  It wasn’t anything too fancy, just a spreadsheet that took your unbuffed character sheet values and calculated DPS, TPS, and stat weights for the 969 rotation.  But it was the tool we had, and probably one of the first situations where someone had tried to model prot paladin mechanics as a whole rather than just looking at one part of the puzzle.  Unfortunately, while the links remain, the spreadsheet itself seems to have been lost to time.  Even I don’t have a copy lying around.

But while spreadsheets are a nice tool, arguably the most common tool back in those days, they’re rather limited.  If you code a spreadsheet to calculate DPS, like Jonesey did, it can be difficult to adapt it to do something else.  For example, if you want to compare a bunch of weapons, you need to plug in each weapon, note the result, and make a new spreadsheet with those ordered pairs to make plots.  And there are even worse examples, like comparing different rotations, which that sort of spreadsheet really can’t do without a complete overhaul.

My first major contribution to theorycrafting was to take Jonesey’s spreadsheet and transcribe it into MATLAB.  I chose MATLAB because it was a tool I was familiar with and used heavily during my graduate work, and because it was designed around doing the sorts of things that the spreadsheets of the time can’t.  It treats everything like an array (or matrix, hence the name: MATrix LABoratory), and makes plotting intuitive and simple.  If you want to find out how DPS scales with, say, strength, all you need to do is change strength from a scalar to an array, and all of your outputs are now identically-sized arrays.  Simple as pi.

I first used the MATLAB model to show that, in contrast to the conventional wisdom of the time, hit was actually our second-best threat stat behind strength.  The thread I posted those results into (Hit so bad?) ended up going from a discussion about hit into a discussion of the MATLAB model and what we could do with it, and eventually got split off into its own thread.  That thread became my WotLK MATLAB thread, and saw that simple analytical MATLAB DPS model grow to encompass everything from stat and talent comparisons to detailed calculations of seal trade-offs and weapon choices.

But that was only half of the story.  Inspired by Aldriana of rogue theorycrafting fame, whom I still admire for his incredible thoroughness and attention to detail, I also set myself to testing many of the mechanics in-game, because several of the equations in the original spreadsheet made incorrect assumptions about how certain spells worked.  And in the process, we discovered a lot of things that we didn’t previously know about how different spells were implemented and how they interacted.  Slowly, the pieces of the puzzle came together.

By the end of Wrath, prot paladins had an incredibly sophisticated tool that put us at the forefront of the theorycrafting community as one of the most-thoroughly-investigated and rigorously-modeled class/spec combinations.  Heading into Cataclysm, it looked like the MATLAB juggernaut I had created would guide us for years to come.

And then it all came crashing down.

The Modeling Cataclysm

The beginning of Cataclysm was pretty tame.  I had several people helping me work on the code, and we moved the entire project to google code to have a real versioning system.   We did our homework building up to it, with a Call to Arms thread requesting various in-game tests on beta servers to make sure we could verify all of the mechanics, including the new Holy Power system and “939″ rotation.  As a result, we already had very complete models before Cataclysm went live, and the Cataclysm MATLAB thread was off to a good start.

Then, at some point after the release of patch 4.0.3a but before 4.1, they made a massive change – Crusader Strike stopped granting Holy Power on misses, dodges, and parries.

This was a big deal for several reasons.  Up until this point, most players had ignored hit and expertise.  Even in the “threat crisis” days of Wrath, which Meloree and I are skeptical ever existed (but that’s another blog post entirely), we ran with as close to zero hit and expertise as possible.  Suddenly, there was a potential reason to care.  Which was actually a good thing from a game-design perspective, in my opinion.

Unfortunately, it was a horrible thing for modeling.  Not being able to rely on Crusader Strike’s Holy Power income completely undermined the analytical model we had so carefully crafted over the course of the beta.  The nice, deterministic model simply wouldn’t work, so we had to go back to the drawing board.  I whipped up a quick Monte-Carlo to handle the rotational dynamics, and was dismayed to find that I had to run it for an incredibly long time to get the statistical accuracy I wanted.

Of course, I’ve gotten much better at these things since then, as my exploits with the defensive Monte Carlo sims have demonstrated over the past year.  Looking back at it, I could probably have knocked that run time down by a factor of 10 or more if I were approaching it nowadays.  But alas, time travel hadn’t been invented yet, so there was no way for future me to tell past me that he was being obtuse.  And boy, was past me obtuse.

Yet, even when things looked bad, luck stepped in.  A new collaborator contacted me offering a new approach that might solve our problems.  And together we built the current Finite State Machine code that forms the basis of the MATLAB DPS simulations.  This new technique treats the modeling much like a Quantum Mechanics problem, and as such gives incredible results – repeatability down to +/- 1 DPS, and accuracy limited only by the inputs you feed it.  And it was fast to boot, giving me outputs in under a second compared to the (admittedly, poorly-coded) Monte-Carlo that would take hours.

And so, for the remaining part of Cataclysm, the faithful FSM code carried us through.  With this new tool in our back pocket, we seemed unstoppable.  And then, with Mists of Pandaria, the unthinkable happened: we started caring about defense.

The Sha of Modeling

You see, in the entire history of paladin tanking before Mists, tank survivability was mostly a passive concern.  You shored up your gear in Stormwind or Orgrimmar to be as defensive as it could be, and then stepped into the raid and took a beating.  Apart from cooldowns, which were generally off-GCD, your entire rotation was determined by threat and DPS constraints.

Mists gave us the DK treatment, and introduced Active Mitigation.  I don’t think it’s unreasonable to say that this has been an unqualified success – tanking has never been as dynamic, fun, or interesting as it has been this expansion.

But for modeling and theorycrafting, it’s a nightmare.  We suddenly had more things to keep track of, more variables to consider, and more details to obsess over.  That isn’t a bad thing in and of itself, it just means we have more work to do.  But over the first few patches, a problem slowly became apparent.  The FSM was getting slow.

You see, Finite State Machines operate by figuring out all of the possible “states” you can be in.  So for a simple example, let’s just consider Crusader Strike.  The simplest state is the one we start in, with Crusader Strike available and no holy power.  Let’s call that state $(0, 0)$ to indicate that there are zero seconds left on the CS cooldown and we have zero Holy Power.

If we’re in that state, then we’re going to cast CS, of course, which might take us to a state $(4.5, 1)$ – 4.5 seconds on CS’s cooldown, and one Holy Power.  It might also take us to state $(4.5, 0)$ if we miss with CS.  And if we allow one GCD to pass, then we may end up in states $(3.0, 1)$ or $(3.0, 0)$ depending on which one of the $(4.5, X)$ states we started in.

The FSM attempts to compile a list of all of these potential states along with the transitions between states (like $(0,0) \rightarrow (4.5, 1)$) and the probability of those transitions.  That works very well for small numbers of states (usually called the “state space”).  But as the number of things to track gets larger, the number of states gets larger exponentially.  Introducing haste effects via Sanctity of Battle only compounded this problem, because it was no longer sufficient to work in simple 0.5-second increments. Worse yet were the one-minute cooldowns introduced by level 90 talents and the 30-second duration of Sacred Shield, each of which is several times worse than simply adding another spell with a short (<15 second) cooldown.

But the real nail in the coffin was Grand Crusader.  Specifically, when Grand Crusader stopped being completely offense-triggered and started triggering on avoided attacks.  That wasn’t the straw that broke the camel’s back, it was the ten-ton weight that dropped out of the sky and obliterated the poor camel, leaving a smoking crater where the dromedary used to stand.

Since that change, the FSM has gotten slow to the point of being unwieldy.  Coupled with a few annoying bugs that cause it to crash once in a while, and it’s hard to produce useful data with it anymore.  Refreshing the simulation results has become an effort in frustration that takes several days, and often can’t be done simultaneously with other work.  It’s become clear that the FSM just isn’t the right tool for this job anymore.

And more importantly, my exploits in this blog have convinced me that the separation of survivability and DPS simulations is less than ideal.  Even though our SotR usage is somewhat divorced from our rotation by being off-GCD, there’s still a small amount of interaction.  And, for example, while the sims I provide here can tell us whether the 2- or 4-piece set bonuses give any appreciable survival benefit, they don’t tell us the cost in the DPS arena.  Even if using WoG to maintain the 2-piece had come out ahead, we would have had to estimate the DPS cost by hand.

It’s clear that a single simulation that does both is needed.  In fact, that’s been clear to me for the better part of six months now, and I spent the first few months of that investigating and debating different options.  For example, I clearly have a working event-driven Monte Carlo that does defensive calculations.  Do I expand that to include offensive components, which would roughly mean merging it into the MATLAB trunk to replace the rotation module?  Do I recode it from scratch in C# to take advantage of the extra speed it would give me (MATLAB is slow for these applications when compared to languages like C# and C++)?

This wasn’t a question that could simply be answered by expedience or numerical accuracy either.  Most of my regular collaborators have reduced their involvement in the project, so I’d be doing most of this alone.  And that means the time investment I’m going to have to put in becomes a factor.  Not to mention that this is all focused on paladins; I regularly get requests to revisit the warrior simulations, or to write something for DKs or monks.  If I’m going to write new code, I’d like to be able to re-use as much of it as possible to make those side tasks easier if I choose to tackle them.

I was staring down the possibility of writing a fully-featured event-driven simulation for protection paladin mechanics that may eventually be extensible to other classes.  And that was a frightening thought.  Remember, I’m not a professional programmer.  While I can write usable code, my talents lie elsewhere: in the analysis and interpretation of data, the extensive testing and verification of game mechanics, and in translating those mechanics into a software model.

Over the course of the last few months, the answer became very clear.  If I’m going to be at all successful in continuing to theorycraft at the level you all are familiar with, it cannot be with code I am writing exclusively by myself.  Luckily, it doesn’t have to be.

After all, it would be awfully foolish to try and write the sort of simulation code that I need when it already exists.

Sorry MATLAB, It’s Not Me, It’s You

The Simulationcraft project, also known as Simcraft or SimC, is exactly what I’m after.  It’s an event-driven combat simulator that seeks to model class dynamics.  It already has nearly all of the game’s basic functionality implemented, and can handle a wide variety of options.  And it’s incredibly fast and well-optimized, partly because there are real computer science types that work on it.

What it doesn’t have is a protection paladin developer.

Or, rather, that’s what it didn’t have.  Now it does.

This has been a bit of a challenge, since SimC is written in C++.  I haven’t used C++ since college, and had only very limited exposure to it then.  Luckily it’s not that far removed from the C# I’ve been using in the FSM code, so the re-learning was pretty quick.  I’m still not a C++ wizard, but I know enough to get around and write usable code.

Over the past two weeks, I’ve been heavily updating the protection paladin module of SimC.  It was in a pretty sorry state when I got to it.  Most of the abilities and mechanics had not been updated since Cataclysm.  While it has been “working” for almost two months now thanks to another dev fixing some bugs (before that, it wouldn’t even simulate if you loaded a prot paladin), the results were more or less useless because they didn’t even resemble what happens in-game.

The latest release of SimC (530-3) is mostly correct for basic DPS calculations.  It’s still missing a few things, like some DPS glyphs (Alabaster Shield, Focused Shield/Wrath) and T14/T15 set bonuses.  Those have all been implemented, but didn’t make the cut for 530-3; they will be working in 530-4.  There are other things that I still plan on implementing in the next two weeks, like Glyph of the Battle Healer and correcting the way that SotR mitigation recalculation is performed (i.e. not at all when the buff is extended).  I also want to tweak the Holy Prism implementation a bit and clean up a few other oddities.  I may even go as far as to add Clemency and Selfless Healer, though both of those are niche enough that I’m not sure it’s worth the effort.  But, barring unforseen circumstances, my plan is for protection paladins to be more or less fully supported by SimC version 530-4.

The other side of the coin is the defensive results.  SimC currently supports determining tank scale factors based on overall damage taken per second – in other words, on total damage reduction (TDR).  If you’ve read anything on this blog, there’s a good chance you already know what I think of TDR metrics.  So I’m working with the other SimC devs to implement better tanking metrics.  So far, the groundwork has already been laid to perform exactly the same smoothing calculations that I do with the Monte-Carlo code, and I intend to focus on getting those up and running as soon as the Paladin module is working to my satisfaction.

This means that not only will we get the sorts of results from SimC that you’ve come to expect from my MATLAB simulations, but we’ll be able to translate them into numerical scale factors.  And as an added bonus, it won’t just be useful to paladins – any tanking spec that has a working SimC module can take advantage of them.

But perhaps the best part is the increase in accessibility.  While I’ve made my MATLAB code public for years, very few people have the knowledge necessary to read the code and look for errors, let alone verify that it’s working correctly.  Even fewer have MATLAB installed, and thus the ability to run the code themselves.  It was a nice gesture to make it public, but ultimately didn’t make much difference and was ineffective from a bug-finding and bug-fixing standpoint.

However, anyone can download SimC, load up their character, and look at the output.  The types of comparisons that players often ask for are as simple as tweaking the configuration, which requires next to no coding experience.  And best of all, players can load their own character up and calculate results rather than relying on extrapolated results from a small set of arbitrary gear sets that I’ve run calculations with.  With potentially thousands of people running simulations and testing hypotheses independently, we’re far more likely to uncover oddities, quirks, and edge cases.  And that means we’ll know more about how our class works than ever before.

Going Forward

All in all, I’m very excited about where this is headed.  Being able to team up with SimC means that I can spend less time coding and more time doing analysis and constructing tests, and the automatic extensibility to other classes means that anything I do in the tanking department benefits more than just paladins.

What does this mean for the blog, you ask?  I’m not entirely sure yet.  You may have noticed that the updates have been scarcer and more focused on data dumps lately.  Partly that’s because I’ve been busy integrating myself into the Simcraft project, and those posts are less time-consuming than a wordy, game-design-focused post.  It takes three or four hours to write a post like this one, and longer for ones that analyze a particular feature or aspect of the game.  A “data dump” post might only take an hour or two once the simulation data is done (and that can be run in the background while I do other things).

Partly it’s because of where we are in the expansion.  The beta period is where the design-centric blog posts have greatest effect, because we’re more likely to influence changes.  During the bulk of the expansion, things are less volatile.  While there are certainly topics of relevance that may influence change (see Valor Morghulis for example), they’re less common.

But there’s certainly no shortage of topics I could write about.  I imagine some people are curious to hear my thoughts on Flex raids, 5.3 daily content, and the new-and-improved valor upgrade system.  I just haven’t had time, and have been struggling to keep up with my own self-imposed goal of one post per week.  With any luck, moving to Simcraft will buy me more time in the long run to write those sorts of posts.

The other thing I’m hoping is that a new focus on Simcraft may draw Anafielle out of hiding.  I know she runs her character through Simcraft on a regular basis – probably daily – and I suspect she has a lot of wisdom to share about how to interpret a SimC report that would be applicable to both protection and retribution.

I also haven’t decided how I’m going to split myself between this blog and my usual Maintankadin thread format.  This expansion, the DPS-focused work has been on Maintankadin, while the survivability-focused content has been here.  As with the code, I think there’s a happy medium of unification somewhere.  A blog and a forum serve very different purposes and are good at very different things.  The comment system here isn’t really ideal for long threaded discussions, for example.  But the Advanced Theorycraft and Calculations forum, which I moderate, is.  I’m still thinking about the best way to integrate the blog and the forum without abandoning either, but it may be as simple as creating a “blog discussion” thread (or multiple topic-specific threads) in AT&C.  Much like the MATLAB threads, results could both foster discussion and lead to new calculations (i.e. a blog post that grows out of the discussion).

In any event, change is on the way, and I think it’s a change for the better.  If you have any advice, comments, questions, etc. about Simcraft, the blog, or anything else, feel free to share in the comments.  I’ll try to answer anything I can, and would love to hear how you think I can make this blog more effective.

Just keep it low-profile; I haven’t told MATLAB we’re breaking up yet, and it’s better that she hears it from me.

## A Tier In My Eye

Sorry for the slow updates, I’ve been deeply engrossed in a secret side project that I’ll hopefully get around to unveiling/announcing next week. However, for this week’s installment of “what Theck could throw together in his spare time” I bring you an updated analysis of the tier 15 set bonuses.

We’ve looked at this issue before, in a more limited fashion.  This time, we have a model that not only includes Sacred Shield and Seal of Insight, but does a better job of modeling Word of Glory as well.  I’ve updated it to use the same “backward-facing” healing algorithm for WoG as it does for SoI, such that every WoG hits for full strength, but can only eliminate damage taken in the previous melee attack (i.e. in the last 1.5 seconds).  Thus, it only overheals when there’s no damage remaining in that previous attack, and is completely independent of what other healers are doing.

Since we want to look at the 4-piece bonus as well, I’m also having the simulation use Divine Protection on cooldown in all of these simulations, and since we’re dealing with melee I’m assuming it’s glyphed to provide 20% mitigation against everything.

Tier 15 2-Piece Bonus: Shield of Glory

For those that aren’t aware, the 2-piece bonus grants a buff called Shield of Glory that increases your block chance by 40% whenever you cast Word of Glory.  The new WeakAuras I posted last week include a tracker for this, in case you want one.  The speculation has been that it may potentially be worth inserting WoG into the rotation every now and then to gain a passive 40% block chance.  However, our previous simulations suggested that just wasn’t the case.

Let’s see if that predictions look like now that we have a more complete model.  I’m using the Control/Haste set for this one – for stats see the later section on the 4-piece bonus.  First, the 10-man normal boss that hits for 150k after mitigation:

Boss Attack = 150k, SoI model=nooverheal data set setbonus-10000-18

| Set: |      S |    SH1 |    SH2 |     TS |     ST |
| mean |  0.214 |  0.211 |  0.212 |  0.187 |  0.181 |
|  std |  0.106 |  0.102 |  0.105 |  0.107 |  0.102 |
|   S% |  0.522 |  0.522 |  0.523 |  0.324 |  0.353 |
|   HP |   755k |   755k |   755k |   755k |   755k |
|  nHP |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  10% | 37.819 | 38.798 | 38.069 | 30.111 | 28.232 |
|  20% |  6.596 |  5.340 |  6.715 |  5.674 |  4.641 |
|  30% |  0.591 |  0.125 |  0.568 |  0.471 |  0.355 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  10% | 60.371 | 62.391 | 60.451 | 48.822 | 47.568 |
|  20% | 18.540 | 15.786 | 18.130 | 15.413 | 13.248 |
|  30% |  1.852 |  0.815 |  1.800 |  1.877 |  1.337 |
|  40% |  0.006 |  0.001 |  0.004 |  0.015 |  0.008 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  20% | 36.461 | 34.535 | 36.098 | 28.422 | 26.059 |
|  30% | 10.131 |  8.544 |  9.942 |  7.234 |  5.641 |
|  40% |  0.584 |  0.456 |  0.424 |  1.021 |  0.574 |
|  50% |  0.005 |  0.009 |  0.005 |  0.066 |  0.024 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  20% | 52.949 | 51.886 | 52.468 | 42.073 | 39.935 |
|  30% | 21.685 | 19.972 | 21.240 | 14.724 | 12.361 |
|  40% |  3.624 |  2.914 |  3.320 |  3.042 |  1.964 |
|  50% |  0.404 |  0.263 |  0.379 |  0.364 |  0.153 |
|  60% |  0.002 |  0.005 |  0.003 |  0.022 |  0.005 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  30% | 35.491 | 34.051 | 34.905 | 24.589 | 21.829 |
|  40% | 10.156 |  8.489 |  9.571 |  6.452 |  4.784 |
|  50% |  1.700 |  1.153 |  1.521 |  1.017 |  0.524 |
|  60% |  0.043 |  0.028 |  0.036 |  0.085 |  0.023 |
|  70% |  0.001 |  0.000 |  0.000 |  0.001 |  0.000 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  30% | 49.033 | 47.968 | 48.496 | 36.357 | 33.367 |
|  40% | 20.545 | 18.725 | 19.756 | 12.933 | 10.640 |
|  50% |  5.634 |  4.616 |  5.325 |  2.939 |  1.991 |
|  60% |  0.650 |  0.511 |  0.620 |  0.380 |  0.184 |
|  70% |  0.052 |  0.032 |  0.048 |  0.022 |  0.009 |
|  80% |  0.001 |  0.000 |  0.001 |  0.000 |  0.000 |

If you recall the old findings, it was highly dependent on exactly how much overheal we assumed for WoG.  At 100% overheal it was disastrously bad, but at 0% overheal it was an improvement. In these simulations, “TS” puts up about 77% overheal while “ST” puts up about 64%.  And remember, this is just the overheal we’re creating ourselves with this queue, so it’s about as best-case as it can get.  It only gets worse if you start insinuating extra overhealing done by healers.

Nonetheless, the set bonus versions fare relatively well here.  These results show that it’s not bad, matching or beating out the simple “Spam SotR” queue (“S”) in most cases.  However, the smarter shifting queue (“SH1″) tends to beat it in all the important categories.  So again, there doesn’t seem to be any strong incentive to use the set bonus as a rotational buff.

If you can target the heal effectively such that the overheal is very low, then the set bonus becomes stronger.  But that’s basically how we use WoG without the set bonus: as an emergency heal when we’re low on health.  So my recommendation remains unchanged: don’t worry about keeping the set bonus up all the time, just keep using SotR and WoG like you normally would.  Of course, special cases (like SotR+1HP-WoG for Dread Thrash) are exempt from that advice.

Since the differences are just amplified in the 250k and 350k swing data, I’ll just present that data without commentary:

Boss Attack = 250k, SoI model=nooverheal data set setbonus-10000-19

| Set: |      S |    SH1 |    SH2 |     TS |     ST |
| mean |  0.237 |  0.234 |  0.236 |  0.206 |  0.200 |
|  std |  0.110 |  0.101 |  0.108 |  0.111 |  0.105 |
|   S% |  0.522 |  0.523 |  0.522 |  0.324 |  0.353 |
|   HP |   755k |   755k |   755k |   755k |   755k |
|  nHP |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  20% | 35.459 | 37.448 | 35.993 | 30.374 | 28.103 |
|  30% | 13.947 | 12.025 | 13.790 | 11.171 |  9.825 |
|  40% |  3.303 |  1.217 |  3.219 |  3.003 |  2.527 |
|  50% |  0.716 |  0.080 |  0.553 |  0.519 |  0.418 |
|  60% |  0.021 |  0.001 |  0.002 |  0.014 |  0.011 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  20% | 59.506 | 63.282 | 59.920 | 49.323 | 47.801 |
|  30% | 34.636 | 33.267 | 34.531 | 26.334 | 24.242 |
|  40% | 12.076 |  6.691 | 11.722 | 10.644 |  8.773 |
|  50% |  2.535 |  0.956 |  2.223 |  2.915 |  2.086 |
|  60% |  0.237 |  0.097 |  0.178 |  0.386 |  0.248 |
|  70% |  0.002 |  0.001 |  0.002 |  0.014 |  0.007 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  30% | 54.078 | 54.395 | 54.182 | 42.576 | 40.788 |
|  40% | 30.414 | 27.240 | 30.235 | 22.782 | 20.543 |
|  50% | 14.037 | 11.123 | 13.588 | 10.229 |  8.339 |
|  60% |  4.436 |  3.083 |  4.216 |  3.853 |  2.689 |
|  70% |  0.764 |  0.421 |  0.637 |  1.265 |  0.694 |
|  80% |  0.039 |  0.041 |  0.034 |  0.297 |  0.130 |
|  90% |  0.000 |  0.002 |  0.001 |  0.024 |  0.010 |
| 100% |  0.000 |  0.000 |  0.000 |  0.002 |  0.001 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  40% | 48.076 | 47.293 | 47.961 | 36.490 | 34.364 |
|  50% | 29.001 | 26.410 | 28.575 | 20.068 | 17.550 |
|  60% | 13.957 | 11.397 | 13.578 |  9.420 |  7.382 |
|  70% |  4.965 |  3.271 |  4.706 |  3.837 |  2.448 |
|  80% |  1.175 |  0.521 |  1.128 |  1.204 |  0.616 |
|  90% |  0.153 |  0.060 |  0.151 |  0.241 |  0.094 |
| 100% |  0.007 |  0.005 |  0.009 |  0.053 |  0.013 |
| 110% |  0.000 |  0.000 |  0.001 |  0.007 |  0.002 |
| 120% |  0.000 |  0.000 |  0.000 |  0.001 |  0.000 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  40% | 63.435 | 64.507 | 63.513 | 50.915 | 48.899 |
|  50% | 44.899 | 44.256 | 44.658 | 32.381 | 29.659 |
|  60% | 27.162 | 24.543 | 26.683 | 17.553 | 15.031 |
|  70% | 13.311 |  9.897 | 12.802 |  8.124 |  5.989 |
|  80% |  4.733 |  2.563 |  4.468 |  2.973 |  1.849 |
|  90% |  1.136 |  0.482 |  1.057 |  0.806 |  0.391 |
| 100% |  0.179 |  0.057 |  0.143 |  0.193 |  0.064 |
| 110% |  0.014 |  0.003 |  0.011 |  0.033 |  0.008 |
| 120% |  0.000 |  0.000 |  0.001 |  0.005 |  0.001 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  50% | 58.991 | 59.193 | 58.898 | 45.495 | 42.817 |
|  60% | 41.645 | 40.168 | 41.218 | 28.683 | 25.778 |
|  70% | 25.355 | 22.592 | 24.937 | 15.685 | 13.075 |
|  80% | 12.788 |  9.976 | 12.368 |  7.225 |  5.457 |
|  90% |  5.342 |  3.594 |  5.086 |  2.698 |  1.768 |
| 100% |  1.761 |  0.978 |  1.658 |  0.852 |  0.449 |
| 110% |  0.429 |  0.194 |  0.412 |  0.210 |  0.094 |
| 120% |  0.066 |  0.020 |  0.060 |  0.039 |  0.011 |
| 130% |  0.006 |  0.001 |  0.006 |  0.006 |  0.002 |
| 140% |  0.001 |  0.000 |  0.001 |  0.001 |  0.000 |

.

Finisher = S, Boss Attack = 350k, SoI model=nooverheal data set setbonus-10000-20

| Set: |      S |    SH1 |    SH2 |     TS |     ST |
| mean |  0.247 |  0.245 |  0.246 |  0.217 |  0.210 |
|  std |  0.111 |  0.103 |  0.110 |  0.113 |  0.107 |
|   S% |  0.522 |  0.522 |  0.522 |  0.324 |  0.354 |
|   HP |   755k |   755k |   755k |   755k |   755k |
|  nHP |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  20% | 50.804 | 53.070 | 50.570 | 45.730 | 43.729 |
|  30% | 30.239 | 28.970 | 29.752 | 27.484 | 25.189 |
|  40% | 15.067 | 13.081 | 15.006 | 11.815 | 10.663 |
|  50% |  6.810 |  4.612 |  6.868 |  5.772 |  4.813 |
|  60% |  2.719 |  0.988 |  2.585 |  2.744 |  2.208 |
|  70% |  0.838 |  0.133 |  0.627 |  0.921 |  0.743 |
|  80% |  0.171 |  0.007 |  0.068 |  0.136 |  0.112 |
|  90% |  0.012 |  0.000 |  0.002 |  0.009 |  0.009 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  30% | 55.882 | 57.944 | 55.703 | 47.208 | 45.410 |
|  40% | 37.334 | 36.158 | 37.386 | 29.144 | 27.209 |
|  50% | 21.831 | 17.103 | 21.445 | 16.996 | 14.874 |
|  60% | 10.587 |  5.848 | 10.326 |  9.534 |  7.601 |
|  70% |  3.906 |  1.635 |  3.545 |  4.186 |  3.105 |
|  80% |  1.102 |  0.381 |  0.837 |  1.234 |  0.848 |
|  90% |  0.169 |  0.074 |  0.132 |  0.365 |  0.212 |
| 100% |  0.002 |  0.001 |  0.002 |  0.016 |  0.007 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  40% | 57.905 | 58.424 | 57.950 | 46.925 | 45.257 |
|  50% | 42.374 | 40.439 | 42.199 | 32.005 | 29.846 |
|  60% | 28.348 | 24.918 | 28.297 | 21.010 | 18.397 |
|  70% | 15.984 | 12.856 | 15.755 | 11.851 |  9.771 |
|  80% |  7.819 |  5.515 |  7.435 |  6.051 |  4.498 |
|  90% |  2.902 |  1.783 |  2.660 |  2.937 |  1.884 |
| 100% |  0.650 |  0.410 |  0.572 |  1.210 |  0.653 |
| 110% |  0.086 |  0.060 |  0.063 |  0.369 |  0.181 |
| 120% |  0.007 |  0.012 |  0.007 |  0.125 |  0.061 |
| 130% |  0.000 |  0.000 |  0.000 |  0.017 |  0.009 |
| 140% |  0.000 |  0.000 |  0.000 |  0.001 |  0.001 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  50% | 59.997 | 60.331 | 59.760 | 47.679 | 45.805 |
|  60% | 46.133 | 44.822 | 45.961 | 34.436 | 31.709 |
|  70% | 32.199 | 29.660 | 32.037 | 22.568 | 19.890 |
|  80% | 19.945 | 16.986 | 19.531 | 13.468 | 11.003 |
|  90% | 10.663 |  8.286 | 10.288 |  7.559 |  5.523 |
| 100% |  4.800 |  3.365 |  4.708 |  3.810 |  2.426 |
| 110% |  1.774 |  0.993 |  1.747 |  1.628 |  0.860 |
| 120% |  0.643 |  0.288 |  0.614 |  0.671 |  0.314 |
| 130% |  0.117 |  0.054 |  0.109 |  0.219 |  0.085 |
| 140% |  0.021 |  0.009 |  0.017 |  0.058 |  0.021 |
| 150% |  0.001 |  0.001 |  0.000 |  0.014 |  0.005 |
| 160% |  0.000 |  0.000 |  0.000 |  0.004 |  0.001 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  60% | 61.948 | 62.917 | 61.881 | 49.198 | 46.570 |
|  70% | 48.615 | 48.429 | 48.479 | 35.854 | 32.936 |
|  80% | 35.005 | 33.118 | 34.640 | 24.029 | 21.086 |
|  90% | 23.003 | 20.044 | 22.601 | 14.894 | 12.082 |
| 100% | 13.353 | 10.307 | 13.060 |  8.336 |  6.174 |
| 110% |  6.957 |  4.520 |  6.769 |  4.171 |  2.680 |
| 120% |  3.171 |  1.692 |  2.995 |  1.909 |  1.060 |
| 130% |  1.057 |  0.502 |  0.991 |  0.756 |  0.348 |
| 140% |  0.261 |  0.095 |  0.201 |  0.238 |  0.099 |
| 150% |  0.059 |  0.015 |  0.039 |  0.072 |  0.024 |
| 160% |  0.011 |  0.002 |  0.004 |  0.017 |  0.003 |
| 170% |  0.001 |  0.000 |  0.000 |  0.003 |  0.000 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  70% | 62.789 | 63.383 | 62.669 | 49.582 | 46.628 |
|  80% | 50.099 | 49.631 | 49.764 | 36.918 | 33.775 |
|  90% | 37.508 | 35.868 | 37.132 | 25.779 | 22.467 |
| 100% | 25.986 | 23.685 | 25.677 | 16.567 | 13.711 |
| 110% | 16.787 | 14.151 | 16.541 |  9.782 |  7.530 |
| 120% |  9.943 |  7.741 |  9.758 |  5.341 |  3.769 |
| 130% |  5.115 |  3.583 |  4.957 |  2.611 |  1.649 |
| 140% |  2.208 |  1.390 |  2.104 |  1.108 |  0.640 |
| 150% |  0.835 |  0.462 |  0.813 |  0.415 |  0.218 |
| 160% |  0.280 |  0.124 |  0.269 |  0.137 |  0.061 |
| 170% |  0.086 |  0.030 |  0.080 |  0.042 |  0.014 |
| 180% |  0.026 |  0.005 |  0.021 |  0.010 |  0.003 |
| 190% |  0.005 |  0.001 |  0.003 |  0.002 |  0.000 |
| 200% |  0.002 |  0.000 |  0.001 |  0.001 |  0.000 |

Tier 15 4-Piece Bonus: Divine Protection

There’s been mixed reactions to this bonus.  Some players love it, some are hesitant to give up well-itemized (and potentially thunderforged) off-set pieces for two more set pieces given how poorly most of our set is itemized for control/haste.

To test that, I’ve come up with the following simulation.  We’ll compare the data for Control/Haste and Control/Stamina gear sets that do not have the set bonus against a gear set that does use the set bonus, but sacrifices some stats.  The stat differences are based on this comment by Zothor, where he worked out the ideal swap from thunderforged off-set to 4-piece tier.  I have, however, taken the liberty to do some reforging of hit->expertise to maintain caps.  Here are the final stats for the different sets:

|    Set: |  C/Ha |  C/St |  C/Sg | C/Set |
|     Str | 15000 | 15000 | 15000 | 15720 |
|     Sta | 28000 | 34000 | 31000 | 27240 |
|   Parry |  1500 |  1500 |  1500 |  2423 |
|   Dodge |  1500 |  1500 |  1500 |  1614 |
| Mastery |  1500 |  1500 |  1500 |  2137 |
|     Hit |  2550 |  2550 |  2550 |  2576 |
|     Exp |  5100 |  5100 |  5100 |  5100 |
|   Haste | 12000 |  8000 |  8000 | 10788 |

Note that the direct comparison is C/Ha to C/Set; I’ve just included the stamina sets in case the set bonus is more powerful than expected and to have another reference point.

Now, let’s see how they compare.  First, the 150k data:

Finisher = SH1, Boss Attack = 150k, SoI model=nooverheal data set setbonus-10000-23

| Set: |   C/Ha |   C/St |   C/Sg |  C/Set |
| mean |  0.210 |  0.233 |  0.233 |  0.205 |
|  std |  0.101 |  0.106 |  0.106 |  0.102 |
|   S% |  0.522 |  0.482 |  0.482 |  0.511 |
|   HP |   755k |   876k |   816k |   740k |
|  nHP |  5.034 |  5.843 |  5.439 |  4.932 |
| ---- |  --- 2 | Attack | Moving | Avg.-- |
|  10% | 38.550 | 36.768 | 43.808 | 38.757 |
|  20% |  5.233 |  2.554 |  4.759 |  6.061 |
|  30% |  0.116 |  0.015 |  0.025 |  0.179 |
| ---- |  --- 3 | Attack | Moving | Avg.-- |
|  20% | 15.460 | 11.241 | 16.514 | 16.666 |
|  30% |  0.809 |  0.383 |  0.555 |  1.200 |
|  40% |  0.001 |  0.000 |  0.005 |  0.017 |
| ---- |  --- 4 | Attack | Moving | Avg.-- |
|  20% | 34.034 | 31.020 | 36.894 | 34.493 |
|  30% |  8.381 |  4.645 |  7.337 |  8.809 |
|  40% |  0.450 |  0.168 |  0.481 |  0.563 |
|  50% |  0.009 |  0.001 |  0.006 |  0.014 |
| ---- |  --- 5 | Attack | Moving | Avg.-- |
|  20% | 51.302 | 49.340 | 55.036 | 51.044 |
|  30% | 19.624 | 14.006 | 19.151 | 20.041 |
|  40% |  2.826 |  1.518 |  3.128 |  3.318 |
|  50% |  0.243 |  0.035 |  0.185 |  0.283 |
|  60% |  0.004 |  0.000 |  0.003 |  0.004 |
| ---- |  --- 6 | Attack | Moving | Avg.-- |
|  30% | 33.546 | 27.377 | 34.258 | 33.419 |
|  40% |  8.214 |  5.209 |  8.906 |  8.952 |
|  50% |  1.091 |  0.262 |  0.913 |  1.234 |
|  60% |  0.027 |  0.002 |  0.017 |  0.032 |
| ---- |  --- 7 | Attack | Moving | Avg.-- |
|  30% | 47.345 | 42.301 | 49.405 | 46.919 |
|  40% | 18.329 | 13.850 | 19.839 | 18.883 |
|  50% |  4.451 |  2.189 |  4.609 |  4.885 |
|  60% |  0.510 |  0.133 |  0.464 |  0.604 |
|  70% |  0.030 |  0.001 |  0.017 |  0.032 |

It’s hard to tell from this data since there’s so little of it, but it doesn’t look like the 4-piece is bringing any significant advantage to the table.  It provides lower SotR uptime and worse spike presence pretty much across the board.  For the 10-man raider, the 4-piece seems fairly unattractive.  It’s not terrible, per se, but it definitely doesn’t seem to compete with the extra haste and stamina you get from off-set pieces.

However, unlike the 2-piece bonus, the 4-piece is a lot more sensitive to boss attack size.  Let’s see what happens when we crank the dial up to 250k boss swings:

Finisher = SH1, Boss Attack = 250k, SoI model=nooverheal data set setbonus-10000-22

| Set: |   C/Ha |   C/St |   C/Sg |  C/Set |
| mean |  0.234 |  0.256 |  0.257 |  0.221 |
|  std |  0.102 |  0.105 |  0.105 |  0.103 |
|   S% |  0.523 |  0.482 |  0.482 |  0.536 |
|   HP |   755k |   876k |   816k |   740k |
|  nHP |  3.021 |  3.506 |  3.263 |  2.959 |
| ---- |  --- 2 | Attack | Moving | Avg.-- |
|  20% | 37.499 | 28.886 | 32.327 | 35.130 |
|  30% | 12.061 |  6.843 | 12.024 | 11.676 |
|  40% |  1.221 |  0.502 |  1.483 |  2.655 |
|  50% |  0.081 |  0.022 |  0.033 |  0.146 |
|  60% |  0.001 |  0.000 |  0.001 |  0.005 |
| ---- |  --- 3 | Attack | Moving | Avg.-- |
|  30% | 33.369 | 22.621 | 32.503 | 30.202 |
|  40% |  6.660 |  4.112 |  8.332 | 10.238 |
|  50% |  0.957 |  0.401 |  0.900 |  1.598 |
|  60% |  0.100 |  0.030 |  0.048 |  0.166 |
|  70% |  0.001 |  0.000 |  0.002 |  0.012 |
| ---- |  --- 4 | Attack | Moving | Avg.-- |
|  30% | 54.379 | 46.699 | 55.190 | 50.182 |
|  40% | 27.149 | 21.752 | 29.260 | 27.772 |
|  50% | 11.131 |  5.830 |  9.316 | 11.315 |
|  60% |  3.168 |  1.069 |  2.204 |  3.162 |
|  70% |  0.455 |  0.090 |  0.331 |  0.510 |
|  80% |  0.034 |  0.005 |  0.034 |  0.052 |
|  90% |  0.001 |  0.000 |  0.000 |  0.005 |
| ---- |  --- 5 | Attack | Moving | Avg.-- |
|  40% | 47.137 | 41.709 | 49.760 | 45.135 |
|  50% | 26.457 | 18.178 | 24.735 | 25.319 |
|  60% | 11.518 |  6.259 |  9.722 | 10.977 |
|  70% |  3.346 |  1.053 |  2.809 |  3.369 |
|  80% |  0.536 |  0.159 |  0.520 |  0.685 |
|  90% |  0.060 |  0.007 |  0.043 |  0.095 |
| 100% |  0.003 |  0.000 |  0.003 |  0.010 |
| ---- |  --- 6 | Attack | Moving | Avg.-- |
|  50% | 44.100 | 35.111 | 43.671 | 41.135 |
|  60% | 24.655 | 16.643 | 22.668 | 22.762 |
|  70% | 10.041 |  4.423 |  9.212 |  9.649 |
|  80% |  2.647 |  0.988 |  2.574 |  2.927 |
|  90% |  0.502 |  0.081 |  0.375 |  0.627 |
| 100% |  0.056 |  0.007 |  0.041 |  0.100 |
| 110% |  0.001 |  0.000 |  0.001 |  0.009 |
| ---- |  --- 7 | Attack | Moving | Avg.-- |
|  60% | 40.021 | 32.283 | 39.562 | 36.834 |
|  70% | 22.651 | 14.265 | 22.229 | 20.977 |
|  80% | 10.181 |  5.484 | 10.029 |  9.778 |
|  90% |  3.695 |  1.196 |  3.030 |  3.689 |
| 100% |  1.038 |  0.257 |  0.768 |  1.082 |
| 110% |  0.204 |  0.024 |  0.167 |  0.245 |
| 120% |  0.016 |  0.003 |  0.023 |  0.039 |
| 130% |  0.001 |  0.000 |  0.001 |  0.003 |

In this data, we’re seeing an increase in SotR uptime from the set bonus, which is a good start.  It’s still not really giving  a significant improvement in any of the spike categories though, and trailing in most of them.  That said, it’s close enough that you’re probably fine with either choice – the two aren’t so significantly different that either is a poor choice.  It ends up being a trade-off that doesn’t have much effect in the end.  The set bonus increases SotR uptime, which is good, but costs stamina, which is bad, and the two mostly offset one another.

Let’ see if it improves with 350k swings.

Finisher = SH1, Boss Attack = 350k, SoI model=nooverheal data set setbonus-10000-21

| Set: |   C/Ha |   C/St |   C/Sg |  C/Set |
| mean |  0.244 |  0.267 |  0.268 |  0.223 |
|  std |  0.103 |  0.106 |  0.106 |  0.108 |
|   S% |  0.523 |  0.482 |  0.482 |  0.576 |
|   HP |   755k |   876k |   816k |   740k |
|  nHP |  2.158 |  2.504 |  2.331 |  2.114 |
| ---- |  --- 2 | Attack | Moving | Avg.-- |
|  20% | 53.023 | 54.094 | 55.312 | 48.477 |
|  30% | 28.922 | 27.172 | 32.239 | 26.134 |
|  40% | 13.030 | 11.389 | 15.346 | 12.631 |
|  50% |  4.575 |  2.022 |  4.237 |  4.449 |
|  60% |  0.965 |  0.306 |  0.920 |  0.983 |
|  70% |  0.130 |  0.022 |  0.032 |  0.137 |
|  80% |  0.006 |  0.000 |  0.002 |  0.012 |
| ---- |  --- 3 | Attack | Moving | Avg.-- |
|  40% | 36.134 | 32.386 | 39.629 | 33.580 |
|  50% | 17.051 | 10.788 | 17.012 | 15.700 |
|  60% |  5.776 |  3.107 |  5.565 |  5.750 |
|  70% |  1.608 |  0.667 |  1.416 |  1.586 |
|  80% |  0.370 |  0.048 |  0.257 |  0.396 |
|  90% |  0.070 |  0.002 |  0.032 |  0.069 |
| 100% |  0.001 |  0.000 |  0.003 |  0.010 |
| ---- |  --- 4 | Attack | Moving | Avg.-- |
|  50% | 40.315 | 35.246 | 41.916 | 35.838 |
|  60% | 24.832 | 18.204 | 24.447 | 21.789 |
|  70% | 12.821 |  7.603 | 12.312 | 11.274 |
|  80% |  5.436 |  2.222 |  4.236 |  4.977 |
|  90% |  1.731 |  0.507 |  1.307 |  1.713 |
| 100% |  0.397 |  0.097 |  0.324 |  0.455 |
| 110% |  0.062 |  0.014 |  0.054 |  0.092 |
| 120% |  0.014 |  0.000 |  0.003 |  0.019 |
| 130% |  0.001 |  0.000 |  0.000 |  0.003 |
| ---- |  --- 5 | Attack | Moving | Avg.-- |
|  60% | 44.695 | 37.974 | 45.599 | 38.878 |
|  70% | 29.605 | 22.269 | 29.850 | 25.662 |
|  80% | 16.860 | 10.325 | 16.311 | 15.070 |
|  90% |  8.185 |  4.229 |  7.607 |  7.605 |
| 100% |  3.365 |  1.154 |  2.908 |  3.188 |
| 110% |  0.982 |  0.279 |  0.828 |  1.121 |
| 120% |  0.261 |  0.037 |  0.180 |  0.317 |
| 130% |  0.044 |  0.004 |  0.036 |  0.075 |
| 140% |  0.006 |  0.000 |  0.002 |  0.011 |
| ---- |  --- 6 | Attack | Moving | Avg.-- |
|  70% | 48.266 | 40.831 | 49.405 | 41.463 |
|  80% | 33.005 | 24.500 | 33.392 | 28.608 |
|  90% | 19.919 | 12.898 | 19.867 | 17.715 |
| 100% | 10.243 |  5.314 |  9.942 |  9.496 |
| 110% |  4.460 |  1.690 |  4.110 |  4.265 |
| 120% |  1.621 |  0.369 |  1.392 |  1.605 |
| 130% |  0.482 |  0.072 |  0.338 |  0.543 |
| 140% |  0.082 |  0.005 |  0.056 |  0.139 |
| 150% |  0.014 |  0.000 |  0.006 |  0.018 |
| 160% |  0.001 |  0.000 |  0.000 |  0.003 |
| ---- |  --- 7 | Attack | Moving | Avg.-- |
|  80% | 49.407 | 41.995 | 51.019 | 42.359 |
|  90% | 35.667 | 27.965 | 37.047 | 31.028 |
| 100% | 23.619 | 16.265 | 24.129 | 20.791 |
| 110% | 14.079 |  8.029 | 13.905 | 12.506 |
| 120% |  7.655 |  3.461 |  7.154 |  6.817 |
| 130% |  3.511 |  1.270 |  3.141 |  3.372 |
| 140% |  1.318 |  0.405 |  1.151 |  1.427 |
| 150% |  0.423 |  0.088 |  0.393 |  0.500 |
| 160% |  0.116 |  0.012 |  0.104 |  0.154 |
| 170% |  0.028 |  0.001 |  0.020 |  0.046 |
| 180% |  0.006 |  0.000 |  0.001 |  0.007 |
| 190% |  0.000 |  0.000 |  0.000 |  0.001 |

Better… but… still a little disappointing.  We now have significantly higher SotR uptime with the set bonus active thanks to the higher incoming damage rate.  However that high uptime isn’t translating to a huge decrease in spike presence.  At best, it’s a complete wash.  It just doesn’t seem strong enough to have a big effect.

That may seem puzzling – after all, 5% more SotR uptime seems like it should be worth something, right?  But the reasons for the lackluster performance are pretty easy to explain.  I think there are two primary reasons that the set bonus falls short.  First, we lose about 2% of our total health by using the set pieces instead of thunderforged off-set items.  That in and of itself is a fairly noticeable loss given how strongly stamina performs in the simulation.

But the more subtle reason is in the timing of the set bonus.  You receive that extra holy power only while you already have a 20% mitigation cooldown active – in other words, during a time when you’re already less susceptible to spikes.  The big spikes aren’t happening when you have Divine Protection up because you have Divine Protection up, so having higher SotR uptime during Divine Protection just serves to lower total damage taken.

In a sense, instead of applying that holy power to the top spikes, or the tail of the distribution, you’re just taking a chunk out of the middle and shifting it further down.  You’re turning “not deadly” sequences into “still not deadly” sequences, which explains why it has very little effect on the dangerous spikes at the top of the distribution.

The haste set, on the other hand, gives you more holy power to use mitigating the large spikes at all times, which translates into better spike mitigation over the entire distribution, including (and especially at) the top where the deadly spikes are.

Conclusions

So  the updated simulation seems to reinforce our earlier impressions of the set bonus.  In short, the 2-piece is a nice bonus for when we have to WoG, but not worth using as a maintenance buff.  The 4-piece is similarly not bad, but also not effective enough to warrant giving up well-itemized thunderforged off-set pieces.  The latter is especially worth noting if you’re in a situation where you have access to much higher-ilvl off-set pieces (i.e. heroic and/or thunderforged off-set vs. normal-mode tier).

## Patch 5.3 WeakAuras Configuration

Since 5.2, I’ve made a few modifications to my WeakAuras configuration.  Nothing major, but definitely some quality-of-life improvements.

One option that WeakAuras lacks is the ability to set a trigger based on Spell ID and time remaining.  You can do one or the other, but not both – as soon as you chose “Use Full Scan” to filter by Spell ID you lose the ability to check duration.  This makes it impossible to create a warning aura to tell you that Sacred Shield is about to expire with the default UI.  The best you can do is alert yourself that the buff has already expired, which is too late.

Luckily, pvita has written a custom trigger to fix that.  He built his indicator with differently-colored shields; I’ve more or less just taken the trigger and used it to make the Sacred Shield icon “bounce” whenever you have less than 8 seconds left.  I’ve also moved it to the left of the Weakened Blows icon and made it larger so that it’s a little more obnoxious (and thus, easier to notice).

Sucellus over at Light’s Hammer also noted that it isn’t just Vengeance we care about for Sacred Shield, we also care about overall attack power.  And there happen to be several nice haste trinkets with strength procs this tier, so it’s worth adjusting for that.  I’ve incorporated his attack power modifications into my own auras, so now they record overall attack power.  I’ve also added it to the Vengeance display for consistency.  Since that made it harder to see exactly how much of that contribution is from Vengeance, I modified it to give both values in the format “Attack Power (Vengeance)”.  For example, “50k (0k)” would mean you have 50k attack power, none of which comes from Vengeance.

Finally, Reverde asked if it would be worth tracking haste as well, since Sacred Shield scales very well with haste.  He pointed out that in many cases it wouldn’t be worth over-writing a Sacred Shield cast near the end of Bloodlust unless the attack power change was very significant.  So I’ve added a spell-haste-tracker for Sacred Shield as well.  You can see what these modifications look like in the YouTube video below:

I’m not sure why the videos didn’t record with sound this time, but it’s not worth going back and re-uploading just for that.

I’ve also been playing a priest alt pretty heavily, so I finally have auras to share for Shadow and Atonement/Discipline.  They look something like this:

I think I also updated the Rogue auras from level 85 to 90, though I don’t play that character heavily so they’re still fairly barebones.  I believe I made slight modifications to the Warlock auras as well, but I honestly can’t remember what they were.

WordPress is finicky about text boxes containing large strings, so all of my Auras are hosted at Pastebin.  Here are direct links to the two WeakAuras strings used in my tanking UI:

Theck – Prot – Priority Row

Theck – Prot – Cooldowns Row

Theck – Prot – Vengeance / SS text indicators

And of course all of my auras can be found by browsing my Pastebin account:

http://pastebin.com/u/Theck

Here are direct links to the class/spec combinations I have updated there:

Death Knight – Any (used by both specs)
Death Knight – Blood
Death Knight – Unholy
Druid – Guardian
Hunter – Any (used by all hunter specs)
Hunter – Beast Mastery (L85)
Hunter – Marskman
Hunter – Survival
Mage – Any (L85)
Mage – Arcane (L85)
Mage – Fire (L85)
Monk – Brewmaster
Monk – Chi (used by both specs)
Monk – Stagger (used by Brewmaster)
Monk – Windwalker
Rogue – Any (used by both specs)
Rogue – Combat
Rogue – Subtlety
Paladin – Retribution (just cooldowns, I use clcRet for rotation)
Priest – Any

Priest – Disc/Atonement
Warlock – Any (used by all three specs)
Warlock – Affliction
Warlock – Demonology
Warrior – Any (used by all three specs)
Warrior – Arms (L85)
Warrior – Fury
Warrior – Protection
Amber-Shaper Unsok Vehicle HUD

Posted in Tanking, Theck's Pounding Headaches, UI, Uncategorized | | 30 Comments

## Out of Insight, Out of Mind

In the last post, we discussed a variety of topics related to modeling Seal of Insight.  Now it’s time to put that modeling discussion to work.

The Model

I decided to stick with the conclusion I came to in my last post.  I’m modeling SoI with a backwards-facing method, in which each SoI proc reduces the damage done by the previous attack.  This limits the scope of SoI to one attack in the past and creates incidental overheal whenever that attack was a dodge or parry.  I’m also not applying any sort of overheal function to simulate indirect overhealing, so every Seal of Insight proc acts at full strength.

This will over-represent Seal of Insight’s usefulness in overall damage mitigation (i.e. TDR), because in many cases it will compete with HoTs and other low-throughput healing effects and cause a significant amount of overhealing.  However, it will more accurately represent the behavior during high-throughput periods (i.e. spikes), where that healing is far less likely to be wasted.  Since we’re mostly looking at the top two or three levels of spike damage in these simulations anyway, it makes more sense to bias the results towards accuracy in that region.

I’ll also note that I’ve implemented the 5.3 nerf to Shield of the Righteous, so it’s base mitigation is already 25% in these simulations.

For completeness, and for any newcomers to this blog, here’s a quick overview of how the simulation works:

To better understand the data below, here’s a rough overview of how it’s generated: I run a Monte-Carlo sim that simulates 10k minutes of combat (think Simcraft, but paladin-specific and more limited in scope), making all combat rolls and logging all damage events.  I take the resulting string of attacks (something like “1, 0, 0.7, 1, 0, 0, …” where 0 is an avoid (no damage), 1 is a full hit, 0.7 is a block, and so on) and do some calculations on it.  I calculate the average damage intake normalized to 100% possible throughput (i.e. “1, 1, 1, 1, 1, …”), and report that in the “mean” row, representing mean damage intake (lower is better, represents better TDR).  “std” is just the standard deviation of that mean as averaged over 5 attacks.  “S%” is SotR uptime.

The rest of the rows are smoothing data for strings of N attacks.  For now, let’s just consider the first gear column (C/Ha).  I take the damage event sequence and perform a moving average on it (i.e. an N-attack moving average).  I then calculate how many of those N-attack averages exceed a certain percentage of the player’s health.  So for example, if we look at a 3-attack moving average, the “70%” row tells me how many of those 3-attack averages exceed 70% of the player’s health.  Note that the categories are cumulative, so if 5% of attacks exceed 90% health, those attacks are also being counted in the 80% and 70% rows (thus, if 17% of attacks exceed 80% health, the percentage between 80% and 90% is 17%-5%=12%).  I should add that the repeatability on these simulations is quite good thanks to the long integration time – results usually fluctuate by less than +/- 0.1% (absolute, i.e. 5% +/- 0.1%).

I do this for a bunch of different gear sets, i.e. “C/Ha” for Control/Haste, etc.  The gear list tables provide the stats of each gear configuration so you get a rough idea of what they look like.  They’re roughly equivalent to stats in ilvl 522 gear.

The code can be found in the matlabadin repository, as usual.  The two files in particular are pally_mc.m and pally_mc_smooth.m.

I’m going to dump a lot of data on you here, so bear with me.  I’ll provide as much commentary as makes sense, but there will be a lot of repetition since most of the data sets look roughly similar.

Standard Panels

First, we’ll do our “standard panel” that compares the basic gear sets: Control/Haste, Control/StamGem (where we convert 4k haste into 3k stamina by swapping gems), Control/Mastery, Control/Avoidance, Control/Balance, Control/HasteMastery, Avoidance, Avoidance/Mastery, and Mastery/Avoidance.  Those gear sets are given in the table below:

|    Set: |  C/Ha |  C/Sg |  C/Ma |  C/Av | C/Bal |  C/HM | Avoid | Av/Mas | Mas/Av |
|     Str | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 |  15000 |  15000 |
|     Sta | 28000 | 31000 | 28000 | 28000 | 28000 | 28000 | 28000 |  28000 |  28000 |
|   Parry |  1500 |  1500 |  1500 |  7500 |  4125 |  1500 | 10825 |   7717 |   4000 |
|   Dodge |  1500 |  1500 |  1500 |  7500 |  4125 |  1500 | 10825 |   7717 |   4000 |
| Mastery |  1500 |  1500 | 13500 |  1500 |  4125 |  6750 |  1500 |   7716 |  15150 |
|     Hit |  2550 |  2550 |  2550 |  2550 |  2550 |  2550 |   500 |    500 |    500 |
|     Exp |  5100 |  5100 |  5100 |  5100 |  5100 |  5100 |   500 |    500 |    500 |
|   Haste | 12000 |  8000 |     0 |     0 |  4125 |  6750 |     0 |      0 |      0 |

I haven’t updated these for 5.3, mostly because I haven’t had time.  In all likelihood, nothing changes by bumping the ilvl slightly anyway.  First, let’s look at the data for a 10-man normal mode boss that hits for 150k per swing after mitigation:

Finisher = SH1, Boss Attack = 150k, SoI model=nooverheal, data set smooth-10000-77

| Set: |   C/Ha |   C/Sg |   C/Ma |   C/Av |  C/Bal |   C/HM |  Avoid | Av/Mas | Mas/Av |
| mean |  0.227 |  0.251 |  0.248 |  0.254 |  0.244 |  0.222 |  0.253 |  0.258 |  0.262 |
|  std |  0.103 |  0.106 |  0.110 |  0.125 |  0.113 |  0.102 |  0.138 |  0.131 |  0.126 |
|   S% |  0.522 |  0.482 |  0.410 |  0.420 |  0.452 |  0.471 |  0.366 |  0.362 |  0.357 |
|   HP |   755k |   816k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  5.034 |  5.439 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |
| ---- | ------ |  --- 2 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  10% | 43.049 | 48.638 | 46.573 | 48.233 | 48.137 | 44.968 | 45.969 | 46.010 | 47.654 |
|  20% |  6.546 |  5.883 | 11.663 | 12.846 | 10.383 |  7.632 | 14.289 | 14.371 | 14.275 |
|  30% |  0.165 |  0.036 |  0.665 |  1.117 |  0.682 |  0.266 |  1.774 |  1.448 |  1.304 |
| ---- | ------ |  --- 3 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  20% | 19.140 | 20.327 | 26.172 | 30.344 | 26.195 | 20.294 | 31.925 | 31.083 | 30.555 |
|  30% |  1.131 |  0.808 |  4.640 |  6.188 |  3.544 |  1.718 |  8.119 |  7.231 |  7.526 |
|  40% |  0.001 |  0.005 |  0.259 |  0.390 |  0.147 |  0.004 |  0.841 |  0.750 |  0.747 |
|  50% |  0.001 |  0.000 |  0.001 |  0.014 |  0.006 |  0.000 |  0.064 |  0.037 |  0.035 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  20% | 39.889 | 42.935 | 47.796 | 50.088 | 47.584 | 40.228 | 49.763 | 50.423 | 51.479 |
|  30% | 10.957 |  9.586 | 13.558 | 19.193 | 14.404 |  9.897 | 20.855 | 19.195 | 19.098 |
|  40% |  0.679 |  0.707 |  2.204 |  3.037 |  1.757 |  0.941 |  4.865 |  4.176 |  4.346 |
|  50% |  0.017 |  0.012 |  0.150 |  0.257 |  0.111 |  0.041 |  0.709 |  0.600 |  0.629 |
|  60% |  0.001 |  0.000 |  0.000 |  0.001 |  0.000 |  0.000 |  0.025 |  0.020 |  0.017 |
| ---- | ------ |  --- 5 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  30% | 24.849 | 23.976 | 30.836 | 35.357 | 30.603 | 23.005 | 35.410 | 34.973 | 36.024 |
|  40% |  4.000 |  4.359 |  8.320 | 11.603 |  8.412 |  4.380 | 13.892 | 13.213 | 13.085 |
|  50% |  0.404 |  0.283 |  1.177 |  2.515 |  1.182 |  0.344 |  3.978 |  3.317 |  3.211 |
|  60% |  0.008 |  0.005 |  0.130 |  0.206 |  0.088 |  0.011 |  0.632 |  0.519 |  0.539 |
|  70% |  0.000 |  0.000 |  0.004 |  0.011 |  0.001 |  0.001 |  0.069 |  0.055 |  0.043 |
|  80% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |  0.002 |  0.001 |
| ---- | ------ |  --- 6 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  30% | 41.134 | 41.499 | 47.962 | 50.478 | 47.235 | 38.445 | 49.038 | 49.938 | 52.001 |
|  40% | 11.311 | 12.159 | 19.450 | 23.400 | 19.099 | 11.473 | 25.190 | 25.009 | 25.453 |
|  50% |  1.748 |  1.394 |  4.638 |  7.871 |  4.398 |  1.570 | 10.062 |  9.292 |  8.998 |
|  60% |  0.046 |  0.033 |  0.668 |  1.436 |  0.605 |  0.080 |  2.764 |  2.347 |  2.127 |
|  70% |  0.001 |  0.000 |  0.064 |  0.190 |  0.041 |  0.002 |  0.541 |  0.407 |  0.388 |
|  80% |  0.000 |  0.000 |  0.003 |  0.007 |  0.002 |  0.000 |  0.065 |  0.051 |  0.045 |
|  90% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.006 |  0.003 |  0.003 |
| ---- | ------ |  --- 7 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  40% | 23.886 | 25.744 | 33.245 | 36.754 | 32.783 | 23.224 | 37.333 | 38.102 | 39.434 |
|  50% |  6.574 |  6.640 | 11.688 | 16.426 | 10.957 |  5.941 | 18.512 | 18.043 | 17.997 |
|  60% |  0.835 |  0.743 |  2.535 |  4.717 |  2.290 |  0.846 |  6.948 |  6.274 |  5.910 |
|  70% |  0.059 |  0.033 |  0.293 |  0.913 |  0.253 |  0.067 |  1.954 |  1.576 |  1.414 |
|  80% |  0.001 |  0.000 |  0.025 |  0.090 |  0.012 |  0.002 |  0.373 |  0.283 |  0.246 |
|  90% |  0.000 |  0.000 |  0.001 |  0.006 |  0.000 |  0.000 |  0.052 |  0.030 |  0.032 |
| 100% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.004 |  0.002 |  0.001 |

This seems like a pretty clear win for Control/Haste.  You may have been expecting Control/Mastery to pull ahead thanks to the SotR nerf, and if we were ignoring Seal of Insight it does. In fact, without SoI active, Control/Mastery is very competitive across the board.

But Seal of Insight procs push haste significantly ahead.  Remember that each Seal of Insight proc is healing for about 20% of a boss attack, so as long as the previous attack wasn’t avoided each proc acts like a miniature block.  And we get more procs than we do boss attacks, statistically speaking, so we basically have about one 20% block ready for each potential melee attack.  That’s a huge value.

As I noted in the last post, this gives Control/Haste a strong passive mitigation component via Seal of Insight, which is what it lacked in previous simulations.  That’s the main reason that Control/Mastery was able to compete in the higher-number-of-attacks categories before.  But here we see Control/Haste taking that spot.

I should add, however, that Control/Stamina still reigns supreme for raw survivability.  We still get more survivability by converting Haste gems to Stamina gems, even at this low attack size threshold.  The reason I call this category for Control/Haste is that even a 7-attack string doesn’t exceed 80% of the player’s health, so that extra stamina isn’t really necessary.  Note, however, that this assumes a tank with 755k health raid-buffed, and many 10-man tanks are running less than that.  But I still think Control/Haste wins the day for normal-mode 10-man content.

Next, we’ll look at the 250k boss attack data, which is our 10-man heroic / 25-man normal boss:

Finisher = SH1, Boss Attack = 250k, SoI model=nooverheal data set smooth-10000-76

| Set: |   C/Ha |   C/Sg |   C/Ma |   C/Av |  C/Bal |   C/HM |  Avoid | Av/Mas | Mas/Av |
| mean |  0.250 |  0.274 |  0.268 |  0.270 |  0.264 |  0.249 |  0.269 |  0.275 |  0.278 |
|  std |  0.102 |  0.105 |  0.106 |  0.122 |  0.112 |  0.103 |  0.137 |  0.130 |  0.123 |
|   S% |  0.522 |  0.482 |  0.411 |  0.419 |  0.453 |  0.471 |  0.366 |  0.362 |  0.357 |
|   HP |   755k |   816k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  3.021 |  3.263 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |
| ---- | ------ |  --- 2 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  20% | 42.078 | 36.083 | 45.410 | 45.450 | 45.211 | 44.773 | 42.991 | 44.828 | 46.785 |
|  30% | 14.655 | 14.598 | 17.825 | 20.553 | 18.808 | 16.156 | 22.076 | 22.961 | 22.151 |
|  40% |  1.581 |  1.950 |  4.326 |  4.564 |  3.465 |  2.270 |  7.173 |  7.537 |  7.114 |
|  50% |  0.114 |  0.049 |  0.520 |  0.874 |  0.516 |  0.164 |  1.560 |  1.420 |  1.309 |
|  60% |  0.000 |  0.003 |  0.018 |  0.025 |  0.016 |  0.005 |  0.149 |  0.148 |  0.124 |
| ---- | ------ |  --- 3 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  30% | 39.360 | 38.142 | 37.345 | 44.477 | 41.242 | 38.137 | 42.986 | 44.382 | 42.508 |
|  40% |  8.503 | 10.763 | 15.188 | 18.103 | 14.772 | 10.706 | 21.322 | 21.559 | 20.696 |
|  50% |  1.355 |  1.289 |  4.676 |  5.786 |  3.746 |  2.142 |  8.101 |  7.849 |  7.994 |
|  60% |  0.151 |  0.077 |  1.027 |  1.399 |  0.700 |  0.269 |  2.643 |  2.421 |  2.543 |
|  70% |  0.002 |  0.003 |  0.130 |  0.278 |  0.102 |  0.003 |  0.672 |  0.649 |  0.641 |
|  80% |  0.000 |  0.000 |  0.014 |  0.060 |  0.018 |  0.000 |  0.184 |  0.161 |  0.135 |
|  90% |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |  0.000 |  0.027 |  0.025 |  0.014 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  40% | 32.289 | 35.037 | 36.081 | 39.780 | 37.409 | 33.129 | 39.981 | 42.235 | 42.126 |
|  50% | 14.136 | 11.959 | 15.007 | 21.016 | 16.922 | 13.521 | 22.454 | 22.357 | 21.442 |
|  60% |  4.256 |  3.039 |  5.228 |  8.388 |  5.820 |  3.907 | 10.804 |  9.415 |  9.129 |
|  70% |  0.639 |  0.506 |  1.494 |  2.212 |  1.392 |  0.980 |  4.060 |  3.521 |  3.732 |
|  80% |  0.067 |  0.048 |  0.402 |  0.545 |  0.334 |  0.185 |  1.357 |  1.326 |  1.414 |
|  90% |  0.001 |  0.001 |  0.034 |  0.051 |  0.029 |  0.005 |  0.355 |  0.388 |  0.369 |
| 100% |  0.000 |  0.000 |  0.001 |  0.003 |  0.003 |  0.000 |  0.083 |  0.077 |  0.063 |
| 110% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |  0.003 |  0.001 |
| ---- | ------ |  --- 5 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  50% | 32.320 | 30.188 | 35.995 | 39.665 | 35.861 | 31.226 | 38.853 | 40.103 | 40.903 |
|  60% | 15.028 | 12.682 | 18.679 | 23.359 | 19.306 | 13.900 | 24.320 | 23.745 | 24.010 |
|  70% |  4.623 |  4.047 |  6.961 | 11.113 |  8.347 |  4.777 | 13.320 | 12.426 | 12.309 |
|  80% |  0.799 |  0.773 |  2.132 |  4.000 |  2.715 |  1.320 |  6.258 |  5.748 |  5.314 |
|  90% |  0.100 |  0.063 |  0.496 |  1.027 |  0.610 |  0.215 |  2.419 |  2.207 |  1.948 |
| 100% |  0.009 |  0.004 |  0.097 |  0.205 |  0.119 |  0.028 |  0.824 |  0.727 |  0.672 |
| 110% |  0.000 |  0.000 |  0.015 |  0.033 |  0.016 |  0.001 |  0.227 |  0.206 |  0.207 |
| 120% |  0.000 |  0.000 |  0.001 |  0.003 |  0.001 |  0.000 |  0.059 |  0.054 |  0.055 |
| 130% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.011 |  0.010 |  0.011 |
| 140% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |  0.001 |  0.001 |
| ---- | ------ |  --- 6 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  60% | 31.122 | 28.454 | 36.137 | 39.727 | 35.931 | 28.814 | 38.649 | 39.354 | 40.844 |
|  70% | 13.490 | 12.783 | 18.888 | 24.148 | 19.920 | 13.297 | 25.299 | 24.893 | 25.561 |
|  80% |  3.788 |  3.859 |  7.984 | 11.956 |  8.868 |  4.952 | 14.591 | 14.231 | 13.811 |
|  90% |  0.778 |  0.566 |  2.575 |  4.953 |  2.970 |  1.275 |  7.308 |  7.083 |  6.474 |
| 100% |  0.103 |  0.070 |  0.689 |  1.795 |  0.848 |  0.238 |  3.425 |  3.105 |  2.694 |
| 110% |  0.003 |  0.002 |  0.143 |  0.552 |  0.183 |  0.014 |  1.401 |  1.172 |  1.031 |
| 120% |  0.000 |  0.000 |  0.021 |  0.085 |  0.026 |  0.000 |  0.469 |  0.388 |  0.336 |
| 130% |  0.000 |  0.000 |  0.002 |  0.008 |  0.003 |  0.000 |  0.128 |  0.120 |  0.106 |
| 140% |  0.000 |  0.000 |  0.000 |  0.001 |  0.001 |  0.000 |  0.034 |  0.035 |  0.033 |
| 150% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.007 |  0.007 |  0.006 |
| 160% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |  0.001 |  0.001 |
| ---- | ------ |  --- 7 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  60% | 48.319 | 47.006 | 54.198 | 55.111 | 52.824 | 46.176 | 52.256 | 54.221 | 56.922 |
|  70% | 29.026 | 28.625 | 34.520 | 39.075 | 35.332 | 27.789 | 38.363 | 39.050 | 40.749 |
|  80% | 13.750 | 13.940 | 18.621 | 23.875 | 19.770 | 13.974 | 25.522 | 25.841 | 25.816 |
|  90% |  5.280 |  4.517 |  8.249 | 12.710 |  8.748 |  5.686 | 15.166 | 15.259 | 14.590 |
| 100% |  1.585 |  1.229 |  3.069 |  5.933 |  3.316 |  1.898 |  8.483 |  8.080 |  7.473 |
| 110% |  0.323 |  0.258 |  0.915 |  2.406 |  1.068 |  0.488 |  4.283 |  3.848 |  3.447 |
| 120% |  0.040 |  0.035 |  0.202 |  0.727 |  0.247 |  0.089 |  1.847 |  1.619 |  1.348 |
| 130% |  0.002 |  0.003 |  0.036 |  0.185 |  0.034 |  0.007 |  0.715 |  0.601 |  0.492 |
| 140% |  0.000 |  0.000 |  0.003 |  0.039 |  0.005 |  0.001 |  0.252 |  0.212 |  0.168 |
| 150% |  0.000 |  0.000 |  0.000 |  0.006 |  0.000 |  0.000 |  0.068 |  0.060 |  0.047 |
| 160% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.017 |  0.016 |  0.013 |
| 170% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |  0.003 |  0.002 |

Again, Control/Stamina and Control/Haste lead the pack by a good margin.  Not much else has changed from the 150k swing data; avoidance sets still perform poorly and none of the other secondary stats seem capable of coming close to haste.  The loss going from haste to mastery is significant enough now that we’re not even seeing any advantage from the Control/HasteMastery set.  That said, we’ve seen in the past that the results can fluctuate with small haste changes, so it’s something we’ll have to investigate in more detail in the future.

On to the heroic 25-man boss that hits for 350k per swing:

Finisher = SH1, Boss Attack = 350k, SoI model=nooverheal data set smooth-10000-75

| Set: |   C/Ha |   C/Sg |   C/Ma |   C/Av |  C/Bal |   C/HM |  Avoid | Av/Mas | Mas/Av |
| mean |  0.262 |  0.285 |  0.280 |  0.280 |  0.275 |  0.259 |  0.278 |  0.283 |  0.289 |
|  std |  0.103 |  0.106 |  0.107 |  0.123 |  0.114 |  0.104 |  0.138 |  0.132 |  0.124 |
|   S% |  0.523 |  0.483 |  0.410 |  0.419 |  0.452 |  0.472 |  0.366 |  0.363 |  0.357 |
|   HP |   755k |   816k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  2.158 |  2.331 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |
| ---- | ------ |  --- 2 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  30% | 32.885 | 36.244 | 40.808 | 38.572 | 38.969 | 36.939 | 38.423 | 40.839 | 43.191 |
|  40% | 15.408 | 18.540 | 20.995 | 21.878 | 21.142 | 16.677 | 23.657 | 23.467 | 25.393 |
|  50% |  5.739 |  5.277 | 10.463 | 11.052 |  9.539 |  7.228 | 13.314 | 13.769 | 13.182 |
|  60% |  1.303 |  1.273 |  4.355 |  4.130 |  3.296 |  2.186 |  6.670 |  7.288 |  6.599 |
|  70% |  0.178 |  0.055 |  1.180 |  1.249 |  0.933 |  0.332 |  2.565 |  2.571 |  2.748 |
|  80% |  0.007 |  0.004 |  0.192 |  0.275 |  0.124 |  0.034 |  0.640 |  0.569 |  0.432 |
|  90% |  0.001 |  0.000 |  0.011 |  0.022 |  0.011 |  0.005 |  0.134 |  0.128 |  0.084 |
| ---- | ------ |  --- 3 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  40% | 41.345 | 45.922 | 44.756 | 46.843 | 47.672 | 39.535 | 45.936 | 45.980 | 47.873 |
|  50% | 20.671 | 20.835 | 27.177 | 30.869 | 27.204 | 21.644 | 32.210 | 32.404 | 30.639 |
|  60% |  7.600 |  7.351 | 15.196 | 16.911 | 13.611 |  9.223 | 20.256 | 20.430 | 19.339 |
|  70% |  2.257 |  2.039 |  6.787 |  7.854 |  5.660 |  2.801 | 11.065 | 10.039 | 11.303 |
|  80% |  0.573 |  0.398 |  2.467 |  3.043 |  1.549 |  0.843 |  5.222 |  4.618 |  4.970 |
|  90% |  0.122 |  0.056 |  0.704 |  1.031 |  0.575 |  0.247 |  2.032 |  2.109 |  1.943 |
| 100% |  0.002 |  0.006 |  0.152 |  0.208 |  0.088 |  0.005 |  0.622 |  0.623 |  0.588 |
| 110% |  0.000 |  0.000 |  0.022 |  0.074 |  0.019 |  0.000 |  0.219 |  0.203 |  0.176 |
| 120% |  0.000 |  0.000 |  0.003 |  0.012 |  0.002 |  0.000 |  0.076 |  0.071 |  0.036 |
| 130% |  0.000 |  0.000 |  0.000 |  0.002 |  0.000 |  0.000 |  0.023 |  0.022 |  0.009 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  50% | 46.101 | 48.063 | 53.848 | 52.875 | 51.408 | 46.459 | 51.488 | 53.661 | 55.098 |
|  60% | 29.993 | 29.341 | 35.771 | 38.316 | 35.793 | 29.800 | 38.827 | 40.483 | 39.444 |
|  70% | 16.269 | 15.744 | 20.123 | 24.773 | 21.738 | 14.960 | 26.918 | 25.458 | 25.876 |
|  80% |  7.343 |  5.809 |  9.455 | 14.266 |  9.213 |  7.089 | 17.064 | 14.897 | 14.156 |
|  90% |  2.505 |  1.944 |  3.698 |  6.638 |  4.040 |  3.146 |  8.845 |  8.408 |  7.297 |
| 100% |  0.629 |  0.550 |  1.679 |  2.031 |  1.473 |  0.862 |  3.761 |  3.634 |  3.773 |
| 110% |  0.100 |  0.106 |  0.560 |  0.719 |  0.428 |  0.214 |  1.728 |  1.601 |  1.741 |
| 120% |  0.024 |  0.007 |  0.191 |  0.272 |  0.173 |  0.068 |  0.830 |  0.862 |  0.810 |
| 130% |  0.001 |  0.001 |  0.041 |  0.056 |  0.034 |  0.007 |  0.378 |  0.400 |  0.344 |
| 140% |  0.000 |  0.000 |  0.004 |  0.006 |  0.003 |  0.000 |  0.127 |  0.128 |  0.112 |
| 150% |  0.000 |  0.000 |  0.000 |  0.001 |  0.000 |  0.000 |  0.030 |  0.021 |  0.013 |
| 160% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |  0.003 |  0.002 |
| ---- | ------ |  --- 5 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  70% | 35.977 | 36.111 | 41.985 | 43.683 | 41.448 | 33.547 | 43.246 | 43.420 | 45.369 |
|  80% | 21.514 | 20.865 | 27.602 | 31.282 | 26.381 | 20.972 | 32.239 | 31.350 | 32.486 |
|  90% | 11.041 | 10.355 | 15.528 | 20.259 | 16.278 | 11.805 | 21.718 | 21.915 | 20.642 |
| 100% |  4.732 |  4.254 |  7.547 | 11.143 |  8.637 |  4.665 | 13.143 | 12.780 | 12.541 |
| 110% |  1.444 |  1.318 |  3.458 |  5.760 |  3.860 |  1.705 |  7.889 |  7.226 |  6.808 |
| 120% |  0.432 |  0.323 |  1.337 |  2.676 |  1.635 |  0.628 |  4.439 |  4.190 |  3.346 |
| 130% |  0.080 |  0.058 |  0.485 |  0.940 |  0.639 |  0.154 |  2.293 |  2.083 |  1.794 |
| 140% |  0.013 |  0.011 |  0.163 |  0.334 |  0.173 |  0.033 |  1.098 |  0.889 |  0.925 |
| 150% |  0.001 |  0.001 |  0.050 |  0.082 |  0.044 |  0.007 |  0.448 |  0.409 |  0.420 |
| 160% |  0.000 |  0.000 |  0.013 |  0.020 |  0.011 |  0.002 |  0.184 |  0.186 |  0.174 |
| 170% |  0.000 |  0.000 |  0.001 |  0.003 |  0.001 |  0.000 |  0.063 |  0.064 |  0.052 |
| 180% |  0.000 |  0.000 |  0.000 |  0.001 |  0.000 |  0.000 |  0.024 |  0.025 |  0.015 |
| 190% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.008 |  0.007 |  0.004 |
| 200% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |  0.002 |  0.001 |
| ---- | ------ |  --- 6 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  80% | 40.461 | 40.647 | 47.076 | 48.097 | 45.131 | 38.743 | 46.983 | 47.697 | 50.313 |
|  90% | 25.807 | 25.747 | 32.971 | 36.104 | 32.510 | 25.812 | 35.946 | 37.248 | 37.413 |
| 100% | 13.941 | 13.685 | 20.968 | 24.599 | 21.034 | 13.747 | 25.613 | 25.758 | 26.552 |
| 110% |  6.410 |  6.079 | 12.042 | 15.716 | 11.953 |  6.662 | 17.727 | 17.135 | 17.270 |
| 120% |  2.491 |  2.278 |  6.197 |  9.342 |  6.245 |  3.192 | 11.550 | 11.481 | 10.490 |
| 130% |  0.786 |  0.576 |  2.721 |  4.881 |  3.065 |  0.959 |  7.133 |  6.803 |  5.942 |
| 140% |  0.148 |  0.120 |  1.121 |  2.209 |  1.311 |  0.253 |  4.166 |  3.639 |  3.378 |
| 150% |  0.023 |  0.016 |  0.416 |  0.981 |  0.411 |  0.067 |  2.282 |  2.020 |  1.680 |
| 160% |  0.001 |  0.001 |  0.113 |  0.385 |  0.139 |  0.014 |  1.162 |  1.000 |  0.816 |
| 170% |  0.000 |  0.000 |  0.031 |  0.104 |  0.035 |  0.001 |  0.497 |  0.415 |  0.377 |
| 180% |  0.000 |  0.000 |  0.006 |  0.027 |  0.005 |  0.000 |  0.227 |  0.177 |  0.149 |
| 190% |  0.000 |  0.000 |  0.001 |  0.006 |  0.002 |  0.000 |  0.095 |  0.084 |  0.078 |
| 200% |  0.000 |  0.000 |  0.000 |  0.001 |  0.000 |  0.000 |  0.039 |  0.034 |  0.030 |
| ---- | ------ |  --- 7 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  90% | 43.690 | 45.119 | 51.532 | 51.648 | 50.017 | 43.265 | 49.747 | 52.171 | 53.999 |
| 100% | 30.208 | 30.859 | 37.827 | 39.954 | 37.183 | 29.006 | 39.154 | 40.469 | 42.328 |
| 110% | 18.998 | 18.736 | 25.529 | 29.152 | 25.283 | 18.275 | 29.816 | 30.055 | 30.993 |
| 120% | 10.886 | 10.197 | 15.879 | 20.203 | 15.635 | 10.932 | 21.752 | 22.116 | 21.480 |
| 130% |  5.243 |  4.758 |  8.926 | 12.754 |  8.948 |  5.267 | 15.153 | 14.860 | 14.171 |
| 140% |  2.103 |  1.868 |  4.458 |  7.229 |  4.739 |  2.301 |  9.946 |  9.269 |  9.033 |
| 150% |  0.689 |  0.703 |  2.115 |  3.889 |  2.124 |  1.030 |  6.316 |  5.840 |  5.478 |
| 160% |  0.196 |  0.202 |  0.909 |  1.959 |  0.918 |  0.362 |  3.784 |  3.466 |  2.881 |
| 170% |  0.052 |  0.039 |  0.310 |  0.889 |  0.322 |  0.105 |  2.073 |  1.787 |  1.471 |
| 180% |  0.011 |  0.005 |  0.093 |  0.398 |  0.088 |  0.030 |  1.148 |  0.893 |  0.705 |
| 190% |  0.001 |  0.000 |  0.020 |  0.138 |  0.023 |  0.004 |  0.558 |  0.433 |  0.328 |
| 200% |  0.000 |  0.000 |  0.004 |  0.035 |  0.003 |  0.000 |  0.251 |  0.183 |  0.156 |

No surprises here, as the haste sets continue to dominate.  The other control sets still lag the haste sets, and the avoidance sets continue to trail even further in the distance.  There’s no question that, going into 5.3, you’re going to want to focus your item upgrades on your haste/mastery/hit/expertise gear rather than any gear with dodge or parry on it.

Stamina Panel

Next, I have a few sets here to compare Stamina trades.  We’ve already seen that Stamina is better than haste in gem slots by a slim margin, but this panel includes trinket trades (C/St) and a high-stamina gear set that splits the remaining itemization between mastery and haste.  Here are the stats of the gear sets:

|    Set: |  C/Ha |  C/St |  C/Sg | C/Shm |  C/Ma |
|     Str | 15000 | 15000 | 15000 | 15000 | 15000 |
|     Sta | 28000 | 34000 | 31000 | 31000 | 28000 |
|   Parry |  1500 |  1500 |  1500 |  1500 |  1500 |
|   Dodge |  1500 |  1500 |  1500 |  1500 |  1500 |
| Mastery |  1500 |  1500 |  1500 |  4750 | 13500 |
|     Hit |  2550 |  2550 |  2550 |  2550 |  2550 |
|     Exp |  5100 |  5100 |  5100 |  5100 |  5100 |
|   Haste | 12000 |  8000 |  8000 |  4750 |     0 |

And here’s the data.  Rather than give individual commentary for each section, I’ll just provide a wall-o-data and talk about all of the sets at the end.

150k:

Finisher = SH1, Boss Attack = 150k, SoI model=nooverheal data set smooth-10000-78

| Set: |   C/Ha |   C/St |   C/Sg |  C/Shm |   C/Ma |
| mean |  0.227 |  0.251 |  0.251 |  0.262 |  0.249 |
|  std |  0.103 |  0.106 |  0.106 |  0.109 |  0.111 |
|   S% |  0.523 |  0.482 |  0.482 |  0.454 |  0.410 |
|   HP |   755k |   876k |   816k |   816k |   755k |
|  nHP |  5.034 |  5.843 |  5.439 |  5.439 |  5.034 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  10% | 43.022 | 40.482 | 48.479 | 48.121 | 46.739 |
|  20% |  6.469 |  3.214 |  5.837 |  8.332 | 11.753 |
|  30% |  0.164 |  0.024 |  0.039 |  0.139 |  0.682 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  20% | 18.949 | 14.004 | 20.200 | 25.006 | 26.345 |
|  30% |  1.089 |  0.530 |  0.767 |  2.048 |  4.732 |
|  40% |  0.005 |  0.000 |  0.006 |  0.055 |  0.257 |
|  50% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  20% | 39.772 | 36.744 | 42.836 | 48.174 | 47.968 |
|  30% | 10.888 |  6.091 |  9.454 | 11.538 | 13.719 |
|  40% |  0.666 |  0.241 |  0.689 |  0.884 |  2.252 |
|  50% |  0.012 |  0.002 |  0.012 |  0.024 |  0.153 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  30% | 24.760 | 17.744 | 23.760 | 28.425 | 30.966 |
|  40% |  3.940 |  2.123 |  4.331 |  5.915 |  8.371 |
|  50% |  0.382 |  0.068 |  0.288 |  0.495 |  1.221 |
|  60% |  0.008 |  0.000 |  0.004 |  0.021 |  0.136 |
|  70% |  0.001 |  0.000 |  0.000 |  0.000 |  0.002 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  30% | 41.148 | 33.863 | 41.358 | 46.465 | 48.106 |
|  40% | 11.141 |  7.171 | 12.030 | 15.812 | 19.552 |
|  50% |  1.678 |  0.430 |  1.371 |  2.591 |  4.707 |
|  60% |  0.045 |  0.004 |  0.029 |  0.201 |  0.685 |
|  70% |  0.002 |  0.000 |  0.000 |  0.006 |  0.068 |
|  80% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  40% | 23.781 | 18.316 | 25.654 | 30.083 | 33.487 |
|  50% |  6.487 |  3.211 |  6.569 |  8.118 | 11.848 |
|  60% |  0.799 |  0.220 |  0.715 |  1.045 |  2.554 |
|  70% |  0.055 |  0.003 |  0.030 |  0.047 |  0.309 |
|  80% |  0.002 |  0.000 |  0.000 |  0.000 |  0.023 |

250k:

Finisher = SH1, Boss Attack = 250k, SoI model=nooverheal data set smooth-10000-79

| Set: |   C/Ha |   C/St |   C/Sg |  C/Shm |   C/Ma |
| mean |  0.250 |  0.274 |  0.274 |  0.286 |  0.268 |
|  std |  0.102 |  0.105 |  0.105 |  0.108 |  0.106 |
|   S% |  0.522 |  0.483 |  0.482 |  0.454 |  0.410 |
|   HP |   755k |   876k |   816k |   816k |   755k |
|  nHP |  3.021 |  3.506 |  3.263 |  3.263 |  3.021 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  20% | 42.151 | 32.857 | 36.254 | 40.191 | 45.407 |
|  30% | 14.668 |  8.370 | 14.755 | 15.533 | 17.767 |
|  40% |  1.567 |  0.737 |  1.982 |  3.311 |  4.335 |
|  50% |  0.121 |  0.037 |  0.062 |  0.218 |  0.506 |
|  60% |  0.001 |  0.000 |  0.003 |  0.016 |  0.016 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  30% | 39.373 | 26.912 | 38.369 | 39.100 | 37.228 |
|  40% |  8.513 |  5.704 | 10.856 | 13.586 | 15.144 |
|  50% |  1.359 |  0.587 |  1.341 |  2.633 |  4.648 |
|  60% |  0.142 |  0.047 |  0.081 |  0.403 |  1.028 |
|  70% |  0.001 |  0.000 |  0.004 |  0.041 |  0.117 |
|  80% |  0.000 |  0.000 |  0.000 |  0.003 |  0.013 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  40% | 32.341 | 26.812 | 35.236 | 37.719 | 36.062 |
|  50% | 14.193 |  7.784 | 12.065 | 15.074 | 14.948 |
|  60% |  4.290 |  1.568 |  3.093 |  4.422 |  5.201 |
|  70% |  0.665 |  0.146 |  0.518 |  0.760 |  1.473 |
|  80% |  0.060 |  0.007 |  0.049 |  0.154 |  0.377 |
|  90% |  0.002 |  0.000 |  0.001 |  0.004 |  0.033 |
| 100% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  40% | 54.097 | 48.919 | 57.263 | 59.186 | 57.725 |
|  50% | 32.478 | 22.916 | 30.390 | 35.916 | 35.990 |
|  60% | 15.061 |  8.617 | 12.834 | 17.288 | 18.606 |
|  70% |  4.652 |  1.601 |  4.092 |  5.910 |  6.957 |
|  80% |  0.789 |  0.254 |  0.800 |  1.501 |  2.061 |
|  90% |  0.101 |  0.014 |  0.068 |  0.290 |  0.477 |
| 100% |  0.007 |  0.001 |  0.004 |  0.025 |  0.095 |
| 110% |  0.000 |  0.000 |  0.000 |  0.003 |  0.014 |
| 120% |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  50% | 52.320 | 42.349 | 51.355 | 56.269 | 55.371 |
|  60% | 31.193 | 21.903 | 28.692 | 34.990 | 36.098 |
|  70% | 13.524 |  6.437 | 12.865 | 16.944 | 18.868 |
|  80% |  3.851 |  1.594 |  3.908 |  6.248 |  7.912 |
|  90% |  0.779 |  0.136 |  0.599 |  1.792 |  2.550 |
| 100% |  0.089 |  0.014 |  0.067 |  0.349 |  0.654 |
| 110% |  0.002 |  0.001 |  0.003 |  0.050 |  0.139 |
| 120% |  0.000 |  0.000 |  0.000 |  0.005 |  0.020 |
| 130% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  60% | 48.396 | 39.916 | 47.325 | 53.984 | 54.160 |
|  70% | 29.080 | 18.943 | 28.735 | 33.378 | 34.456 |
|  80% | 13.894 |  8.067 | 14.051 | 16.554 | 18.524 |
|  90% |  5.346 |  1.929 |  4.590 |  6.626 |  8.174 |
| 100% |  1.580 |  0.453 |  1.226 |  1.952 |  3.000 |
| 110% |  0.319 |  0.045 |  0.269 |  0.436 |  0.889 |
| 120% |  0.035 |  0.005 |  0.036 |  0.056 |  0.201 |
| 130% |  0.001 |  0.000 |  0.001 |  0.005 |  0.034 |
| 140% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |

350k:

Finisher = SH1, Boss Attack = 350k, SoI model=nooverheal data set smooth-10000-80

| Set: |   C/Ha |   C/St |   C/Sg |  C/Shm |   C/Ma |
| mean |  0.261 |  0.286 |  0.285 |  0.296 |  0.279 |
|  std |  0.103 |  0.106 |  0.106 |  0.109 |  0.107 |
|   S% |  0.523 |  0.483 |  0.482 |  0.455 |  0.411 |
|   HP |   755k |   876k |   816k |   816k |   755k |
|  nHP |  2.158 |  2.504 |  2.331 |  2.331 |  2.158 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  30% | 32.655 | 31.390 | 36.075 | 39.645 | 40.546 |
|  40% | 15.258 | 13.987 | 18.369 | 21.260 | 20.745 |
|  50% |  5.626 |  2.668 |  5.192 |  7.446 | 10.378 |
|  60% |  1.289 |  0.428 |  1.252 |  1.662 |  4.211 |
|  70% |  0.186 |  0.036 |  0.060 |  0.216 |  1.123 |
|  80% |  0.009 |  0.000 |  0.005 |  0.020 |  0.180 |
|  90% |  0.001 |  0.000 |  0.000 |  0.000 |  0.010 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  40% | 41.125 | 38.171 | 45.569 | 47.260 | 44.575 |
|  50% | 20.420 | 13.837 | 20.588 | 25.682 | 27.031 |
|  60% |  7.512 |  4.311 |  7.327 |  9.046 | 14.943 |
|  70% |  2.261 |  1.006 |  2.026 |  3.562 |  6.643 |
|  80% |  0.560 |  0.080 |  0.396 |  0.873 |  2.381 |
|  90% |  0.110 |  0.005 |  0.061 |  0.204 |  0.669 |
| 100% |  0.003 |  0.000 |  0.004 |  0.040 |  0.134 |
| 110% |  0.000 |  0.000 |  0.000 |  0.003 |  0.016 |
| 120% |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  50% | 45.896 | 41.533 | 47.686 | 52.960 | 53.508 |
|  60% | 29.735 | 22.478 | 29.189 | 31.558 | 35.477 |
|  70% | 15.994 | 10.134 | 15.554 | 17.602 | 19.942 |
|  80% |  7.202 |  3.215 |  5.747 |  6.774 |  9.302 |
|  90% |  2.452 |  0.780 |  1.908 |  2.307 |  3.580 |
| 100% |  0.601 |  0.158 |  0.517 |  0.745 |  1.608 |
| 110% |  0.095 |  0.027 |  0.097 |  0.229 |  0.525 |
| 120% |  0.026 |  0.000 |  0.006 |  0.027 |  0.186 |
| 130% |  0.001 |  0.000 |  0.001 |  0.002 |  0.034 |
| 140% |  0.000 |  0.000 |  0.000 |  0.000 |  0.006 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  60% | 51.494 | 44.824 | 52.189 | 54.630 | 57.324 |
|  70% | 35.639 | 27.906 | 35.791 | 39.964 | 41.670 |
|  80% | 21.239 | 13.761 | 20.612 | 23.618 | 27.228 |
|  90% | 10.783 |  5.950 | 10.163 | 12.882 | 15.272 |
| 100% |  4.579 |  1.768 |  4.144 |  5.902 |  7.348 |
| 110% |  1.397 |  0.452 |  1.291 |  2.219 |  3.306 |
| 120% |  0.427 |  0.065 |  0.309 |  0.848 |  1.295 |
| 130% |  0.081 |  0.008 |  0.065 |  0.189 |  0.458 |
| 140% |  0.011 |  0.001 |  0.005 |  0.046 |  0.162 |
| 150% |  0.001 |  0.000 |  0.001 |  0.006 |  0.054 |
| 160% |  0.000 |  0.000 |  0.000 |  0.001 |  0.015 |
| 170% |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  70% | 56.207 | 48.772 | 56.781 | 60.612 | 60.808 |
|  80% | 40.135 | 31.100 | 40.264 | 43.807 | 46.758 |
|  90% | 25.368 | 17.472 | 25.388 | 29.499 | 32.593 |
| 100% | 13.595 |  7.749 | 13.518 | 17.807 | 20.617 |
| 110% |  6.246 |  2.696 |  6.007 |  8.688 | 11.776 |
| 120% |  2.429 |  0.627 |  2.185 |  4.207 |  6.054 |
| 130% |  0.768 |  0.120 |  0.565 |  1.397 |  2.603 |
| 140% |  0.132 |  0.014 |  0.120 |  0.489 |  1.041 |
| 150% |  0.025 |  0.001 |  0.014 |  0.136 |  0.405 |
| 160% |  0.002 |  0.000 |  0.002 |  0.028 |  0.114 |
| 170% |  0.001 |  0.000 |  0.000 |  0.005 |  0.033 |
| 180% |  0.000 |  0.000 |  0.000 |  0.000 |  0.007 |
| 190% |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  90% | 43.224 | 35.259 | 44.614 | 49.400 | 51.175 |
| 100% | 29.814 | 21.840 | 30.534 | 35.183 | 37.393 |
| 110% | 18.636 | 11.397 | 18.494 | 21.431 | 25.169 |
| 120% | 10.629 |  5.206 | 10.057 | 12.467 | 15.597 |
| 130% |  5.082 |  2.008 |  4.658 |  5.921 |  8.690 |
| 140% |  2.015 |  0.696 |  1.827 |  2.659 |  4.286 |
| 150% |  0.672 |  0.171 |  0.672 |  1.000 |  2.040 |
| 160% |  0.191 |  0.020 |  0.181 |  0.300 |  0.854 |
| 170% |  0.050 |  0.003 |  0.045 |  0.067 |  0.301 |
| 180% |  0.009 |  0.001 |  0.004 |  0.010 |  0.094 |
| 190% |  0.001 |  0.000 |  0.000 |  0.001 |  0.019 |
| 200% |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |

There’s not a lot to say about this data, we’re really seeing more of the same.  Stamina is better than haste on gems, and a lot better than haste on trinkets.  Dual stamina trinkets should probably be a given for most tanks unless they’re already exceeding their stamina goals with full haste gemming.  The haste/mastery combination set still looks lackluster, and of course Control/Mastery trails everything else since it’s got much lower haste.

Hit/Exp Panel

A question that came up in one of my discussions on mmo-champion was whether it was still worthwhile to cap hit and expertise.  I had been testing a “pure haste” set that funneled most of that hit and expertise into haste, and it wasn’t really performing well.  But I hadn’t done a breakdown at the various expertise caps that are relevant.  This panel addresses those concerns.

We start with Control/Haste, and then drop back to a set that caps hit but only “soft-caps” expertise (thus 7.5% hit, 7.5% expertise), which we’ll call “Haste/hitexp” or “Ha/he” for short.  The itemization we freed up gets put into haste, obviously.  The next set drops to 500 expertise rating to simulate avoiding expertise entirely, but with some residual left on gear.  That set has 7.5% hit and 1.47% expertise, so we’ll ca” it “Haste/hit” or “Ha/h” for short.  Finally, we have the “pure haste” set that drops all but 500 hit rating and 500 expertise rating but ramps our haste up to 18650 (about 43.8% melee haste).

The stats for these sets are given below:

|    Set: |  C/Ha | Ha/he |  Ha/h |    Ha |
|     Str | 15000 | 15000 | 15000 | 15000 |
|     Sta | 28000 | 28000 | 28000 | 28000 |
|   Parry |  1500 |  1500 |  1500 |  1500 |
|   Dodge |  1500 |  1500 |  1500 |  1500 |
| Mastery |  1500 |  1500 |  1500 |  1500 |
|     Hit |  2550 |  2550 |  2550 |   500 |
|     Exp |  5100 |  2550 |   500 |   500 |
|   Haste | 12000 | 14550 | 16600 | 18650 |

Now let’s look at the data.  Starting with our 150k boss swing set:

Finisher = SH1, Boss Attack = 150k, SoI model=nooverheal data set smooth-10000-86

| Set: |   C/Ha |  Ha/he |   Ha/h |     Ha |
| mean |  0.227 |  0.230 |  0.230 |  0.235 |
|  std |  0.103 |  0.107 |  0.108 |  0.110 |
|   S% |  0.522 |  0.520 |  0.518 |  0.498 |
|   HP |   755k |   755k |   755k |   755k |
|  nHP |  5.034 |  5.034 |  5.034 |  5.034 |
| ---- |  --- 2 | Attack | Moving | Avg.-- |
|  10% | 43.110 | 43.217 | 43.027 | 43.824 |
|  20% |  6.517 |  7.382 |  7.563 |  8.460 |
|  30% |  0.166 |  0.253 |  0.296 |  0.411 |
| ---- |  --- 3 | Attack | Moving | Avg.-- |
|  20% | 19.120 | 21.076 | 22.165 | 24.070 |
|  30% |  1.119 |  1.712 |  2.044 |  2.959 |
|  40% |  0.001 |  0.009 |  0.021 |  0.050 |
| ---- |  --- 4 | Attack | Moving | Avg.-- |
|  20% | 39.923 | 41.081 | 41.467 | 43.293 |
|  30% | 10.978 | 12.263 | 12.344 | 13.360 |
|  40% |  0.667 |  1.059 |  1.245 |  1.759 |
|  50% |  0.013 |  0.044 |  0.058 |  0.121 |
| ---- |  --- 5 | Attack | Moving | Avg.-- |
|  30% | 24.908 | 26.517 | 26.389 | 27.785 |
|  40% |  3.980 |  5.161 |  5.399 |  6.370 |
|  50% |  0.396 |  0.630 |  0.641 |  0.878 |
|  60% |  0.006 |  0.020 |  0.020 |  0.060 |
|  70% |  0.001 |  0.000 |  0.001 |  0.002 |
| ---- |  --- 6 | Attack | Moving | Avg.-- |
|  30% | 41.286 | 42.546 | 42.076 | 43.360 |
|  40% | 11.279 | 13.377 | 14.526 | 16.362 |
|  50% |  1.693 |  2.544 |  3.060 |  4.119 |
|  60% |  0.048 |  0.128 |  0.228 |  0.479 |
|  70% |  0.001 |  0.003 |  0.008 |  0.036 |
| ---- |  --- 7 | Attack | Moving | Avg.-- |
|  40% | 23.930 | 25.998 | 26.529 | 28.571 |
|  50% |  6.519 |  8.063 |  8.533 | 10.285 |
|  60% |  0.814 |  1.266 |  1.463 |  2.292 |
|  70% |  0.062 |  0.120 |  0.161 |  0.338 |
|  80% |  0.000 |  0.002 |  0.008 |  0.027 |
|  90% |  0.000 |  0.000 |  0.000 |  0.002 |

This data is pretty straightforward.  Control/Haste leads the soft-capped set Ha/he, and dropping more expertise or hit only makes things worse.  There’s two reasons for this.  First is the obvious one, the under-capped sets have lower holy power generation, as evidenced by the SotR uptime percentage (S%).  Trading the expertise doesn’t incur a very large loss, as haste is actually pretty competitive with expertise for raw HPG.  Dropping the hit obviously hurts a lot more.

More importantly though, consider that SoI proc triggers are Crusader Strike, Shield of the Righteous, and auto-attacksAll three of those get the full benefit from expertise, and an attack that doesn’t hit can’t proc Seal of Insight.  So despite breaking even in terms of overall HPG, dropping 7.5% (or 15%) expertise for 6% (or 12%) more haste is a net loss because you get fewer Seal of Insight procs.   So there doesn’t seem to be any advantage to dropping expertise hard-cap for more haste in terms of survivability.

I will note, however, that if you turn off SoI procs entirely, the C/Ha, Ha/he, and Ha/h sets are all about even.  At normal Vengeance levels, Ha/he should end up doing slightly more DPS than C/Ha because haste is a better DPS stat than expertise above the 7.5% dodge “soft-cap.”  So this is another case where you may consider making a survivability-for-DPS trade if you’re hitting a rough enrage timer.

There’s really nothing different about the 250k or 350k data, so I’ll provide them here without further commentary:

Finisher = SH1, Boss Attack = 250k, SoI model=nooverheal data set smooth-10000-87

| Set: |   C/Ha |  Ha/he |   Ha/h |     Ha |
| mean |  0.251 |  0.253 |  0.252 |  0.259 |
|  std |  0.102 |  0.107 |  0.107 |  0.109 |
|   S% |  0.522 |  0.521 |  0.518 |  0.499 |
|   HP |   755k |   755k |   755k |   755k |
|  nHP |  3.021 |  3.021 |  3.021 |  3.021 |
| ---- |  --- 2 | Attack | Moving | Avg.-- |
|  20% | 42.364 | 42.075 | 41.379 | 42.452 |
|  30% | 14.804 | 15.479 | 15.127 | 16.332 |
|  40% |  1.603 |  2.062 |  2.294 |  2.863 |
|  50% |  0.120 |  0.217 |  0.228 |  0.298 |
|  60% |  0.001 |  0.005 |  0.006 |  0.009 |
| ---- |  --- 3 | Attack | Moving | Avg.-- |
|  30% | 39.804 | 39.985 | 39.238 | 40.705 |
|  40% |  8.624 | 10.322 | 11.422 | 13.700 |
|  50% |  1.391 |  1.987 |  2.303 |  3.334 |
|  60% |  0.150 |  0.261 |  0.367 |  0.643 |
|  70% |  0.002 |  0.009 |  0.018 |  0.044 |
|  80% |  0.000 |  0.001 |  0.002 |  0.002 |
| ---- |  --- 4 | Attack | Moving | Avg.-- |
|  40% | 32.701 | 33.328 | 32.916 | 34.879 |
|  50% | 14.472 | 15.458 | 15.110 | 16.482 |
|  60% |  4.444 |  5.239 |  5.370 |  6.320 |
|  70% |  0.677 |  0.982 |  1.100 |  1.632 |
|  80% |  0.063 |  0.140 |  0.172 |  0.312 |
|  90% |  0.001 |  0.010 |  0.014 |  0.037 |
| 100% |  0.000 |  0.001 |  0.002 |  0.006 |
| ---- |  --- 5 | Attack | Moving | Avg.-- |
|  50% | 32.962 | 33.697 | 32.956 | 34.861 |
|  60% | 15.381 | 16.717 | 16.447 | 18.059 |
|  70% |  4.777 |  5.857 |  5.885 |  7.115 |
|  80% |  0.823 |  1.303 |  1.419 |  1.956 |
|  90% |  0.103 |  0.224 |  0.233 |  0.398 |
| 100% |  0.009 |  0.030 |  0.040 |  0.077 |
| 110% |  0.001 |  0.004 |  0.005 |  0.011 |
| ---- |  --- 6 | Attack | Moving | Avg.-- |
|  60% | 31.711 | 33.063 | 32.622 | 34.657 |
|  70% | 13.959 | 15.843 | 16.659 | 18.964 |
|  80% |  3.929 |  5.224 |  6.191 |  8.061 |
|  90% |  0.805 |  1.338 |  1.773 |  2.723 |
| 100% |  0.098 |  0.248 |  0.404 |  0.758 |
| 110% |  0.005 |  0.030 |  0.066 |  0.157 |
| 120% |  0.001 |  0.003 |  0.009 |  0.026 |
| 130% |  0.000 |  0.001 |  0.001 |  0.003 |
| ---- |  --- 7 | Attack | Moving | Avg.-- |
|  60% | 48.902 | 49.435 | 48.666 | 50.557 |
|  70% | 29.619 | 31.090 | 31.034 | 33.518 |
|  80% | 14.198 | 15.685 | 15.964 | 18.612 |
|  90% |  5.547 |  6.577 |  6.817 |  8.753 |
| 100% |  1.646 |  2.259 |  2.452 |  3.562 |
| 110% |  0.334 |  0.605 |  0.714 |  1.245 |
| 120% |  0.041 |  0.105 |  0.142 |  0.310 |
| 130% |  0.002 |  0.018 |  0.024 |  0.069 |
| 140% |  0.000 |  0.003 |  0.004 |  0.014 |
| 150% |  0.000 |  0.000 |  0.000 |  0.002 |

350k

Finisher = SH1, Boss Attack = 350k, SoI model=nooverheal data set smooth-10000-88

| Set: |   C/Ha |  Ha/he |   Ha/h |     Ha |
| mean |  0.261 |  0.263 |  0.262 |  0.270 |
|  std |  0.103 |  0.108 |  0.108 |  0.111 |
|   S% |  0.523 |  0.520 |  0.519 |  0.498 |
|   HP |   755k |   755k |   755k |   755k |
|  nHP |  2.158 |  2.158 |  2.158 |  2.158 |
| ---- |  --- 2 | Attack | Moving | Avg.-- |
|  30% | 32.782 | 33.380 | 33.626 | 35.883 |
|  40% | 15.245 | 16.273 | 16.244 | 17.843 |
|  50% |  5.653 |  6.601 |  6.744 |  7.835 |
|  60% |  1.320 |  1.803 |  1.973 |  2.520 |
|  70% |  0.194 |  0.327 |  0.395 |  0.542 |
|  80% |  0.009 |  0.033 |  0.045 |  0.068 |
|  90% |  0.001 |  0.002 |  0.003 |  0.007 |
| ---- |  --- 3 | Attack | Moving | Avg.-- |
|  40% | 41.101 | 41.710 | 41.461 | 43.507 |
|  50% | 20.429 | 22.534 | 23.262 | 25.979 |
|  60% |  7.533 |  9.316 | 10.294 | 12.646 |
|  70% |  2.282 |  3.240 |  3.750 |  5.124 |
|  80% |  0.595 |  0.962 |  1.120 |  1.827 |
|  90% |  0.131 |  0.205 |  0.260 |  0.516 |
| 100% |  0.002 |  0.010 |  0.019 |  0.048 |
| 110% |  0.000 |  0.001 |  0.001 |  0.003 |
| ---- |  --- 4 | Attack | Moving | Avg.-- |
|  50% | 45.862 | 46.587 | 46.365 | 48.892 |
|  60% | 29.730 | 30.929 | 30.862 | 33.529 |
|  70% | 16.109 | 17.575 | 17.627 | 19.657 |
|  80% |  7.290 |  8.733 |  8.909 | 10.582 |
|  90% |  2.510 |  3.359 |  3.519 |  4.657 |
| 100% |  0.639 |  0.938 |  0.989 |  1.564 |
| 110% |  0.110 |  0.229 |  0.254 |  0.491 |
| 120% |  0.026 |  0.071 |  0.073 |  0.167 |
| 130% |  0.001 |  0.012 |  0.016 |  0.042 |
| 140% |  0.000 |  0.002 |  0.003 |  0.010 |
| ---- |  --- 5 | Attack | Moving | Avg.-- |
|  70% | 35.663 | 36.814 | 36.555 | 39.284 |
|  80% | 21.308 | 23.175 | 22.976 | 25.547 |
|  90% | 10.906 | 12.709 | 12.668 | 14.766 |
| 100% |  4.701 |  5.908 |  5.860 |  7.296 |
| 110% |  1.474 |  2.162 |  2.191 |  2.922 |
| 120% |  0.445 |  0.738 |  0.733 |  1.132 |
| 130% |  0.093 |  0.215 |  0.225 |  0.401 |
| 140% |  0.016 |  0.062 |  0.060 |  0.130 |
| 150% |  0.002 |  0.014 |  0.016 |  0.041 |
| 160% |  0.000 |  0.002 |  0.004 |  0.011 |
| 170% |  0.000 |  0.001 |  0.000 |  0.001 |
| ---- |  --- 6 | Attack | Moving | Avg.-- |
|  80% | 40.086 | 41.524 | 40.823 | 43.481 |
|  90% | 25.437 | 27.621 | 27.811 | 30.764 |
| 100% | 13.756 | 15.994 | 16.776 | 19.629 |
| 110% |  6.423 |  8.139 |  9.110 | 11.391 |
| 120% |  2.511 |  3.591 |  4.242 |  5.898 |
| 130% |  0.818 |  1.397 |  1.773 |  2.776 |
| 140% |  0.161 |  0.407 |  0.568 |  1.095 |
| 150% |  0.030 |  0.118 |  0.190 |  0.427 |
| 160% |  0.005 |  0.028 |  0.052 |  0.145 |
| 170% |  0.001 |  0.006 |  0.012 |  0.042 |
| 180% |  0.000 |  0.002 |  0.002 |  0.011 |
| 190% |  0.000 |  0.000 |  0.001 |  0.004 |
| ---- |  --- 7 | Attack | Moving | Avg.-- |
|  90% | 43.220 | 44.588 | 44.158 | 46.917 |
| 100% | 29.850 | 31.686 | 31.638 | 34.768 |
| 110% | 18.732 | 20.614 | 20.875 | 23.980 |
| 120% | 10.758 | 12.378 | 12.615 | 15.407 |
| 130% |  5.213 |  6.419 |  6.732 |  8.979 |
| 140% |  2.094 |  2.902 |  3.120 |  4.675 |
| 150% |  0.728 |  1.182 |  1.305 |  2.248 |
| 160% |  0.208 |  0.443 |  0.511 |  1.023 |
| 170% |  0.057 |  0.170 |  0.190 |  0.423 |
| 180% |  0.015 |  0.060 |  0.072 |  0.172 |
| 190% |  0.002 |  0.014 |  0.020 |  0.058 |
| 200% |  0.000 |  0.004 |  0.005 |  0.017 |

Conclusions

There’s a lot of data in this post, but the conclusions are pretty straightforward.  We’ve been ignoring Seal of Insight for a long time based on a hand-wavy overheal argument, and this data clearly shows that we weren’t getting the whole picture.  We knew haste was good, of course – the old model got that much correct, at least – but led us to incorrect conclusions about how haste compared with its nearest competitor, mastery.

The old model would have told us that the recent nerf to SotR’s base mitigation dropped haste behind mastery in terms of survivability value, primarily due to the strong passive mitigation value of blocking.  But Seal of Insight gives us a competing effect that, quite frankly, blows blocking out of the water.  We get more than one Seal of Insight proc per boss attack – in fact, with the C/Ha set we get approximately 1.3 procs per boss attack – and each one of those procs gives us a guaranteed 20% “mini-block” on damage already taken.  Combine that with a more favorable rating-to-percent conversion for haste than mastery, and haste looks like the better passive mitigation stat.

In short, Seal of Insight tips the scales solidly in favor of the Control/Haste gearing paradigm.  The only argument you could make for Control/Mastery is that it doesn’t rely on the player operating a strong rotation.  But it does still require that the player times Shield of the Righteous well, which may not be a compatible assumption.  A player that can’t maintain a rotation is probably less likely to be precise with their Active Mitigation too, which pulls the entire claim that Control/Mastery excels at passive mitigation into question.  It’s still got the “no skill required” benefit of blocking, but Seal of Insight procs from auto-attacks don’t require any player interaction either.

In fact, I’d have to argue at this point that there’s very little reason to pursue a Control/Mastery gearing paradigm at all.  Stamina is still the king survivability stat, and it’s truly passive.  A strong player will still want to gear for as much haste as they can while maintaining a comfortable level of stamina.  A weak player would be better-off stam-stacking and taking whatever stats they get on gear.  A truly abysmal player may just use traditional tanking gear, which will give them high stamina and lots of passive survivability via avoidance and blocking.  I’m not sure that any level of player would find a mastery build optimal outside of special cases (the standard “Heroic Sha” disclaimer).

Some players have suggested that maybe it would be beneficial to drop expertise for haste, but the data solidly refutes that hypothesis. The data confirms that it’s still a priority to maintain hit (7.5%) and expertise (15%) caps before piling on the haste.  Nowadays, that should be easy to do with reforges alone, possibly with a few expertise/stamina or expertise/haste gems to dance around the cap more effectively.

So, the TLDR summary:

• Stamina is still your best survivability stat, haste is a reasonably close second, mastery a distant third, dodge and parry tied for an even more distant fourth.
• Capping hit (7.5%) and expertise (15%) are still your most important secondary stat goals (i.e. Control comes before Haste).  It’s not clear from the data whether stamina is better or worse than hit and expertise – my guess is that stamina is better, but it should rarely come up in practice since you can’t reforge into stamina anyway.
• Control/Haste should be the default gearing strategy for pretty much everyone nowadays, augmented by as much stamina as you need to feel comfortable in the encounter.  Rule of thumb: if you keep going splat, pick up some more stamina.

## Modeling Seal of Insight

Seal of Insight is the last major paladin mechanic that has yet to be added to the simulation.  The last piece of the puzzle, as it were.  There are a number of reasons I’ve put off adding SoI, some of which I discussed in the last two posts.

SoI is a more complicated beast than effects like Sacred Shield, for starters.  It has a lot of “moving parts” as far as the simulation is concerned.  While we don’t have to cast it, it requires adding melee swings to the simulation, which means adding another event type.  It also adds another buff to track in the form of our fake absorb bubble, and we’ll need a model to calculate the effectiveness of that bubble.  And since we’re adding melee swings, we also need to add parry-hasting if the model is to be completely accurate.  That doesn’t mean any of the logic is particularly hard, just that it has tendrils in several sections of the simulation, which makes it annoying to implement and bug-check.

It also causes a moderate performance hit.  First, from the inclusion of another event type (melee swings), and then from the additional calculation being performed each time that event occurs.  There’s also a small performance decrease due to the extra calculations on the SoI absorb bubble.  Together, that all added up to be a bit of an issue.  Performance had been a problem with the simulation in general even before this point, and now seemed like an appropriate time to fix it.

I enlisted the help of a friend of mine who happens to be a real computer scientist type, and he promptly told me to stop thinking like a physicist and start thinking like a computer scientist.  Together we (and by we, I mean he) hashed out a few improvements that would drastically improve performance.  To give you an idea of how significant that improvement was, it now runs about five to six times faster than it did before I added Seal of Insight.  Runtime dropped from about 400-500 seconds per simulation to around 60 seconds.

So now that it’s implemented, I can spit out lots and lots of data relatively quickly.  But first, we need to discuss exactly how we’re modeling Seal of Insight, and provide some justification for that model.  That will be the topic of today’s post.

Effectiveness – Logs

The first part of modeling is figuring out exactly what we’re aiming for.  One of the big arguments about Seal of Insight is how much of it ends up simply being overhealing.  It’s going to be important to get that right, so rather than guess, we go to the logs and see what they say.  I scrutinized about 20 different logs from the last month for a variety of guilds ranging from normal-mode to heroic-mode content in both 10- and 25-man categories.  While this only gives me a few data points per individual boss, it’s enough to get a rough idea of how much overhealing we expect.  Here are the numbers:

Boss 10N 10H 25N 25H
Jin’Rokh 66% 68% 66% 77%
Horridon 53% 62% 74% 74%
Council of Elders 51% 31% 64% 60%
Tortos 54% N/A 68% N/A
Megaera 41% 44% 46% 60%
Ji-Kun 62% 52% 65% 77%
Durumu 57% 60% 56% 68%
Primordius 38% 32% 60% 46%
Dark Animus 52% 58% 46% 49%
Iron Qon 47% 61% 46% 60%
Twin Consorts 59% 72% 72%
Lei Shen 51% 60%

That’s a lot of overhealing.  This data doesn’t suggest that there’s a huge difference between 10- and 25-mans.  And note that there’s a mix of data in here.  Some logs are from solo-tanking a boss, while some are from multiple-tanking;  some tanks are on boss duty while others are on adds.  So there are larger variations to be had on a situational basis.

The lack of distinction between 10- and 25-man seemed a little strange at first.  My intuition is that in 25-mans, you’d expect a dedicated tank healer, leading to higher overheal values for SoI.  In 10-mans, I’d expect the “tank healer” to split his attention a lot more to help with raid healing, and thus allow SoI to pull more weight.  But while there may be a little of that happening, it’s not a large effect.  We’re not seeing many cases where we get double the overhealing in 25-mans (Primordius stands out, but I suspect that’s due to 1- vs. 2-tanking distinctions).

To take a look at why that is, I looked a little more carefully at my own healing taken breakdowns.  And I was actually a bit surprised by what I found.

First, Sacred Shield and Seal of Insight regularly produce 35%-50% of my total healing taken.  That Sacred Shield is consistently 20%-30% isn’t all that surprising – absorption effects are your first line of defense against damage, so they’ll naturally be pretty efficient and will tend to get utilized.  But Seal of Insight fairly regularly shows up in second place, accounting for 10%-20%.  That’s a bit higher than I expected, to be honest – I thought that when we’re pushing 60%-70% overheal, it would account for much less.

But what’s more surprising is the sheer amount of healing that’s coming from passive sources.  When I totaled up the amount of healing coming from “passive” sources, including HoTs and incidental absorbs, it was 75%-80% of all healing I received.  Only 20%-25% is due to “direct” healing, like Holy Light, Divine Light, Nourish, Healing Touch, etc.

Now, that’s considering all healing done, including overhealing.  You might assume that the passive sources show a much higher amount of overhealing than the direct sources.  And to a limited degree, that intuition seems correct.  But even the direct heals are seeing a large amount of overheal.  Holy Light and Nourish regularly clocked 60%-80% overheal in my logs.  Big heals like Healing Touch and Divine Light tended to be lower, ranging from 30% to 50% from boss to boss.

From all of that, we can draw a few conclusions.  First, we’re a long way from the “spam Holy Light on the tank” healing model of Wrath.  The triage model seems to be working correctly, with healers dropping efficient, low-cost heals (HoTs, Holy Light) on the tank when the situation is relatively safe, and only resorting to big or fast direct heals when they’re needed.  This also explains the similarities between the 10- and 25-man data; in both cases, a dedicated “tank-spamming” healer really isn’t necessary most of the time.

Second, I think it reinforces this idea that spike damage is the only dangerous damage.  We’re blanketed with an incredible amount of healing from passive sources, so low-throughput sections of an encounter will rarely cause a death.  It’s really those situations where we take a sudden spike of damage that our healers even reach into their toolkit for the big, fast heals.  And the best thing we can do to survive is to reduce the number of times they need to do that and buy them as much time as possible in the cases where they do.

But most importantly, it’s somewhat amazing how much self-healing we really do.  In many cases, we’re not even receiving direct heals, and just being kept afloat by HoTs and our own healing contributions.  It also means that it’s probably not fair to toss aside SoI as irrelevant because of the sheer amount of overhealing it does.  A lot of that overhealing happens during the stable, low-throughput situations that we don’t care that much about.  But during a spike, the amount of overheal will be very small.  And while it’s not guaranteed healing since SoI is a proc mechanism, it’s still going to give us some degree of buffer against those spikes because it’s passive.  There’s no reaction time involved – it just happens when it happens, which means some of the time it will be there exactly when it needs to be.

Overhealing and Effective Overhealing

The other thing to consider is that this isn’t the entire story.  This is the overhealing that World of Logs registers, but it’s not representative of the effective overhealing.  To explain that thought, consider the following situation.  You take 30k damage, and within the next second you get a 30k SoI proc, a 30k Rejuvenation tick, and a 60k Holy Light.  Any one of them brings you up to full health individually, so which one overhealed?

The game and World of Logs will register the first heal received as being effective, while the latter two will be recorded as overhealing.  But that’s not very realistic – for example, if the SoI proc hadn’t happened, the Rejuvenation tick would have healed you to full anyway.  So you end up in the same state whether the SoI proc occurred or not.  In some sense, the SoI proc was completely irrelevant, because it didn’t do anything effective for your survivability in that situation thanks to the competing heals.  Right?

Well, you could make the same argument about the Rejuvenation, or the Holy Light.  It’s not entirely clear which of the three should get credited with overhealing, because any two of the three are irrelevant depending on your perspective.  But they weren’t all irrelevant, because clearly one of them did something.

This is one problem with logging.  It will always credit the early heals, but can’t easily figure out how much overhealing those heals create later on.  In the case of Seal of Insight and Rejuvenation, I think you could argue that the difference comes out in the wash.  It’s probably about equally likely that the Rejuv tick follows the SoI proc as it is for the reverse to happen.  So the logs probably already account for this interaction between passive effects.  But when it comes to the direct heals that have a cast time, these periodic ticks and procs eat away at the effectiveness.  You may have benefited from the entire Holy Light at the time the cast started, but half of it may be overheal by the time the cast finishes.

So while we might see 60% overhealing for Seal of Insight in a given log, it’s likely that it’s created some non-trivial amount of overhealing in our direct heal accrual.  It’s very hard to say exactly how much that will be without looking at specific logs, and it’s likely to vary significantly based on healer composition.  A tank being healed by a Restoration Druid and a Holy Paladin’s Beacon of Light is going to have a very different amount of direct heal contribution than, say, a Restoration Shaman and an Atonement/Discipline priest.

But this raises some obvious questions about how to accurately model SoI.  Do we try and model it with the overheal values given by World of Logs?  Do we aim a little higher to account for heal-sniping?  If so, how much higher?  And how exactly do we implement that overhealing?

Overhealing Implementations

I’ve had a number of conversations about this topic over the past week, and gotten a lot of different answers. If you recall, we model heals in the code by granting small absorption bubbles that last for a limited amount of time.  We model overhealing by adjusting the size of these bubbles.

Of course, there’s the simple method that we’ve used previously with Word of Glory, which is to just reduce the size of every single heal by a certain amount to account for overhealing.  In other words, if we want approximately 50% overhealing, we just halve the size of each SoI proc.  The downside is that this version doesn’t adapt to damage intake, so an SoI proc occurring after a few avoids gives us the same absorb bubble as one occuring after three full melee hits in a row, even though the latter is far less likely to be overhealing than the former.

We could be a little more sophisticated and include a degree of randomness to the size of the overheal bubbles.  Rather than using a half-sized bubble to represent 50% overhealing, we could just roll the dice for each proc.  We’d grant a full-sized bubble 50% of the time, and no bubble the other 50% of the time.  That “random binary” model would probably mimic the randomness of heal-sniping pretty well, but it still doesn’t give us a method that adapts to damage intake.  In the comments of a previous blog post, Weeby and I discussed using a discrete set of different probability distributions, dynamically choosing which one we use based on prior damage intake.

The method I originally thought about using was to implement an adaptive overhealing function.  Basically, every time we got an SoI proc we would calculate the amount of overheal for that proc based on the previous few boss attacks.  The functional form is a little bit arbitrary, but the essential characteristics I had in mind were as follows:

• If we took very little damage in the last few attacks, then the SoI proc should do basically nothing, because passive heals from other sources will top us off.
• If we took a lot of damage in the last few seconds, the SoI proc should be 100% effective, as we can use all the healing we can get.
• In between those extremes we should have a continuous variation in effectiveness.

The function I had in mind is one encountered commonly in solid-state physics: the Fermi-Dirac distribution, or “Fermi function” for short.  The Fermi function is actually the inverse of what we want – it takes on a value of one for small $x$ and a value of 0 for large $x$, and we want the reverse, so the modified form I used is this:

$$\large f(x)=\frac{1}{1+e^{-(x-x_0)/\sigma}}$$

where $x_0$ and $\sigma$ control the size and shape of the transition.  If we plot this function, it looks something like this:

Example of the fermi function for $x_0=1.5$ and $\sigma = 0.15$.

On the y-axis we have the effectiveness of Seal of Insight, while the x-axis it the sum of the damage from the last three boss attacks.  By setting the halfway point at $x_0=1.5$ we end up with about 75% overheal, which is a little on the high end of our estimates.  But we can tweak $x_0$ and $\sigma$ to match the function to whatever level of overheal we’d like.

There are a few problems with this method, though.  It’s very deterministic by design, so if you take 2-3 full attacks in a row, you’re always going to get full strength SoI proc.  But there are situations where that isn’t an accurate model.  For example, if you receive a Lay on Hands immediately after the third attack, any subsequent SoI procs are basically useless.  And on the other extreme, if you only take a few very weak hits in a row while your healer is distracted, those SoI procs will just heal you up and allow the healer to focus on whatever they’re doing.

So while I like this idea, I also think it introduces a lot of complexity without really accomplishing much.  We could probably get a similar effect by just assuming a flat amount of overhealing on every SoI proc or using one of our random models (binary or discrete set).

One school of thought is to not include overhealing interactions at all – every SoI acts at full strength, no matter what.  The reasoning is pretty simple: we can’t turn it off.  It’ll be there when it occurs no matter what, regardless of what or how many healers you have.  The healers can choose to use that GCD in another way, but our only choice is to swap seals to a mediocre DPS seal.

There’s another argument for full-strength SoI.  We care most about the high-damage spikes, and those are situations where SoI tends to do less overhealing.  We care about healing during that critical time between the start of the spike and our  healers reacting and dumping heals on us, and pretty much every SoI heals for its full amount during that window.  So by assuming SoI is full strength, we probably get a fairly accurate representation of how it works during the danger periods that we care about most.  The downside is that during low-damage periods, we’ll be overestimating its value during the low-damage periods, which will skew our TDR metrics.  But if we’re not that concerned about those low-damage periods anyway, maybe that’s OK.

Backwards-Facing vs. Forward-Facing Modeling

There’s another issue that I’ve been wrestling with for the past few weeks, which is how to model healing more effectively.  The absorb bubble method I’ve been using is a little artificial, in that it makes healing apply to future attacks rather than previous attacks.  But of course, in practice healing replaces damage that’s already occurred. I think you could make a good argument that healing is essentially giving you extra hit points that future attacks need to chew through.  But it’s also not a very intuitive model for most people.

Instead of this “forward-facing” method, we could use what I call a “backward-facing” method.  For example, when we get an SoI proc, we just apply it to a previous attack and reduce the damage that attack did retroactively.  This better matches peoples intuition for how healing works, and doesn’t end up to be much more computationally expensive than the forward-modeling method.

In a pure stochastic sense, it shouldn’t matter which we do as long as the size of the SoI proc doesn’t depend on the attacks surrounding it.  We’re just as likely to avoid the attack before an SoI proc as we are to avoid the attack afterward.  But when you start putting any sort of time dependency into the simulation you get some subtle differences in the results the two modeling methods give you.  And we have a lot of that going on in our system.

For example, SotR itself biases the results.  SotR is a proc trigger for Seal of Insight, and the attack after a SotR cast is about 50% smaller on average than the attack before a SotR cast.  As a result, if you use the forward-facing model, you’ll get more overhealing overall because those procs are being applied to smaller attacks.  The backward-facing model doesn’t have that same bias.  Parry-hasting causes a similar effect, but in reverse: a parry results in 0 damage taken and increases the likelihood of a proc, which causes slightly higher overhealing in the backwards-facing model.

Dynamic overhealing models and Sacred Shield absorbs can enhance or suppress some of those effects, causing further perturbations.  And the SH finisher models create even more complicated interactions between all of those components, because they moderate SotR usage based on damage taken in the last few attacks.  Thus, SoI procs can suppress SotR casts in the backwards-facing model or exacerbate the overhealing caused in the forward-facing model.

I’ve modified the code to be able to handle both methods, but I think I’m probably going to transition to the backwards-modeling case.  It’s easier to explain, for starters, and I think it’s a little more intuitive.  But most importantly, I think it tends to be a little more realistic due to the interactions with SotR, especially for conditional finisher queues.  I’ll probably convert WoG over to the backwards model as well so that I can more naturally incorporate the effects of overhealing, and even come up with queues that only use WoG if it will not be wasted.

Going Forward (But Healing Backward!)

Now that the code’s been updated, we just have to settle on the correct way to do the modeling.  We have a lot of options, but despite all of the sophisticated techniques we have to employ overheal modeling, I’m actually leaning towards the “no-overheal” method, where every SoI proc occurs at full strength.  If we’re mostly concerned with large damage spikes, then this model seems like it would do the best job of accurately representing how SoI affects those peaks.  It does come at the cost of reducing the accuracy of our information during the low-damage periods, though.

It’s possible we could use the Fermi function to adjust for that by setting a fairly low threshold $(x_0)$.  But I’m a little hesitant to do that, because the whole thing feels fairly artificial to me.  It might give us the behavior we think we want, but it’s hard to trust data if we’re not sure we trust the model.  At least with the “full-strength” SoI model, we’re aware that we may be over-estimating its effectiveness in certain situations, as well as which situations those are in particular.  And the backward-facing SoI method tends to reduce the impact of dynamic overhealing modeling anyway, so maybe it’s unnecessary.

Even with the “full-strength” SoI model, we get a fair bit of overhealing.  For starters, we’re only applying Seal of Insight to adjacent melee attacks – in other words, with the backward-facing model we only look one attack into the past.  So if we avoided the previous attack, that SoI proc is all overhealing, because there’s no damage to remove.  The same can be said of the forward-facing model if we avoid the following attack.

And on top of that, we get some overhealing due to other mitigation effects.  Multiple SoI procs, for example, can reduce a blocked or mitigated attack to zero damage.  Keep in mind that each SoI proc is approximately 20% of a boss attack, making it almost as large as a block.  Three SoI procs following a SotR-mitigated block is enough to null out all of that damage.  And in a high-haste set, we get about 25% more SoI procs than we do boss attacks, so we expect about least one SoI proc per attack, and often get clumps of 3 (melee+SotR+CS all falling within 1.5 seconds).

When you throw Sacred Shield absorbs into the mix, you can get situations where even a single SoI proc is predominantly overheal.  In my testing, with Sacred Shield turned off we get about 19% overhealing due to our ~19% avoidance, but with Sacred Shield turned on we rocket up to about 33% overhealing.  About 6% of that difference is due to full absorbs via Sacred Shield, but the last 8% is due to multiple SoI procs.

I think that it’s worth dwelling on the block analogy here.  In the past, we’ve discussed how mastery gives us an active benefit (SotR mitigation) and a passive benefit (block chance), while haste primarily gives us an active benefit.  But if we include Seal of Insight, that’s not really the case.  Haste also gives us more passive SoI procs, which act like slightly smaller blocks.  So both stats give us a fairly significant passive benefit, though in haste’s case it does still rely on us following a rotation and attacking the target.

In any event, I think that many people, myself included, haven’t been giving Seal of Insight enough credit.  I’ve generally written it off as a fairly small effect, and didn’t think too much about it because of the sheer amount of overhealing involved.  But if you asked me if I’d like a bunch of free 20% mitigation blocks, I certainly wouldn’t pass that off as irrelevant.  As long as some of them are occurring during a spike period, I’d care.  And given how frequently we get procs in a haste set, we’re almost guaranteed to have at least $N$ procs within any given string of $N$ attacks.

I hope to have some data ready to publish later this week, as things are finally starting to slow down in real life.  I may put up a post comparing and contrasting several of the different SoI modeling techniques to see what, if any, difference they make in the overall data.  It’s possible that for all of my agonizing over the different models, they all give more or less the same results, at which point maybe we don’t need to worry as much about scrutinizing the model in the first place.

## On Measuring Survivability

The last few posts have garnered a lot of comments, and some of them have indicated that there’s some misunderstandings about the simulations we’re performing.  This set of simulations started back in September, and has been evolving ever since.  And the rationale behind how we perform the simulations is spread out over 6 months of posts.  It seemed like a good idea to consolidate that information in one place.

Basic Modeling Problems

First, let’s consider the point of modeling.  Obviously we want to generate data that helps us make more informed decisions about how we gear and play.  For modeling to be of any benefit, it has to generate information that’s useful.  And generally, that means that you want the model to be accurate.

Most people would assume that means you want the model to be perfect – all-inclusive, with tanks and healers that play perfectly and react with mechanical precision.  But in fact that’s not the case.  Consider what would happen if we did have perfect tanks and perfect healers.  Your perfect tanks would execute their rotation flawlessly, never miss an encounter cue, and would always apply their mitigation skills in the most optimum way.  Your perfect healers would react flawlessly to spikes in damage intake, always select the correct heal at the right time, and would be as mana-efficient as possible.  In your perfect model, you’d have at least enough healing to cover damage intake given perfect conditions, so your perfect healer would never run out of mana.  And the net result would be a tank that never dies.

Unfortunately, that perfect simulation wouldn’t be very useful.  If the tank plays perfectly and never dies, then it barely matters how they gear or what they do.  They’ll be unkillable with any reasonable gear set.  Which highlights the flaw with a perfect simulation: it’s not accurate.  It doesn’t reflect reality. Because in real encounters, players make mistakes and tanks die.  And there’s a fairly high correlation between those mistakes and tank deaths.  Which means that if we want a good, useful simulation, we need to account for that imperfection.

Imperfect Tanks

Unfortunately modeling imperfection is almost as hard as modeling perfection is.  For example, let’s consider how many ways there are to model an imperfect tank.

• Active Mitigation Usage – You could do it by varying the precision of their active mitigation.  For example, a sloppy player might be macro-ing Shield of the Righteous to Crusader Strike – essentially the “S” rotation we’ve used in the past.  On the other extreme, you could model a near-perfect tank that pools holy power and only blows SotR early during what seems to be a spike – the “SH1″ and “SH2″ rotations we’ve used.  And there are hundreds of variations in-between that differ in effectiveness based on the logic used to control SotR usage.  But which one of those best models a real tank?
• Rotation – Maybe your tank is perfect and follows CS>J>AS>SS to the letter.  That’s pretty easy to model.  On the other hand, maybe your tank slips up and prioritizes J over CS once in a while by accident.  But how often do they do that?  Are they just as likely to push AS ahead of CS as well, or forget to cast SS when it’s available? Again, we have an infinite number of variations based on the probability distribution you use to determine whether the player makes these errors.
• Latency – Maybe the player lives next to the server farm, and has sub-millisecond latency.  On the other hand, maybe they’re playing from Australia, and regularly struggle with pings of 350 ms or greater.  Cast queuing helps quite a bit to mitigate these problems, but it still affects events that you need to react to in-game, because even with perfect reactions you’re behind by your latency value.  How much latency should our imperfect player have to deal with?
• Player Reaction – And even if you live next to the server farm, nobody’s reaction time is instant.  So a player’s response to an event will always be delayed somewhat based on their reaction time and attentiveness.  They may react more slowly to an event if they were watching some other information stream, like DBM timers or their action bars.  How often does our imperfect tank stand in the fire?

It should be evident from this that there’s a huge parameter space to work in here.  And the problem is that it’s very, very difficult to determine what’s “average.”  A reaction time of a full second is certainly below average, but there are players who operate at that capacity.  A completely perfect rotation is possible, but awfully difficult – arguably difficult enough that even the best players can’t manage it.  Everyone slips up once in a while.

Meloree posted a great comment on the last article that I’d like to quote, because it seems fairly relevant here:

As far as imperfect play goes – during wrath/Cataclysm the best I managed to do over the course of a full fight was roughly a 1.53s GCD average over 10 minutes. Thats roughly 98% efficient, and it’s pretty close to an upper bound – not many people ran a tighter rotation than I did. ….

I regularly saw parses from good tanks – in well progressed heroic mode guilds – who weren’t better than ~80% efficient at their rotations. ….

Being more than 90% efficient in your rotation places you in the upper half a percent of tanks in WoW.

So if even the greats are struggling to beat 95% efficiency, what’s our estimate for an average tank?  90%?  80%? 70%?  More to the point, do we really want to be running simulations for an average tank?  The readership of this blog in particular is decidedly skewed towards above-average.  Not many tanks of average or below-average play quality actively seek out blogs to try to improve their play in the first place.  And of the ones that do, how many are willing to struggle through my verbose and technical blog posts?  Probably a small minority.

Imperfect Healers

More problematic yet is the matter of healers.  How do we model an imperfect healer? They have many of the same complications that tanks do.  Latency and reaction time are obvious factors one can tweak.  But the difficult part is really the healer “rotation,” because there really isn’t one in most cases.

For starters, their rotation varies based on the situation – they may be focusing on single-target healing if they’re assigned to a tank, or on area-of-effect healing if they’re assigned to the raid.  And in a 10-man raid, often one healer will be switching back and forth between those two play styles constantly based on the demands of the encounter.  So the type of healing you get depends not just on your play, but on what’s going on with the rest of the raid as well.

Further, a healer’s play style is far more reactive than tanking or DPS play. They may have a basic rotation they use as a default during less dangerous periods, but they switch gears and change cast priorities during a crisis.  They’ll use different spells if the tank has four or five GCDs to live than they will if death could happen in two or three.  And while healers don’t have active mitigation, they do have cooldowns they can throw at the tank if the shit really hits the fan.

So there’s a huge number of variations in how you model an imperfect healer.   Is the healer a little slow to switch modes when the tank takes a spike?  Or do they over-commit to expensive heals and run out of mana too early?  Or do they just not make effective use of their emergency buttons? We could model a “dumb healer” that just spams their mana-efficient heal on the tank regardless of what else is happening, but that’s probably not an accurate model of even the worst healers.

And just as for tanks, each healer plays a little differently.  The model of one imperfect healer may not give accurate results for a different healer.  Not to mention the inherent variations between healers of different classes with slightly different toolkits.  The results may be totally different for a healer that relies heavily on HoTs than they would be for a healer that heavily leans on absorption effects or direct heals.  How do you build a model that’s general and widely applicable when the inputs are so widely varied?

The short answer is: you don’t!

Rethinking The Approach

It’s clear that there’s way too much variation involved here to write the sort of modeling software that most people think of when they talk about wow.  We could certainly write an equivalent to Simcraft, given enough time and effort, but it isn’t clear that it would give us much in the way of useful results.  Tracking things like “how often does the tank die” would vary significantly based on the details of your imperfect healers and tanks.

Not to mention that, while we could model a healer any way we wanted, in practice we have no control over how they play.  We might even have a different healer from week to week or encounter to encounter.  Tying ourselves down to a particular healer model is doomed from the start to be too specific – it just won’t give us results that we can apply everywhere.   We need something that is both more general and simpler to implement.

So we go back to the drawing board.  All the way back to the beginning, in fact.  We reconsider what survivability means at a fundamental level.  What is the root cause of tank death?  I’ll put forth the following hypothesis:

Hypothesis: Tanks are in the most danger of dying when their instantaneous average damage taken per second (DTPS) greatly exceeds their instantaneous average healing received per second (HRPS).

Now, that certainly shouldn’t be very controversial.  I’ve basically said “you die when you don’t get enough heals,” but put it in a more technically rigorous form.  We all know what it means to not receive enough healing.  That happens when our healers are distracted or otherwise incapacitated – in other words, when they make a mistake.

And we’re also familiar with the first half of that statement.  Our time-averaged DTPS goes up when we take a lot of damage in a short period of time.  In other words, a damage spike.  To illustrate that thought, let’s consider some data.  Here’s what the DTPS profile may look like for a tank over an entire encounter (this happens to be Council of Elders):

Tank DTPS plotted against time for an entire encounter.

This is the broad overview, showing how damage fluctuates over long periods of time.  We have extended periods of high intake and periods where the tank isn’t actively tanking anything.  Rather than look at the broad view, let’s narrow our focus to the section in the middle, with the large spike followed by three smaller spikes.  That looks like this:

Tank DTPS plotted against time for a ~two minute period.

So over a two-minute period, our tank sees massive fluctuations in damage intake.  It drops as low as 40k DTPS, and spikes as high as 150k-230k DTPS for 5- to 10-second periods. The danger periods are obviously these peaks, where damage intake abruptly increases – these are the moments when we’re most at-risk of dying.

From the same log, the tank healers’ average healing throughput is about 100k HPS.  Of course, during this period it gets ratcheted up to around 220 HPS (and other healers chime in to help).  But then again, this is from a log where the tank didn’t die.  If the healer hadn’t cranked his output up fast enough to meet this new level of damage intake, we’re very likely looking at a dead tank.

Let’s assume for the moment that we don’t have any control over our imperfect healers.  Let’s also assume that they screw up every so often during the encounter – maybe they fail to react to a spike quickly enough, or maybe they just stood in fire too long and have to move or break off of the tank to heal themselves.  If one of those screw-ups coincides with one of the damage spikes, we’re probably going to die.

If we accept the premise that we have no control over what our healers do, just what they perceive, then what can we as tanks do to minimize the chance of this happening?  This is what a scientist would call an “overlap integral” problem.  We can increase our survivability by reducing the likelihood that a spike and a healer screw-up overlap in time.  And how do we do that?  Well, consider what would happen if we had a way to perfectly smooth our damage intake, such that instead of the pink line, it looks like the blue line on this plot:

DTPS over a 2-minute period before and after a perfect smoothing algorithm.  And by “perfect smoothing algorithm,” I mean “Photoshop’s Line Tool.”

Suddenly everything changes.  First, we don’t have any big spikes to worry about – our mean intake is a little over half of our peak intake (and higher than our average), but it’s very steady.  So it’s far less likely that the healer’s screw-up coincides with a period of extremely high intake, because there simply aren’t any periods of extremely high intake.  More subtly, and perhaps more importantly, the fact that there aren’t any big spikes that require the healer to change modes means that it doesn’t matter if they’re a little slow in doing so.  In practice, that’s a big deal because the “slow to react” healer model is far more likely to cause the sort of overlap that kills you than random healer movement is.  So our “perfect smoothing” mechanism turns a tank that dies some of the time into a tank that never dies.

Now of course, this is an unrealistic model – we have no way to perform this perfect smoothing (outside of Photoshop, at least).  But it gives us a clear goal to aim for.  As tanks, we can’t make our healers play better.  But we can give them an easier damage profile to work with: one that doesn’t require rapid fluctuations in healer throughput.

So I propose the following corollary to our hypothesis:

Corollary: If spike damage is dangerous, then minimizing the frequency and magnitude of high-damage periods is the most direct way to increase survivability.

This is a nice, tidy little statement.  It narrows our focus from an all-encompassing simulation with many variables to a much smaller subset of parameter space.  Instead of worrying about what the healer is doing, we just concern ourselves with the damage intake profile we receive.  In essence, we’ve removed healers from the equation.

Of course, without healers, we don’t have much use for health either.  If we’re only concerned with the plot of damage taken per second, it doesn’t matter how much health we have.    So if we’re ignoring healers, and we’re not tracking tank deaths, then keeping track of the tank’s current hit points is no longer necessary, and we can add “tank health” to the list of things we can cut from the simulation.

Now, that sounds awfully controversial when taken in isolation.  What use is a simulation without healers or tank health? But it follows rather naturally from the corollary.  We’ve been conditioned to think that for a simulation to be useful, it must model everything down to the last detail with near-infinite precision.  But that just isn’t always the case.  It’s great if you want details about a specific situation.  But not if you want general, portable results that apply to a great variety of situations.  By eliminating healers and health from the equation, we can focus our efforts on variables we can control and make sure our modeling of those factors is as accurate as possible.

Building the Simulation

Now that we’ve defined the problem, we can go about building the simulation.  This part is pretty boring unless you’re enthralled by mathematical detail and code, so I’ll try and summarize it as briefly as possible.  We want our sim to do the following:

1. Simulate a tank being attacked by a boss
2. Track the damage intake as a function of time
3. Take the resulting series of damage events and perform calculations on that sequence

Each of these steps has a number of details to consider.  For example, we need to choose the boss’s damage so that we can appropriately assign Vengeance values.  We’ll also need to estimate the player’s gear so that we can appropriately calculate avoidance and block chances.  And of course, later on we’ll want to be able to vary both of these parameters.

Likewise, since we’re tracking damage intake, we need to properly calculate mitigation and absorption effects.  Since our mitigation depends on the tank’s rotation and active mitigation usage, we need to model all of that as well.

The simulation I’ve written does all of those things and more.  It’s a Monte-Carlo style simulation, which means that it simulates combat the same way the game calculates it – making rolls for each event as they happen.  So for example, it cycles through a loop, incrementing time until an event (like a boss attack) occurs.  It then rolls to see if that boss attack is avoided.  If so, it rolls again for a grand crusader proc.  If not, it rolls to see if it was blocked, and so on.  It works the same way for our rotation, following a priority queue (which we can modify) to cast spells and update the system according to their result.

We run it for a very long time (10k minutes of combat, generally) to smooth out random fluctuations and get stable, statistically significant results.  And the output is a string of numbers that looks something like this (but a lot longer):

[... 100 55 0 70 0 100 55 55 38 0 100 55 38 100 0 0 0 100 55 55 100 0 ...]

Where each number represents an amount of damage.  So 100 would be a full boss attack taken to the face, 70 would be a blocked attack, 55 would be an attack mitigated by a 45% mitigation Shield of the Righteous, 38 would be an attack that was blocked and mitigated by SotR, and so on.  In practice these values vary a bit more because of absorption effects (Sacred Shield), but that’s the basic gist of it.

Once we have that string of events, we perform some post-processing on it.  We perform a moving average to generate the sort of data you would see in a World of Logs plot like the one I’ve shown above.  We then take that moving average and calculate how many of its elements exceed a given threshold – say, 100% of the player’s health.  This is the data I present in the tables.  In essence, it’s telling you the two things we care about most: how many spikes are there, and how large are they?

A Word on Healing

One drawback of this style of modeling is that without player health tracking, healing becomes awkward.  That wouldn’t be a problem if it weren’t for the fact that we have a non-trivial amount of self-healing abilities.  For example, how do you model a Word of Glory or Seal of Insight heal if you can’t… well… heal?

The answer is that you treat them as short-term absorption bubbles.  If WoG heals us for 200k health, we instead give ourselves a 200k absorption bubble.  We keep the duration short because this healing is only relevant over short time windows.  In the case of WoG I’ve been using 3 seconds, which is probably too generous; for Seal of Insight I’m using 1.5 seconds.  It wouldn’t make sense to grant a 200k absorption bubble that lasts for 10 seconds, because in 10 seconds a real healer would react and top us off.  So the absorption needs to only apply to boss attacks that happen shortly after the heal occurs.  Another way to think of this is that, by not modeling healers, we’re assuming perfect healers that never let you die, and they react within a few seconds.  Thus, if the absorption bubble isn’t used up within a few seconds, it just gets wasted (i.e. turns into overheal).

Which brings up another issue with healing in this model: overhealing and efficiency.  We need to make assumptions about how much overhealing occurs. For Seal of Insight, you can think of this as trying to estimate how many procs occur when we’re already at full health since our simulation doesn’t have health.  But the issue is a little more subtle than that, even.

To illustrate why, consider the following example: lets say you take a 200k attack from a boss, and react by casting a 200k WoG on yourself.  Your healer also drops a 200k Holy Light on you in response to the attack.  Which one of you overhealed, and how efficient were you?

Logs will base the answer on whomever acted first.  But that doesn’t cut it for our analysis.  Either way, there was 200k worth of overhealing happening in that scenario, and whether it was my WoG or the healer’s Holy Light, one of them was wasted.  No matter who the combat log credits with the overhealing, I would have been better off letting the healer top me off and using that holy power on a Shield of the Righteous instead.

I tend to take a rather pessimistic view on healing efficiency for that reason.  I generally assume that the healer is going to do what they do regardless of whether I WoG or not, because they can’t assume that I will WoG at any given moment.  And likewise, I can’t assume they’ll stop healing me because I know where my WoG button is.  Since neither of us can reliable predict the others’ actions, we’re bound to cause a good chunk of overhealing.  This is less true with incoming healing notifications on unit frames, but not all frames have this capability, nor do all healers use it on frames that do.  However, since opinions vary on this, I generally present results for a variety of overheal levels when I’m discussing results involving WoG.

A Word on Patchwerk

To wind down this post, I want to have a quick discussion about one of the more common criticisms of this sort of modeling.  The simulation is a Patchwerk model, which for newer players means “a boss that blindly melees you and does nothing else.”  But real fights rarely look like Patchwerk.  Real fights have tank swaps, movement, different phases, magical damage.  The criticism I often see is that because of all of those factors we’re ignoring, these simulation results have no relevance to real play.

I think that attitude is a bit narrow-minded, and I don’t think it’s entirely valid.  Sure, there are tank swaps.  Sure, you’ll use cooldowns during a fight.  But you’re obviously not going to die when you don’t have aggro. And you’re probably not going to die while you have Holy Avenger up and are coasting along on 100% uptime of a 50+% damage mitigation buff. You’re not very likely to die when you have a big cooldown running either, for that matter. You’re not even that likely to die right after a tank swap, since you’ll have extra SotR uptime during that period if you’ve pooled holy power.

You’re most likely to die when you get a big damage spike, and that really only happens when you don’t have any of those safety nets. It happens when you just get unlucky and take a couple big unmitigated melees because you’re rebuilding Holy Power.  In other words, it happens in the in-between sections of a fight, when you’re essentially tanking Patchwerk.  By that logic the simple, Patchwerk simulation much more relevant than it would initially appear.  Thus, I think a boss mindlessly hitting you is a pretty good model for the bulk of our death scenarios.

The “big, predictable boss attack” death scenario is pretty dangerous too, and shows up a lot in current content.  But I think it’s less dangerous than many seem to think if you’re using active mitigaton properly.  Shaving 50% off of the predictable spike, and likely one of the neighboring melees as well, usually makes it quite manageable.  Often it reduces the big attack to less than a regular melee swing.  And since it’s a predictable spike, your healers know its coming – they have DBM timers telling them that you’re going to take a big spike in X seconds, so they are more likely to use proactive tools, like absorption shields, small cooldowns, or simply pre-casting a heal on you so that it lands right after the large attack does.

In any event, the “big predictable attack” is something I plan on adding to the simulation once I get time – possibly even before the next round of data posts, since the Seal of Insight code is almost finished.

Despite all of that, it’s worth remembering that specific bosses or mechanics can lead to different strategies being optimal.  We’re trying to model the most general situation possible so that it’s applicable to as many fights as possible.  But mechanics like Dread Thrash can certainly trump steady-state modeling.  A boss like Lei Shi forces us to reconsider whether the model is applicable to that particular boss.  If we had another Algalon-like encounter where you have three healers spamming the tank just to keep up with the damage, you may care a lot less about smoothness and a lot more about stamina, armor, or even avoidance.  This model abstracts all of those things out, so it’s important to keep in mind that this is a guideline for when all of those other effects are already taken care of.  A good tank needs to know when the model is appropriate and when to break from the model to handle specific problems.

Summary

This post doesn’t really have a conclusion.  I haven’t presented anything incredibly new here.  Tanks doing high-end content have been focusing on spike damage for years now.  But up until recently, we really haven’t had good tools to quantify those concerns.  We’ve been able to calculate total damage reduction fairly reliably in the past, and often that metric was used as a stand-in to approximate smoothness.  But the simulations I’ve run in the past six months have demonstrated the inadequacy of that approach.  A stat like haste can be absolutely terrible at reducing total damage taken while being fantastic at reducing spike events.

I hope that the logic behind the simulation is more apparent now, though.  It should, at least, address the common criticism that the results can’t be valid or useful without including healers.  While it’s definitely important to consider what healers think and how they react, I don’t think it’s critical to have a specific healer model in mind when answering the question, “what makes me more survivable.”  While our simulation doesn’t model healers at all, the thought process that we used to arrive at our observables certainly did.  So they are included in the simulation in an indirect manner, in that rather than participating in the simulation explicitly, they determined how we perform the simulation and assess the results.  Healers are the lens we look through when we decide what metrics accurately reflect our survivability.

## Stamina: Updated Smoothness Data

In the last post, I mentioned in passing that there was an odd thing happening when a gear set dropped from 7k to 6k haste.  I elaborated a little on what I thought was the cause: we were crossing the 33.33% spell haste mark, which dropped Sacred Shield’s tick interval to less than 4.5 seconds, thus ensuring it was up for every third boss attack.  That all made sense, and seemed like a good explanation for the strange jump in spike presence when dropping below that haste breakpoint.

What didn’t make sense was that we were getting a very large jump in damage taken at that point too.  The damage mitigation of Sacred Shield should be very continuous and slowly-varying, so that was a hint that something else was going on, and warranted further investigation.  So I did….

… and found out that it was being caused by a bug.  The code was occasionally resetting Sacred Shield a little early thanks to a debugging line that had been commented out (i.e. made inactive), but managed to get un-commented at some point along the way.  Thus, some of the time it would arbitrarily grant your next Sacred Shield bubble earlier than it should have if the previous one had been consumed.

This had a few noticeable effects on the results.  First, it exaggerated the discontinuity at the 33% spell haste threshold, which is the effect that alerted us to it in the first place.  The reason we saw the jump in damage mitigation at that point is that all of the sudden we were getting a lot more early refreshes due to a Moire-like effect.

The second effect is that it obviously made Sacred Shield stronger than it should have been.  It’s still quite powerful, but this bug was causing the code to overestimate its value.  Thus, in the corrected results I present below, we expect higher damage intake across the board as well as less effective spike prevention.

Finally, it has an odd effect on stats.  Since we’re getting free refreshes early, it actually means that it was undervaluing haste.  Haste gives you SS bubbles faster, but that advantage is reduced somewhat when the code was artificially gives you a bubble early some of the time.  Thus, we expect haste to increase in value relative to other stats in both the smoothing department and the TDR department.

Since we have a lot of data to slog through, let’s get started.  This post will be data-heavy and analysis-light, since most of the analysis given in previous posts is still accurate.  I’m going to try and highlight the things that have changed.

Secondary Stat Smoothness Analysis – Gear

First, let’s return to the secondary stat smoothness analysis.  This is the one where we try all sorts of gear sets with different secondary stat allocations.  The gear sets are the same as before, though I’ve brought back Control/Haste+Mastery and the pure Haste build just for completeness.  The stats on each gear set are given below:

|    Set: |  C/Ha |  C/Ma |  C/Av | C/Bal |  C/HM |    Ha | Avoid | Av/Mas | Mas/Av |
|     Str | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 | 15000 |  15000 |  15000 |
|     Sta | 28000 | 28000 | 28000 | 28000 | 28000 | 28000 | 28000 |  28000 |  28000 |
|   Parry |  1500 |  1500 |  7500 |  4125 |  1500 |  1500 | 10825 |   7717 |   4000 |
|   Dodge |  1500 |  1500 |  7500 |  4125 |  1500 |  1500 | 10825 |   7717 |   4000 |
| Mastery |  1500 | 13500 |  1500 |  4125 |  6750 |  1500 |  1500 |   7716 |  15150 |
|     Hit |  2550 |  2550 |  2550 |  2550 |  2550 |   500 |   500 |    500 |    500 |
|     Exp |  5100 |  5100 |  5100 |  5100 |  5100 |   500 |   500 |    500 |    500 |
|   Haste | 12000 |     0 |     0 |  4125 |  6750 | 18650 |     0 |      0 |      0 |

Data – 150k Swings

Here’s the data for the 10N model boss:

Finisher = SH1, Boss Attack = 150k, data set smooth-10000-54

| Set: |   C/Ha |   C/Ma |   C/Av |  C/Bal |   C/HM |     Ha |  Avoid | Av/Mas | Mas/Av |
| mean |  0.370 |  0.361 |  0.354 |  0.360 |  0.362 |  0.355 |  0.323 |  0.331 |  0.341 |
|  std |  0.128 |  0.129 |  0.152 |  0.139 |  0.128 |  0.128 |  0.158 |  0.148 |  0.139 |
|   S% |  0.522 |  0.410 |  0.419 |  0.452 |  0.472 |  0.499 |  0.366 |  0.363 |  0.357 |
|   HP |   755k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |  5.034 |
| ---- | ------ |  --- 2 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  20% | 22.700 | 29.013 | 23.363 | 24.014 | 26.152 | 20.559 | 20.444 | 23.374 | 26.473 |
|  30% |  6.953 |  4.207 |  8.496 |  2.608 |  2.516 |  4.532 |  6.757 |  3.614 |  4.156 |
| ---- | ------ |  --- 3 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  20% | 54.132 | 57.541 | 48.624 | 52.663 | 58.336 | 49.501 | 42.242 | 48.225 | 48.747 |
|  30% | 27.413 | 19.642 | 25.915 | 14.937 | 14.729 | 23.603 | 20.554 | 16.322 | 18.614 |
|  40% |  1.513 |  3.732 |  3.881 |  2.584 |  2.450 |  1.978 |  3.709 |  3.920 |  4.283 |
|  50% |  0.000 |  0.023 |  0.274 |  0.024 |  0.000 |  0.000 |  0.280 |  0.158 |  0.122 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  30% | 51.312 | 47.154 | 47.174 | 42.967 | 45.038 | 46.142 | 38.660 | 38.607 | 41.522 |
|  40% | 16.894 | 16.704 | 17.272 | 16.254 | 17.122 | 12.803 | 13.689 | 15.421 | 13.154 |
|  50% |  4.832 |  2.201 |  5.650 |  2.156 |  2.157 |  3.678 |  4.483 |  2.808 |  3.111 |
|  60% |  0.061 |  0.209 |  0.335 |  0.233 |  0.193 |  0.099 |  0.517 |  0.583 |  0.510 |
| ---- | ------ |  --- 5 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  40% | 39.951 | 39.884 | 35.843 | 37.449 | 40.071 | 35.061 | 28.730 | 33.249 | 33.285 |
|  50% | 16.712 | 13.088 | 18.232 | 14.927 | 13.321 | 12.918 | 13.923 | 12.362 | 12.036 |
|  60% |  1.823 |  2.506 |  4.506 |  2.852 |  2.049 |  0.612 |  3.569 |  3.563 |  2.547 |
|  70% |  0.080 |  0.230 |  0.745 |  0.200 |  0.058 |  0.128 |  0.766 |  0.540 |  0.556 |
|  80% |  0.000 |  0.009 |  0.025 |  0.009 |  0.005 |  0.000 |  0.082 |  0.062 |  0.069 |
| ---- | ------ |  --- 6 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  40% | 61.898 | 60.106 | 53.983 | 58.784 | 62.406 | 56.114 | 44.454 | 50.722 | 52.255 |
|  50% | 36.677 | 32.226 | 33.623 | 32.905 | 32.038 | 30.645 | 26.056 | 25.518 | 27.926 |
|  60% | 12.653 | 11.299 | 13.852 | 11.918 | 10.236 | 10.124 | 10.410 | 11.511 | 10.098 |
|  70% |  1.428 |  1.728 |  3.906 |  2.605 |  0.857 |  1.482 |  3.269 |  2.675 |  2.055 |
|  80% |  0.019 |  0.079 |  0.620 |  0.139 |  0.022 |  0.089 |  0.620 |  0.389 |  0.338 |
|  90% |  0.000 |  0.004 |  0.043 |  0.005 |  0.001 |  0.011 |  0.100 |  0.071 |  0.069 |
| 100% |  0.000 |  0.000 |  0.001 |  0.000 |  0.000 |  0.000 |  0.006 |  0.001 |  0.002 |
| ---- | ------ |  --- 7 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  50% | 55.597 | 52.773 | 49.689 | 52.379 | 53.030 | 49.731 | 39.605 | 41.014 | 45.659 |
|  60% | 30.524 | 26.001 | 27.718 | 28.772 | 27.060 | 25.182 | 20.731 | 23.245 | 22.259 |
|  70% |  9.065 |  8.487 | 10.887 | 10.841 |  8.191 |  6.198 |  8.438 |  7.881 |  7.726 |
|  80% |  2.241 |  1.160 |  3.455 |  2.287 |  1.667 |  1.444 |  2.748 |  2.315 |  1.705 |
|  90% |  0.076 |  0.068 |  0.489 |  0.260 |  0.103 |  0.066 |  0.578 |  0.378 |  0.262 |
| 100% |  0.000 |  0.002 |  0.005 |  0.002 |  0.001 |  0.003 |  0.039 |  0.027 |  0.034 |
| 110% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.008 |  0.005 |  0.007 |

Not a whole lot has changed here.  Haste has seen a little improvement, but not very much.  It’s still better than mastery at eliminating the highest spikes in a category until we get into the 7-attack category, where mastery’s stochastic block inches it ahead.  C/HM performs pretty well in this low-damage category as well, arguably as good as C/H, albeit at a DPS cost.

Data – 250k Swings

Now for the 10H/25N boss:

Finisher = SH1, Boss Attack = 250k, data set smooth-10000-53

| Set: |   C/Ha |   C/Ma |   C/Av |  C/Bal |   C/HM |     Ha |  Avoid | Av/Mas | Mas/Av |
| mean |  0.390 |  0.377 |  0.368 |  0.375 |  0.378 |  0.377 |  0.336 |  0.345 |  0.355 |
|  std |  0.129 |  0.129 |  0.152 |  0.140 |  0.129 |  0.129 |  0.159 |  0.150 |  0.140 |
|   S% |  0.523 |  0.410 |  0.419 |  0.452 |  0.471 |  0.499 |  0.366 |  0.362 |  0.357 |
|   HP |   755k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |  3.021 |
| ---- | ------ |  --- 2 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  20% | 54.327 | 57.943 | 50.704 | 54.520 | 57.903 | 52.367 | 45.420 | 51.608 | 54.981 |
|  30% | 44.852 | 39.832 | 42.398 | 43.459 | 45.381 | 42.809 | 37.786 | 39.011 | 37.803 |
|  40% | 16.688 | 18.278 | 17.627 | 17.476 | 18.118 | 14.038 | 14.979 | 16.213 | 16.977 |
|  50% |  6.991 |  4.890 |  8.450 |  2.683 |  2.680 |  4.604 |  6.693 |  3.520 |  4.838 |
|  60% |  0.156 |  0.746 |  1.021 |  0.689 |  0.527 |  0.143 |  1.103 |  1.029 |  0.644 |
| ---- | ------ |  --- 3 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  40% | 49.264 | 39.300 | 42.411 | 43.781 | 48.055 | 44.661 | 35.319 | 37.762 | 36.571 |
|  50% | 29.561 | 23.042 | 26.579 | 15.851 | 16.212 | 26.999 | 21.023 | 16.317 | 21.391 |
|  60% |  6.911 | 10.785 | 10.271 |  9.627 |  8.853 |  7.761 |  8.966 |  9.600 |  9.269 |
|  70% |  1.536 |  3.492 |  2.785 |  2.683 |  2.704 |  2.026 |  2.957 |  3.781 |  4.223 |
|  80% |  0.323 |  0.616 |  0.865 |  0.647 |  0.558 |  0.542 |  1.110 |  1.093 |  0.833 |
|  90% |  0.000 |  0.047 |  0.048 |  0.015 |  0.000 |  0.000 |  0.076 |  0.084 |  0.053 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  50% | 56.781 | 52.448 | 49.803 | 45.523 | 48.859 | 53.922 | 40.873 | 39.346 | 46.674 |
|  60% | 33.474 | 31.087 | 31.783 | 34.582 | 33.344 | 30.369 | 25.869 | 26.871 | 25.203 |
|  70% | 17.003 | 12.678 | 16.798 | 16.233 | 14.823 | 12.906 | 13.223 | 13.225 | 13.060 |
|  80% |  8.689 |  4.933 |  9.319 |  6.910 |  4.197 |  6.643 |  7.492 |  4.765 |  4.966 |
|  90% |  1.136 |  1.688 |  1.770 |  1.271 |  1.424 |  1.058 |  1.786 |  1.850 |  1.981 |
| 100% |  0.300 |  0.414 |  0.658 |  0.327 |  0.284 |  0.281 |  0.827 |  0.654 |  0.628 |
| 110% |  0.008 |  0.061 |  0.107 |  0.077 |  0.042 |  0.029 |  0.206 |  0.186 |  0.108 |
| ---- | ------ |  --- 5 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  60% | 59.483 | 55.688 | 51.792 | 56.686 | 56.561 | 55.647 | 43.142 | 45.840 | 47.831 |
|  70% | 40.480 | 37.121 | 35.733 | 37.290 | 38.462 | 36.053 | 28.242 | 31.063 | 33.100 |
|  80% | 27.276 | 21.955 | 25.709 | 23.432 | 21.921 | 23.470 | 19.943 | 18.292 | 17.793 |
|  90% | 11.237 |  9.947 | 12.957 | 10.586 | 10.110 |  9.378 |  9.840 |  9.320 |  8.741 |
| 100% |  4.183 |  3.352 |  6.709 |  3.880 |  2.789 |  3.361 |  5.288 |  3.884 |  3.615 |
| 110% |  0.309 |  0.911 |  1.791 |  1.461 |  0.740 |  0.351 |  1.700 |  1.577 |  1.384 |
| 120% |  0.027 |  0.267 |  0.293 |  0.213 |  0.100 |  0.120 |  0.423 |  0.521 |  0.515 |
| 130% |  0.001 |  0.043 |  0.088 |  0.051 |  0.012 |  0.031 |  0.180 |  0.180 |  0.151 |
| 140% |  0.000 |  0.002 |  0.004 |  0.001 |  0.000 |  0.000 |  0.030 |  0.037 |  0.016 |
| ---- | ------ |  --- 6 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  70% | 63.681 | 58.649 | 54.080 | 58.665 | 61.755 | 58.844 | 44.043 | 49.095 | 51.853 |
|  80% | 49.886 | 42.187 | 43.512 | 43.182 | 43.426 | 44.341 | 34.345 | 34.477 | 35.127 |
|  90% | 30.485 | 27.290 | 27.892 | 26.206 | 25.868 | 26.951 | 21.186 | 21.653 | 22.258 |
| 100% | 17.015 | 14.738 | 17.648 | 14.466 | 12.701 | 15.379 | 13.362 | 12.233 | 12.433 |
| 110% |  6.924 |  5.901 |  8.643 |  7.910 |  5.064 |  6.212 |  6.617 |  6.431 |  5.914 |
| 120% |  1.512 |  1.780 |  3.449 |  2.732 |  1.066 |  1.601 |  2.830 |  2.746 |  2.187 |
| 130% |  0.344 |  0.419 |  1.454 |  0.765 |  0.076 |  0.492 |  1.336 |  1.007 |  0.882 |
| 140% |  0.019 |  0.079 |  0.349 |  0.077 |  0.018 |  0.084 |  0.424 |  0.358 |  0.300 |
| 150% |  0.001 |  0.014 |  0.091 |  0.006 |  0.001 |  0.023 |  0.163 |  0.102 |  0.103 |
| 160% |  0.000 |  0.001 |  0.005 |  0.002 |  0.000 |  0.002 |  0.035 |  0.036 |  0.025 |
| 170% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.006 |  0.005 |  0.005 |
| 180% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |  0.001 |  0.000 |
| ---- | ------ |  --- 7 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  80% | 67.922 | 63.019 | 59.700 | 61.358 | 63.740 | 63.525 | 48.731 | 51.069 | 53.904 |
|  90% | 52.045 | 48.114 | 45.093 | 46.050 | 47.873 | 47.795 | 35.112 | 37.118 | 39.348 |
| 100% | 38.218 | 31.246 | 33.097 | 32.830 | 32.301 | 34.092 | 25.051 | 24.625 | 25.820 |
| 110% | 23.400 | 17.473 | 21.107 | 21.873 | 18.835 | 19.504 | 15.385 | 14.997 | 15.775 |
| 120% | 11.159 |  9.020 | 10.803 | 10.849 |  8.886 |  8.928 |  8.120 |  8.162 |  8.504 |
| 130% |  4.807 |  3.897 |  5.992 |  4.860 |  3.490 |  3.574 |  4.703 |  4.199 |  4.294 |
| 140% |  1.187 |  1.164 |  2.434 |  1.750 |  1.348 |  1.214 |  2.204 |  2.013 |  1.311 |
| 150% |  0.270 |  0.202 |  0.970 |  0.602 |  0.396 |  0.320 |  1.004 |  0.707 |  0.443 |
| 160% |  0.025 |  0.020 |  0.198 |  0.162 |  0.073 |  0.031 |  0.277 |  0.209 |  0.156 |
| 170% |  0.000 |  0.003 |  0.001 |  0.002 |  0.002 |  0.006 |  0.045 |  0.044 |  0.058 |
| 180% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.001 |  0.015 |  0.015 |  0.015 |
| 190% |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |  0.005 |  0.002 |

Again, we see haste continue to perform well at the higher spike categories, but there isn’t a huge difference with previous data sets.  It still falls behind in the stochastic limit, and trails in isolated spots, but does a better job of reducing spikes overall than the other options.

Data – 350k Swings

Finally, our 25H boss:

Finisher = SH1, Boss Attack = 350k, data set smooth-10000-52

| Set: |   C/Ha |   C/Ma |   C/Av |  C/Bal |   C/HM |     Ha |  Avoid | Av/Mas | Mas/Av |
| mean |  0.397 |  0.382 |  0.373 |  0.383 |  0.386 |  0.385 |  0.343 |  0.351 |  0.362 |
|  std |  0.128 |  0.130 |  0.152 |  0.141 |  0.130 |  0.129 |  0.159 |  0.150 |  0.141 |
|   S% |  0.523 |  0.410 |  0.419 |  0.452 |  0.472 |  0.499 |  0.366 |  0.362 |  0.358 |
|   HP |   755k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |   755k |
|  nHP |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |  2.158 |
| ---- | ------ |  --- 2 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  30% | 54.184 | 57.816 | 50.504 | 54.584 | 57.929 | 52.341 | 45.553 | 51.635 | 54.312 |
|  40% | 48.931 | 43.293 | 45.537 | 48.438 | 47.393 | 46.907 | 40.798 | 41.732 | 41.059 |
|  50% | 22.808 | 28.980 | 23.253 | 24.346 | 26.366 | 20.853 | 20.356 | 23.287 | 25.939 |
|  60% | 15.162 | 15.085 | 16.635 | 17.418 | 15.120 | 13.183 | 14.506 | 15.113 | 14.394 |
|  70% | 11.912 |  8.926 | 13.651 |  7.842 |  7.404 | 11.136 | 12.303 |  8.761 |  9.103 |
|  80% |  0.161 |  1.459 |  0.999 |  0.695 |  0.506 |  0.146 |  1.126 |  1.175 |  1.483 |
|  90% |  0.127 |  0.418 |  0.844 |  0.546 |  0.348 |  0.143 |  0.990 |  0.982 |  0.639 |
| ---- | ------ |  --- 3 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  50% | 57.074 | 57.812 | 48.826 | 53.168 | 58.627 | 54.232 | 42.471 | 48.295 | 48.161 |
|  60% | 46.547 | 35.270 | 40.640 | 43.544 | 37.484 | 41.770 | 34.365 | 33.883 | 32.861 |
|  70% | 32.767 | 26.239 | 32.499 | 30.979 | 20.905 | 31.113 | 28.618 | 23.522 | 25.511 |
|  80% | 10.379 | 14.224 | 12.970 | 10.229 |  9.710 | 11.248 | 11.193 | 11.643 | 13.991 |
|  90% |  5.008 |  5.126 |  7.770 |  6.719 |  5.890 |  5.976 |  7.096 |  7.111 |  5.798 |
| 100% |  1.494 |  3.457 |  2.733 |  2.708 |  2.717 |  2.041 |  2.970 |  3.647 |  4.036 |
| 110% |  0.333 |  0.805 |  1.027 |  0.764 |  0.556 |  0.596 |  1.303 |  1.195 |  1.099 |
| 120% |  0.000 |  0.052 |  0.114 |  0.036 |  0.000 |  0.000 |  0.162 |  0.186 |  0.146 |
| 130% |  0.000 |  0.026 |  0.048 |  0.017 |  0.000 |  0.000 |  0.076 |  0.074 |  0.052 |
| ---- | ------ |  --- 4 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  70% | 59.217 | 54.900 | 54.673 | 57.632 | 53.989 | 57.008 | 48.098 | 47.227 | 50.113 |
|  80% | 40.377 | 40.341 | 37.417 | 37.736 | 38.705 | 37.945 | 31.175 | 32.140 | 36.523 |
|  90% | 30.866 | 21.198 | 27.995 | 27.665 | 27.966 | 28.556 | 22.937 | 23.090 | 19.457 |
| 100% | 13.576 | 12.627 | 14.346 | 16.291 | 14.281 | 11.201 | 12.021 | 13.097 | 10.900 |
| 110% |  8.694 |  5.762 |  9.495 |  8.043 |  8.025 |  7.142 |  7.949 |  6.898 |  6.312 |
| 120% |  5.019 |  2.807 |  5.585 |  2.410 |  2.977 |  3.928 |  4.458 |  3.110 |  3.561 |
| 130% |  0.489 |  1.368 |  1.098 |  1.254 |  1.459 |  0.585 |  1.345 |  1.720 |  1.976 |
| 140% |  0.263 |  0.429 |  0.690 |  0.357 |  0.352 |  0.385 |  0.920 |  0.782 |  0.782 |
| 150% |  0.009 |  0.092 |  0.102 |  0.086 |  0.057 |  0.030 |  0.204 |  0.202 |  0.170 |
| 160% |  0.006 |  0.044 |  0.087 |  0.068 |  0.038 |  0.028 |  0.181 |  0.177 |  0.110 |
| ---- | ------ |  --- 5 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
|  80% | 65.490 | 62.774 | 57.587 | 61.874 | 63.608 | 62.398 | 49.518 | 52.278 | 57.261 |
|  90% | 56.952 | 48.754 | 48.803 | 49.451 | 51.764 | 53.463 | 40.807 | 41.324 | 42.984 |
| 100% | 39.003 | 36.552 | 33.508 | 37.486 | 38.130 | 35.898 | 27.221 | 31.054 | 30.808 |
| 110% | 27.878 | 25.264 | 26.175 | 27.833 | 27.280 | 24.884 | 21.065 | 21.061 | 20.984 |
| 120% | 18.893 | 14.895 | 18.804 | 15.440 | 16.556 | 16.016 | 14.447 | 13.948 | 12.795 |
| 130% | 10.296 |  7.161 | 10.998 | 10.182 |  9.577 |  8.751 |  8.554 |  8.108 |  7.450 |
| 140% |  4.290 |  3.355 |  6.775 |  5.162 |  3.002 |  3.550 |  5.648 |  4.335 |  4.062 |
| 150% |  0.783 |  1.349 |  2.841 |  1.591 |  1.240 |  0.603 |  2.423 |  2.100 |  1.819 |
| 160% |  0.191 |  0.657 |  1.305 |  0.855 |  0.366 |  0.222 |  1.330 |  1.044 |  0.978 |
| 170% |  0.030 |  0.267 |  0.285 |  0.235 |  0.103 |  0.125 |  0.419 |  0.473 |  0.518 |
| 180% |  0.003 |  0.104 |  0.156 |  0.104 |  0.057 |  0.034 |  0.263 |  0.281 |  0.301 |
| 190% |  0.000 |  0.015 |  0.028 |  0.011 |  0.007 |  0.000 |  0.094 |  0.111 |  0.088 |
| 200% |  0.000 |  0.003 |  0.003 |  0.001 |  0.000 |  0.000 |  0.030 |  0.031 |  0.022 |
| ---- | ------ |  --- 6 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
| 100% | 63.532 | 58.136 | 52.739 | 58.916 | 61.791 | 59.520 | 43.661 | 49.346 | 50.626 |
| 110% | 51.860 | 46.531 | 44.403 | 50.157 | 49.884 | 47.543 | 36.245 | 37.720 | 38.793 |
| 120% | 40.761 | 35.198 | 34.973 | 33.654 | 35.808 | 36.376 | 27.296 | 28.500 | 29.747 |
| 130% | 29.361 | 23.450 | 26.015 | 25.456 | 25.301 | 25.646 | 20.029 | 19.633 | 20.487 |
| 140% | 20.548 | 14.873 | 18.660 | 18.012 | 14.284 | 18.427 | 14.605 | 13.646 | 13.831 |
| 150% |  8.730 |  8.894 | 11.042 |  9.770 |  7.942 |  8.419 |  8.660 |  8.185 |  8.265 |
| 160% |  5.244 |  4.011 |  7.239 |  5.430 |  4.020 |  5.141 |  5.703 |  5.331 |  4.196 |
| 170% |  2.411 |  1.779 |  3.834 |  2.763 |  1.053 |  2.296 |  3.101 |  2.500 |  2.371 |
| 180% |  0.483 |  0.637 |  1.808 |  1.282 |  0.511 |  0.688 |  1.701 |  1.438 |  1.123 |
| 190% |  0.265 |  0.242 |  0.989 |  0.197 |  0.067 |  0.381 |  0.964 |  0.667 |  0.584 |
| 200% |  0.004 |  0.081 |  0.190 |  0.079 |  0.016 |  0.043 |  0.296 |  0.313 |  0.281 |
| ---- | ------ |  --- 7 | Attack | Moving | Avg.-- | ------ | ------ | ------ | ------ |
| 120% | 61.023 | 57.190 | 51.807 | 54.107 | 57.313 | 57.034 | 41.765 | 45.130 | 48.563 |
| 130% | 50.736 | 44.161 | 43.401 | 44.980 | 47.764 | 46.326 | 34.243 | 34.933 | 37.238 |
| 140% | 41.940 | 31.846 | 34.947 | 37.077 | 34.785 | 38.072 | 27.156 | 27.042 | 27.614 |
| 150% | 28.043 | 22.872 | 24.477 | 26.571 | 25.060 | 24.928 | 18.812 | 18.451 | 19.944 |
| 160% | 18.939 | 14.241 | 18.328 | 17.192 | 15.452 | 15.934 | 13.799 | 13.304 | 12.601 |
| 170% | 12.203 |  9.027 | 12.248 | 10.905 |  9.212 |  9.447 |  9.056 |  8.053 |  8.848 |
| 180% |  6.625 |  4.665 |  7.329 |  7.161 |  5.257 |  4.806 |  5.649 |  5.165 |  5.066 |
| 190% |  2.948 |  2.272 |  4.421 |  3.007 |  2.739 |  2.313 |  3.694 |  3.177 |  2.467 |
| 200% |  1.079 |  1.138 |  2.061 |  1.529 |  1.395 |  1.141 |  1.834 |  1.837 |  1.281 |

As before, haste excels in the top 3 or 4 damage ranges in each category.  Not a whole lot of new information here either.  The most surprising part is that the bug didn’t seem to be overvaluing haste as much as I expected.  It may simply be that the bug wasn’t as problematic as it could have been due to other interactions that similarly affected the mastery set.  Or maybe I just over-estimated how much of an effect the bug had in the first place.

Let’s see if the stamina data has changed much.

Stamina Comparisons – Gear

We’re using the same five gear sets as the last post. C/Ha and C/Ma for our benchmarks, and then three stamina sets.  The first is the trinket conversion rate (4k haste for 6k stamina), the second is the gem conversion rate (4k haste for 3k stamina).  C/St3 just converts some of the 8000 haste of C/St2 into mastery.

|    Set: |  C/Ha | C/St1 | C/St2 | C/St3 |  C/Ma |
|     Str | 15000 | 15000 | 15000 | 15000 | 15000 |
|     Sta | 28000 | 34000 | 31000 | 31000 | 28000 |
|   Parry |  1500 |  1500 |  1500 |  1500 |  1500 |
|   Dodge |  1500 |  1500 |  1500 |  1500 |  1500 |
| Mastery |  1500 |  1500 |  1500 |  4750 | 13500 |
|     Hit |  2550 |  2550 |  2550 |  2550 |  2550 |
|     Exp |  5100 |  5100 |  5100 |  5100 |  5100 |
|   Haste | 12000 |  8000 |  8000 |  4750 |     0 |

Data – 150k Swings

Again, we’ll test our 10N boss first:

Finisher = SH1, Boss Attack = 150k, data set smooth-10000-56

| Set: |   C/Ha |  C/St1 |  C/St2 |  C/St3 |   C/Ma |
| mean |  0.371 |  0.397 |  0.397 |  0.391 |  0.362 |
|  std |  0.128 |  0.133 |  0.133 |  0.132 |  0.129 |
|   S% |  0.523 |  0.482 |  0.482 |  0.454 |  0.410 |
|   HP |   755k |   876k |   816k |   816k |   755k |
|  nHP |  5.034 |  5.843 |  5.439 |  5.439 |  5.034 |
|  has |  12000 |   8000 |   8000 |   4750 |      0 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  20% | 22.749 | 20.931 | 26.875 | 28.063 | 29.033 |
|  30% |  6.979 |  0.627 |  2.114 |  3.325 |  4.183 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  30% | 27.641 |  9.657 | 13.986 | 17.342 | 19.706 |
|  40% |  1.491 |  0.781 |  0.853 |  1.152 |  3.740 |
|  50% |  0.000 |  0.000 |  0.000 |  0.011 |  0.023 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  30% | 51.621 | 39.828 | 46.886 | 48.352 | 47.278 |
|  40% | 17.041 | 12.727 | 16.866 | 14.805 | 16.793 |
|  50% |  4.853 |  0.969 |  1.557 |  1.537 |  2.250 |
|  60% |  0.064 |  0.000 |  0.073 |  0.071 |  0.208 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  40% | 40.307 | 34.595 | 40.056 | 39.117 | 40.028 |
|  50% | 16.833 |  8.102 | 13.235 | 12.060 | 13.173 |
|  60% |  1.873 |  0.700 |  1.393 |  1.758 |  2.527 |
|  70% |  0.074 |  0.010 |  0.076 |  0.075 |  0.232 |
|  80% |  0.000 |  0.000 |  0.000 |  0.000 |  0.007 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  50% | 37.026 | 22.789 | 34.094 | 29.987 | 32.365 |
|  60% | 12.829 |  4.994 |  8.961 |  9.746 | 11.411 |
|  70% |  1.418 |  0.045 |  1.099 |  0.951 |  1.731 |
|  80% |  0.017 |  0.000 |  0.001 |  0.029 |  0.090 |
|  90% |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  50% | 55.902 | 44.770 | 55.480 | 52.236 | 52.989 |
|  60% | 30.812 | 18.308 | 27.914 | 26.135 | 26.232 |
|  70% |  9.193 |  3.293 |  8.847 |  7.201 |  8.632 |
|  80% |  2.270 |  0.199 |  1.557 |  1.063 |  1.203 |
|  90% |  0.081 |  0.001 |  0.104 |  0.007 |  0.076 |
| 100% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |

As before, stamina continues to come out ahead.  The trinket version (C/St1) shows a considerable margin, the gem version’s less so.  Both versions have seen their leads considerably lessened though.  We’re no longer seeing as many large order-of-magnitude gaps as before, though a few are still there.  Stamina shouldn’t have had any interaction with the bug, so this seems to confirm that we were overvaluing haste and mastery in the last few posts.

Data – 250k Swings

Finisher = SH1, Boss Attack = 250k, data set smooth-10000-55

| Set: |   C/Ha |  C/St1 |  C/St2 |  C/St3 |   C/Ma |
| mean |  0.389 |  0.415 |  0.415 |  0.407 |  0.376 |
|  std |  0.128 |  0.133 |  0.133 |  0.134 |  0.130 |
|   S% |  0.522 |  0.482 |  0.482 |  0.455 |  0.411 |
|   HP |   755k |   876k |   816k |   816k |   755k |
|  nHP |  3.021 |  3.506 |  3.263 |  3.263 |  3.021 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  30% | 44.835 | 27.844 | 47.965 | 48.519 | 39.834 |
|  40% | 16.695 | 16.685 | 19.379 | 20.753 | 18.229 |
|  50% |  6.928 |  0.627 |  2.096 |  3.128 |  4.911 |
|  60% |  0.147 |  0.000 |  0.466 |  0.730 |  0.751 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  40% | 49.074 | 49.012 | 50.430 | 51.822 | 39.107 |
|  50% | 29.299 |  9.782 | 14.358 | 18.038 | 22.977 |
|  60% |  6.939 |  2.851 |  7.055 |  8.487 | 10.796 |
|  70% |  1.529 |  0.795 |  0.848 |  1.119 |  3.533 |
|  80% |  0.306 |  0.000 |  0.000 |  0.042 |  0.626 |
|  90% |  0.000 |  0.000 |  0.000 |  0.013 |  0.042 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  50% | 56.611 | 43.105 | 47.910 | 51.596 | 52.273 |
|  60% | 33.395 | 22.972 | 34.675 | 34.049 | 30.926 |
|  70% | 16.869 |  9.358 | 13.501 | 14.602 | 12.670 |
|  80% |  8.617 |  1.583 |  3.025 |  3.463 |  4.923 |
|  90% |  1.115 |  0.292 |  0.967 |  1.144 |  1.731 |
| 100% |  0.268 |  0.000 |  0.066 |  0.117 |  0.433 |
| 110% |  0.007 |  0.000 |  0.000 |  0.000 |  0.072 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  60% | 59.442 | 48.023 | 59.659 | 58.173 | 55.535 |
|  70% | 40.213 | 32.244 | 38.413 | 38.677 | 36.919 |
|  80% | 27.083 | 12.842 | 23.219 | 20.973 | 21.773 |
|  90% | 11.140 |  2.939 |  9.958 |  9.575 |  9.918 |
| 100% |  4.097 |  0.759 |  2.364 |  2.304 |  3.380 |
| 110% |  0.298 |  0.071 |  0.233 |  0.387 |  0.955 |
| 120% |  0.028 |  0.000 |  0.038 |  0.089 |  0.281 |
| 130% |  0.002 |  0.000 |  0.000 |  0.000 |  0.045 |
| 140% |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
|  80% | 49.834 | 34.352 | 48.294 | 43.318 | 41.953 |
|  90% | 30.239 | 17.863 | 28.385 | 25.971 | 27.184 |
| 100% | 16.774 |  6.042 | 12.333 | 11.954 | 14.625 |
| 110% |  6.853 |  1.275 |  5.252 |  4.275 |  5.820 |
| 120% |  1.466 |  0.033 |  0.828 |  1.139 |  1.777 |
| 130% |  0.333 |  0.001 |  0.017 |  0.109 |  0.429 |
| 140% |  0.017 |  0.000 |  0.001 |  0.009 |  0.086 |
| 150% |  0.000 |  0.000 |  0.000 |  0.000 |  0.013 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
|  90% | 51.853 | 39.900 | 51.290 | 48.524 | 47.951 |
| 100% | 37.961 | 22.500 | 33.930 | 31.424 | 31.089 |
| 110% | 23.201 | 10.541 | 19.930 | 16.645 | 17.281 |
| 120% | 10.984 |  3.282 |  8.909 |  7.780 |  8.934 |
| 130% |  4.684 |  1.053 |  3.053 |  2.699 |  3.845 |
| 140% |  1.168 |  0.208 |  1.050 |  0.741 |  1.172 |
| 150% |  0.249 |  0.002 |  0.189 |  0.139 |  0.223 |
| 160% |  0.021 |  0.000 |  0.001 |  0.002 |  0.018 |
| 170% |  0.000 |  0.000 |  0.000 |  0.000 |  0.003 |

Again, a solid win for stamina, but at a much reduced lead, at least for gem swaps.    Trinket swaps are still a flat-out win by a large margin.

Data – 350k Swings

Finisher = SH1, Boss Attack = 350k, data set smooth-10000-51

| Set: |   C/Ha |  C/St1 |  C/St2 |  C/St3 |   C/Ma |
| mean |  0.398 |  0.422 |  0.422 |  0.413 |  0.383 |
|  std |  0.129 |  0.133 |  0.133 |  0.134 |  0.130 |
|   S% |  0.522 |  0.483 |  0.482 |  0.455 |  0.411 |
|   HP |   755k |   876k |   816k |   816k |   755k |
|  nHP |  2.158 |  2.504 |  2.331 |  2.331 |  2.158 |
| ---- |  --- 2 | Attack | Moving | Avg.-- | ------ |
|  40% | 49.022 | 40.344 | 48.450 | 48.483 | 43.319 |
|  50% | 22.900 | 19.886 | 26.298 | 28.645 | 29.060 |
|  60% | 15.323 | 15.355 | 17.130 | 16.479 | 15.022 |
|  70% | 12.052 |  0.613 |  2.084 |  3.072 |  8.893 |
|  80% |  0.161 |  0.000 |  0.619 |  0.712 |  1.453 |
|  90% |  0.131 |  0.000 |  0.000 |  0.000 |  0.403 |
| ---- |  --- 3 | Attack | Moving | Avg.-- | ------ |
|  60% | 46.718 | 39.737 | 49.339 | 40.739 | 35.243 |
|  70% | 32.919 | 13.398 | 14.730 | 17.745 | 26.191 |
|  80% | 10.503 |  6.912 |  9.690 | 10.376 | 14.237 |
|  90% |  5.178 |  0.838 |  2.989 |  3.719 |  5.121 |
| 100% |  1.525 |  0.759 |  0.860 |  1.085 |  3.465 |
| 110% |  0.353 |  0.000 |  0.000 |  0.039 |  0.795 |
| 120% |  0.000 |  0.000 |  0.000 |  0.016 |  0.055 |
| 130% |  0.000 |  0.000 |  0.000 |  0.000 |  0.032 |
| ---- |  --- 4 | Attack | Moving | Avg.-- | ------ |
|  70% | 59.459 | 46.700 | 51.823 | 51.213 | 54.834 |
|  80% | 40.727 | 32.743 | 39.771 | 38.545 | 40.335 |
|  90% | 31.198 | 17.590 | 26.492 | 21.848 | 21.237 |
| 100% | 13.789 |  9.362 | 13.329 | 14.323 | 12.595 |
| 110% |  8.843 |  2.703 |  8.292 |  3.881 |  5.795 |
| 120% |  5.101 |  0.924 |  1.630 |  1.940 |  2.796 |
| 130% |  0.499 |  0.063 |  0.968 |  0.557 |  1.380 |
| 140% |  0.278 |  0.052 |  0.066 |  0.111 |  0.436 |
| 150% |  0.009 |  0.000 |  0.052 |  0.087 |  0.080 |
| 160% |  0.007 |  0.000 |  0.000 |  0.000 |  0.034 |
| ---- |  --- 5 | Attack | Moving | Avg.-- | ------ |
|  90% | 57.303 | 42.564 | 53.495 | 47.479 | 48.820 |
| 100% | 39.424 | 32.256 | 38.364 | 38.293 | 36.630 |
| 110% | 28.273 | 17.653 | 28.107 | 23.406 | 25.308 |
| 120% | 19.148 |  8.624 | 16.206 | 14.246 | 14.852 |
| 130% | 10.426 |  2.628 |  8.215 |  5.924 |  7.099 |
| 140% |  4.357 |  0.796 |  2.640 |  2.318 |  3.398 |
| 150% |  0.804 |  0.177 |  0.910 |  1.249 |  1.339 |
| 160% |  0.215 |  0.039 |  0.183 |  0.197 |  0.630 |
| 170% |  0.034 |  0.000 |  0.037 |  0.081 |  0.258 |
| 180% |  0.005 |  0.000 |  0.007 |  0.018 |  0.108 |
| 190% |  0.001 |  0.000 |  0.000 |  0.001 |  0.014 |
| 200% |  0.000 |  0.000 |  0.000 |  0.000 |  0.002 |
| ---- |  --- 6 | Attack | Moving | Avg.-- | ------ |
| 110% | 52.349 | 39.300 | 52.428 | 46.700 | 46.664 |
| 120% | 41.139 | 27.819 | 38.181 | 34.191 | 35.300 |
| 130% | 29.689 | 13.639 | 27.188 | 21.015 | 23.417 |
| 140% | 20.845 |  7.252 | 13.596 | 12.826 | 14.926 |
| 150% |  8.896 |  2.891 |  8.533 |  7.673 |  8.858 |
| 160% |  5.392 |  0.779 |  2.896 |  2.209 |  3.968 |
| 170% |  2.504 |  0.041 |  0.828 |  1.089 |  1.733 |
| 180% |  0.507 |  0.002 |  0.039 |  0.231 |  0.631 |
| 190% |  0.280 |  0.000 |  0.013 |  0.066 |  0.240 |
| 200% |  0.006 |  0.000 |  0.002 |  0.007 |  0.074 |
| ---- |  --- 7 | Attack | Moving | Avg.-- | ------ |
| 130% | 51.289 | 36.460 | 49.677 | 44.510 | 44.160 |
| 140% | 42.462 | 24.666 | 36.270 | 32.524 | 31.861 |
| 150% | 28.426 | 14.059 | 26.602 | 23.477 | 22.944 |
| 160% | 19.249 |  8.613 | 16.063 | 12.465 | 14.234 |
| 170% | 12.436 |  3.379 |  8.884 |  7.693 |  9.014 |
| 180% |  6.783 |  1.510 |  5.022 |  4.267 |  4.707 |
| 190% |  3.008 |  0.491 |  1.891 |  1.533 |  2.233 |
| 200% |  1.099 |  0.132 |  0.827 |  0.692 |  1.112 |

I think we can still call this one for stamina, though there are a few areas where haste is catching up to the gem swap set.  Overall though, the stamina set still outperforms C/Ha. For every category in which they tie, there are 2-3 where stamina wins.  And we’re still seeing factors of 2 or more improvement in many areas.  But relatively few of the factors of 10 that we saw in earlier sims.

Conclusions

So, the bug in the code was definitely inflating the relative value of stamina compared to haste by undervaluing the latter.  I think it’s safe to say that stamina is still the survivability king, but it’s not as head-and-shoulders above haste as the earlier simulations made it seem.  It’s still the dominant choice for trinket slots though, secondary effects nonwithstanding.

And again, this entire comparison is based on purely physical boss throughput.  In practice, a decent chunk of fights contain non-trivial amounts of magical damage, which shifts the comparison much farther towards stamina.  And on top of that, stamina doesn’t take the same sort of micromanaging that it does to get the levels of performance we’re seeing out of haste with the SH1 queue.

That said, the gem trades are getting close enough that we’re not losing that much survivability by gemming haste.  It’s still a net loss, but experienced tanks might feel more comfortable making that trade for DPS knowing that the loss isn’t as severe as previously predicted.

Mel and I discussed this over e-mail, and I felt his insight was worth quoting:

I think the sim now underrates Stamina, though – I think healing effects and healer reactions (and just general all around quality as an oops-proof stat) give a somewhat larger edge to Stam for raw survival.  While the sim probably offers an upper-bound for the value of haste/mastery, given that it plays almost perfectly, it probably offers a lower bound for stamina’s value.

…..
I suspect fairly strongly that just allowing for some incidental healing will vastly inflate the value of stamina, and somewhat inflate haste and mastery.

I think he’s probably correct in that prediction.  Apart from the differential benefits that the bug was introducing between the different secondary stats, which was a relatively small effect, the majority of what the bug did was introduce a chunk of excess passive absorption, which is basically how we’d model incidental healing.  It seems quite likely that if we implemented a passive, “dumb healer” that just cast Power Word: Shield or Renew on the tank, stamina would leap out ahead again like it did in previous sims.

Which is enough of a motivator that I think I need to buckle down and implement the one mechanic I’ve been avoiding for quite some time: Seal of Insight.  I’ve been avoiding it for a few reasons.  It will be time consuming to implement and bug-check, for starters.  And I expect it to be a large performance hit – the code will probably run about two times slower, maybe more, with the addition of melee swing tracking and another short-term buff.  And there are still a lot of unanswered questions about how to properly model the benefits of SoI.  But it’s exactly the sort of “dumb healing” that Mel wants, with the caveat that it scales with our haste as well.  The common-sense assumption is that SoI healing will inflate haste’s value, but the “dumb healing” aspect may very well provide a stronger benefit to stamina than haste.

Luckily, Weeby and I have had some good discussions in the comments that have given me a good idea how to model it effectively.  I’m still not looking forward to it, but at this point it’s one of the last puzzle pieces, and it really needs to be put in.

Before I get to that (and partly to buy myself some time to do it), I do have two more analyses I want to do with the current code, looking at haste->mastery and haste->stamina trades in finer detail.  And I still have the T15 4-piece to test now that it’s implemented.  So there’s plenty of stuff I can be simulating and posting about while I work on the new code.