ah so as i said in my last reply to outcharm, i just multiply until its a whole number, thatll be accurate?
Not necessarily because if it is already a whole number, the weighing would be unbalanced because all of a sudden all the numbers a whole. You should use a common multiplier on all the numbers to keep the proportionality.
Modified Code:
function percentToWeight(percent)
return percent * 100 --Change this if needed, I assumed 100 because you are only going to the 100ths place
end
local Items = {
{"Table", percentToWeight(0.01)},
{"Lamp", percentToWeight(0.5)},
{"Chair", percentToWeight(0.25)},
}
local TotalWeight = 0
for _,ItemData in pairs(Items) do
TotalWeight = TotalWeight + ItemData[2]
end
local 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
for i = 1, 20 do
print(chooseRandomItem())
end
You just have to multiply it by the right number yes, like in the example I provided, I just multiplied everything by 10 so they were all whole numbers:
.1 â 1, 99.9 â 999
If you want to use smaller decimals, such as .01, youâd need to multiply them by 100, and for .001 by 1000 and so on.
well the 0.01 was just an example, the core of the game has to do with rng so itd be up to the millions or however id like the rarest to be
also, there will be a lot of changes from the rarest in the egg, so how would i be able to make it check how much is necessary
You can use functions to calculate total weights so you can have very rare chances, such as .001% and very common chances, such as 5%.
See here (youâd need to modify this code to work for yourself obviously):
local eggs = {}
eggs.Egg1 = {
Dog = 45; -- 45 % chance
Cat = 45; -- 45 % chance
Dinosaur = 10; -- 10% chance
}
eggs.Egg2 = {
Cow = 99999; -- 99.999% chance
Rainbow_Cow = 1; -- 0.001% chance
}
function GetChanceOfEgg(egg)
local chance = 0
for eggName,eggChance in pairs(egg) do
chance += eggChance
end
return chance
end
function PickRandomFromEgg(egg)
local chance = GetChanceOfEgg(egg)
local chance = math.random(0, chance)
for eggName,eggChance in pairs(egg) do
chance -= eggChance
if chance <= 0 then
return eggName
end
end
end
local pet = PickRandomFromEgg(eggs.Egg2)
print(pet)
-- Extra Code To Test Probability:
local n = 0
repeat chosenPet = PickRandomFromEgg(eggs.Egg2) n += 1 until
chosenPet == "Rainbow_Cow"
print("It took " .. n .. " tries until you got a " .. chosenPet)
local Items = {
{"Table", 2},
{"Lamp", 0.5},
{"Chair", 0.25},
}
local multiplier = 1
for _, item in pairs(Items) do --Essentially edits the multiplier so that even the smallest decimal will become whole
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
print(multiplier)
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
local 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
for i = 1, 20 do
print(chooseRandomItem())
end
well ive tested this with lamp and table, table being 0.01% and i got it at a reasonable attempt so its all looking good so far, thanks
Glad @outcharm and I could help ! Reply if you come across anything else relating to the code that was sent.
hello, so ive made this implementing the system into mine
function multiplyToWhole(egg)
local multiplier = 1
for _, pet in pairs(eggModule.Eggs[egg].Rarities) do --Essentially edits the multiplier so that even the smallest decimal will become whole
local function zeros(amount)
local total = "1"
for i = 1, amount do
total = total.. "0"
end
return total
end
local split = string.split(tostring(pet["Chance"]), ".")
if split[2] ~= nil then
if tonumber(zeros(string.len(split[2]))) > multiplier then
multiplier = tonumber(zeros(string.len(split[2])))
end
end
end
print(multiplier)
for _, pet in pairs(eggModule.Eggs[egg].Rarities) do
pet["Chance"] = pet["Chance"] * multiplier
end
end
eggModule.ChoosePetTest = function(eggToHatch)
multiplyToWhole(eggToHatch)
local TotalWeight = 0
for _,PetData in pairs(eggModule.Eggs[eggToHatch].Rarities) do
TotalWeight = TotalWeight + PetData["Chance"]
end
local Chance = math.random(1,TotalWeight)
local Counter = 0
for i,PetData2 in pairs(eggModule.Eggs[eggToHatch].Rarities) do
Counter = Counter + PetData2["Chance"]
if Chance <= Counter then
local rarityTab = eggModule.Eggs[eggToHatch].Pets[i]
local chosenPet = rarityTab[1] or rarityTab
local cost = eggModule.Eggs[eggToHatch].Cost
local rarity = PetData2["Rarity"]
local percent = PetData2["Percent"]
local legendtier
if rarity == "Legendary" then
legendtier = PetData2["Tier"]
else
legendtier = 1
end
local divinetier
if rarity == "Divine" then
divinetier = PetData2["Tier"]
else
divinetier = 1
end
return chosenPet, rarity, percent, cost, legendtier, divinetier
end
end
end
just wanted to know if this will work.
also just in case, i have my table setup like this:
["Common Egg"] = {
Cost = 500,
Secrets = {"Giant Kitty","TV"},
Rarities = {
["Doggy"] = {["Chance"] = 37.38595, ["Rarity"] = "Common",["Percent"] = "37.3"},["Kitty"] = {["Chance"] = 27.5, ["Rarity"] = "Uncommon",["Percent"] = "27.5"},
["Bunny"] = {["Chance"] = 25, ["Rarity"] = "Rare",["Percent"] = "25"},["Bear"] = {["Chance"] = 10, ["Rarity"] = "Epic",["Percent"] = "10"},
["Deer"] = {["Chance"] = 0.1, ["Rarity"] = "Legendary",["Percent"] = "0.1",["Tier"] = 1},["Dragon"] = {["Chance"] = 0.01, ["Rarity"] = "Legendary",["Percent"] = "0.01",["Tier"] = 2},
["Totem (A)"] = {["Chance"] = 0.002, ["Rarity"] = "Legendary",["Percent"] = "0.002",["Tier"] = 3},["Totem (B)"] = {["Chance"] = 0.002, ["Rarity"] = "Legendary",["Percent"] = "0.002",["Tier"] = 3},
["Giant Kitty"] = {["Chance"] = 0.00004, ["Rarity"] = "Secret",["Percent"] = "4e-05"},["TV"] = {["Chance"] = 0.00001, ["Rarity"] = "Secret",["Percent"] = "1e-05"}
},
Pets = {
["Doggy"] = {"Doggy"}, ["Kitty"] = {"Kitty"},
["Bunny"] = {"Bunny"},
["Bear"] = {"Bear"}, ["Deer"] = {"Deer"}, ["Dragon"] = {"Dragon"}, ["Totem (A)"] = {"Totem (A)"}, ["Totem (B)"] = {"Totem (B)"}, ["Giant Kitty"] = {"Giant Kitty"}, ["TV"] = {"TV"}
}
},
nvm, it works fine,
how can i implement a x2 luck thing, everything im trying isnt working
On this line, you may be able to modify it so that it would look like this:
if plrOwnsMultiplierPass then
--Another if statement to see if the rarity counts in the multiplier. Otherwise, the probability will remain the same.
Counter = Counter + PetData2["Chance"] * 2
else
Counter = Counter + PetData2["Chance"]
end
ah let me give that a try (chars)
wel actually, would this multiply all the chances (no difference), what if i want just the epics+ to be x2 only
nvm, i just added an if statement to check its rarity, thanks
im getting an error where it says âinvalid argument #2 to randomâ (caused by âTotalWeightâ being 0
code:
local TotalWeight = 0
for _,PetData in pairs(eggModule.Eggs[eggToHatch].Rarities) do
TotalWeight = TotalWeight + PetData["Chance"]
end
local Chance = random:NextInteger(1,TotalWeight)
If the total weight has a value of 0 when the random is being called, you will get an error because the minimum is greater than the maximum. (1>0)
random:NextInteger(min,max)
yea, im aware of that but what i dont understand is why the total isnt over 1, it should be like way over 1
You have probably figured this out by now but The reason is because some of the total Weights end up below 1 when the chance for the item is lower than 1 since you are just basically setting the total weight to equal the chance there (TotalWeight = TotalWeight + PetData["Chance"]
) due to the TotalWeight Starting as 0. I would either set TotalWeight To 1 or The Min Random Value to 0.
edit: oh wait random wont generate a decimal.
edit2: you could instead use Random.new():NextNumber(Min,Max)
which can return decimals. Also, For Random.new():NextNumber(Min,Max)
the Min and max can be reversed, it just returns a random number between the two inputed values.
May i ask,
This is me being a bit stupid but is the 2 for table 2%? or is it 20? or 0.2? sounds like a dumb question but yeah
Itâs the table index, basically the second item in that table, you mean the âItemData[2]â right?