In the past week or two, I’ve been requesting data sets from beta in order to work out the new diminishing returns formulas in Mists of Pandaria. Last week I successfully nailed down the last few pieces of the puzzle and posted the results on maintankadin. However, it makes sense to put these results somewhere more visible so that it’s easier to find them (a random thread on maintankadin is a little harder to remember than “Theck’s blog”). So this week, I’ll be re-posting the results here.

I started out with a very nice data set provided by Klaudandus at maintankadin, covering a pretty wide range of strength, parry, and dodge rating. I managed to get a pretty decent fit with the dodge rating data, but I had trouble getting anything conclusive out of the parry data. Part of the problem was that despite the wide range of strength and parry *rating*, the data only covers a limited range of parry *percentage* – the max was around 16%. The other part of the problem was based on an assumption I made early on. Initially, I assumed that the parry cap would be reasonably close to what it is now. But the near-linearity of the data set contradicted that – either some portion of it wasn’t affected by DR (i.e. str->parry), or the cap was a lot higher than I was expecting. And it was nearly impossible to get good fitting values out of it as a result – there were simply too many free parameters to nail any of them down accurately.

I ended up determining that the linearity was due to the parry cap. The dodge cap is, as far as I can tell, unchanged from Cata (around 65.5%). But the parry cap has increased to around **235%**. Since that sounds sort of crazy, I’ll provide the methodology and data I used to come to that conclusion (“so here’s my numbers, call me on any mistakes maybe”).

All of the data and curve-fitting calculations are available here, for those with MATLAB: dr_eqn_data_L85.m

I have not tested this file with Octave/FreeMat, but I didn’t use anything fancier than fit() calls.

**Background on Diminishing Returns
**

The traditional form of the diminishing returns equation is

$\Large \frac{1}{\rm postAvoid} = \frac{1}{C}+\frac{k}{\rm preAvoid}$

where ${\rm postAvoid}$ is the post-DR avoidance gained from ${\rm preAvoid}$ pre-DR avoidance. In other words, if your dodge tooltip says “$X$ dodge rating gives you $Y$% avoidance before diminishing returns,” ${\rm preAvoid}=Y$ and ${\rm postAvoid}$ is the amount of dodge you actually gain on the character sheet. $C$ and $k$ are the constants that govern how quickly avoidance diminishes.

$k$ scales the pre-DR avoidance value; since $k=0.956$ in Cataclysm, we actually get slightly more than 1% post-DR avoidance from the first 1% of pre-DR avoidance (but past that point, diminishing returns has kicked in enough to eliminate this advantage). Another way to think of this is that $k$ scales the horizontal axis of the DR curve, by turning 1% pre-DR avoidance into $(1/k)$%. As long as $k<1$, this scaling is in our favor, and the lower it is the more it favors us. Alternatively, you could think of $k$ as a modifier on the rating-to-percentage conversion factor; instead of taking 176ish dodge rating to get 1% avoidance, we really only need $176*k$, which is a little less.

$C$ is the avoidance cap. This isn’t the same type of “cap” as the hit- or expertise-caps, nor is it the same type as the “block cap” (or full “Combat Table Coverage”). It’s not a discontinuous point at which avoidance stops working. It’s the asymptotic value that ${\rm postAvoid}$ approaches at very high avoidance values. It’s pretty clear how this works if you consider an example: what happens if you have infinite pre-DR avoidance?

$\large \frac{1}{\rm postAvoid} = \frac{1}{C}+\frac{k}{\infty} = \frac{1}{C}$

${\rm postAvoid} = C$

Thus, $C$ is the degree of freedom that has the biggest effect on diminishing returns. A very low value of $C$ will mean very harsh diminishing returns that kick in very early. Conversely, a very high value of $C$ will mean very light diminishing returns and increase the region over which the curve looks linear. Foreshadowing a bit, we’ll see that this is why the level 90 data was so hard to fit. The parry cap (which we’ll call $C_p$ so we can keep it distinct from the dodge cap $C_d$) was increased significantly, making everything look pretty linear at the levels of parry we were able to achieve with beta gear. The value of $C$ in Cataclysm is the same for both dodge and parry, around 65.6%.

