This is a script I’m working on to pick random items from a table based on its weight but it doesn’t seem to pick based on weight all the time. Occasionally while testing online, one of the items is in the table is picked every time, usually the one with the lowest weight. I’ve tired running a simulation when the server starts but the numbers check out. Sometime when it’s not picking the same item over and over, it picks the rarest one much more frequently that it should.
Script:
local RarityTable= WeightedTable.new({ Rare = 50, Uncommon = 75, Common = 100})
print(RarityTable:ChooseRandom()) --Rare = 22%, Uncommon = 33%, Common = 44%
Simulation code
spawn(function() --won't let me indent for some reason
local probs = {}
for i=1,100 do
wait(.1)
local item = RarityTable:ChooseRandom()
probs[item] = (probs[item] ~= nil and probs[item] + 1) or 0
end
print("DONE SIMULATING",probs["Rare"],probs["Uncommon"],probs["Common"])
end)
ModuleScript:
local WeightedTable = {}
WeightedTable.__index = WeightedTable
function WeightedTable.new(tab)
local this = {}
setmetatable(this, WeightedTable)
this.Ranges = {}
this.Sum = 0
this.Probability = {}
local rangeIndex = 0
for key,value in pairs(tab) do
this.Ranges[key] = {rangeIndex,rangeIndex + value}
rangeIndex = rangeIndex + value + 1
end
this.Sum = rangeIndex - 1
return this
end
local random = Random.new()
function WeightedTable:ChooseRandom()
local randomNumber = random:NextInteger(0,self.Sum)
--see what number range the random number falls under
for key,range in pairs(self.Ranges) do
if randomNumber >= range[1] and randomNumber <= range[2] then
return key
end
end
end
return WeightedTable