Log inGet started

Random

Updated October 20, 2026

Seeded random-number generators. Each generator holds its own stream, so any number of independent, reproducible sequences run side by side, and none of them draws from or reseeds math.random.

A generator made from a seed produces the same sequence on every platform and every build: the same seed gives the same numbers on a native engine and in the browser, run after run. local rng = Random.new(1234) -- the same seed, the same stream local roll = rng:nextInteger(1, 6) -- integer in [1, 6], both ends included local t = rng:nextNumber() -- float in [0, 1) local x = rng:nextNumber(-5, 5) -- float in [-5, 5) Members every generator answers: rng:nextNumber() float in [0, 1), 53 random bits rng:nextNumber(min, max) float in [min, max) rng:nextInteger(min, max) integer in [min, max], both ends included, every value equally likely rng:clone() an independent generator at the same position: it draws what this one would draw next rng:state() the position as a 32-character hex string a save, a record or a network message can hold Random.fromState(rng:state()) makes a generator that continues the sequence from where rng stood, so a saved level, a replayed AI decision or a regenerated design picks up exactly where it left off. Random.new() with no seed takes its seed from the clock. math.random is a different thing: one stream per Luau VM, shared by every script in that VM and reseeded for all of them by math.randomseed. A generator here is a value of its own; drawing from one moves no other. The algorithm is xoshiro128** (Blackman and Vigna) over 32-bit words. A seed is read as the bits of its IEEE-754 double: the low word and the high word each go through the MurmurHash3 32-bit finalizer to give the first two state words, and the last two are mixed from those, so every distinct number is a distinct stream. nextNumber() joins the top 27 bits of one output and the top 26 of the next into a 53-bit fraction; nextInteger rejects the draws that would bias the range.

require("@builtin::modules.random") -- Random (also available as global 'Random')

The Random namespace: 4 functions.

globals/Random/fromState

Random.fromState(state: string) -> RandomGenerator

Make a generator that continues a sequence from a position rng:state() recorded. It draws exactly what the recorded generator drew next, so a save holds the string and a load picks the stream up.

Parameters

  • state string — The 32-character hex string rng:state() returned.

Returns RandomGenerator — A generator at that position.

local resumed = Random.fromState(Random.new(7):state())

globals/Random/new

Random.new(seed: number?) -> RandomGenerator

Make a generator with its own stream. The same seed gives the same sequence on every platform and build; any number of generators run side by side without moving one another or math.random. With no seed it takes one from the clock, and rng:state() records where it stands.

Parameters

  • seed number (optional) — Any finite number; every distinct number is a distinct stream. Omitted, the clock seeds it.

Returns RandomGenerator — A generator answering :nextNumber(), :nextNumber(min, max), :nextInteger(min, max), :clone() and :state().

local roll = Random.new(42):nextInteger(1, 6)
local jitter = Random.new(42):nextNumber(-0.5, 0.5)
local clockSeeded = Random.new()

modules/Random/fromState

fromState(state: string): RandomGenerator

Make a generator that continues a sequence from a position rng:state() recorded. It draws exactly what the recorded generator drew next, so a save holds the string and a load picks the stream up.

Parameters

  • state string — The 32-character hex string rng:state() returned.
local resumed = Random.fromState(Random.new(7):state())

modules/Random/new

new(seed: number?): RandomGenerator

Make a generator with its own stream. The same seed gives the same sequence on every platform and build; any number of generators run side by side without moving one another or math.random. With no seed it takes one from the clock, and rng:state() records where it stands.

Parameters

  • seed number? (optional) — Any finite number; every distinct number is a distinct stream. Omitted, the clock seeds it.
local roll = Random.new(42):nextInteger(1, 6)
local jitter = Random.new(42):nextNumber(-0.5, 0.5)
local clockSeeded = Random.new()
  • api
  • reference