Theorycraft 201: Advanced RPPM

This is a continuation of my Theorycraft 101 post that introduced trinket uptimes and RPPM. I’m going to assume here that you read that post. The main audience for this post is people trying to any theorycraft work, whether making a full-blown spreadsheet or simply doing a standalone calculation about some trinket. You should be able to find the equation you need here without needing to redo a lot of work.

A bit of terminology from last time:

  • PPM is the proc’s built-in PPM constant.
  • H is your haste factor (1 + your average haste %)
  • D (used below) will be the duration of a buff

Our first basic conclusion was that if you ignore the possibility of proc overlaps, the uptime of a proc is:

PPM cdot D cdot H / 60

We called this value lambda  (lambda) for any given trinket. It’s a good approximation of uptime as long as uptime is low (overlaps are unlikely), and it will also come into many later results. Conceptually, lambda  is the ratio of the buff’s duration to its mean proc time.

The next conclusion was that if you account for the possibility of overlaps, the uptime is:

1 - e^{-lambda}

Seeing how uptime (y) relates to lambda (x) is helpful. In the low range, they’re mostly the same (the curve approximates the y=x line). As lambda increases, overlaps becomes more important and uptime starts to slow down in its asymptotic approach to 1.

Today we’re going to see how this is modified in a few different scenarios.

The “Bad Luck” Correction

In the prior post I commented that the RPPM system was not a correction to increase your proc chance. But they recently added just such a correction in the case of trinkets (for now I won’t discuss why they might have done so). It kicks in anytime you haven’t had a proc for more that 1.5 times your mean proc time, and begins to rapidly increase proc chance. Specifically, from that point on, every 1% of MPT that passes increases proc chance by 3%. I’m not going to walk through in detail a calculation of how much this increases overall proc rate–it’s somewhat tedious and the focus of this post is on the results more than the derivation (and I don’t feel like LaTeX-ing the whole thing). I’ll include my original calculation in an appendix.

Here’s a graph comparing the two:


(Wolfram link for reference)

The x-axis is time, in units of mean proc time. The y-axis is the chance that your next proc will come at a particular time after the previous proc. As you can see, the two are identical until x=1.5, and then the new system (purple line) gives a burst of added proc chance that drastically shortens the tail of the curve.

Estimating the new MPT requires finding an equation for the new probability curve and integrating it (see appendix).  In general, what I computed is that, once the boost kicks in, the expected proc time is roughly half (48%) of what it would have been otherwise. Since you only reach that point 22.3% (e^(-1.5)) of the time all in all the average wait for each proc is reduced to 88.4% of what it was, or 13.1% more procs over a given time.

The Effect on Uptime

In the low-uptime case, where we can approximate uptime with  lambda , then we would now simply take it to be  1.13lambda . Unfortunately, to account for overlaps, we can’t simply multiply lambda  by 1.13 in the above formula. This implicitly assumes two events are independent (overlaps, and activation of the boost) when they’re definitely not. In fact, application of the boost can never cause an overlap unless  lambda > 1.5 “> (which is far beyond the uptime range of any real trinket).</p>

<p>The correct model, fortunately, is even simpler. Multiply the previous uptime (including overlaps and all) by 1.13. After all, those 13% new procs have to happen somewhere, and they can’t contribute to overlaps:</p>

<figure class=1.13cdot (1 - e^{-lambda})

If the equation bothers you because it’s not manifestly limited to 1 as an uptime should be, remember that it’s expressly valid only for  lambda < 1.5  (and in that range it reaches roughly 88%). Essentially, what this is model is saying is that everything is happening as it was before, including overlaps, but total proc events are going to happen 13% more often.

Stacking Trinkets

Trinkets like Talisman of Bloodlust and Horridon’s Last Gasp have an added twist–on a repeat proc, they don’t simply overlap and refresh the prior buff, but also add another stack (up to 5). This makes the math more complex but still manageable.

Recall the logic of the main uptime formula from the prior post. In a Poisson or similar process, at any given moment, the chance of not having had an event in the past unit time is  e^{-lambda} .

But now in the (1-e^{-lambda})  case where our buff us up because we have had a recent proc, we need further information: was the buff already up when this proc started? Well, the answer is the same–it was up (1-e^{-lambda})  of the time. The memory-less nature of Poisson processes is key here–the answer to that question is the same no matter when you ask it (we’ve not accounted for the boost yet, but remember that it cannnot affect stacks or overlaps as long as lambda < 1.5 ).

So at any given moment, the chance that we have at least one stack is 1-e^{-lambda} , same as always. The chance that we’ll have at least two stacks is:


From here it’s easy to see the chance of having at least k stacks at a given moment. To find the overall average stack height (which gives our actual buff contribution), we need to sum all those components up to the maximum number of stacks, N:

sum_{k=1}^N (1-e^{-lambda})^k

Recalling the partial sum of a geometric series:

sum_{k=1}^N r^k = frac{r(1-r^N)}{1-r}

In our case:

sum_{k=1}^N (1-e^{-lambda})^k = frac{(1-e^{-lambda})(1-(1-e^{-lambda})^N)}{1-(1-e^{-lambda})}
= (e^{lambda} - 1)(1-(1-e^{-lambda})^N)

