So if you use the number 1 as the 1/1M chance then up to now if the random number lands on 1 then you get that pet otherwise you get something else.
If you then ask if the number is less than or equal to 10 for the next rarity then its asking if its equal to:
1,2,3,4,5,6,7,8,9,10
Which is 10 numbers however since the number 1 is used for the 1/1M chance, its actually only checking then following numbers:
2,3,4,5,6,7,8,9,10
Which is only 9 numbers. 1M / 9 = 111111.111111 which is roughly a 1/111111 chance instead of a 1/100k.
I haven’t seen any examples of how they do it exactly but I would presume they would just use a similar system to this. If I find anything about it though I’ll let you know.
NOTE: you could use a more complex system by creating some kind of dictionary of rarities like you have but then picking random numbers out of the 1000000 chances and adding them to that rarity which would link that specific number to each egg type.
This may be overly complex though for no good reason. Ill run some tests and see if it makes much of a difference given that there are no true random numbers.
ah so that’s why the pets would seem harder than it should be, thanks
Yes please do let me know if you find anything on that because for bgs they have some extremely high chances like millions and billions and it all seems really accurate so i wanted to know how they did it
also, the original way i did it was that the random number would be 1,100 and each of the chances would have to be equal to 100 (just a weighted selection) would it be more accurate to do that? also if so how would i do it with decimal chances (the example 0.001 pet)
So on the quote before where you talked about how it should be 11 instead of 10 how would i do that with a higher number like how should i replace 100,000 with its accurate chance (random number is 1,1M)
Also, i’ve heard of something called random.new so would it be easier to make a chances system with that?
You can then use a function to get the total chance based from all rarities in the dictionary.
function GetRarityTotalChance()
local total = 0
for k, v in next, rarities do
total += v["Chance"]
end
return total
end
local TotalChance = GetRarityTotalChance()
Now to get the correct Min and Max values for each number e.g. 1/1M was 1 and 1/100K was 2 - 11 we need to run a function to calculate this. The following function does that.
function SetRandomChanceMinMax()
local currentMin = 0
local currentMax = 0
for k, v in next, rarities do
currentMin = currentMax + 1
currentMax = currentMax + v["Chance"]
rarities[k]["Min"] = currentMin
rarities[k]["Max"] = currentMax
--print(k .. " " .. rarities[k]["Min"] .. " " .. currentMin .. " " .. rarities[k]["Max"] .. " " .. currentMax)
end
end
SetRandomChanceMinMax()
All that’s left is to pick a random pet, this function picks a random value and checks if it is between the Min and Max of each pet rarity. Once it finds the correct one it will return the values from each dictionary.
function choosePet()
local randomChance = math.random(1, TotalChance) --Chance for specific pet
for k, v in next, rarities do
if randomChance >= v["Min"] and randomChance <= v["Max"] then
local rarity = v["Rarity"]
--local rarityTab = petModule.pets[k]
--local chosenPet = rarityTab[1]
return k, rarity --Replace K with chosen pet
end
end
end
NOTE: these will need adding or editing to suit your module. Also the choosePet Function will need k removing from the return and changing out for your chosenPet value. Since I didn’t have this value I just returned K for testing purposes
Either should work fine for your purpose. If you’re interested in more detail however this discussion about it may be useful.
math.random() is a global random object and you may make use of it in many different places. This may lead to what appears to be inaccurate Random Chances as the next pseudo random has already been called.
Random.new() creates a new random object with a given seed e.g. tick() and can be used to return pseudorandom integers with :NextInteger(min, max) or number (decimal) (double) using :NextNumber(min,max).
Using Random.new() ensures that you will get the right distribution of rarities as no other script can call it unless you allow it.
I see,
A few questions i have is i don’t know what for k, v in next is
and if i were to put all the egg modules into one module would i just have to do something like petModule.CommonEgg = {
}
i also see that it says that random.new is better for fairness so wouldn’t it be better for my case
So for k, v in next, rarities is a loop through the rarities dictionary.
rarities = {
["Common"] = 0;
["Uncommon"] = 1;
}
for k, v in next, rarities do
--k is the key so in this loop it would pass over Common and Uncommon
--v is the value so for common it would be 0 and for uncommon it would be 1
end
NOTE: Do keep in mind that dictionaries have no specific order so it will not always do common first. Just be aware of this when expanding on code and loops involving these
you could do it like that or you could do something like this:
i know this isn’t related but,
how would i go about making a viewport frame into like an image
for example. i have a viewport frame that shows a pet and stuff but i want to store all of that into a image into a module script so i can just access any pets image from anywhere
One note about the cost section of the common egg. Was it intended to be:
cost = {
["Coins"] = 500
}
Just wondering as you would currently have to access the cost part like an array e.g. petModule.Eggs["Common Egg"]["Cost"][1]
instead of: petModule.Eggs["Common Egg"]["Cost"]["Coins"]
for the cost coins i intended it to be cost = {“Coins”,500} so i know what currency it is and how much of it even though there is 1 currency in my game but i added it just for future games and if i will have eggs that cost multiple currencys
also, when i make the pet model should i put values inside the pet like stat multipliers and it’s state (flying or standing for the animation)
Yeah, you could either put the values in the pet or you could store a current pet in a server script in a
dictionary containing each player and store information about that pet there instead. Either way is fine so whichever you prefer.
hey,
so ive made the script so far and i tested it and the chances seem to have some problems like:
min/maxs are wrong example, for bunny it says the min is 1 (which should be for the tv)
local eggModule = {}
local random = Random.new()
eggModule.Eggs = {
["Common Egg"] = {
Cost = {"Coins",500},
Secrets = {"Giant Kitty","TV"},
Rarities = {
["Doggy"] = {["Chance"] = 3750000, ["Rarity"] = "Common",["Percent"] = "37.5"},["Kitty"] = {["Chance"] = 2750000, ["Rarity"] = "Uncommon",["Percent"] = "27.5"},
["Bunny"] = {["Chance"] = 2500000, ["Rarity"] = "Rare",["Percent"] = "25"},["Bear"] = {["Chance"] = 988794, ["Rarity"] = "Epic",["Percent"] = "9.88"},
["Deer"] = {["Chance"] = 10000, ["Rarity"] = "Legendary",["Percent"] = "0.1"},["Dragon"] = {["Chance"] = 1000, ["Rarity"] = "Legendary",["Percent"] = "0.01"},
["Golem"] = {["Chance"] = 200 , ["Rarity"] = "Legendary",["Percent"] = "0.002"},["Giant Kitty"] = {["Chance"] = 5, ["Rarity"] = "Secret",["Percent"] = "5E-05"},
["TV"] = {["Chance"] = 1, ["Rarity"] = "Secret",["Percent"] = "1E-05"}
},
Pets = {
--Not done with all pets
["Doggy"] = {game.ReplicatedStorage.Assets.Pets.}
}
}
}
function GetRarityTotalChance(eggToHatch)
local total = 0
for k, v in next, eggModule.Eggs[eggToHatch].Rarities do
total += v["Chance"]
end
return total
end
function SetRandomMinMax(eggToHatch)
local currentMin = 0
local currentMax = 0
for k, v in next, eggModule.Eggs[eggToHatch].Rarities do
currentMin = currentMax + 1
currentMax = currentMax + v["Chance"]
eggModule.Eggs[eggToHatch].Rarities[k]["Min"] = currentMin
eggModule.Eggs[eggToHatch].Rarities[k]["Max"] = currentMax
end
end
eggModule.ChoosePet = function(eggToHatch)
SetRandomMinMax(eggToHatch)
local randomChance = random:NextInteger(1,GetRarityTotalChance(eggToHatch))
for k, v in next, eggModule.Eggs[eggToHatch.Rarities] do
if randomChance >= v["Min"] and randomChance <= v["Max"] then
local rarity = v["Rarity"]
local percent = v["Percent"]
local rarityTab = eggModule.Eggs[eggToHatch].Pets[k]
local chosenPet = rarityTab[1]
return chosenPet, rarity, percent
end
end
end
return eggModule
also, how do i do x2 luck
(i know i have to multiply and divide chances but im not sure which ones should get multiplied or divided)
also wondering if you have a discord so i dont have to flood this post lol
Right, It may seem that they’re wrong but its most likely that its because when looping a dictionary it doesn’t do it in a specific order so bunny may be the first see below:
This dictionary appears to be in order from One to Five however when you print it:
local stringToPrint = ""
for k, v in next, testDict do --K is the key e.g. One - Two
stringToPrint = stringToPrint .. k .. " "
end
print(stringToPrint)
This may look odd at first however if you make sure to only get and set information based on k, v the key and value of the dictionary loop then it will all work. Just as you said you may get the chances for bunny first as >= 1 and <= 2,500,000 and TV may have its chances as >= 2,500,001 and <= 2,500,001.
So there are probably multiple ways to do this however the easiest may be to pass a luck value into a function for a player and then calculate the chances of the egg based on that luck value. This is similar to what we discussed before however instead of calculating just once, you would calculate each time someone unlocked an egg.
This does depend on if you plan the x2 luck to just affect rare items in the egg or all items in the egg though.