I have a central idea on how to code this but every attempt I’ve tried its came out either the weights not correlating correctly or it just being finicky.
Basically what I’m going for is a function where it cycles through a list of objects, every object having a rarity ex) {Name = Iron; Rarity = 2}
It would then run math.random(1,2) say if it chose 1 then cycle to the next one until it doesn’t roll 1 and then choose that one as the chosen object. I dont know how/ what more to explain so yeah.
Lost the code since I was experimenting in the same script and didn’t save it so I’m just starting fresh and right.
This is not weighted randomness since you are not selecting items based on their weight, it’s literally 50-50. You want to iterate through their weights in lieu with a counter and set up the weights such that they add up to a nice number like 100
local rarities = {
[“Iron”] = 70;
[“Bronze”] = 25;
[“Gold”] = 5
}
local counter = 0
local num = math.random(1,100)
for item,rarity in pairs(rarities) do
counter += rarity
if counter >= num then
print(item..” selected!”)
break
end
end
local rarities = {
{ item = "Iron", weight = 70 },
{ item = "Bronze", weight = 25 },
{ item = "Gold", weight = 10 },
}
local ironNum = 0
local goldNum = 0
local bronzeNum = 0
local function getWeightedRandom(lootTable)
local totalWeight = 0
for _, entry in ipairs(lootTable) do
totalWeight = totalWeight + entry.weight
end
local randomWeight = math.random() * totalWeight
local cumulativeWeight = 0
for _, entry in ipairs(lootTable) do
cumulativeWeight = cumulativeWeight + entry.weight
if randomWeight <= cumulativeWeight then
return entry.item
end
end
end
for i = 1, 250 do
local reward = getWeightedRandom(rarities)
if reward == "Bronze" then
bronzeNum = bronzeNum + 1
elseif reward == "Iron" then
ironNum = ironNum + 1
elseif reward == "Gold" then
goldNum = goldNum + 1
end
end
print("Iron:", ironNum, "Bronze:", bronzeNum, "Gold:", goldNum)