Theorycrafting 101: Haste Part 2 - DoTs and HoTs Math
by, 24-09-2012 at 04:24 AM (19812 Views)
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:
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.Code:TotalHastePercentage = ( 1 + ( hasterating / 42500 ) * (1 + hastebuff1 ) * (1 + hastebuff2 ) - 1
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:
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.Code:HastedTickCount = (BaseDuration/BaseTickTime) * (1 + Haste)
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:
Reverse Calculation: Haste Breakpoint from Tick CountCode:HastedTickCount = Round( (BaseDuration/BaseTickTime) * (1 + Haste) ,0 )
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.
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:TickSpeed = BaseDuration / ( TickCount - 0.5 )
There are a few functions here that are probably unfamiliar to most, so Iíll explain what they do:Code:=IF ( ISEVEN ( TickCount ) , FLOOR ( TickSpeed , 1 ) + 0.5 , CEILING ( TickSpeed , 1 ) - 0.5 )
So what the formula is doing is this:
- 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.
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.
- 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
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.
Part 3: Haste RatingsCode:Haste% = BaseTickSpeed / NewTickSpeed - 1
To calculate the haste rating required to obtain that Haste %, we use:
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.Code:CEILING ( MAX ( Haste% * 42500 , 0 ) , 1 )
For those, we divide the Haste% by each haste source:
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.Code:CEILING ( MAX ( ( (1 + Haste%) / (1 + HasteBuff1%) / ( 1 + HasteBuff2% ) ) * 42500 , 0 ) , 1 )
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.
Total Trackbacks 0