The avoidance values given on your character sheet include base avoidance:

${\rm totalAvoid} = {\rm baseAvoid} + {\rm postAvoid}$

So for example, if you have 5% base dodge and 7.25% post-DR dodge from rating, your character sheet reads 12.25%.

**Testing**

The first thing I did was hop onto beta and make a new pre-made 85 human paladin. The problem with testing diminishing returns at 90 is that we don’t have enough gear to climb the parry curve very far. But the relative gear level is much higher on an 85 pre-made, which lets us push the boundaries further and produce better curve fits. If I had been thinking clearly, I’d have transferred another copy of Theck to push things even higher. Oops. In any event, the 85 pre-made managed to do the job.

The procedure was as follows. I first stripped the pre-made of all gear and recorded all of the base values of interest: strength, agi, dodge, and parry. I then equipped one piece of gear at a time, recording the new strength, agi, total dodge percentage, total parry percentage, dodge rating, pre-DR dodge percentage due to that rating (from the tooltip), parry rating, and pre-DR parry percentage due to that rating. After equipping all gear, I started to gem and enchant it one piece at a time, using STR and/or dodge enchants and parry gems. I then stripped the character again and repeated the process with ret gear to test strength scaling independently, this time using STR gems/enchants to keep parry/dodge rating at zero. At no point during this process did I cast any spells – all of these values are completely unbuffed. The data from this test is summarized in the table below:

