Need Help to Convert RNG

Hello, I need help with this, i don’t what it named

This is my List (Using weight chance)

local Items = {
{“Basic”, 1},
{“Basic+”, 0.5},
{“Basic++”, 0.1},
{“Regular-”, 0.01},
{“Regular”, 0.001},
{“Regular+”, 0.0005},
{“Regular++”, 0.0001},
{“Common-”, 0.00005},
{“Common”, 0.00001},
}

So my Question is how do i make that to RNG like 1/0 or 1/1 or 1/100
I was trying to make game like Sword Factory i tried to make board to show all rarities with the multiplier and RNG but i dont know how do i make the RNG? any solution for this?

This is code how to get the item

local multiplier = 1

for _, item in pairs(Items) do
local function zeros(amount)
local total = “1”
for i = 1, amount do
total = total… “0”
end
return total
end
local split = string.split(tostring(item[2]), “.”)

if split[2] ~= nil then
	if tonumber(zeros(string.len(split[2]))) > multiplier then
		multiplier = tonumber(zeros(string.len(split[2])))
	end
end

end

for _, item in pairs(Items) do
item[2] = item[2] * multiplier
end

local TotalWeight = 0

for _,ItemData in pairs(Items) do
TotalWeight = TotalWeight + ItemData[2]
end

function chooseRandomItem()
local Chance = math.random(1,TotalWeight)
local Counter = 0

for _,ItemData in pairs(Items) do
	Counter = Counter + ItemData[2]
	if Chance <= Counter then
		return ItemData[1]
	end
end

end

A simple way to calculate a random event is:

math.random(1,10) == 7

The expression above basically returns true or false based on a 1/10 chance. You can change the 10 and the 7 to any number (as long as 7 is lower than 10). For example,

math.random(1,1000) == 389

This would be an incredibly lucky event and would be 1/1000.

I hope this answers your question.

function something()
  if math.random(1,1000) == 389 then
    print('very lucky :o')
  else
    print('no luck!')
  end
end

i still not understand about that :sweat_smile:

can u give more example and explain more but use this

local Items = {
{“Basic”, 1},
{“Basic+”, 0.5},
{“Basic++”, 0.1},
{“Regular-”, 0.01},
{“Regular”, 0.001},
{“Regular+”, 0.0005},
{“Regular++”, 0.0001},
{“Common-”, 0.00005},
{“Common”, 0.00001},
}

Hi, I’m not sure of the use to that table. Sorry.

local Items = {
{“Basic”, 1},
{“Basic+”, 0.5},
{“Basic++”, 0.1},
{“Regular-”, 0.01},
{“Regular”, 0.001},
{“Regular+”, 0.0005},
{“Regular++”, 0.0001},
{“Common-”, 0.00005},
{“Common”, 0.00001},
}

local function getItemByRandomChance()
  local return_item = Items[1] -- the return item defaults to the first item so that something is always returned
  
  for i, item in ipairs(Items) do
    local percent_chance = item[2]
    local max_value = 1 / percent_chance 
    if math.random(1, max_value) == 1 then
      return_item = item
    end
  end
  
  return return_item
end

local item = getItemByRandomChance()
print(item)

This function loops through all the items and gets a random number based on that item’s chance value. If the random number is equal to 1, then you “won”. As fully1insane mentioned, what you compare the number to can be arbitrary as long as it’s less than the max possible value. However, in this case it’s easy to use 1 since you know all the max values are at least 1 or higher.

In order to get the max value, you simply divide 1 by the percent chance. if the chance is 0.01 (1%), then 1 / 0.01 = 100. Then the random function returns a number between 1 and this new max value, so between 1 and 100. Each number between 1 and 100 has an equal chance of output, so comparing the output to 1 is the same as checking a 1 in 100 (or 1%) chance of something occurring.

Let me know if this makes sense or if you have any questions.

not that what i mean i want how do it return the rng number like example the weight basic+ was 0.5 so it will return the rng is 1/2 if basic that will 1/1 like that

local item = Items[1]
local rng = "1/"..math.floor(1/item[2])
print("Chance is "..rng)
1 Like

if i want combine it with luck it will be like this?
math.floor(1/(item[2]*LuckLevel))

If the LuckLevel the chance will be easiler

Hey buddy, the previous answers so far are… lets just say less than useful.

What you are looking for is a weight table solver, here’s mine:

local weightTable = {
	["Basic"] = 1,
	["Basic+"] = 0.5,
	["Basic++"] = 0.1,
	["Regular-"] = 0.01,
	["Regular"] = 0.001,
	["Regular+"] = 0.0005,
	["Regular++"] = 0.0001,
	["Common-"] = 0.00005,
	["Common"] = 0.00001,
}

function RandomFromWeightTable(weightTable)
	local total = 0
	for _, weight in pairs(weightTable) do
		total+= weight
	end

	local picked = math.random() * total

	local pickCounter = 0
	local pickedItem 
	for item, weight in pairs(weightTable) do
		pickCounter += weight
		if picked <= pickCounter then
			pickedItem = item
			break
		end
	end

	return pickedItem
end

The way it works is that it adds together all the numbers, picks a random number within 0 and that total, and then does the inverse job, obtaining the result from the random number. It is reliable, supports all kinds of numbers and most importantly it is a very fast algorithm

As you can see I converted your table into a dictionary, as it is much more convenient to work with in this scenario.

All you have to do is call RandomFromWeightTable(weightTable) and it will return you the string name that is picked.

You can test this code by going into studio and running:

local total = {}
	
for i = 1, 1000000 do
	local result = RandomFromWeightTable(weightTable)
	if total[result] then
		total[result] += 1
	else
		total[result] = 1
	end
end
print(total)

This will simulate 1000000 rolls and then print them

Let me know if this works for you, good luck.

1 Like