Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

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 (-0 and 0 are one). With no seed it takes one from the clock.
  • Random.fromState(state) -> RandomGenerator: a generator at the position rng: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 == max returns min.
  • 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), where fmix32 is 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. nextInteger draws a 32-bit output (a 53-bit value when the range holds more than 2^32 integers) and rejects the draws past the largest multiple of the range size, so no value is favoured.
  • Reference. Random.new(42):state() is 92ca2f0eaa64209e59489e0d87b32caf, and its first nextNumber() is 0.8002608102920379. The random test suite holds the first 1000.