Help with rng system

ok so im trying to make a rng system just like anime adventure had one

the problem is that the loop is going to the legendary first but it should go first secret the mythical etc
image

i tried switching to numerical indexes for it to work but its not a very good option so i was wondering if anyone had another solution for me pls

local module = {}

local banner = {}

module.list = {
	["Secret"] = {"Secret King", "Ruffy skibidi"},
	["Mythical"] = {"Garp", "Baboucheka"},
	["Legendary"] = {"Legende omg", "Skibidi pomni"},
	["Epic"] = {"Cocomelon", "Todoroki"},
	["Rare"] = {"Rare ", "OMG A RARE"}
}

module.Chances = {
	["Secret"] = 1,
	["Mythical"] = 25,
	["Legendary"] = 200,
	["Epic"] = 1525,
	["Rare"] = 8249
}

local totalChance = 0
for i, v in module.Chances do
	totalChance += v
end

module.CreateBanner = function()
	local seed = math.floor((os.time())/3600)
	local RNG = Random.new(seed)
	for i, v in module.list do
		local unit = v[RNG:NextInteger(1, #v)]
		banner[i] = unit
		workspace.Banner.SurfaceGui:WaitForChild(i).Text = unit
	end
end

module.Spin = function(boost, number)
	local boost = boost or 1
	local ret = {}
	
	for i = 1, (number or 1) do
		local number = math.random(1, totalChance)
		local counter = 0
		
		for rarity, weight in module.Chances do
			print(rarity)
			counter += weight
			if number <= counter * boost then
				ret[i] = banner[rarity]
			end
		end
	end
	return ret
end

return module

ok so this is my module script i use for rng

2 Likes

Dictionaries are not sorted, iterating through them will give you an arbitrary order.

1 Like

yeah i know but using an arraw was a pretty hard to maintain option caus it would caus a lot of converting every time beetween the actual rarity and the number
so i was wondering if you had a better idea of doing this

1 Like

You don’t need an array to accomplish this. I have my own open source WeightedRandom module you can use or reference from (the source code is available, the Next function is what you are looking for):

local module = {}

local banner = {}

module.list = {
	["Secret"] = {"Secret King", "Ruffy skibidi"},
	["Mythical"] = {"Garp", "Baboucheka"},
	["Legendary"] = {"Legende omg", "Skibidi pomni"},
	["Epic"] = {"Cocomelon", "Todoroki"},
	["Rare"] = {"Rare ", "OMG A RARE"}
}

module.Chances = {
	[1] = 1, -- Secret etc
	[2] = 25,
	[3] = 200,
	[4] = 1525,
	[5] = 8249
}

module.Convert = {
	[1] = "Secret", 
	[2] = "Mythical",
	[3] = "Legendary",
	[4] = "Epic",
	[5] = "Rare"
}

local totalChance = 0
for i, v in module.Chances do
	totalChance += v
end

module.CreateBanner = function()
	local seed = math.floor((os.time())/3600)
	local RNG = Random.new(seed)
	for i, v in module.list do
		local unit = v[RNG:NextInteger(1, #v)]
		banner[i] = unit
		workspace.Banner.SurfaceGui:WaitForChild(i).Text = unit
	end
end

module.Spin = function(boost, number)
	local boost = boost or 1
	local ret = {}
	
	for i = 1, (number or 1) do
		local number = math.random(1, totalChance)
		local counter = 0
		
		for rarity, weight in module.Chances do
			print(module.Convert[rarity])
			counter += weight
			if number <= counter * boost then
				ret[i] = banner[module.Convert[rarity]]
			end
		end
	end
	return ret
end

return module

its working now but is it a good method od doing things ?