How to make percentage math

Several people asked this same question but never got a proper solution or didn’t explain it well.

I want to make a item that have a spawn-rate percentage. I want something similar like math.random(1,max numbers) that generates the number in a percentage and spawns it.

It would be great if someone can help me with it.

Spawn-rate:
70%, Blue item
25%, Green item
5% Red item

2 Likes

Hi, would this thread be of any help for you?

Basically, the pets rarity script in the thread modified to your use case would be something like this:

local itemTable = {
	percentageRarity = {0.7, 0.25, 0.05},
	items = {
		{
			name="Blue item";
			rarity="Common";
		},
		{
			name="Green item";
			rarity="Uncommon";
		},
		{
			name="Red item";
			rarity="Rare";
		}	
	}
}

local totalweight = 0

for _, v in ipairs(itemTable.percentageRarity) do
	totalweight = totalweight + v
end

local at = math.random() * totalweight

for key, v in pairs(itemTable.percentageRarity) do
	if at < v then
		print(itemTable.items[key].name)
		break
	end
	at = at - v
end
3 Likes

The above method is a pretty feasible way of going about this, but you could alternatively use folders instead of dictionaries. From this thread below, the same concept is applied; choose a random number, iterate throught the items and see which item is within or equal to the math.random() number.

Personally, I would use folders, apply the same concept, but loop the children of the chosen folder and spawn the tools using math.random.

The code modified to:

local ServerStorage = game:GetService("ServerStorage")
local ItemsFolder = ServerStorage.Items -- Folder for items

local Items = {
	{"Red",5}, -- SubFolder [Red folder within ItemsFolder] -- Red Items within folder
	{"Green",25}, -- GreenFolder [Green folder within ItemsFolder] -- Green Items within folder
	{"Blue",70},  -- BlueFolder [Blue folder within ItemsFolder] -- Blue Items within folder
}
local TotalWeight = 0

for _,ItemData in pairs(Items) do
	TotalWeight = TotalWeight + ItemData[2]
end

local function chooseRandomItem()
	local Chance = math.random(1,TotalWeight)
	local Counter = 0
	for _,ItemData in pairs(Items) do
		Counter = Counter + ItemData[2]
		if Chance <= Counter then
			local Item = ItemsFolder:FindFirstChild(ItemData[1]) -- Find Folder using weighted rarities. Make sure that the folder name, e.g "Red" is the name of the Red Folder
			local tool = Item:GetChildren()[math.random(1, #Item:GetChildren())] -- Pick a random children from folder, so an item
			local ClonedTool = tool:Clone() -- Clone()
			ClonedTool.Parent = game.Workspace -- Spawn the tool
			return ItemData[1]
		end
	end
end

chooseRandomItem()
3 Likes

thanks both of your solutions works!

2 Likes