Level 85 human paladin baseStr=164 baseDodge=3.01 baseParry=3.67 baseAgi=97 Protection gear: Total % pre-DR Dodge pre-DR Parry STR AGI Dodge Parry Rating Pct Rating Pct 510.00 97.00 3.01 6.35 0.00 0.00 260.00 0.98 737.00 97.00 3.01 7.91 0.00 0.00 389.00 1.47 1018.00 97.00 3.72 9.99 169.00 0.64 595.00 2.24 1244.00 97.00 3.72 11.64 169.00 0.64 760.00 2.87 1610.00 97.00 4.78 13.21 427.00 1.61 760.00 2.87 1817.00 97.00 4.78 14.67 427.00 1.61 909.00 3.43 2098.00 97.00 5.62 15.85 638.00 2.41 909.00 3.43 2308.00 97.00 5.62 16.72 638.00 2.41 909.00 3.43 2674.00 97.00 6.51 19.20 868.00 3.27 1172.00 4.42 2884.00 97.00 7.57 20.05 1150.00 4.34 1172.00 4.42 3057.00 97.00 8.40 20.74 1377.00 5.19 1172.00 4.42 3284.00 97.00 8.93 21.65 1525.00 5.75 1172.00 4.42 3459.00 97.00 9.37 22.34 1651.00 6.23 1172.00 4.42 3606.00 97.00 9.88 23.46 1799.00 6.79 1326.00 5.00 3606.00 97.00 9.88 23.70 1799.00 6.79 1393.00 5.26 3606.00 97.00 9.88 23.94 1799.00 6.79 1460.00 5.51 3606.00 97.00 9.88 24.18 1799.00 6.79 1527.00 5.76 3606.00 97.00 9.88 24.32 1799.00 6.79 1567.00 5.91 3606.00 97.00 9.88 24.47 1799.00 6.79 1607.00 6.06 3606.00 97.00 9.88 24.61 1799.00 6.79 1647.00 6.21 3606.00 97.00 9.88 24.75 1799.00 6.79 1687.00 6.36 3606.00 97.00 9.88 24.89 1799.00 6.79 1727.00 6.52 3606.00 97.00 9.88 25.03 1799.00 6.79 1767.00 6.67 3606.00 97.00 9.88 25.17 1799.00 6.79 1807.00 6.82 3606.00 97.00 9.88 25.31 1799.00 6.79 1847.00 6.97 3606.00 97.00 9.88 25.45 1799.00 6.79 1887.00 7.12 3989.00 97.00 9.88 26.91 1799.00 6.79 1887.00 7.12 3989.00 97.00 9.96 26.91 1824.00 6.88 1887.00 7.12 3989.00 97.00 10.13 26.91 1874.00 7.07 1887.00 7.12 4039.00 97.00 10.13 27.10 1874.00 7.07 1887.00 7.12 4039.00 97.00 10.43 27.10 1960.00 7.39 1887.00 7.12 4039.00 97.00 10.65 27.10 2026.00 7.64 1887.00 7.12 4039.00 97.00 10.82 27.10 2077.00 7.84 1887.00 7.12 4039.00 97.00 10.82 27.43 2077.00 7.84 1984.00 7.48 4039.00 97.00 10.99 27.43 2130.00 8.04 1984.00 7.48 4039.00 97.00 10.99 27.64 2130.00 8.04 2046.00 7.72 4039.00 97.00 10.99 27.83 2130.00 8.04 2099.00 7.92 4039.00 97.00 10.99 28.04 2130.00 8.04 2160.00 8.15 4039.00 97.00 10.99 28.19 2130.00 8.04 2206.00 8.32 4039.00 97.00 10.99 28.40 2130.00 8.04 2267.00 8.55 4039.00 97.00 10.99 28.53 2130.00 8.04 2306.00 8.70 Retribution Gear: Total % pre-DR Dodge pre-DR Parry STR AGI Dodge Parry Rating Pct Rating Pct 510.00 97.00 3.01 5.27 0.00 0.00 0.00 0.00 737.00 97.00 3.01 6.30 0.00 0.00 0.00 0.00 1018.00 97.00 3.01 7.57 0.00 0.00 0.00 0.00 1244.00 97.00 3.01 8.57 0.00 0.00 0.00 0.00 1610.00 97.00 3.01 10.19 0.00 0.00 0.00 0.00 1837.00 97.00 3.01 11.18 0.00 0.00 0.00 0.00 2118.00 97.00 3.01 12.39 0.00 0.00 0.00 0.00 2399.00 97.00 3.01 13.60 0.00 0.00 0.00 0.00 2765.00 97.00 3.01 15.14 0.00 0.00 0.00 0.00 3047.00 97.00 3.01 16.32 0.00 0.00 0.00 0.00 3274.00 97.00 3.01 17.26 0.00 0.00 0.00 0.00 3501.00 97.00 3.01 18.19 0.00 0.00 0.00 0.00 3884.00 97.00 3.01 19.74 0.00 0.00 0.00 0.00 4292.00 97.00 3.01 21.37 0.00 0.00 0.00 0.00 4359.00 97.00 3.01 21.64 0.00 0.00 0.00 0.00 4426.00 97.00 3.01 21.90 0.00 0.00 0.00 0.00 4493.00 97.00 3.01 22.17 0.00 0.00 0.00 0.00 4533.00 97.00 3.01 22.32 0.00 0.00 0.00 0.00 4573.00 97.00 3.01 22.48 0.00 0.00 0.00 0.00 4613.00 97.00 3.01 22.64 0.00 0.00 0.00 0.00 4653.00 97.00 3.01 22.79 0.00 0.00 0.00 0.00 4693.00 97.00 3.01 22.95 0.00 0.00 0.00 0.00 4743.00 97.00 3.01 23.15 0.00 0.00 0.00 0.00 4793.00 97.00 3.01 23.33 0.00 0.00 0.00 0.00 4843.00 97.00 3.01 23.54 0.00 0.00 0.00 0.00 4893.00 97.00 3.01 23.73 0.00 0.00 0.00 0.00

**Analysis – Dodge**

First, I analyzed the dodge data, since that’s the simplest. I already knew that it was pretty close to what we have on live based on Klaud’s L90 data. I used the usual DR formula:

$\large {\rm totalDodge} = {\rm baseDodge} +\left (\frac{1}{C}+\frac{k}{\rm preDodge}\right )^{-1},$

