Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect Effective Durability Calculations #16

Closed
madsmith opened this issue Sep 9, 2014 · 3 comments
Closed

Incorrect Effective Durability Calculations #16

madsmith opened this issue Sep 9, 2014 · 3 comments
Labels

Comments

@madsmith
Copy link

madsmith commented Sep 9, 2014

I took a glance at the code and realized that Reinforced 10 basically equals Infinite durability...

This made me think about how you do the "Effective Durability" calculations and I realized that it's completely incorrect.

in ToolHelper.java under getEffectiveDurability
return (int) (toolTag.getInteger("TotalDurability") * (1f + getReinforcedLevel(toolTag) * .1f));

This says that each level of reinforcement is a 10% increase in effective durability. If this were true, then Reinforced 10 would be 2 * "Total Durability".

The correct formula is
effectiveDurability = totalDurability * ( 1 / (reinforcedLevel / 10)

At Reinforced 5, 50% (half) of the time you do not use durability, so you have effectively twice the durability. So our multiplier to total durability would be 1 / ( 1 - 5/10) = 1 / (1 - .5) = 1 / .5 = 2

If there was a Reinforced 7.5, that would be 3/4 of the time, you do not use durability, and the remaining 1/4 you do. Our total durability is used in the 1/4 of the time, the other 3/4 is effectively free so your effective durability would be 4x.

 `1 / (1 - 7.5/10) = 1 / (1 - .75 ) = 1 / .25 = 4`

If we go conceptually halfway closer to Reinforced 10 and compute reinforced 8.75, we would see an 8x improvement. The closer you get to reinforced 10, the larger the improvement.

For a tool with 100 durability here is how effective durabilty would change as we make it accurate.

  • Reinforced 1 - OLD 110 NEW 111
  • Reinforced 2 - OLD 120 NEW 125
  • Reinforced 3 - OLD 130 NEW 142
  • Reinforced 4 - OLD 140 NEW 166
  • Reinforced 5 - OLD 150 NEW 200
  • Reinforced 6 - OLD 160 NEW 250
  • Reinforced 7 - OLD 170 NEW 333
  • Reinforced 8 - OLD 180 NEW 500
  • Reinforced 9 - OLD 190 NEW 1000
  • Reinforced 10 - OLD 200 with special case to show infinity NEW Infinity

The correct code should be

    int r = getReinforcedLevel(toolTag);
    return r == 10 ?
        -1 :
        (int) (toolTag.getInteger("TotalDurability") * ( 1f / (1f - r/10f)));

Note, we use the ternary conditional to circumvent the divide by zero. I've chosen to use -1 here as you use that elsewhere in TooltipHandler.java instead of something like Double.POSITIVE_INFINITY or Integer.MAX_VALUE.

I'd send a patch but I don't have a modding environment setup and I'm hesitant to send a patch for code that I haven't compiled myself.

@madsmith
Copy link
Author

madsmith commented Sep 9, 2014

That code could be simplified slightly by moving total durability into the numerator of the second term

    int r = getReinforcedLevel(toolTag);
    return r == 10 ?
        -1 :
        (int) (toolTag.getInteger("TotalDurability") / (1f - r/10f));

@squeek502
Copy link
Owner

Thank you very much for the detailed correction. I clearly didn't think that through at all. I'll make those changes ASAP.

@squeek502 squeek502 added the bug label Sep 9, 2014
@madsmith
Copy link
Author

madsmith commented Sep 9, 2014

Also, it should be r >= 10. Just realized that you could insanely keep pushing reinforced up past 10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants