How do I do random object based on chance

I gave tags to tools. The tags are, “UltraRare”,“Rare”,“Uncommon”,“Common”. So basiclly I have one script that caculates the chances and another script that spawns the objects with the tags on it. I want to make a object spawn based on the rarity. Problem is I don’t know how to go about this.
ChanceModule:

local WeightedChanceModule = {}
--//This module basiclly handles the chance system\\--
function WeightedChanceModule.RandomItem(items)
	local totalweight = 0
	
	for _,ItemData in pairs(items) do
		totalweight = totalweight + ItemData[2]
	end

	local object = math.random(1,totalweight)
	local counter = 0 
	for _,ItemData in pairs(items) do
		counter = counter + ItemData[2]
		if object <= counter then
			return ItemData[1]
		end
	end
end

return WeightedChanceModule

RandomObjectModule:

local RandomObjectModule = {}

--//Functions\\--
function RandomObjectModule.SetTable(table1,objectDirectory,pattern)
	for index,value in pairs(objectDirectory:GetChildren()) do
		if string.find(value.Name,pattern) then
			table.insert(table1,value)
		end
	end
end

function RandomObjectModule.ChoseRandomObject(table1)
	local Obj = math.random(1,#table1)
	local picked_value = table1[Obj]
	
	return picked_value
end

return RandomObjectModule

Main Script:

local item = WeightedChanceModule.RandomItem(table)
local tool = RandomObjectModule.ChoseRandomObject(tools) --I wanna make it so that if common item is picked, then tool with the tag of common gets picked

Not entirely sure what you’re asking about here. There’s a lot of functions that take in some arbitrary types.

Which one is the problem?

And what structure do table1 or ItemData have?

As long as you know the total weight of all your ojects you can simply multiply the total weight with math.random(), then iterate through all of them and subtract each individual weight from that value until it goes below 0.
For example:

local weightedValues = {
	{weight = 10, value = "10%"},
	{weight = 60, value = "60%"},
	{weight = 30, value = "30%"}
}

local totWeight = 0

for _, v in ipairs(weightedValues) do
	totWeight += v.weight
end

local function getRandomWeighted()
	local weight = totWeight * math.random()
	for _, v in ipairs(weightedValues) do
		weight -= v.weight
		if weight <= 0 then
			return v
		end
	end
end

print(getRandomWeighted().value)

I can try this when I get home. Is it possible for me to do this with a module though?

I don’t exactly know the situation but let’s say it’s when a character opens a chest, after the chest had Been opened you’d do something like

local rn = math.random(1,10) -- this will pick a number between 1 and 10, now we can do something with it
if rn == 1 or 2 or 3 or 4 then -- this would give the chance to get a common tool to be 4/10, or a 40% chance, you could use any numbers of course
local CommonToolNumber = math.random(1,8) --i just picked 8 cos why not, but you would put how many common tools you have of course
if CommonToolNumber == 1 then
--here you would put a code to give the player 1 of the common tools
else if CommonToolNumber == 2 then
--insert code to give another common tool here

--you'd continue going until... 
if CommonToolNumber == 8 then
--blah blah blah

--end the code with and end or 2
else if rn == 5 or 6 or 7 then
local RareToolNumber = math.random(1,3) --assuming there are only 3 rare tools
if RareToolNumber == 1 then
--insert code to give 1 of the 3 rare tools

-- until you're done

else if rn == 8 or 9 then
local EpicTooNumber = math. random(1,4) -- assuming there are 4 epic tools

And so on until you’re done, obviously, make or so that it suits you, maybe you’ll have legendary tools or something I don’t know, whatever us best for you.

So something like that, I guess you could do it a more efficient way maybe using for i, v in pairs() do, but this is also a way, gave fun!