Rng Random System

Hello there, I know you have probably seen all of the rng games popping up all over roblox and you might be asking yourself how the interworkings are made. Well here is some basic code that you can use to randomly get a item from a database based off of rarity!

local items = {
	{
		["Name"] = "Common",
		["Id"] = "common",
		["Rarity"] = 1
	},
	
	{
		["Name"] = "Uncommon",
		["Id"] = "uncommon",
		["Rarity"] = 5
	},
	
	{
		["Name"] = "Rare",
		["Id"] = "rare",
		["Rarity"] = 30
	},
	
	{
		["Name"] = "Epic",
		["Id"] = "epic",
		["Rarity"] = 80
	},
	
	{
		["Name"] = "Legendary",
		["Id"] = "epic",
		["Rarity"] = 300
	},
	
	{
		["Name"] = "God",
		["Id"] = "god",
		["Rarity"] = 100000
	}
}

local function getRandomItem()
	local possibleItems = {}
	for _, item in next, items do
		local number = math.random(1, item.Rarity)
		if number ~= 1 then continue end
		
		table.insert(possibleItems, item)
	end
	
	local bestItem = nil
	for _, possibleItem in next, possibleItems do
		if bestItem == nil then bestItem = possibleItem continue end
		if possibleItem.Rarity < bestItem.Rarity then continue end
		
		if possibleItem.Rarity == bestItem.Rarity then
			local switch = math.random(1, 2) == 1
			if not switch then continue end
		end
		
		bestItem = possibleItem
	end
	
	return bestItem
end

-- DELETE THIS
while true do
	local item = getRandomItem()
	print(item.Name, item.Id, string.format("1 / %d", item.Rarity))
	
	task.wait()
end

How dose it work:

Well it loops through all of the items in the items table and generates a random number from 1 to rarity. Then if the number is 1 it adds it to a list of possible items. Then It gets the best item from the list and returns it. Also if 2 items are the same rarity it just picks a random one.

How to use this code:

All you need to do is add your own custom items to the list.
You should probably put them inside a module script and then require that.

And then when you want to get a random item just call the getRandomItem() function!

Thanks for reading and if you want to see this system in action I made a video using something similar to this here.

7 Likes

why not use the already created weighted luck system?

weighted luck system seems like less lines, easier to understand, and it is very well explained (mathematically)

3 Likes

You know it is easier and take less line of code to simply do the table like that:

local items = {
    ["Name"] = {Id, Rarity};
    ["Name"] = {Id, Rarity}
}

Also, this method is not bad, i remade it in a better way if you want:

local PrizeTable = {
	["Rarity1"] = 1; --1/1
	["Rarity2"] = 1; --1/1
	["Rarity3"] = 10; --1/10
	["Rarity4"] = 100; --1/100
	["Rarity5"] = 1000; --1/1,000
	["Rarity6"] = 10000; --1/10,000
	["Rarity7"] = 100000; -- 1/100,000
	["Rarity8"] = 1000000; -- 1/1,000,000
	["Rarity9"] = 10000000; -- 1/10,000,000
	["Rarity10"] = 100000000; -- 1/100,000,000
	["Rarity11"] = 1000000000 -- 1/1,000,000,000
}

local function Randomize()
	local SelectedPrizes = {}
	local BestPrize = nil
	
	for Prize, Chance in pairs(PrizeTable) do
		if math.random(1, Chance) == 1 then
			table.insert(SelectedPrizes, Prize)
		end
	end

	for _, Prize in pairs(SelectedPrizes) do
		if BestPrize == nil then
			BestPrize = Prize
		elseif BestPrize and PrizeTable[Prize] > PrizeTable[BestPrize] then
			BestPrize = Prize
		elseif BestPrize and PrizeTable[Prize] == PrizeTable[BestPrize] and math.random(1, 2) == 1 then
			BestPrize = Prize
		end
	end
	
	return BestPrize
end

-- Test on 100,000 rolls - check the table result in output
local TotalPrizes = {}
for Count = 1, 100000 do
	local BestPrize = Randomize()
	
	if not (TotalPrizes[BestPrize]) then
		TotalPrizes[BestPrize] = 1
	else 
		TotalPrizes[BestPrize] += 1
	end
end
print(TotalPrizes)
9 Likes

This will help me alot, thanks! I have seen some other developers mention you could shorten the code by putting them in single line tables, which i may do. Thanks!

2 Likes

Just made my own and thought I would share it here. Same could be said for pretty much anything anyone has posted as there are alternate versions.

1 Like

Thank you sirrβ€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž β€Ž

how would i implement luck on this

You could either have two item lists or have a script that edits the item list if requirements are met.

Not a great choice, what if I need 2,3,4, and other luck multipliers?

Adjust the amount using a script.
Or roll it 2x, 3x or 4x and choose the best option

Yea no, that is definitely not performance or design wise since I have upto 100M luck in my rng game.

Well then do what Ive been saying the whole time: Adjust the amount using a script.

You could do a loop changing it by a multiplier

local items = require(ItemsList) --Set to your item list directory
local multiplier = 2 --Set to your luck multiplier

for i,v in items do
    v["Rarity"] = v["Rarity"] / multiplier 
end
1 Like

This doesnt change anything, you multiply all the items with the same number so theres no change.

Wdym?

If you have an item where the chance is 1 in 50 then divide it by your multiplier (lets say two)
and now its 1 in 25. which is more common.

What I mean is that if there is an item thats chance is 1 in 2 when divided it will by 1 in 1, which doesn’t do anything to make the more commons one more rare but even worse.

Then you can always have a limit to the maximum amount of times it can be divided or just add +1 (or any amount +) after it has been divided.

1 Like

Your solution does not work, just admit that.

It literally does, there is nothing wrong with it now. You should try it and see for yourself.

1 Like

So i was making a chance system and i guess got the right one and this also have a luck

local items = {
	{item = "Gold Coin", chance = 100},
	{item = "Silver Coin", chance = 50},
	{item = "Rusty Silver Coin", chance = 30},
	{item = "Bronze Coin", chance = 10}
}

function Chance(items,luck)
	if not tonumber(luck) then return end
	local totalWeight = 0
	for _, item in items do
		totalWeight += (1 / item.chance)
	end

	local randomPoint = math.random() * totalWeight
	local cumulativeWeight = 0

	for _, item in items do
		cumulativeWeight += (1 / item.chance) * luck
		if randomPoint <= cumulativeWeight then
			return item
		end
	end
end
1 Like

If you’re not happy with their solution, why don’t you just do it on your own?

I mean, if you’re so good at scripting, you wouldn’t need assisting, right?

3 Likes