How to make a chance system with very rare chances

hello, so ive made this implementing the system into mine

function multiplyToWhole(egg)
	local multiplier = 1

	for _, pet in pairs(eggModule.Eggs[egg].Rarities) do --Essentially edits the multiplier so that even the smallest decimal will become whole
		local function zeros(amount)
			local total = "1"
			for i = 1, amount do
				total = total.. "0"
			end
			return total
		end
		local split = string.split(tostring(pet["Chance"]), ".")
		if split[2] ~= nil then
			if tonumber(zeros(string.len(split[2]))) > multiplier then
				multiplier = tonumber(zeros(string.len(split[2])))
			end
		end
	end
	print(multiplier)
	for _, pet in pairs(eggModule.Eggs[egg].Rarities) do
		pet["Chance"] = pet["Chance"] * multiplier
	end
end

eggModule.ChoosePetTest = function(eggToHatch)
	multiplyToWhole(eggToHatch)
	local TotalWeight = 0

	for _,PetData in pairs(eggModule.Eggs[eggToHatch].Rarities) do
		TotalWeight = TotalWeight + PetData["Chance"]
	end


	local Chance = math.random(1,TotalWeight)
	local Counter = 0
	for i,PetData2 in pairs(eggModule.Eggs[eggToHatch].Rarities) do
		Counter = Counter + PetData2["Chance"]
		if Chance <= Counter then
			local rarityTab = eggModule.Eggs[eggToHatch].Pets[i]
			local chosenPet = rarityTab[1] or rarityTab
			
			local cost = eggModule.Eggs[eggToHatch].Cost
			
			local rarity = PetData2["Rarity"]
			local percent = PetData2["Percent"]
			
			local legendtier
			if rarity == "Legendary" then
				legendtier = PetData2["Tier"]
			else
				legendtier = 1
			end

			local divinetier
			if rarity == "Divine" then
				divinetier = PetData2["Tier"]
			else
				divinetier = 1
			end
			
			return chosenPet, rarity, percent, cost, legendtier, divinetier
		end
	end
end

just wanted to know if this will work.
also just in case, i have my table setup like this:

["Common Egg"] = {
		Cost = 500,
		Secrets = {"Giant Kitty","TV"},
		Rarities = {
			["Doggy"] = {["Chance"] = 37.38595, ["Rarity"] = "Common",["Percent"] = "37.3"},["Kitty"] = {["Chance"] = 27.5, ["Rarity"] = "Uncommon",["Percent"] = "27.5"},
			["Bunny"] = {["Chance"] = 25, ["Rarity"] = "Rare",["Percent"] = "25"},["Bear"] = {["Chance"] = 10, ["Rarity"] = "Epic",["Percent"] = "10"},
			["Deer"] = {["Chance"] = 0.1, ["Rarity"] = "Legendary",["Percent"] = "0.1",["Tier"] = 1},["Dragon"] = {["Chance"] = 0.01, ["Rarity"] = "Legendary",["Percent"] = "0.01",["Tier"] = 2},
			["Totem (A)"] = {["Chance"] = 0.002, ["Rarity"] = "Legendary",["Percent"] = "0.002",["Tier"] = 3},["Totem (B)"] = {["Chance"] = 0.002, ["Rarity"] = "Legendary",["Percent"] = "0.002",["Tier"] = 3},
			["Giant Kitty"] = {["Chance"] = 0.00004, ["Rarity"] = "Secret",["Percent"] = "4e-05"},["TV"] = {["Chance"] = 0.00001, ["Rarity"] = "Secret",["Percent"] = "1e-05"}
		},
		Pets = {
			["Doggy"] = {"Doggy"}, ["Kitty"] = {"Kitty"},
			["Bunny"] = {"Bunny"},
			["Bear"] = {"Bear"}, ["Deer"] = {"Deer"}, ["Dragon"] = {"Dragon"}, ["Totem (A)"] = {"Totem (A)"}, ["Totem (B)"] = {"Totem (B)"}, ["Giant Kitty"] = {"Giant Kitty"}, ["TV"] = {"TV"}
		}
	},

nvm, it works fine,
how can i implement a x2 luck thing, everything im trying isnt working

On this line, you may be able to modify it so that it would look like this:

if plrOwnsMultiplierPass then
    --Another if statement to see if the rarity counts in the multiplier. Otherwise, the probability will remain the same.
   Counter = Counter + PetData2["Chance"] * 2
else
    Counter = Counter + PetData2["Chance"]
end

ah let me give that a try (chars)

wel actually, would this multiply all the chances (no difference), what if i want just the epics+ to be x2 only

nvm, i just added an if statement to check its rarity, thanks

im getting an error where it says “invalid argument #2 to random” (caused by ‘TotalWeight’ being 0

code:

local TotalWeight = 0

	for _,PetData in pairs(eggModule.Eggs[eggToHatch].Rarities) do
		TotalWeight = TotalWeight + PetData["Chance"]
	end


	local Chance = random:NextInteger(1,TotalWeight)

If the total weight has a value of 0 when the random is being called, you will get an error because the minimum is greater than the maximum. (1>0)

random:NextInteger(min,max)

yea, im aware of that but what i dont understand is why the total isnt over 1, it should be like way over 1

You have probably figured this out by now but The reason is because some of the total Weights end up below 1 when the chance for the item is lower than 1 since you are just basically setting the total weight to equal the chance there (TotalWeight = TotalWeight + PetData["Chance"]) due to the TotalWeight Starting as 0. I would either set TotalWeight To 1 or The Min Random Value to 0.

edit: oh wait random wont generate a decimal.
edit2: you could instead use Random.new():NextNumber(Min,Max) which can return decimals. Also, For Random.new():NextNumber(Min,Max) the Min and max can be reversed, it just returns a random number between the two inputed values.

May i ask,
This is me being a bit stupid but is the 2 for table 2%? or is it 20? or 0.2? sounds like a dumb question but yeah

1 Like

It’s the table index, basically the second item in that table, you mean the ‘ItemData[2]’ right?