Jump to content

Modifier Stacking, An Addendum

Recommended Posts

Hi all, I had noticed that the stacking of "recovery time" modifiers seemed unusual. I think it is reasonably known that most positive "multiplicative" effects stack additively, as multipliers of some base value (usually).  E.g. +21% damage from might and +60% from legendary -> 1.81X damage.  

Negative percentage modifiers usually do not work this way, ie: -30% recovery time from dual wielding and -15% from two weapon style does not equal 0.55X recovery time, it actually equals ~0.63X recovery time. I was having a difficult time figuring out how this is actually calculated, so I had a peak at the DLLs.


As it turns out, looking through the "adjustedvalue" class in Ilspy, "multiplication" is done in 3 steps of a somewhat unusual operation (and 3 of addition). Multipliers from a given source are classified into one of these 3 steps, but from what I can tell, all "recovery time" multipliers go into the same step when calculating recovery time. Even "action speed" multipliers seem to be converted into the usual type ("multiplySteps", 2nd multiply step) of multiplier, rather than e.g. "m_multiplyBaseValueSteps" or "m_multiplyPostAddSteps".


For each stage: All multipliers in a given stage are added together, as follows

Multipliers >1 (ie: increases) are reduced by 1(IE: +30% (1.30) and +50% (1.50) -> 0.3 and 0.5)

Multipliers < 1 (ie: reductions) are converted into 1 - 1/(multiplier), then added. e.g. 0.85 -> -0.176. 

These values are totaled for a given stage. 


When a given step is applied, this total is taken.

If the total is >=0, then the final modifier is increased by 1. (ie: total of 1.3, 1.6, 1.2 -> 1+(0.3+0.6+0.2) -> 2.1)

if the total is <=0, then the final modifier is 1/(1-x). (ie: total of 1.3,1.6, 0.5 and 0.5) -> 0.3+0.6+(1-1/0.5)+(1-1/0.5) -> -1.1; then 1/(1-(-1.1)) -> 0.476)

This is then multiplied by the prior stage to reach the next stage.


In terms of recovery time,


This ends up being largely equivalent to additive "action speed" bonuses if recovery time is reduced. As increasing a divisor gives significantly diminishing returns, e.g. dual wielding is at its most beneficial when reducing recovery time penalties to ~ 0. 



        value += m_addBaseValueBonus * HiddenMultiplier;
        value *= Math.StepsToMultiplier(m_multiplyBaseValueSteps);
        value += m_addPreMultiplyBonus * HiddenMultiplier;
        value *= Math.StepsToMultiplier(m_multiplySteps);
        value += m_additiveBonus * HiddenMultiplier;
        value *= Math.StepsToMultiplier(m_multiplyPostAddSteps);
        value += m_addPostMultiplyBonus * HiddenMultiplier;
    return value;

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...