“elseif tab[1][2] < rand” is unnecessary, by the time it reaches that elseif the condition is already true

[lua]-- if you want these to be exact percentages, tally them up to 100

– or don’t, it doesn’t really matter

local t = {

{“very_rare_entity”, 5},

{“rare_entity”, 10},

{“common_entity”, 25},

{“very_common_entity”, 60},

}

– helper function to sort by ascending probability

local function sortProb(a, b)

return a[1] > b[1]

end

local function pickWeighted(t)

table.sort(t, sortProb)

```
local range = 0
for i, tbl in ipairs(t) do
range = range + tbl[2]
end
-- pick random number in the the range
-- this allows for probabilities that aren't integers e.g. 0.5%
local pick = math.Rand(1, range)
-- 1st item will be 0 + 5 = 5, so between 0 and 5 => 5%
-- 2nd item will be 5 + 10 = 15, so between 5 and 15 => 10%
-- 3rd item will be 15 + 25 = 40, so between 15 and 40 => 25%
-- 4th item will be 40 + 60 = 100, so between 40 and 100 => 60%
-- etc etc
local ct = 0
for i, tbl in ipairs(t) do
if pick < ct + tbl[2] then
return tbl[1]
end
ct = ct + tbl[2]
end
```

end

print(pickWeighted(t))[/lua]

if the iterator part is confusing, consider the following:

note the numbers on the bottom: if you think of each item as a percentage chance out of some total (in this case, 100) those are the start and end of the ranges, so you can pick a random number between 0 and 100 and it’ll have about a 25% chance of landing between 15.0 and 40.0.

thus the “ct = ct + tbl[2]”, which gets you the end of the last range and the start of the next one.