What is wrong with my luck system?

This is a rarity system I made a bit ago, you can use it if you want to also compare it to your original rarity system and you’ll probably find what went wrong, since a lot of time its just math and conditions, but from a glance it does seem like you got close

Modulescript

function RaritySystem.TotalWeight(Rarities)
	local TotalWeight = 0
	for i, item in ipairs(Rarities) do
		TotalWeight = TotalWeight + item.weight
	end
	return TotalWeight
end

function RaritySystem.SelectRarity(Rarities)
	local RandomValue
	local SelectedRarity
	local TotalWeight = RaritySystem.TotalWeight(Rarities)
	repeat
		RandomValue = RandomSeed:NextNumber(0, 1)

		for _, Rarity in ipairs(Rarities) do
			if RandomValue <= Rarity.weight / TotalWeight then
				SelectedRarity = Rarity
				break
			else
				RandomValue = RandomValue - Rarity.weight / TotalWeight
			end
		end

		task.wait()
	until SelectedRarity ~= nil

	return SelectedRarity
end

function RaritySystem.CalculateAndDisplayChances(Rarities)
	local TotalWeight = RaritySystem.TotalWeight(Rarities)
	for _, Rarity in ipairs(Rarities) do
		local chance = (Rarity.weight / TotalWeight) * 100
		warn(Rarity.name .. ": " .. tostring(string.format("%.4f", chance)) .. "% chance")
	end
end

Serverscript
Use case

local RarityWeights = {name = "Common", weight = 70},
			{name = "Uncommon",  weight = 25},
			{name = "Rare", weight = 4},
			{name = "Epic", weight = 2},
			{name = "Legendary", weight = 0.01},
local SelectedRarity = RarityList.SelectRarity(RarityWeights) -- Gives rarity

Not too good with module scripts so you’re gonna have to walk me through here, keep getting unknown global for RaritySystem

Here is the modulescript
RaritySystem.lua (1.1 KB)

You can place into serverstorage

then to use it

local RarityList = require(game.ServerStorage:FindFirstChild("RaritySystem"))

local RarityWeights = {
{name = "Common", weight = 70},
{name = "Uncommon",  weight = 25},
{name = "Rare", weight = 4},
{name = "Epic", weight = 2},
{name = "Legendary", weight = 0.01},
}

local SelectedRarity = RarityList.SelectRarity(RarityWeights) -- Gives rarity
print(SelectedRarity)
-- if you want to see the chances 
RarityList.CalculateAndDisplayChances(RarityWeights)

Alright, its working, one more thing though, how do I make it give the actual stat

What I’d do would have a table with the stats like

local tablestats = {
["Common"] = {
Multiplier = 0.01
}
}
local SelectedRarity = RarityList.SelectRarity(RarityWeights) 

local statgot = tablestats[SelectedRarity] -- if you get the common rarity it'll grab it from the table and then you can do whatever you want with it like

Stat.Multiplier += statgot.Multiplier

Mind giving me an example of how I could get the stat added into the datastore, because I already have a system of making it multiply everything, I all I need is for the rune to give whatever stat it rolls

EDIT: After tweaking it a little bit I finally got it to work, thanks!

got a question about the TotalWeight thing, is that the amount of luck the player has? So if I change that value in theory It would change the chances of everything in the rarityweights table?

I mean kind of, yes if you minus the total weight all the rarity chances go up. if you were to do this you’d have to have a formula for the luck stat like 1000 luck equal -1 to total weight then have a math.clamp on the value so it doesn’t go above the total weight and while your at it you’ll have to slowly add new rarities so the total weight also goes up.

So if I changed TotalWeight to a negative number like -2, a 1/1000 chance could be a 1/2000, and if its a positive number like 2, it would be a 1/500?

Nah I mean totalweight - 5 = higher chances. so if the chances were 1/500 then you minus 5 from the totalweight it would be like 1/350.

so what value would make a 1/500 become a 1/250, like what value would make the chance divide in half

Dividing the totalweight by half.

but the starting value is 0, my math brain ain’t working rn

function RaritySystem.TotalWeight(Rarities)
	local TotalWeight = 0
	for i, item in ipairs(Rarities) do
		TotalWeight = TotalWeight + item.weight
	end
	return TotalWeight -- here it returns the total weight of all the rarities
end

so if you want to change the totalweight

return TotalWeight - math.clamp(100 --[[ This being your luck formula]],0,TotalWeight)

So I change the if I make the 100 negative, it will increase chances of getting a 1/1000?

Here’s how it works

local RarityWeights = {
{name = "Common", weight = 70},
{name = "Uncommon",  weight = 25},
{name = "Rare", weight = 4},
{name = "Epic", weight = 2},
{name = "Legendary", weight = 0.01},
}

Lets say these are your weights, the total weight is all of these combined

70 + 25 + 4 + 2 + 0.01 = 101.01

Now that we have the total weight the way we get the rarity is by doing getting of the rarities like common and dividing it by the total weight

70/101.01 = 0.69 * 100 = 69%

So if we were to lower the total weight by minusing it

TotalWeight = 101.01
TotalWeight - 5 = 96.01

Then we check the chances for common again with this new totalweight

70/96.01 = 0.73 * 100 = 73% 

Here is where the problem starts though because if you lower the totalweight to much

70/65 = 1.07 * 100 = 107%

Now common has a 100% chance of getting picked which is bad because now you’ll only ever get commons.

What you want to do instead is change these weights

{
{name = "Common", weight = 70},
{name = "Uncommon",  weight = 25},
{name = "Rare", weight = 4},
{name = "Epic", weight = 2},
{name = "Legendary", weight = 0.01},
}

If you lower the common weights like “Common” and “Uncommon” than the total weight lowers and gives higher rarities a higher chance

{
{name = "Common", weight = 50},
{name = "Uncommon",  weight = 10},
{name = "Rare", weight = 4},
{name = "Epic", weight = 2},
{name = "Legendary", weight = 0.01},
}

The system in which you do this is for you to figure out.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.