Math and Space
Rand
Seeded random numbers with distributions, vectors, weighted picks, shuffle bags and reproducible forked streams.
Getting it
local Rand = Engine:GetPackage("Rand")Overview
Rand wraps Roblox's Random with everything you usually build on top of it. Create a generator with a seed to get the same sequence every time (procedural maps, replays, daily challenges), or use the shared generator when you don't care.
local Rand = Engine:GetPackage("Rand")
local rng = Rand.new(20261001) -- same seed, same results
local damage = rng:Int(10, 15)
local crit = rng:Bool(0.1) -- 10% chance
local loot = rng:Weighted({ Common = 70, Rare = 25, Legendary = 5 })
local spawn = rng:Pick(spawnPoints)
-- Quick one-off values
print(Rand.Shared:Float(0, 360))Forked streams
rng:Fork(key) derives an independent generator from the seed and a key. The same seed and key always give the same stream, no matter in which order you fork or how many values other streams have used. This keeps procedural generation stable when you add new features.
local world = Rand.new(seed)
local terrain = world:Fork("terrain")
local trees = world:Fork("trees")
local loot = world:Fork("loot") -- adding this later does not change terrain or treesConstructors
new
Rand.new(seed: number?): RngA generator with the given seed, or a random seed when you leave it out. Read it back with rng.Seed.
Shared
Rand.Shared: RngA ready-made generator with a random seed.
Numbers
| Method | Description |
|---|---|
:Int(a, b) | Whole number from a to b, inclusive. |
:Float(a?, b?) | Decimal number in [a, b), default [0, 1). |
:Bool(p?) | true with probability p (default 0.5). |
:Sign() | -1 or 1. |
:Angle() | Radians in [0, 2pi). |
:Gaussian(mean?, stdDev?) | Normally distributed (bell curve), default mean 0 and deviation 1. |
:Exponential(lambda?) | Exponentially distributed, good for "time until next event". |
:Dice(sides?, count?) | Sum of count dice with sides sides (default one six-sided die). |
Vectors, CFrames and colours
| Method | Description |
|---|---|
:UnitVector(), :UnitVector2() | Random direction of length 1. |
:InsideUnitSphere(), :InsideUnitCircle() | Random point inside a sphere or circle of radius 1, evenly spread. |
:Vector3InBox(min, max), :Vector2InBox(min, max) | Random point inside a box. |
:CFrame(position?) | Random rotation, at position or the origin. |
:Color3(saturation?, value?) | Random hue at the given saturation and brightness. |
Picking from lists
| Method | Description |
|---|---|
:Pick(array) | One random item. |
:PickIndex(array) | One random index. |
:Weighted(weights) | A key from { [key] = weight }, more likely the higher its weight. Weights must be 0 or more and not all 0. |
:Sample(array, n) | n different items. |
:Shuffle(array) | Shuffles the array in place and returns it. |
:Shuffled(array) | Returns a shuffled copy. |
Shuffle bags
rng:Bag(items: { any }): BagA bag hands out every item once in random order before any repeats, like drawing cards from a deck. Players perceive this as "fairer" than pure randomness: no long streaks of the same item.
local maps = rng:Bag({ "Desert", "Docks", "Factory", "Forest" })
local function nextMap()
if maps.IsEmpty then
maps:Reset()
end
return maps:Draw()
end| Member | Description |
|---|---|
Size: number, IsEmpty: boolean | Items left. |
:Draw() | Takes the next item. Errors when empty. |
:Reset() | Refills the bag with every item in a new random order. |
:ToArray() | The items still in the bag. |
Streams
| Method | Description |
|---|---|
:Fork(key?) | A new independent generator derived from this seed and key. Without a key, each call gives the next fork in sequence. |
:Clone() | A copy that continues from exactly the same position. |
:Reseed(seed?) | Starts over with a new seed (random when left out). |
Configuration
DefaultConfiguration/Packages/Rand10 settings| Setting | Default | What it does |
|---|---|---|
| DefaultFloatMin | 0 | Lower bound :Float() uses when none is passed. |
| DefaultFloatMax | 1 | Upper bound :Float() uses when none is passed. |
| DefaultBoolProbability | 0.5 | Chance :Bool() returns true when no probability is passed. |
| DefaultGaussianMean | 0 | Mean :Gaussian() uses when none is passed. |
| DefaultGaussianStdDev | 1 | Standard deviation :Gaussian() uses when none is passed. |
| DefaultExponentialLambda | 1 | Rate :Exponential() uses when none is passed. |
| DefaultDiceSides | 6 | Sides per die :Dice() rolls when none is passed. |
| DefaultDiceCount | 1 | Dice :Dice() rolls when no count is passed. |
| DefaultColorSaturation | 1 | Saturation :Color() uses when none is passed. |
| DefaultColorValue | 1 | Value/brightness :Color() uses when none is passed. |
Types
export type Rng
export type Bag