Simple RNG opensource module

RNG Module

The RNG module provides a utility to generate weighted random selections based on specified rarity percentages. This module is designed for use in Luau (Roblox’s Lua dialect) and can be particularly useful in games or systems where probability-based outcomes are required, such as loot tables, random events, or gacha mechanics.


Install: GitHub | Studio Model


Features

  • Rarity-Based Probability: Define multiple
  • High Precision: Su
  • Efficient Lookups: Uses NumberRange to map percentages to rarity items for fast retrieval.

API Documentation

Types

RarityPercents

A list of rarities and their associated probabilities.

export type RarityPercents = {
    { rarity: string, percent: number }
}

RandomItems

A dictionary mapping NumberRange objects to rarity strings.

export type RandomItems = {
    [NumberRange]: string
}

Functions

RNG.new(rarityPercents: RarityPercents): RNG

Creates a new RNG object.

  • Parameters:
    • rarityPercents: A list of rarity strings and their corresponding percentages. The total of all percentages must equal 100.
  • Returns:
    • A new instance of the RNG object.

RNG:Roll(): string

Performs a random roll and returns a rarity based on the defined percentages.

  • Returns:
    • A string representing the selected rarity.

Usage Example

local RNG = require(path.to.RNG)

local rarities = {
    { rarity = "Common", percent = 70 },
    { rarity = "Rare", percent = 29.99999999999 },
    { rarity = "Legendary", percent = 0.00000000001 },
}

local rng = RNG.new(rarities)

local result = rng:Roll()
print("You got:", result)

Internals

getDecimalPlaces(num: number): number

Calculates the number of decimal places in a given number.

isNumberInRange(num: number, numRange: NumberRange): boolean

Checks if a number is within a specified NumberRange.

_Initialize(rarityPercents: RarityPercents)

Initializes the RNG object by calculating the mapping of NumberRange to rarity strings based on percentages.


Notes

  • The total percentage of all rarities must sum to exactly 100. If this condition is not met, the module will throw an assertion error.
  • Internally, the module handles decimal precision dynamically, so you can use fractional percentages like 33.3 or 66.7 with confidence.

This module ensures a robust and flexible approach to probability-based randomization for your Roblox projects.

7 Likes

thanks to your resource, people can now engage in gambling more easily, which is deeply concerning. instead of dedicating your time and effort to creating tools that contribute to this issue, perhaps you should focus on developing resources that are actually helpful and constructive. by supporting this, you’re only contributing to a problem that puts vulnerable individuals, especially children, at risk of being exposed to harmful gambling behaviors.

2 Likes

I hope you understand that this isn’t the point of this resource and can be useful for so many other purposes. If it was meant for that it would clearly state that. Stop yapping nonsense and think about what your saying before putting it on here. If this was classified as gambling then why don’t you oppose litterally every game on roblox. If you’re really this against this then don’t go on roblox, its that simple.

This module ensures a robust and flexible approach to probability-based randomization for your Roblox projects.

“Probabilty based randomization” is what it is and this is really useful for lets say map randomization for example. It says you can use it for stuff like that, doesn’t mean they’re promoting gambling and thats up to the actual game developer.

5 Likes

Feels rather complex for a simple concept like this. I don’t think you really need OOP for this at all and a simple function which just accepts a table works just fine. Not a huge fan of the fact that you need to make sure that the percentages add up to a total of 100 either.

A simple function like this is all you need:

--| Variables
local rng = Random.new()

local rarities = {
	Common = 90,
	PI = math.pi,
	PointOne = 0.1,
	RandomOrder = 200,
	Omega = 0.001
}

--| Functions
local function roll(rarities : {string : number}) : string
	local weight = 0

	for _, v in rarities do
		weight += v
	end
	
	local randomNumber = rng:NextNumber(0, weight)
	weight = 0
	
	for k, v in rarities do
		weight += v
		if weight >= randomNumber then
			return k
		end
	end
end

--| Start
while task.wait() do
	print(roll(rarities))
end

All that bloat also makes the performance worse, but only by a few hundred microseconds. The initialization gets hurt the most as it’s a few thousand microseconds slower than my simple function.


(used the same rarities that you gave in your example)

Your module also has a bunch of bugs that I had to fix in order to benchmark it.

4 Likes

*you’re

i’m not yapping. if i wanted to get a random map,i have no need for any modules or any complex solutions. all i would need to do is select a random child element from a designated ‘maps’ folder,

what if you wanted to make a certain map more common and rare. Anyways lets just leave it here. Don’t even start with the grammar corrections mate.

6 Likes

:man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming:

5 Likes

yes. no? … yes… no. the example provided are classic examples of predatory gambling strategies, but it’s very clear that it isn’t the only purpose. but be real, how is this gonna be used? maliciously. the answer is maliciously.