Issues with a rarity system

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve?
    Im trying to make a luck/rarity system
  2. What is the issue? Include screenshots / videos if possible!
    with this system, when i ger the rarest option it just returns nil (I feel I understand why but I also dont)
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
This is a module script and it was ai generated so my understanding of it isn’t the best but i mostly get it

local rarities = {"Common Card", "Red Card", "Black Card", "Gold Card"}
local probabilities = {0.50, 0.25, 0.10, 0.05}

TestPacket.RandomCard = function()
	local r = math.random()
	for i, p in ipairs(probabilities) do 
		if r >= p then
			return rarities[i]
		end
	end
end


Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

The reason it may be returning nil is because if math.random() would return anything below 0.05 (like 0.04), it would not pass the r>=p condition for any of the values in the probabilities list, causing it to not return anything (therefore being nil). As a solution you can either change the probability values to have one that’s 0, or you can add a line of code after the ipairs loop which returns a set value, which will only be reached if the thread has not returned anything yet.

Example:

local rarities = {"Common Card", "Red Card", "Black Card", "Gold Card"}
local probabilities = {0.50, 0.25, 0.10, 0.05}

TestPacket.RandomCard = function()
	local r = math.random()
	for i, p in ipairs(probabilities) do 
		if r >= p then
			return rarities[i]
		end
	end
        return(rarities[1])
end

Found this really useful module the other day called Lootplan and it basically handles all of that stuff for you

I like to use this simple system called roulette wheel selection. Here, see if this works for you:

local cards = {
    {Item = "Common Card", Weight = 60},
    {Item = "Red Card", Weight = 25},
    {Item = "Black Card", Weight = 10},
    {Item = "Gold Card", Weight = 5},
}
-- This table is used to store the cards and their weights.
-- Weight = Probability of the card being selected.

local function GetRandomCard()
    local totalWeight = 0
    -- Used to store the total weight (percentage) of all the cards.
    for _, card in pairs(cards) do
        totalWeight += card.Weight
    end

    local random = math.random(0, totalWeight)
    -- Generates a random number between 0 and the total weight.
    local currentWeight = 0
    -- Used to store the current weight of the card being checked.
    for _, card in pairs(cards) do
        currentWeight += card.Weight
        -- Adds the weight of the current card to the current weight.
        if random <= currentWeight then
            -- If the random number is less than or equal to the current weight, then the card is selected.
            return card.Item
            -- Returns the card.
        end
    end
end

local selectedCard = GetRandomCard()

Alright, it wasn’t working. I forgot this system works with 100 weight, not 1.

Your probability adds up to 0.90.

You should either add another chance or increase the odds of another.