-
What are you attempting to achieve?
I’m currently attempting to do a cooldown system where each skill has the amount of time until the end of the cooldown displayed on a GUI. -
What is the issue?
The number value appears to always turn into some weird huge decimal when subtracting 0.1, or just go to a completely random decimal rather than what the number value would supposed to be.
Watch 2019-05-26 13-32-13 | Streamable -
What solutions have you tried so far?
I’ve tried setting the number values to 0 if they hit one of the random decimals, but this solution is inconsistent and messy. I’ve tried math.floor and math.ceil but they both just go to whole numbers.
Ah yes, you have encountered the dreaded Floating Point Error™ problem. There’s a whole lot of technical mumbo jumbo that I don’t understand that can be summarized as “Because of the way information is stored, NumberValues can’t hold most exact decimals, so it has to store an extremely close version of it instead.” Unless you’re comparing numbers in a script, it shouldn’t cause any issues–the difference is so minimal you’ll never notice. If you do need it to be perfectly accurate for the sake of comparing numbers in a script, the best solution I can provide is, in the script, processing the number a bit like so:
function deError(number)
number=number*10 --we want to preserve the first decimal place
if number-math.floor(number)>=0.5 then --round the number
number=math.ceil(number)
else
number=math.floor(number)
end
return number/10 --return the processed number
end
Use an IntValue
and handle your cooldowns in timestamps instead. When your action goes off check if the current os.time()
is larger than the value of the IntValue
and just set the value to os.time() + cooldown_time
if so and continue with the action.
If you want your cooldown_time
to have decimal places, just multiply your os.time()
values by 10^n
, where n
is how many decimal places of accuracy you want; I suggest just 1 works.
Use client-side prediction. Have the server set a clock ahead of time (using the method above - set a time to current time + usage interval) and have the client animate the countdown instead. Don’t actually change the value of a ValueObject over a period of time.
I’ll attempt each of these solutions, thank you.
A more concise version of Chipio’s function:
function deError(number)
return math.floor(number*10 + 0.5)/10
end
function deError(number)
return math.round(number*10)/10
end
Nothing more to add, these are all good solutions!