This should be a clean formula you can use to find your average weighted uptime on a stacking trinket. As in the non-stacking case, to account for the bad-luck boost, simply multiply the entire thing by 1.13.

1.13(e^{lambda} - 1)(1-(1-e^{-lambda})^N)

A complication not addressed here is that Talisman of Bloodlust itself adds haste, which changes the proc frequency slightly at each iteration. This is better handled in a simulation, but if you wanted to write it down as formula you could break the sum back out into 5 individual terms and independently compute lambda for all of them.

ICD trinkets

A lot of people ask how to correctly model trinkets like Wushoolay’s Final Choice (22 second ICD). This family of trinkets uses RPPM, but has an ICD anyway because their mechanics would be too messy if they allowed overlap procs. In this case, the mean proc time, instead of simply being 60/(PPM*H), should be:

frac{60}{PPMcdot H} + ICD - 10

The -10 is due to the fact that the RPPM system accumulates proc chance for up to 10 seconds. So on your first attack after the ICD runs, you get the benefit of 10 seconds worth of stored-up proc chance.

Since these trinkets do not allow overlaps, the uptime is simply the duration over the MPT:

frac{D}{frac{60}{PPMcdot H} + ICD - 10}

Finally, the boost. Though there’s no firm confirmation on this, I’ll assume here that the time during the ICD does count as a time of no procs for purposes of the boost (this would be consistent with the treatment of the usual 10-second RPPM pool). In that case, you can simply increase overall mean uptime by 1.13 as usual:

frac{1.13D}{frac{60}{PPMcdot H} + ICD - 10}

Unerring Vision

A note on Unerring Vision of Lei Shen. Even though the nominal uptime of this proc is 4 seconds, the actual benefit lies in a set of DoTs with 100% crit rate that lasts long after the proc is over (it has little use unless you make use of this DoT effect). If it reprocs while the previous set of buffeds DoTs is still up, you’re going to clip them with new buffed DoTs. So for overlap purposes, the “duration” and “uptime” of UVLS are really analyzed with reference to the DoTs it produces, not the 4s proc itself. Keep this in mind when theorycrafting the trinket.

Beginning of an Encounter

Finally, one less technical discussion, about the beginning of a fight. When the RPPM system was first introduced, one important ramification of its time-independent nature was that you no longer got the reliable fast proc that ICD-based trinkets produced at the beginning of every encounter. But the “boost” reverts this change for most part, since you’ve necessarily been out of combat and not gotten a proc for a few minutes.

With high-frequency trinkets like the 3.3 RPPM melee trinkets, mean proc time may be 15 seconds or lower with some haste. At that frequency (say it’s exactly 15 seconds), after only 25 seconds out of combat, you’re guaranteed a proc on the first swing of the fight. (You’d normally have a 2/3 chance to proc on that swing, since you’ve pooled 10 seconds out of an MPT of 15, and having “failed” to proc for 1.67 MPT’s gives a further 50% boost.

On the flip side, if you’re a UVLS user with an MPT of 2 minutes, then after a typical 2-minute runback and reset the boost will not have kicked in at all. The 2 minutes still matter because you’ll start getting a boost if you fail to proc by one minute into the fight, but that doesn’t help you get a proc during your initial timer stack. Even if you’ve been out of combat (or not had a proc) for 5 minutes (2.5 MPTs), the 4x increase to proc rate as you start the fight still only means you start the fight with an effect MPT of 30 seconds, which is not a crisp start you can plan on. Only after you’ve been out of combat for roughly 10 minutes (5 MPTs) does the whopping 11.5x increase in proc rate mean that you can expect a proc in the first 10 seconds (which is great benefit, as you can now save timers for it). Now, this is a worst case–most people even with trinkets in the 0.5 RPPM range (say Breath of the Hydra) will have an MPT somewhat under 2 minutes due to haste. But point still remains that people with low-frequency trinkets can get a marginal benefit by avoiding using them for up to many minutes before an important pull.

As a general matter, the amount of time you need to have spent without a proc in order to guarantee a proc on the first hit of a fight is:

frac{MPTcdot (MPT+35)}{30}

Where MPT is your usual mean proc time in seconds (60/PPM*H), so this could be also be written as:

frac{120}{(PPMcdot H)^2} + frac{70}{PPMcdot H}

Remember that H should be your haste with no procs or temp buffs active, as it will be on the first attack of a fight. Note that the result is quadratic in MPT, which explains why some trinkets get it so easily and some have to wait so much longer.


This is where I first worked out the effect of the boost. I added a few notes at the bottom to try to make it understandable. Time is measured using the variable tau, which is a dimensionless time variable scaled so that MPT=1. The first task was writing the probability function P(tau) when the boost is present (for now assuming that it starts at tau=0), which was done with the differential equation involving Q(tau) (the cumulative chance of not having a proc by time tau). Then I integrate that new probability function to finds its mean (the 0.48 I mentioned earlier). All that’s left is to account for the fact that the boost doesn’t kick in until tau=1.5 by properly averaging the old and new functions together.

Scanned Doc