TiC Tooltips

TiC Tooltips

18M Downloads

Incorrect Effective Durability Calculations

madsmith opened this issue ยท 3 comments

commented

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.

commented

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));
commented

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

commented

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