Weighted luck system only chooses highest rarity

I’ve been trying to make a weighted luck system like the game infinite rarities. But my problem is that it only chooses the highest rarity each time instead of starting at common. I’ve tried asking chatgpt for help and looking for public resources but couldn’t seem to find anything. Could anyone help me with this?

this is the script im using:

local rarities = {
	{name = "Common", weight = 1},
	{name = "Uncommon", weight = 5},
	{name = "Rare", weight = 25},
	{name = "Epic", weight = 125},
	{name = "Legendary", weight = 625},
	{name = "Mythical", weight = 3125},
	{name = "Divine", weight = 15625},
	{name = "Ethereal", weight = 78125},
	{name = "Cosmic", weight = 390625},
	{name = "Galactic", weight = 1953125},
	{name = "Universal", weight = 9765625},
	{name = "Omniscient", weight = 48828125},
	{name = "Transcendent", weight = 244140625},
	{name = "Infinite", weight = 1220703125},
	{name = "Eternal", weight = 6103515625},
	{name = "Mythic Eternal", weight = 30517578125},
	{name = "Cosmic Eternal", weight = 152587890625},
	{name = "Galactic Eternal", weight = 762939453125},
	{name = "Universal Eternal", weight = 3814697265625},
	{name = "Omniscient Eternal", weight = 19073486328125}
}

local luckModifier = 1


local totalWeight = 0
local maxWeight = 0
for i, rarity in ipairs(rarities) do
	rarity.weight = rarity.weight * luckModifier
	totalWeight = totalWeight + rarity.weight
	if rarity.weight > maxWeight then
		maxWeight = rarity.weight
	end
end

for i, rarity in ipairs(rarities) do
	rarity.probability = rarity.weight / totalWeight
end

local currentRarity = rarities[1]
local currentProbability = currentRarity.probability

while true do
	wait(1)
	local randomNumber = math.random()

	local chosenRarity
	local chosenProbability = 0
	for i, rarity in ipairs(rarities) do
		chosenProbability = chosenProbability + rarity.probability
		if randomNumber <= chosenProbability then
			chosenRarity = rarity
			break
		end
	end

	if chosenRarity and chosenRarity.probability > currentProbability then
		print("New rarity: " .. chosenRarity.name)
		currentRarity = chosenRarity
		currentProbability = chosenRarity.probability
	end

	local currentWeight = math.floor(currentRarity.weight / luckModifier)
	if currentWeight >= 1000000 then
		currentWeight = math.floor(currentWeight / 1000000) .. "M"
	elseif currentWeight >= 1000 then
		currentWeight = math.floor(currentWeight / 1000) .. "K"
	end

	print("Current rarity: " .. currentRarity.name .. " (" .. currentWeight .. ")")
end

This can maybe help you

1 Like

thanks for the the reply, tho I cant really see how that helps. Could you explain?

Oh, i now understand that its useless…
Sorry! :frowning:

1 Like

no problem! ill try messing with chatgpt some more :slight_smile:

1 Like

Alright, while I’m very much late to the party, I would like to attempt to solve your problem just in case you haven’t found a fix yet!

From what I can gather from your code (I’m not extremely experienced in the field of weight), you have the weight set up so that the smallest number (1) is for the most common rarity.
Later in the script, at around the part of

for i, rarity in ipairs(rarities) do
		chosenProbability = chosenProbability + rarity.probability
		if randomNumber <= chosenProbability then
			chosenRarity = rarity
			break
		end
	end

I noticed that you are checking if the randomNumber is less than or equal to the chosenProbability, however I’m somewhat sure that because of how you set up the initial weights, the higher ones are the most likely to be pulled through this system.

All of this is to say that reversing the weights (e.g. making Common’s weight = 19073486328125) may fix your problem, since I think the largest weights are the most likely ones.

Hopefully this is of use!

2 Likes