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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...