Hi. I made a loot table function that uses weights. It works fine but I am just wondering if this is very inefficient or not.
local spawns = {
gun1 = {
weight = 5;
},
gun2 = {
weight = 1;
}
}
function choose()
local tbl = {}
for k,v in pairs(spawns) do
for x=1, v.weight do
table.insert(tbl, k)
end
end
return tbl[math.random(1, #tbl)]
end
print(choose())
It’s pretty inefficient, since a weight of 1000 would translate to 1000 table assignment calls; while not costly within itself, it can be; it’s inefficient.
We can fix that though, we can modify your current choose function’s logic to look like this:
function choose()
local sumOfWeights = 0
for _, entry in pairs(spawns) do
sumOfWeights = sumOfWeights + entry.weight
end
local randomValue = math.random(0, sumOfWeights)
for key, entry in pairs(spawns) do
if randomValue <= entry.weight then
return key
else
randomValue = randomValue - entry.weight
end
end
end
This would be more efficient, although I still don’t advise it. Here’s the current issues I see still:
It’s prone to typos. If you have a large loot table and misspell “weight”, good luck finding that bug easily. You should focus on a paradigm like functional programming or OOP where errors are more concise.
It’s not extendable at all. This works for one loot table in one case. This isn’t really ever advised in any scope of a project.
With these issues in mind, check here to see an example minimal implementation of loot tables.