Math.random(0,10) vs Random.new():NextNumber(0,10)

I recently just learned that the `Random` class was a thing

Let’s say, for example, I wanted to generate a random number between one and ten. I could do either of the following:

``````--// Option A
print(math.random(1,10)

--// Option B
local RandomObj = Random.new()
print(RandomObj:NextInteger(1,10))
``````

I’m wondering what are the pros and cons of each option, and which would technically be more “random”

4 Likes

math.random and Random internally use the same algorithm, so the only difference is that with Random you can create different instances while with math.random you always use the same instance.

3 Likes

Both are fine. But you probably shouldn’t be doing `Random.new():NextNumber(0,10)` like you suggested in your title. Each successive call of `NextInteger` (or similar) to a `Random` object is supposed to generate “good” pseudorandom numbers. There’s no guarantee that a sequence of the first calls to newly created `Random` objects has the same properties, i.e. you might get “bad” sequences.

Testing the distribution tho it seems fine:

``````local t = {}
local rolls = 10000000
for i = 1, rolls do
local n = Random.new():NextInteger(1, 10)
t[n] = (t[n] or 0) + 1
end

for k, v in pairs(t) do
print(k, (v/rolls) * 10)
end
``````

=>

``````  1 1.001109
2 1.001402
3 0.998534
4 0.999867
5 0.99977
6 1.002493
7 0.999089
8 0.998426
10 0.998571
9 1.000739
``````

Everything is close to 1, as it should be.

The one big advantage of `Random` is that you can have different RNGs with different states, which is useful if you’re trying to generate the same sequence of numbers from the same seed.

1 Like

math.random() for quick and easy access to a random value
Random.new() for a better random for the script environment its used in.

I guess you could look at it this way too: math.random() is global and Random.new() is local.

I find Random.new()'s outcome “feels better” than math.random, even if they use the same algorithm internally.

3 Likes

Just a heads-up, you don’t have to call `Random.new()` multiple times, noting that it is a random number generator. Setting it as a variable is better than getting a new generator every single time, unless you want to refresh the seed. Treat it like an object and use its functions as the equivalent of `math.random()`, not `math.randomseed()`.

2 Likes

As the above person mentioned, you only really need to call Random.new() once per script.

This is what I end up doing most of the time:

``````local newRandom = Random.new()
local function random(a, b)
return newRandom:NextInteger(a, b)
end

print(random(1,10))
``````
2 Likes