How do I create an RNG system with very tiny chances?

I am currently making a mix of a rarity and incremental game, where cubes spawn as a certain rarity that give you more cash when you touch them depending on their rarity. The most difficult part I’ve found about making the rng system is applying multipliers you buy with cash. I did manage to create a basic function for it:

local highestRarity = 1
local ran = r:NextNumber()
for i, v in ipairs(rarites) do
	-- print(v[1].." chance: ".. 1-(1-1/v[2])^multi)
	if ran <= 1-(1-1/v[2])^multi then
		highestRarity = i
	end
end
totals[highestRarity] += 1
print(ran.." Highest Rarity: "..highestRarity)

the rarity module:

local rarities = {}

rarities[1] = {"Common", 1}
rarities[2] = {"Uncommon", 3}
rarities[3] = {"Rare", 5}
rarities[4] = {"Epic", 9}
rarities[5] = {"Legendary", 25}


return rarities

Which works for those rarities, but it soon becomes very limited as I create higher rarities. It seems to stop working in the 1/1t+ range even with high multiplierswhich wont work for my game since rarities will very quickly get into huge numbers. Even though Random.new() has a massive range above 1, it’s very limited in decimal places. And while I could do

if r:NextNumber(0, v[2]/multi) <= 1 then

it wouldn’t be very realistic since a probability should never be 100% or more than 100% with multipliers. Flipping a coin twice doesn’t give you a 100% chance of getting heads, it gives you a 75% chance.
How would I create a rng system with very large numbers?

1 Like