How to make a chance system with a table?

Hello everyone! I’m trying to create a game where you get different rarities/qualities with your ‘paper’ That you make.

I have this:

Quality = script.Parent.Quality
Rarity = script.Parent.Rarity

QualityTexts = {"Bad", "Good", "Normal", "Nice", "Great"}
RarityTexts = {"Common", "Common+", "Rare", "Rare+", "Epic"}

-- Random Rarity and Quality
Quality.SurfaceGui.SIGN.Text = QualityTexts[math.random(1, #QualityTexts)]
Rarity.SurfaceGui.SIGN.Text = RarityTexts[math.random(1, #RarityTexts)]

I want to make a system where something like bad would be 50%, Good would be 30% and so on.

Any help appreciated. (I looked into things like weights but they were to confusing and couldn’t figure out how to add them to my game.

Hey, so I believe that weight is the correct way to go about this idea. I have some code that I believe should work for you.

Commented Code.
--// Defining the signs, I assume.
local Quality = script.Parent.Quality
local Rarity = script.Parent.Rarity

--// Setting the chances.
local Chances = {
	{Rarity = "Common"; Quality = "Bad", Chance = 50};
	{Rarity = "Common+"; Quality = "Good", Chance = 30};
	{Rarity = "Rare"; Quality = "Normal", Chance = 10};
	{Rarity = "Rare+"; Quality = "Nice", Chance = 7};
	{Rarity = "Epic"; Quality = "Great", Chance = 3};
}

--// This is the function to generate a random rarity
local function GetRandomRarity()
	local Sum = 0
	
	--// Loops through the chances and gets the amount of all the chances added up.
	--// For this example, the sum would be 100 because 50 + 30 + 10 + 7 + 3 = 100.
	for _, Table in ipairs(Chances) do
		Sum += Table.Chance
	end
	
	--// Generates a random integer between 1 and the sum.
	--// Lets say, for instance, it generated the number 72.
	local RNG = Random.new():NextInteger(1, Sum)

	local Weight = 0
	
	--// Loops through each possible table of chances.
	for _, Table in ipairs(Chances) do
		--// Difficult to visualise, but increases 'Weight' by the chance.
		--// This means that on the first loop, Weight would equal 50.
		--// On the second loop, Weight would equal 80.
		--// Then 90, then 97, and finally 100.
		Weight += Table.Chance
		--// Checks if the weight is greater than or equal to the RNG.
		--// So on the first loop it would be false, because 50 is not >= 72.
		--// However, on the second loop, 80 IS >= 72. Therefore, it would return the second table.
		if Weight >= RNG then
			--// Returns the rarity and quality.
			return Table.Rarity, Table.Quality
		end
	end
end

--// Gathers the random rarity and quality.
local RandomRarity, RandomQuality = GetRandomRarity()

--// Finally, sets the signs to the randomly generated values!
Quality.SurfaceGui.SIGN.Text = RandomQuality
Rarity.SurfaceGui.SIGN.Text = RandomRarity
Code without comments.
local Quality = script.Parent.Quality
local Rarity = script.Parent.Rarity

local Chances = {
	{Rarity = "Common"; Quality = "Bad", Chance = 50};
	{Rarity = "Common+"; Quality = "Good", Chance = 30};
	{Rarity = "Rare"; Quality = "Normal", Chance = 10};
	{Rarity = "Rare+"; Quality = "Nice", Chance = 7};
	{Rarity = "Epic"; Quality = "Great", Chance = 3};
}

local function GetRandomRarity()
	local Sum = 0
	
	for _, Table in ipairs(Chances) do
		Sum += Table.Chance
	end
	
	local RNG = Random.new():NextInteger(1, Sum)

	local Weight = 0
	
	for _, Table in ipairs(Chances) do
		Weight += Table.Chance
		if Weight >= RNG then
			return Table.Rarity, Table.Quality
		end
	end
end

local RandomRarity, RandomQuality = GetRandomRarity()

Quality.SurfaceGui.SIGN.Text = RandomQuality
Rarity.SurfaceGui.SIGN.Text = RandomRarity

I hope that this helps you out.

5 Likes