Randomizer techniques?

Recently I’ve been working on a simulator game, and I’ve been working on spawning random collectibles in a set region.

I want to make it so theres random chances of spawning higher valued collectibles in said regions but the only way to randomize the collectibles (That I can think of) is the following:

while wait(1) do
	local Randomizer = math.random(1,1000)
	
	if Randomizer <= 600 then
		print("Common")
	elseif Randomizer >= 601 and Randomizer <= 800 then
		print("Uncommon")
	elseif Randomizer >= 801 and Randomizer <= 900 then
		print("Rare")
	elseif Randomizer >= 901 and Randomizer <= 950 then
		print("Super Rare")
	elseif Randomizer >= 951 and Randomizer <= 1000 then
		print("Ultra Rare")		
	end
end

This , to me , looks like a very unorganized way of doing this, so I was wondering if there was any other way to randomize things.

Thanks!

1 Like

looks organized to me, I don’t think there’s any way to organize it better.

Yes: There is a better way!

Its “organized”, but it is going to be a real pain to edit if you need to change the weight of the chance an item can be obtained. And so maybe a better term is “readability” or “versatility” compared to “organized” in this case.

PSA:

Its 11 PM so my brain probably is not working properly, here is the approach I would currently take…

Solution: “Weight” Table

Weight dictionary where you clone the elements n times so the chance of randomly indexing it is higher.

Disclaimer

This is a bad solution if you want weights of like 10^9 (or honestly any high number), if so try something like picking a random number and comparing it to the values in an array.

Example Code

Highly suggested you read and consider the comments so you can fully grasp how the underlying concept of the code works.

local set = {
    Common = 600,
    Uncommon = 199, --// Notice how this is 800 - 601
    Rare = 99, --// And how this is 900 - 81
    SuperRare = 49, --// And so on
    UltraRare = 49 --[[
You may be thinking, "why is ultra rare the same as super rare?" 
Well if you look at your code the range of numbers between or equal to the bounds
for ultra rare and super rare are actually the same. 
This means you have the same chance in practice. And so you had a lapse in 
judgement in your initial code. (Unless they're supposed to be the same rarity?)
]]--
}

local realSet = {}

for setName, iterations in pairs(set) do 
    for i = 1, iterations do
        realSet[#realSet + 1] = setName
    end
end

--[[
And so when you pick a random element from the array `realSet`, 
elements that are cloned more often will get picked more often. 
]]--

local randomIndex = math.random(1, #realSet)
local randomValue = realSet[randomIndex]
2 Likes

Not really a “real pain” unless you have a lot of possible outcomes being checked. Furthermore your way may be slightly easier to change, but it’s a lot less efficient, but it is a more convenient way to do it if a lot of outcomes I guess.

Editing one condition in the if then statements in his code means you immediately have to edit another or there will be a set of numbers lying within the gap created.

Example, Common (600) becomes 500; Now if you don’t edit the conditions for Uncommon there is a set of 100 integers just lost.

It is a problem directly caused by the code and it’s easy to fix so it should be fixed. The “just because it works” case is usually a bad mindset.

As I said, for a small number of outcomes, it is not really hard to edit. And it is more optimal (in terms of performance) than your way (but your way is more convenient when there’s a number of outcomes).

Kind of confused, but I think I got the concept:

Does that basically just make a really huge table and then picking one of the values from it at random?
Thats smart tbh

but wont that cause lag?

I addressed the issue of it potentially causing lag. You shouldn’t have to worry about it.

If you’re worried about the memory usage or potential latency that could be generated, then I suggest a different take. Generate a random number and compare it to the indices in an array.

local myArray = {
     Uncommon = 600
     --// and so on
}

local randomNumber = math.random(0, 1000)

Compare the random number to the value of everything in the array such that you start from the top most rarity to the lowest.

1 Like

Ahhh alright, thanks bro! I would have never thought of doing it this way lol