where ${\rm totalDodge}$ and ${\rm preDodge}$ are the values from the table, ${\rm baseDodge}$ is the 3.01% recorded initially, and $C$ and $k$ are the dodge cap and scale factor, respectively. $C$ and $k$ are the variables we’re trying to find, of course. Using MATLAB’s nonlinear least squares fitting algorithm to fit ${\rm netDodge} = {\rm totalDodge}-{\rm baseDodge}$, I get the following results:

d2_try1_fit = General model: d2_try1_fit(x) = 1./(1./C+k./x) Coefficients (with 95% confidence bounds): C = 66.01 (65.28, 66.74) k = 0.8854 (0.8842, 0.8866) d2_try1_gof =sse: 4.7067e-004 rsquare: 1.0000 dfe: 39 adjrsquare: 1.0000 rmse: 0.0035

You can see that the fit is very good – $R^2$ value of one (high coefficient of determination), very small SSE (sum of squares due to error) and RMSE (root-mean-square error). One curious note is that the 95% confidence interval for $C$ includes the current value (65.631440). It’s unlikely they’d tweak the cap value by less than 1%, as it would make very little difference to tank balance. Based on this, I guessed that the dodge cap is in fact unchanged from Cataclysm. So I decided to try fixing $C$ at the Cataclysm value to get a tighter bounding range on $k$:

d2_try2_fit = General model: d2_try2_fit(x) = 1./(1./65.631440+k./x) Coefficients (with 95% confidence bounds): k = 0.8848 (0.8846, 0.885) d2_try2_gof =sse: 4.8415e-004 rsquare: 1.0000 dfe: 40 adjrsquare: 1.0000 rmse: 0.0035

Or, graphically

It’s not surprising that this second fit works just as well, given that we chose to fix $C$ at a value that falls within the confidence interval. And from this data, we can’t be certain that $C$ hasn’t changed slightly, thus throwing off our estimate of $k$ slightly. But intuition strongly suggests we’re right, and if $k$ ends up at the same value for parry (as is the case in Cataclysm), that’s further evidence that we’re correct.

To summarize our conclusions and assumptions from this part:

**Conclusion #1:** The dodge cap ($C_d$) at 85 is very close to the Cataclysm value, but the scale factor ($k_d$) has been reduced slightly.

**Assumption #1:** The dodge cap at 85 is identical to the Cataclysm value, since it falls within experimental error of the value measured. We thus assume $C_d = 65.631440.$

**Assumption #2**: Based on assumption #1, the scale factor has been reduced from $k_d =0.956$ in Cataclysm to $k_d =0.885$ in Mists.

**Analysis – Parry**

Next, I decided to fit the retribution data. Since we’re scaling only with strength, this should tell us very clearly whether the parry granted through strength is affected by diminishing returns, and if so, what the formula looks like. Traditionally the effects granted by base stats aren’t affected by DR, so we’re actually going to fit the following values:

${\rm netParry} = {\rm totalParry}-{\rm baseParry}$

${\rm netStr} = {\rm totalStr}-{\rm baseStr}$

using a slightly-modified form of the DR equation:

$\large {\rm netParry} = \left ( \frac{1}{C}+\frac{k}{{\rm netStr}/a} \right )^{-1}.$

In other words, we’re using the usual DR equation, but this time with an additional scale factor $a$ representing the strength-to-parry conversion. You may note that there’s a redundancy in this formula, because $k$ and $a$ aren’t independently measurable. From the data though, it’s clear that it takes between ~216 and ~236 strength to add 1% parry post-DR, so that gives us a rough starting point for $a$. Note that since $k$ is less than one, the actual value of $a$ will be a little higher than our starting point (as I said earlier, smaller $k$ makes rating/strength more effective than the usual pre-DR conversion rate). If we fit the data with this in mind, we get:

p1_try1_fit = General model: p1_try1_fit(x) = 1./(1./C+k./(x./a)) Coefficients (with 95% confidence bounds): C = 235.1 (233.1, 237.1) a = 259.8 (-3.907e+006, 3.908e+006) k = 0.83 (-1.248e+004, 1.248e+004) p1_try1_gof =sse: 3.6086e-004 rsquare: 1.0000 dfe: 23 adjrsquare: 1.0000 rmse: 0.0040

