Reproduction: Simply run this code:
local r = Random.new(4218675221687534) for i=1,178 do r:NextNumber() end print(r:NextNumber())
Actual Result: 0
Impact: While this has an extremely low chance of happening under a non-seeded case, when it does happen, experiences will operate in unexpected ways. For example, code such as 1/r:NextNumber() to display the RNG value will return Infinity and depending on the code used to select the awarded item, can return nil and error later on, or script timeout.
Developer’s Workaround: Check for zero return value for every place that NextNumber is called and set it to 0.5. It’s very tedious to put this.
The documentation for math.random states that the function can return exactly zero in the documentation, but, the documentation for NextNumber does not.
I have a lot of scripts to update if this isn’t a bug. In a incremental game I have code that boosts a currency by 1 + -math.log10(r:NextNumber()). If it returned 0, then it would compute to inf.
The documentation of NextNumber does state it can return exactly zero. At least assuming that common notation has been used, [0, 1] means a number in the range from 0 to 1, inclusive of both 0 and 1. Mind you that’s still wrong if 1 can’t happen, but it is documented that 0 can already.
I don’t think a specific use case of the function not working quite properly is a compelling enough case to change the behavior altogether. In fact, this behavior is expected of just about every single language that implements a way to get a random float.
like Autterfly said this isn’t a bug
[0,1] means from 0 and 1 and including 0 and 1
]0,1] means from 0 to 1 but excluding 0
[0,1[ means from 0 to 1 but excluding 1
]0,1[ means from 0 to one but excluding both
local function safeNextNumber(random)
while true do
local result = random:NextNumber()
if result == result and result ~= math.huge then
return result
end
end
end
Also, it’s basically impossible to get zero.
I ran the function billions of times, and it never returned zero. Unsure why your code does though, mind sharing how you got that seed and the number 178? Point is, in a real scenario, it’s not going to happen. Besides, if you get 1/INF in your RNG game, wouldn’t that mean you just get the rarest item (since you didn’t code a rarer one)? Is it that big of an issue to you that it could return zero?
its possiple to get zero but the chance is very rare and its based on the seed
i got it after 178 tries using the 4218675221687534 seed
--!strict
local r = Random.new(4218675221687534)
for i=0, 1e8 do
local n = r:NextNumber()
if n == 0 then
print("Printed Zero", " | Took " .. i .. " Tries")
end
end
print("LoopDone")
but when i try with a different seed for example local r = Random.new(20) then I didn’t get 0 in 1e8 loops
i got them from the exact script that i sent and i got the seed from the op topic
Script
--!strict
local r = Random.new(4218675221687534)
for i=0, 1e8 do
local n = r:NextNumber()
if n == 0 then
print("Printed Zero", " | Took " .. i .. " Tries")
end
end
print("LoopDone")
that depends on the rng system but for weight rng systems there are systems where the higher the weight the rarer the item and there are systems where the lower the weight the rarer the item
no because I wouldn’t divide 1 by the random number and that would mean that I got the rarest item
This image is for math.random and not Random:NextNumber.
It is actually quite likely that math.random is incorrect and might generate a 1 just like Random:NextNumber.