Than working with status values and make some percent changes the precision is loosed. This leads to some unintended calculation problems.
We can design our status values like 100_000 instead of 100. But we need not always think about that and ineviatable make some bugs and accessive work to work this that paradigm.
I was going through the 3d play ground series. After I have created spike trap. I have encointered that Wizard that has less of all HP is surviving spike trap much longer (4 more interactions). And the Warrior, who has the most HP vas killed first.
You can see that stats without precision can lead to some serious gameplay problems.
@gamingislove We need something that introduces concept of precision to stats. (Preferably float type)
float types are imprecise - though if you want to use them, you could always use object variables on the combatants. I'll investigate offering different value types for stats in future updates.
The spike trap example - yeah ... I'll add a rounding option for this :)
Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found. If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
Which is more inprecise?) int: 6 / 4 = round(1.5) = 2 float: 6 / 4 = 1.5 2/1.5 = 1.33 int is 33% more inprecise than float in that case :)
though if you want to use them, you could always use object variables on the combatants.
Could you explain this. Your mean not to use stat system with their benefits and just use some variables on combatant. Or you mean somehow use those variables without loosing capabilities which stat system gives?
The spike trap example - yeah ... I'll add a rounding option for this :)
Do you think rounding(ceil, floor, round) can somehow solve problem that combatants with different health amounts can survive different ammount of percentage damage? Let say you have 10 ticks of 10%Damage. It is expected to kill any targets with 10 ticks but that will not happen if hp is int and targets has different amount of hp. And this is a gameplay problem which I do not know how to avoid with int type of stats. Maybe I missing something?
I'll investigate offering different value types for stats in future updates.
That would be great. In some cases we can use int/longs in some floats and in some doubles. Hope this will be implemented.
Floats are fundamentally imprecise, especially the implementation in Unity. Unity Floating points specifically only have about 7 digits of precision before things start to really get out of sync.
I've spent a lot of time dealing with floating points and headaches they can cause (granted that was more with transform positions where the precision really matters than just status values) so here's my take on everything.
Do you think rounding(ceil, floor, round) can somehow solve problem that combatants with different health amounts can survive different ammount of percentage damage? Let say you have 10 ticks of 10%Damage. It is expected to kill any targets with 10 ticks but that will not happen if hp is int and targets has different amount of hp. And this is a gameplay problem which I do not know how to avoid with int type of stats. Maybe I missing something?
You just round up to the nearest 1. 255 health, each tick does 26 damage. You die in 10 ticks after 260 damage, while 9 ticks is 234 health. 9274 health, each tick does 928. You die in 10 ticks after 9280 damage was done while 9 ticks is 8352.
Unless your intention is to display fractional status values, I'm not sure what an exact % would help. 255 minus 25.5 health, what do you display to the user, 230 health, 229 health, or 229.5? The first two are inaccurate to the player, and if you're going to hide it from them, why not just round and make it real?
Which is more inprecise?) int: 6 / 4 = round(1.5) = 2 float: 6 / 4 = 1.5 2/1.5 = 1.33 int is 33% more inprecise than float in that case :)
6/4 does equal 1.5, but for a float data type it could actually be 1.5000001. The more calculations you do on this value, the further it may stray from the actual value. Similarly, you'd also need to cast to an int for any comparisons anyways or an extension method to allow for a specified amount of variance (1.500001 != 1.5), which again, is just by definition imprecise since you're either cutting off decimals anyways or saying "about equal" and not actually equal.
If you're just using small values, then you're unlikely to really hit an issue, but the more you start using more and more digits, you get more and more imprecise.
Let's say someone has 50,000 health. If we allow floats and I want to deal 10.5% damage to them.
Math wise, this should deal 4,761.904761904762 damage, however, with Unity using it as a float it gets truncated to 4761.905. That's a lot of precision we ended up chopping off just to get the same end result of 4762 damage that we could have just done with int values and rounding the result up.
As noted by GiL, it currently doesn't round so that does lead to some oddities as you encoutnered, but just rounding up should fix that.
I'm not sure I'm understanding a use case where float status values would be necessary, or where the loss of +1/-1 to the end result in precision would make a reasonable difference.
In the same line, would it also be possible to make the Equipment>Bonus Settings>Status Value Bonus to use a float value selection, to allow using formulas etc, like in the latest update for Efficiencies?
How one can implement DOT that subtracts 1% of maximum life per 0.1 second for 100 ticks. And it should kill Any target independent of its maximum life after whouse 100 ticks. If maximum life is low - like 5 MHP and one is able to use only INTS ?
If you’re going to display 2.5 then I feel like doing larger numbers (25/100 vs 2.5/10) is probably the way to go? I can’t think of very many, if any really, games with fractional health bars.
Your 1% dot example I’d argue starts to push into odd game design too. Using 5hp maximum, you won’t see an actual effect until 20% or 20 ticks when you go down to 4hp. Similar to the first, I feel like that effect would be better solved by using larger numbers for a smoother and more noticeable effect to the player. 1% of 100 or more every tick is something the player can see happening whereas otherwise it’s just in burst.
If you’re doing stuff like 5.00 to 4.95 to 4.90 and display that, what value are you actually getting from using a small number system in the first place if everything is basically x100 anyways but using decimals?
If you’re doing stuff like 5.00 to 4.99 to 4.98 and display that, what value are you actually getting from using a small number system in the first place if everything is basically x100 anyways but using decimals?
5,99 and 599 is still perceived differently by player. First still percieved as small number. Second is perceived as much larger numer.
If you’re going to display 2.5 then I feel like doing larger numbers (25/100 vs 2.5/10) is probably the way to go?
Yes it the way to go.
@gamingislove It turns out that int status values are good enough and even surpass floats in consistency. If we need low numbers with several floating points we can just divide by 100..(ork can do that automatically) to show it in UI but operate with x100 values.
Thanks @Acissathar for the detailed explanation why floats are imprecise :)
@TextusGames Status effects for DOTs can use the Keep Overflow option in their status value changes to keep track of any change exceeding a whole number and add them to the next change.
Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found. If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
I was going through the 3d play ground series.
After I have created spike trap.
I have encointered that Wizard that has less of all HP is surviving spike trap much longer (4 more interactions).
And the Warrior, who has the most HP vas killed first.
You can see that stats without precision can lead to some serious gameplay problems.
@gamingislove
We need something that introduces concept of precision to stats.
(Preferably float type)
I'll investigate offering different value types for stats in future updates.
The spike trap example - yeah ... I'll add a rounding option for this :)
If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
int: 6 / 4 = round(1.5) = 2
float: 6 / 4 = 1.5
2/1.5 = 1.33
int is 33% more inprecise than float in that case :)
Could you explain this. Your mean not to use stat system with their benefits and just use some variables on combatant. Or you mean somehow use those variables without loosing capabilities which stat system gives?
Do you think rounding(ceil, floor, round) can somehow solve problem that combatants with different health amounts can survive different ammount of percentage damage?
Let say you have 10 ticks of 10%Damage. It is expected to kill any targets with 10 ticks but that will not happen if hp is int and targets has different amount of hp. And this is a gameplay problem which I do not know how to avoid with int type of stats. Maybe I missing something?
That would be great.
In some cases we can use int/longs in some floats and in some doubles.
Hope this will be implemented.
I've spent a lot of time dealing with floating points and headaches they can cause (granted that was more with transform positions where the precision really matters than just status values) so here's my take on everything. You just round up to the nearest 1. 255 health, each tick does 26 damage. You die in 10 ticks after 260 damage, while 9 ticks is 234 health. 9274 health, each tick does 928. You die in 10 ticks after 9280 damage was done while 9 ticks is 8352.
Unless your intention is to display fractional status values, I'm not sure what an exact % would help. 255 minus 25.5 health, what do you display to the user, 230 health, 229 health, or 229.5? The first two are inaccurate to the player, and if you're going to hide it from them, why not just round and make it real? 6/4 does equal 1.5, but for a float data type it could actually be 1.5000001. The more calculations you do on this value, the further it may stray from the actual value. Similarly, you'd also need to cast to an int for any comparisons anyways or an extension method to allow for a specified amount of variance (1.500001 != 1.5), which again, is just by definition imprecise since you're either cutting off decimals anyways or saying "about equal" and not actually equal.
If you're just using small values, then you're unlikely to really hit an issue, but the more you start using more and more digits, you get more and more imprecise.
Let's say someone has 50,000 health. If we allow floats and I want to deal 10.5% damage to them.
Math wise, this should deal 4,761.904761904762 damage, however, with Unity using it as a float it gets truncated to 4761.905. That's a lot of precision we ended up chopping off just to get the same end result of 4762 damage that we could have just done with int values and rounding the result up.
As noted by GiL, it currently doesn't round so that does lead to some oddities as you encoutnered, but just rounding up should fix that.
I'm not sure I'm understanding a use case where float status values would be necessary, or where the loss of +1/-1 to the end result in precision would make a reasonable difference.
Thanks for explanation.
For bigger numbers floats/doubles are not necessary I guess.
For low numbers they do make a difference.
0.5 and 1 => difference is 50%
0.5 and 5 => difference is 10%
0.5 and 10 => difference is 5%
0.5 and 50 => differnce is 1%
Some rpg systems use low numbers less then 20 for damage
In that systems that precision will make a difference.
I could soothe this issue by multiplying my status value by 100 or 1000
and show in UI values divided by 1000 (ORK already supports that in UI)
but currently the calculations still wrong:
https://forum.orkframework.com/discussion/7522/bug-setting-value-as-percent-ignores-floating-points-values-of-percent-value#latest
@gamingislove than fixing rounding behaviour could you also inverstigate above links issue too?
I’m curious what would you do (assuming we had float status values) for a low number system?
You have someone with 5hp and an attack does 50% damage.
Are you going to have them be at 2.5 health points, or round it up or down?
In the same line, would it also be possible to make the Equipment>Bonus Settings>Status Value Bonus to use a float value selection, to allow using formulas etc, like in the latest update for Efficiencies?
Thanks!
Shown value will b 2.5 or 3.
How one can implement DOT that subtracts 1% of maximum life per 0.1 second for 100 ticks.
And it should kill Any target independent of its maximum life after whouse 100 ticks.
If maximum life is low - like 5 MHP and one is able to use only INTS ?
If you’re going to display 2.5 then I feel like doing larger numbers (25/100 vs 2.5/10) is probably the way to go? I can’t think of very many, if any really, games with fractional health bars.
Your 1% dot example I’d argue starts to push into odd game design too. Using 5hp maximum, you won’t see an actual effect until 20% or 20 ticks when you go down to 4hp. Similar to the first, I feel like that effect would be better solved by using larger numbers for a smoother and more noticeable effect to the player. 1% of 100 or more every tick is something the player can see happening whereas otherwise it’s just in burst.
If you’re doing stuff like 5.00 to 4.95 to 4.90 and display that, what value are you actually getting from using a small number system in the first place if everything is basically x100 anyways but using decimals?
First still percieved as small number. Second is perceived as much larger numer. Yes it the way to go.
@gamingislove It turns out that int status values are good enough and even surpass floats in consistency. If we need low numbers with several floating points we can just divide by 100..(ork can do that automatically) to show it in UI but operate with x100 values.
@gamingislove @RustedGames @Acissathar
Thanks.
@TextusGames
Status effects for DOTs can use the Keep Overflow option in their status value changes to keep track of any change exceeding a whole number and add them to the next change.
If you're enjoying my products, updates and support, please consider supporting me on patreon.com!