How to make a Weighted Chance system for Case Opening systems!

Full credit go to @Trulineo since this is just an extended & more detailed version, if you have any questions you may ask him. This is my very first tutorial lol.

In this topic, your prerequisites needed to understand this topic / things you may want to read before going over this:

Tutorial:

Assuming that you have a module script that stores random rarities for each item that you got.
Module Script:

local Rarities = {
   {"Item1", 0.0001},  -- 1/1,000,000
   {"Item2", 0.01}, -- 1/10,000
   {"Item3", 0.1} -- 1/1,000
};

return Rarities;

Random.new()

There are different ways you could execute this, one using Random.new() or math.random, but since math.random was used in the topic above, I’ll just go with Random.new(). None of these are more efficient or biased to use as explained here:

So you’re going to want to make a function, so we can return the item that has been chosen:

local function GetItem()
   return Item;
end

but wait… there’s nothing to return, so what we’d have to do is give it something to return! By that you’re going to want to have a randomizer. Hopefully you know what were going to use here.

Using our local function above, were going to want to have a so called “weight”, randomizer variable (for later) and a the module script. Lets set that up:

local Rarities = require(--[[Module script]])

local function GetItem()
   local RNG = Random.new(); -- Randomizer variable
   local Counter = 0; -- Weight
end

Now that you’ve gotten your weight and randomizer variable, you’re going to want to loop through the table where you have your {Items, rarities} stored at.

local Rarities = require(--[[Module script]])

local function GetItem()
   local RNG = Random.new(); -- Randomizer
   local Counter = 0; -- Weight
   for i, v in pairs(Rarities) do 
	   Counter += Rarities[i][2] -- Here's where were going to set our counter for every item in the table, or shall we call it weight.
   end
end

Random.new():NextNumber()

Were going to be using this as it will return a pseudorandom integer between [Mini_Number, Max_Number];

This is really how the percentages are chosen.

local Rarities = require(--[[Module script]])

local function GetItem()
   local RNG = Random.new(); -- Randomizer
   local Counter = 0; -- Weight
   for i, v in pairs(Rarities) do 
	   Counter += Rarities[i][2] -- Here's where were going to set our counter for every item in the table, or shall we call it weight.
   end
   local Chosen = RNG:NextNumber(0, Counter); -- Randomize Counter
   for i, v in pairs(Rarities) do 
   	   Counter -= Rarities[i][2] 
   end
end

Now we have to find which item to return some how?? We can do this by returning the item that has been gotten through checking if our Weight is > Counter

local Rarities = require(--[[Module script]])

local function GetItem()
   local RNG = Random.new(); -- Randomizer
   local Counter = 0; -- Weight
   for i, v in pairs(Rarities) do 
	   Counter += Rarities[i][2] -- Here's where were going to set our counter for every item in the table, or shall we call it weight.
   end
   local Chosen = RNG:NextNumber(0, Counter); -- Randomize Counter
   for i, v in pairs(Rarities) do 
   	   Counter -= Rarities[i][2] 
       if Chosen > Counter then
		   return Rarities[i][1] -- This will return the first array in the table, which is the item we would like to give chosen randomly..
   	   end
   end
end

Since Lua uses 1-based indexing for arrays, we are able to successfuly return the first item in the array, the item we are going to be giving our players and you’re done! All we simply need to complete the code or give it a test run is by adding:

-- One time use.
print(GetItem())

-- Or to test this out once clicking a button:
script.Parent.MouseButton1Click:Connect(function()
   print(GetItem()) -- prints Item1(1/1M%), Item2(1/10K%) or Item3(1/1K%)
end)

Lets check the output:
image

and we’re good!!

A :heart: would be greatly appreciated while you’re here! Hopefully you’ve learned something new today! Feel free to add anything that I may not have went over on this topic! :cowboy_hat_face:

20 Likes