Builtin Library
README.md
random
Seeded random-number generators. Random.new(seed) makes a generator that
holds its own stream: the same seed gives the same sequence on every platform
and build, any number of generators run side by side, and none of them draws
from or reseeds math.random.
Exposed as the Random Luau global; scripts call Random.new(...) with no
require.
Exports
Random.new(seed?) -> RandomGenerator: a generator seeded from any finite number. Every distinct number is a distinct stream (-0and0are one). With no seed it takes one from the clock.Random.fromState(state) -> RandomGenerator: a generator at the positionrng:state()recorded. It draws exactly what the recorded generator drew next.
Methods (called with :)
rng:nextNumber() -> number: a float in[0, 1)carrying 53 random bits.rng:nextNumber(min, max) -> number: a float in[min, max).min == maxreturnsmin.rng:nextInteger(min, max) -> number: an integer in[min, max], both ends included, every value equally likely. Bounds are integers within+/-2^53.rng:clone() -> RandomGenerator: an independent generator at the same position.rng:state() -> string: the position as 32 hex digits, a value a save, a record or a network message holds.
local rng = Random.new(1234)
local roll = rng:nextInteger(1, 6)
local saved = rng:state()
local resumed = Random.fromState(saved) -- draws what rng draws next
math.random
math.random is one stream per Luau VM, shared by every script that VM runs,
and math.randomseed reseeds it for all of them. Use it for draws nothing has
to reproduce; use a Random for anything that must come out the same again.
Algorithm
The stream is xoshiro128** (Blackman and Vigna) over four 32-bit words,
computed with bit32, so every engine build and platform computes the same
words.
- Seeding. The seed's IEEE-754 double is read as a low and a high 32-bit
word.
s0 = fmix32(lo ~ 0x9E3779B9),s1 = fmix32(hi ~ 0x7F4A7C15),s2 = fmix32(s0 ~ rotl(s1, 16) ~ 0x85EBCA6B),s3 = fmix32((s0 + s1) mod 2^32 ~ 0xC2B2AE35), wherefmix32is the MurmurHash3 32-bit finalizer and~is exclusive or. - Floats.
nextNumber()takes the top 27 bits of one output and the top 26 of the next:((a >> 5) * 2^26 + (b >> 6)) * 2^-53. - Integers.
nextIntegerdraws a 32-bit output (a 53-bit value when the range holds more than2^32integers) and rejects the draws past the largest multiple of the range size, so no value is favoured. - Reference.
Random.new(42):state()is92ca2f0eaa64209e59489e0d87b32caf, and its firstnextNumber()is0.8002608102920379. Therandomtest suite holds the first 1000.