Again, excellent agreement. The huge ranges on $a$ and $k$ reflect the fact that those two values can’t be determined independently this way (more on that in a second though). However, I noted that the fit puts $k$ very close to the value found in the dodge fit. We know that $k$ is the same for dodge and parry in Cataclysm, and was the same for both in Wrath even when the two had different caps. It’s not much of a stretch to guess that $k_p = k_d$ in Mists as well. To confirm this, we try the fit again fixing $k_p=k_d=0.885$:

p1_try2_fit = General model: p1_try2_fit(x) = 1./(1./C+0.885./(x./a)) Coefficients (with 95% confidence bounds): C = 235.1 (233.4, 236.8) a = 243.7 (243.5, 243.8) p1_try2_gof =sse: 3.6086e-004 rsquare: 1.0000 dfe: 24 adjrsquare: 1.0000 rmse: 0.0039

That seems reasonable, but how do we convince ourselves that this combination of k and a is any more valid than another combination? The answer is base parry. While naked, we should have about 3% parry plus the parry generated from base strength. A quick calculation shows:

${\rm baseStr}/243.7 = 0.6730$

which is 0.67 when rounded, consistent with our ${\rm baseParry}$ value of 3.67. The ${\rm baseParry}$ calculation is only so accurate though – due to rounding, ${\rm baseStr}$ gives 0.67% parry for any value of $a$ between 243 and 246.6. But the curve fitting puts a tighter bound on $a$ (233.4 to 236.8). If we perform one final fit to this data, fixing $a=243.7$, we get a slightly tighter range of values for $C$:

p1_try3_fit = General model: p1_try3_fit(x) = 1./(1./C+0.885./(x./243.7)) Coefficients (with 95% confidence bounds): C = 235.5 (235.2, 235.9) p1_try3_gof =sse: 3.6493e-004 rsquare: 1.0000 dfe: 25 adjrsquare: 1.0000 rmse: 0.0038

Or again, graphically:

At this point I stopped looking at the level 85 data and returned to Klaud’s level 90 data set. I could of course try to perform a multi-dimensional fit to the level 85 parry data from prot gear, which has both strength and parry rating, but I decided this wasn’t necessary for the level 85 data. I had gotten what I needed from the 85 data, which was information about $C_d$, $k_d$, $C_p$, $k_p$, and the fact that parry gained through strength is definitely affected by diminishing returns. What remained was to determine whether any of those values changed with character level, and that would only be determined by looking at the L90 data.

To summarize the assumptions and conclusions in this part:

**Assumption #1**: $k_d=k_p$.

**Conclusion #1**: Assuming $k_d=k_p$ gives us a good fit with a value of $a$ that is consistent with the amount of parry gained from base strength. This suggests that assumption #1 is correct, as are the assumptions made in the dodge analysis.

**Conclusion #2**: Under the assumption that $k_d=k_p$, $C_p$ is around **235%**.

In the next post (Wednesday), I’ll provide the level 90 data set and curve-fitting analysis that leads me to the final Diminishing Returns formula (of course, if you’re impatient, you can look at the Maintankadin link, but I’m going to clean up the presentation a bit for the blog and try and give a little more commentary on the analysis).

Pingback: Avoidance Diminishing Returns in MoP – Part 2 | Sacred Duty

Pingback: Avoidance Diminishing Returns in MoP – Part 3 | Sacred Duty

Pingback: [Prot 5.0 Beta] - Code Monkey - Page 3 - Elitist Jerks

First of all thanks for these 3 parts, extremely interesting.

I have one simple question. Why did you prefer to express the diminishing returns equation as

1 / postAvoid = 1 / C + k / preAvoid

which consequently became

(1 / postAvoid = 1 / C + k / preAvoid)^-1

instead of simply putting it like

postAvoid = C + preAvoid / k

Thanks a lot,

Roberto

Ummm nevermind my previous comment 😉

Pingback: TC401: Avoidance Diminishing Returns in WoD | Sacred Duty