So im creating a roulette with a weighted system and tried importing it to a modulescript. the first for loop prints 1000 as it’s supposed to but the second one prints 15 everytime giving the player extra 5 spins every time.
local rewardModule = {}
rewardModule.spinChance = {
Nothing = 86.9;
Extra1Spin = 8.5;
Extra3Spin = 2.5;
Extra5Spin = 1.5;
Coins = .5;
Ugc = .1;
}
function rewardModule.Spin(plr)
local weight = 0
for _, chance in pairs(rewardModule.spinChance) do
weight += (chance * 10)
print("First Chance: "..chance)
print("First Weight: "..weight)
end
local runNumber = math.random(1, weight)
task.wait()
weight = 0
for prize, chance in pairs(rewardModule.spinChance) do
weight += (chance * 10)
print("weight: "..weight)
if weight >= runNumber then
print(plr.Name.." got "..prize)
--[[if prize == "Extra1Spin" then
plr.leaderstats.Spins.Value += 1
elseif prize == "Extra3Spin" then
plr.leaderstats.Spins.Value += 3
elseif prize == "Extra5Spin" then
plr.leaderstats.Spins.Value += 5
elseif prize == "Coins" then
plr.Data.Coins.Value += 1
elseif prize == "Ugc" then
print("not adding yet")
end]]
break
end
--print("Module weight: "..weight.." Module Prize: "..prize.." runNumber: "..runNumber)
return prize, chance
end
weight = 0
end
return rewardModule
Your basically looping through the module with pairs so its going to obviously always start at that exact one it always does, so I would possibly recommend picking randomly if that’s what you want.
pairs is not an ordered iterator. For the type of system you’re trying to make, you have to loop through the prizes from highest to lowest chance order, which is the order you have them listed, but not necessarily the order that pairs is going to step through them. Your code here is basically implementation-defined behavior. You need to use an array-type table with ipairs instead of a dictionary table in order to achieve this, e.g.:
the first loop on the script i provided was working fine but the second one only gets the first item in the table. it was originally on a server script and worked perfectly fine before. i made the weighted system from this Weighted Chance System post
You are placing the return here wrong. It not only exits the loop with the first loop entry, but returns that first entry. Replace the break with the return, remove your current return and it should work. I did this:
-- The ModuleScript
local rewardModule = {}
rewardModule.spinChance = {
Nothing = 86.9;
Extra1Spin = 8.5;
Extra3Spin = 2.5;
Extra5Spin = 1.5;
Coins = .5;
Ugc = .1;
}
function rewardModule.Spin(plr)
local weight = 0
for _, chance in pairs(rewardModule.spinChance) do
weight += (chance * 10)
print("First Chance: "..chance)
print("First Weight: "..weight)
end
local runNumber = math.random(1, weight)
task.wait()
weight = 0
for prize, chance in pairs(rewardModule.spinChance) do
weight += (chance * 10)
print("weight: "..weight)
if weight >= runNumber then
print(plr.Name.." got "..prize)
--[[if prize == "Extra1Spin" then
plr.leaderstats.Spins.Value += 1
elseif prize == "Extra3Spin" then
plr.leaderstats.Spins.Value += 3
elseif prize == "Extra5Spin" then
plr.leaderstats.Spins.Value += 5
elseif prize == "Coins" then
plr.Data.Coins.Value += 1
elseif prize == "Ugc" then
print("not adding yet")
end]]
return prize, weight, chance, runNumber -- Place the return here instead to return price, weight,... etc. when the player won(or did not win anything)
end
--print("Module weight: "..weight.." Module Prize: "..prize.." runNumber: "..runNumber)
end
weight = 0
end
return rewardModule
-- Example usage in a LocalScript
local price, weight, chance, number = rewardModule.Spin(player)
print("Price is: " .. price .. " with weight " .. weight .. " and chance " .. chance .. " and number " .. number)
Please note that everything after the return() won’t be executed, i.e., your print("Module weight: "..weight.." Module Prize: (...) will not be executed. If you want to add code afterwards, then break in the loop instead and store the win, weight etc. that won in a specific local variable.