How to pick a value from a table by chance?

I have multiple values listed in a table, and each have their own “Rarity” property. The rarity is measured in percent, so 30 would be 30/100 or 30%. I want to make a spin system, but I want to know how to make a picker which analyzes each rarity and then picks after analyzing. I want it so there’s a higher chance of getting something with a higher rarity compared to something with a lower rarity. Here’s what my table looks like. As you can probably tell, it’s in a local script:

local spincache = {
{ Ability = “A”, Rarity = 30 },
{ Ability = “B”, Rarity = 20 },
{ Ability = “C”, Rarity = 1 },
{ Ability = “D”, Rarity = 0.2 },
{ Ability = “E”, Rarity = 5 }
}

1 Like
local function getRandom(table)
	local random = math.random(1, 100)
	local total = 0
	for _, v in ipairs(table) do
		total += v.Rarity
		if random <= total then
			return v.Ability
		end
	end
	return nil
end

When the total is added 30 for the first iteration, you have a 30% chance of being lower than 30
for the next iteration, you have a 20% chance of being lower than 50 and more than 30,
and so on

4 Likes

Thanks for the answer. Do I need to replace “table” with the name of my table?

it’s a function with a return value

1 Like

Hey. I altered your script a little to match my game. Here’s what it looks like:

local spincache = {
	{ Ability = "A", Rarity = 1 },
	{ Ability = "B", Rarity = 5 },
	{ Ability = "C", Rarity = 5 },
	{ Ability = "D", Rarity = 5 },
	{ Ability = "E", Rarity = 20 },
	{ Ability = "F", Rarity = 20 },
	{ Ability = "G", Rarity = 20 },
	{ Ability = "H", Rarity = 20 },
	{ Ability = "I", Rarity = 60 },
	{ Ability = "J", Rarity = 60 },
	{ Ability = "K", Rarity = 100 },
	{ Ability = "L", Rarity = 100 }
}
local function getRandom(table)
	local random = math.random(0, 100)
	local total = 0
	print(random)
	for _, v in ipairs(table) do
		total = v.Rarity
		if random <= total then
			print(total)
			print(v.Ability)
			return v.Ability
		end
	end
	return nil
end
getRandom(spincache)

This script mostly works, but the problem is that it goes through each thing in the table by the order of the table. This means that if I have 20 things with the same rarity, only the first thing in the table will be picked. How can I fix this?

your table adds up to 416%… and last time I remember, that’s not how percentages work

local function getTotalPercentage(table)
	local total = 0
	for _, v in ipairs(table) do
		total += v
	end
	return total
end

local function getRandom(table)
	local random = math.random(1, getTotalPercentage(table))
	local total = 0
	for _, v in ipairs(table) do
		total += v.Rarity
		if random <= total then
			return v.Ability
		end
	end
	return nil
end

if you want to ignore the percentage, then do this

Thanks, although it ended up with this error:


Line 18 being total += v

man, you should learn the basics instead of asking for script you don’t even understand.

if you were to understand it, it’d be an easy spot why it’s throwing an error

just an advice

but to fix it, you do total += v.Rarity

Alright, thank you. I’m extremely new to tables, hence such a basic question being asked on the original topic. I also forgot a lot of the stuff I used to know because of a year long break from developing.