Help on a random chance feature [Egg hatching system]

Thanks [Angiris_treecreeper] (Profile - Angiris_treecreeper - Developer Forum | Roblox)Programmer! This really helped me with a script!

1 Like

Yeah :slightly_smiling_face:, I don’t see why it shouldn’t. As long as you can access all of the data in the way you thought you could then any layout should be fine.

petModule.Eggs = {
	["Common Egg"] = { 
		Cost = {
			"Coins",500 --Was this intended to be ["Coins"] = 500 ?
		},
		Secrets = {
			"Giant Kitty",
			"TV"
		},
		Rarities = {
			["Doggy"] = {
				["Chance"] = 000,
				["Rarity"] = "Common"
			}, 
			["Kitty"] = {
				["Chance"] = 000,
				["Rarity"] = "Uncommon"
			}
		}
	}
}

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"]

Keep up the good work :+1:

1 Like

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)

Cool, always good to think ahead.

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:

local testDict = {
    ["One"] = 1,
    ["Two"] = 2,
    ["Three"] = 3,
    ["Four"] = 4,
    ["Five"] = 5
}

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)

PrintedDictionary

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.

Yeah no problem :slightly_smiling_face:, ill private message it to you.

so my code on the random number chance is fine

also wouldnt for i, v in pairs be better since it goes from start to end

Yeah, should be.

I’ve just tested this out and it seems to have the same results

local testDict = {
    ["One"] = 1,
    ["Two"] = 2,
    ["Three"] = 3,
    ["Four"] = 4,
    ["Five"] = 5
}

local stringToPrint = ""
	
for k, v in pairs(testDict) do
	stringToPrint = stringToPrint .. k .. " "
end	
	
print(stringToPrint)

After printing:

PrintedDictionary

I may have understood but it seems to output the same as k, v in next, Dictionary

ah ok, it also could’ve been i got confused cuz at first i was just printing the min value

also, inside of the rarity table form each of the pets do i have to add min and max=0 or does the script auto add it

The function to calculate the chances will automatically add it if it doesn’t already exist. You can add it in by default though if you prefer to however its not necessary.

i want it to only affect epics,legendaries, and secrets
(it goes common, uncommon, rare, epic legendary secret)
problem is that i would assume is when i do the random number i do 1,TotalChance/luck (luck is a varible) and then in the rarities for the ones i want to affect id do (number chance) * luck and for the ones i’d like it to not affect it would be number chance/luck but the thing is if i did that for the common egg the tv wouldn’t be 1/5M

So you could implement luck by just increasing the chance of the Epic, Legendary and Secret items e.g.

1/1M = x1      --1x luck
2/1M = x2      --2x luck
10/1M = x10    --10x luck
100/1M = x100  --100x luck

The other option is to decrease the chances of the other items e.g. Common, Uncommon and Rare e.g.

say we had 2 types of item Common and Epic

Epic is 1/10 chance and Common is 9/10 chance
1/10 - 10%
9/10 - 90%

to double the chance of getting an epic item we could either increase the chance to 2/10 which is 1/5 instead of 1/10 or we could decrease the common chance e.g.

9/10, divide the 9 by 2 to half the chance and round down e.g. 9 / 2 = 4.5

4.5 rounded down = 4

Total chance is now the 1 for the Epic item and the 4 for the common item so new chances are as follows:
Rare = 1/5 - 20%
Common = 4/5 - 80%

Ill keep having a think about it and see if I can come up with a easy way to maintain this in code

so do i only multiply the ones i want and divide the total by 2 or only the multiplying

So if you choose to multiply the Rarer chances then you only need to multiply them, do note however that you will have to run a small modified version of this function to correct the chances before checking them:

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"] -- this will now need to be v["Chance"] * Luck
		eggModule.Eggs[eggToHatch].Rarities[k]["Min"] = currentMin
		eggModule.Eggs[eggToHatch].Rarities[k]["Max"] = currentMax
	end
end

wouldnt that make it so every pet has x2

Yeah so you would have to add an if to check the rarity before multiplying by the luck value e.g.

if v["Rarity"] == "Epic" then
    --Can be multiplied by luck value
end

NOTE: Not sure if you still need to know but BillboardGui have a max distance property

yeah i made it so if you are 15 studs within it it shows but with that if your camera is further it wont show

ok ill check that out

I have to go for a little while so here’s a small example. You would have to edit it to suit your module and some of the code has been removed for things I don’t have but this should give you some idea of how to go around implementing it.

local random = Random.new()

local Eggs = {
	["Common Egg"] = {
		["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"
			}
		}
	}
}

function GetRarityTotalChance(eggToHatch)
	local total = 0
	for k, v in next, eggToHatch["Rarities"] do
		total += v["Chance"]
	end
	return total
end

function GetRarityMaxChance(eggToHatch)
	local total = 0
	for k, v in next, eggToHatch["Rarities"] do
		if v > total then
			total = v["Max"]
		end
	end
	return total
end

function SetRandomMinMax(eggToHatch, luck)
	local currentMin = 0
	local currentMax = 0
	for k, v in next, eggToHatch["Rarities"] do
		currentMin = currentMax + 1
		if v["Rarity"] == "Epic" or v["Rarity"] == "Legendary" or v["Rarity"] == "Secret" then
			currentMax = currentMax + (v["Chance"] * luck)
		else
			currentMax = currentMax + v["Chance"]
		end
		eggToHatch["Rarities"][k]["Min"] = currentMin
		eggToHatch["Rarities"][k]["Max"] = currentMax
	end
end

function ChoosePet(eggToHatch, luck)
	
	SetRandomMinMax(eggToHatch, luck)
	
	local randomChance = random:NextInteger(1,GetRarityTotalChance(eggToHatch))

	for k, v in next, eggToHatch["Rarities"] do
		if randomChance >= v["Min"] and randomChance <= v["Max"] then
			local rarity = v["Rarity"]
			local percent = v["Percent"]

			local chosenPet = k

			return chosenPet, rarity
		end
	end
end


--Everything below this comment is for testing the rarity and luck
local rolls = 0
local bears = 0

while wait(0.001) do
	local chosenPet, rarity = ChoosePet(Eggs["Common Egg"], 2) --The 2 is the luck which the unlock has, 1 is default
	if chosenPet == "Bear" then
		bears = bears + 1
	end
	rolls = rolls + 1
	print(chosenPet .. "    " .. rarity .. "    " .. bears / rolls)
end

NOTE: When I have a little more time I’ll see if I can find another easy to implement option which is better :slightly_smiling_face:

1 Like

alr thanks ill make sure to add this and let you know

How would i go about adding percent into the print(chosenPet … " " … rarity … " " … ???percent???)