View RSS Feed

Blogenstein

Theorycrafting 101: Haste Part 2 - DoTs and HoTs Math

Rating: 3 votes, 5.00 average.
The math behind how haste effects damage & healing over time is complicated. Working out the number of ticks from a given amount of haste is fairly straightforward, but reverse calculating the break points for additional ticks is a bit more complicated.

Before we get started, some history on how we arrived at the current mechanics. Back in July 2011 Hamlet posted a Theorycraft 101 post on Haste Breakponts & Rounding. Comments started to come in with occasional observed values that didnít quite match the breakpoints his calculations produced. A bit of investigation produced a new post in which it was discovered that ďBankerís RoundingĒ or Round Half to Even was being used to calculate the number of ticks. The problem with reading those entries is that the LaTeX plugin on ElitistJerks is currently (as of this post, at least) not working, so it makes it a bit hard to follow the math.

Precursor: Haste Rating to Percentages
Before we begin, Iíll review how your total haste percentage is calculated, as this will be used in reverse in the breakpoint section. The formula goes like this:
Code:
TotalHastePercentage = ( 1 + ( hasterating / 42500 ) * (1 + hastebuff1 ) * (1 + hastebuff2 )  - 1
The first part is your total haste rating, divided by the conversion factor at level 90 which is 425, and divided again by 100 to convert it into a percentage. Then all %-based haste effects have 1 added to them and are multiplied in. Note that this applies to all haste buffs, not just two as mentioned in the above formula. Once that is done, subtract 1 to return it to a normal percentage.

Forward Calculating: Tick Count from Haste
Now on to the forward calculation, where we go from a total haste value as calculated above, to a number of haste ticks. The unrounded tick count formula is this:
Code:
HastedTickCount = (BaseDuration/BaseTickTime) * (1 + Haste)
What weíre doing here is finding the number of ticks the DoT has before haste, and then increasing to account for the fact that haste make all ticks occur more quickly.

The complicated bit for this section is that the Bankerís Rounding (Half to Even) applies here. If we have exactly 6.5 ticks, it will round to 6, but 7.5 ticks rounds to 8. In practice itís unlikely that youíll hit exactly half a tick, so itís OK to use normal rounding:
Code:
HastedTickCount = Round( (BaseDuration/BaseTickTime) * (1 + Haste) ,0 )
Reverse Calculation: Haste Breakpoint from Tick Count
This is where it gets complicated. Iíll take things step by step here to make it a bit easier to follow. Note: Time is measured in milliseconds (ms) for this, as the game rounds to the nearest whole millisecond.

Part 1: Tick Speed
First we need to work out the tick speed required for a particular breakpoint.
Code:
TickSpeed = BaseDuration / ( TickCount - 0.5 )
Subtracting 0.5 off the tick count gives us that point where the tick count will round up to our target value, or would do if normal rounding was used. In order to get it working correctly for Bankerís Rounding, we have to do something complicated. The following is from my haste breakpoint spreadsheet:
Code:
=IF ( ISEVEN ( TickCount ) , FLOOR ( TickSpeed , 1 ) + 0.5 , CEILING ( TickSpeed , 1 ) - 0.5 )
There are a few functions here that are probably unfamiliar to most, so Iíll explain what they do:
  • ISEVEN returns true or false depending on whether the number, truncated to zero decimal places, is even or not.
  • FLOOR rounds a number down to the nearest multiple of the second number
  • CEILING does the same thing as FLOOR, but rounds up rather than down.
So what the formula is doing is this:
  • IF the TickCount is even
  • THEN round TickSpeed down to the nearest multiple of 1, then add 0.5
  • ELSE round TickSpeed up to the nearest multiple of 1, then subtract 0.5
The reason we do this, even though the THEN and ELSE parts of the formula look very similar, is because if we hit an exact whole millisecond tick speed the result depends on whether the tick count is even or odd. For any tick speed that isnít a whole number the results will be the same either way.
This is done because the even ticks will include the normal breakpoints, while odd ticks will occur at a slightly lower tick speed than the normal breakpoint. This is that Bankerís Rounding or Round to Nearest Even behaviour mentioned earlier.

Part 2: Haste Percentages
Now that we have our tick speed (in milliseconds) itís time to convert that into a haste value. This part is fairly easy.
Code:
Haste% = BaseTickSpeed / NewTickSpeed - 1
Part 3: Haste Ratings
To calculate the haste rating required to obtain that Haste %, we use:
Code:
CEILING ( MAX ( Haste% * 42500 , 0 ) , 1 )
If you remember the earlier sections, this is fairly self explanatory. Multiply the Haste% by 42500 to both convert it out of a percentage and get the amount of rating required, and use the CEILING function to round it up to the nearest multiple of 1. The MAX function is to make sure that the lowest result returned is zero. Why we do this will become apparent as we calculate multiple haste sources.

For those, we divide the Haste% by each haste source:
Code:
CEILING ( MAX ( ( (1 + Haste%) / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 , 0 ) , 1 )
As before, there are cases where there are additional haste buffs, so they will get treated in the same way, continually dividing the required haste value by each haste buff until youíve included them all. With one or more haste buffs itís likely that one or more of the breakpoint calculations are negative, so because you canít have negative haste rating thatís why the MAX function was added in.

And now youíre an expert too
Or at least less confused than you were before. Itís OK if you donít understand some of the formulae (they do my head in sometimes too), but now you know what calculations to run to do this yourself. If you follow the reverse calculations correctly you should match the Caster and Healer haste breakpoint cards Iíve made.

Many thanks to Hamlet for clarifying a few things & helping me simplify my formulae.

Submit "Theorycrafting 101: Haste Part 2 - DoTs and HoTs Math" to Google

Comments

  1. Jormund's Avatar
    Hello, thanks for explaining this.
    If I understood correctly, here is an example with Riptide and the 8 ticks cap:
    TickSpeed = BaseDuration / ( TickCount - 0.5 )
    TickSpeed = 18000/(8-0.5) = 2400

    NewTickSpeed = IF ( ISEVEN ( TickCount ) , FLOOR ( TickSpeed , 1 ) + 0.5 , CEILING ( TickSpeed , 1 ) - 0.5 )
    NewTickSpeed = FLOOR(2400)+0.5=2400.5

    BaseTickSpeed = 18000/6 = 3000

    Haste% = BaseTickSpeed / NewTickSpeed - 1
    Haste% = 3000/2400.5 - 1 = 1.249739638 - 1 = 0.249739638

    Haste = CEILING ( MAX ( Haste% * 42500 , 0 ) , 1 )
    Haste = CEILING(10613.9346) = 10614

    Edit: I previously said your card says 10089 instead of 10614. My mistake. It seems I was looking at an older version. The images I see now on http://www.totemspot.com/vb/entry.php?b=41 are correct.
    Updated 24-09-2012 at 07:47 PM by Jormund
  2. Binkenstein's Avatar
    Quote Originally Posted by Jormund
    Hello, thanks for explaining this.
    If i understood correctly, here is an example with Riptide and the 8 ticks cap:
    TickSpeed = BaseDuration / ( TickCount - 0.5 )
    TickSpeed = 18000/(8-0.5) = 2400

    NewTickSpeed = IF ( ISEVEN ( TickCount ) , FLOOR ( TickSpeed , 1 ) + 0.5 , CEILING ( TickSpeed , 1 ) - 0.5 )
    NewTickSpeed = FLOOR(2400)+0.5=2400.5

    BaseTickSpeed = 18000/6 = 3000

    Haste% = BaseTickSpeed / NewTickSpeed - 1
    Haste% = 3000/2400 - 1 = 1.249739638 - 1 = 0.249739638

    Haste = CEILING ( MAX ( Haste% * 42500 , 0 ) , 1 )
    Haste = CEILING(10613.9346) = 10614

    Should i round the 24.97% first ? it seems i have found the same haste percentage as you, but not the same rating. (your card says 10089 haste rating required for 8th tick of Riptide)
    You were good up until the last bit. Since you're referring to the 8085 cap you're using the 5% spell haste aura, so you want to use the second haste rating formula. If you look at the "None" column you see the same 10614 value as you calculated.
  3. Judgejoebrwn's Avatar
    First off, I'd like to thank you for the work you've put into these guides. I've been reading up on them, and although I consider myself a math guy, I was having some trouble with this haste stuff. I think I've finally got it down thanks to the formulas you provided in this Blog, yet while my numbers seem to match your healing haste breakpoints for standard shaman healers, my numbers for the Goblin shammy seem to differ slightly. Am I not factoring in the racial properly?

    Using you're formula (that works for the non-goblin breakpoints):

    (1 + (Haste Rating / 42500)) * 1.05 * 1.05 * 1.01

    This formula (disregarding the 1.01) leaves me with non-goblin numbers that match yours. Adding in the 1.01, however, gives me slightly different percentages starting with Earthliving:

    12.56
    20.06
    20.06
    25.03

    ...and so on. Are these number off slightly, or is the Goblin 1% calculated differently?
  4. Binkenstein's Avatar
    Quote Originally Posted by Judgejoebrwn
    First off, I'd like to thank you for the work you've put into these guides. I've been reading up on them, and although I consider myself a math guy, I was having some trouble with this haste stuff. I think I've finally got it down thanks to the formulas you provided in this Blog, yet while my numbers seem to match your healing haste breakpoints for standard shaman healers, my numbers for the Goblin shammy seem to differ slightly. Am I not factoring in the racial properly?

    Using you're formula (that works for the non-goblin breakpoints):

    (1 + (Haste Rating / 42500)) * 1.05 * 1.05 * 1.01

    This formula (disregarding the 1.01) leaves me with non-goblin numbers that match yours. Adding in the 1.01, however, gives me slightly different percentages starting with Earthliving:

    12.56
    20.06
    20.06
    25.03

    ...and so on. Are these number off slightly, or is the Goblin 1% calculated differently?
    Good catch. The ratings were off because for some reason I put that in as X/1.06/1.05 rather than 1.05/1.05/1.01
  5. Unregistered's Avatar
    Going from haste% to haste ratings, the subtraction of 1 occurs in wrong place, I think. It should be after division of relevant haste multipliers, not before - instead of "Haste% = BaseTickSpeed / NewTickSpeed - 1" and "CEILING ( MAX ( ( Haste% / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 , 0 ) , 1 )", it should be "Haste% = BaseTickSpeed / NewTickSpeed" and "CEILING ( MAX ( ( Haste% / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) -1 ) * 42500 , 0 ) , 1 )".
  6. Binkenstein's Avatar
    Quote Originally Posted by Unregistered
    Going from haste% to haste ratings, the subtraction of 1 occurs in wrong place, I think. It should be after division of relevant haste multipliers, not before - instead of "Haste% = BaseTickSpeed / NewTickSpeed - 1" and "CEILING ( MAX ( ( Haste% / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 , 0 ) , 1 )", it should be "Haste% = BaseTickSpeed / NewTickSpeed" and "CEILING ( MAX ( ( Haste% / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) -1 ) * 42500 , 0 ) , 1 )".
    If you go 3/2.5 you get = 1.2 which is 20% haste, so it's in the right place
  7. Unregistered's Avatar
    I'm talking about the way the required haste rating is computed. Abstractions are beautiful but it's easier to grasp by example. Let's consider Rejuvenation with raid 5% haste and SotF 75%. Let's calculate at which haste rating it will have 8 ticks. Rejuvenation has base duration of 12000 ms and 4 base ticks. The TickSpeed=1600 ms. Due to some mathematical magic the ticks have to occur each 1600.5 ms. The required haste% is 0.874414... Then, according to your formula, the required haste rating will be 20205, which is way off.
    If we are talking about consistency, then expression "Haste% = (BaseTickSpeed / NewTickSpeed-1)*100" should be used. Trying "CEILING ( MAX ( ( (1 + Haste% / 100) / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) -1 ) * 42500 , 0 ) , 1 )" gives 854 haste rating which can be found in the table.
  8. Binkenstein's Avatar
    Quote Originally Posted by Unregistered
    I'm talking about the way the required haste rating is computed. Abstractions are beautiful but it's easier to grasp by example. Let's consider Rejuvenation with raid 5% haste and SotF 75%. Let's calculate at which haste rating it will have 8 ticks. Rejuvenation has base duration of 12000 ms and 4 base ticks. The TickSpeed=1600 ms. Due to some mathematical magic the ticks have to occur each 1600.5 ms. The required haste% is 0.874414... Then, according to your formula, the required haste rating will be 20205, which is way off.
    If we are talking about consistency, then expression "Haste% = (BaseTickSpeed / NewTickSpeed-1)*100" should be used. Trying "CEILING ( MAX ( ( (1 + Haste% / 100) / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) -1 ) * 42500 , 0 ) , 1 )" gives 854 haste rating which can be found in the table.
    No, 87.44% haste is required, but since you already have a 5% buff and a 75% SofF buff you then do the following:
    1.874414/1.05/1.75 = 1.020089, which is why you only require 854 rating to hit that mark.

    I don't scale up by 100 to give "consistency" because every percentage is stored as a decimal, but displayed as a percentage (ie: 0.58 shows as 58%). It's one of those nifty excel formatting tricks. If I multiplied it by 100 I'd have to format everything to show whole numbers, as 0.58/58% would show as 58/580%. Also, it seems odd to add a "multiply by 100" into one stage when at the next you go "divide by 100".
  9. Unregistered's Avatar
    Show me how did you get 854 haste rating with your formulas "Haste% = BaseTickSpeed / NewTickSpeed - 1" and "CEILING ( MAX ( ( Haste% / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 , 0 ) , 1 )".
  10. Binkenstein's Avatar
    Quote Originally Posted by Unregistered
    Show me how did you get 854 haste rating with your formulas "Haste% = BaseTickSpeed / NewTickSpeed - 1" and "CEILING ( MAX ( ( Haste% / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 , 0 ) , 1 )".
    Ticks: 8
    Tickspeed required: 1600 ms
    Adjusted tickspeed required 1600.5 ms
    Base tickspeed 3000 ms
    3000/1600.5 = 1.874414
    Converted to a percentage = 87.4414%

    This is where the first formula is used. Haste % = ( 3000 / 1600.5 ) -1

    For the second part, the CEILING & MAX bits are to round up to the nearest whole number, and to prevent negative rating numbers from showing. Thus the formula is ( (1+ Haste%) / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 (Note: realised Haste% should be 1+Haste%. Fixed in the post).

    1.874414 / ( 1+ 0.05 ) = 1.785156
    1.785156 / ( 1+ 0.75) = 1.020089
    1.020089 - 1 = 0.020089
    0.020089 * 42500 = 853.79887

    This then rounds up to 854 via the CEILING function.
  11. Unregistered's Avatar
    Thanks, really nice explanation. I think you should include it in the blog entry under the subtitle "An easy example".
    P.S. How random is the Random Question?
Leave Comment Leave Comment

Trackbacks

Total Trackbacks 0
Trackback URL:
Powered byvBSocial.com and MMORPG