Need help with this chance system

NOTE: I am basing my chance system off of the solution in How do i make a chance system?, so tell me if it is outdated or something.

So I am making a chance system where there is a chance that you get Moltenite instead of Meteorite.

I made a test one on a baseplate and here is the script:

``````local deb = false
script.Parent.Touched:Connect(function(hit)
if not deb then
if hit.Parent:FindFirstChild("Humanoid") then
if game.Players:GetPlayerFromCharacter(hit.Parent) then
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)

local chances = {
Cash = 75,
Crystals = 25
}

local random = math.random(100)

for i, v in pairs(chances) do
if random <= v then
print(i)
else
--print(i)
end
end

script.Parent.Parent = game.ServerStorage
deb = true
wait(1)
deb = false
script.Parent.Parent = workspace
end
end
end
end)
``````

However, there is one problem. If you get crystals, you also get cash (prints â€śCrystalsâ€ť and â€śCashâ€ť).

How am I supposed to fix this?

END NOTE: Please do not tell me my code is messy, I am not looking for people to say â€śYour code is messyâ€ť. I want to get my problem solved and I will make it less messy later.

1 Like

Alright, right on top of the â€śif random <= v thenâ€ť put â€śrandom = math.random(100)â€ť
try that

1 Like

Basically, you were using the same randomness value for Cash and Crystals, so if you change it after each value, you have different chances of getting them.

1 Like

Try using NumberRanges : Selecting Value from Table - #3 by un1ND3X

Or,

replace that with

``````
-- the if part of your if statement
return
end

``````

1 Like

In the solution, iâ€™ve seen that inside the else statement, it would substract the random variable wiith the entry weight, something like this:

``````else
random = random - v
end
``````

I donâ€™t know if that would be the issue.

Try to finish the loop when you find a random currency, something like this:

``````local AlreadyFound = false

for i, v in pairs(chances) do
if random <= v then
print(i)
else
random = random - v
end
end
end
``````

With your current code, if you get the number 10, the code would search for every item inside your table, and check if the number is smaller than the weight of every item, since the number 10 is smaller than both items you have, then you would recieve two currencies, in the solution of my thread, it would be a function, when it finds an item, it would return the value, since it returns, the code would stop, and your code wouldnâ€™t stop even if you find a result, the way to fix that would be converting the part of the code i quoted in a function, or just check if a result was already found with a boolean variable, as i mentioned before, i hope this helps you

I hope this helps you

1 Like

You iterate through all of the `chances` and in some cases `random` is bigger than 75 and 25, causing you to get both.

Here is some code I wrote to show you how weighted chances would work with your system:

``````local Debounce = false

local Chances = {
Cash = 75,
Crystals = 25
}

local WeightedChances = {}

for Type, Value in next, Chances do -- Iterate through all of the things in the table
for Loop = 1, Value do -- Add x elements to the WeightedChances table
table.insert(WeightedChances, tostring(Type))
end
end

function PickChance()
return WeightedChances[math.random(1, #WeightedChances)] -- Pick a random chance. Think of this like a raffle there are 75 "Cash" tickets and 25 "Crystals" tickets. Picking one randomly should give Cash and Crystals a 75 and 25 percent chance, respectively.
end

function OnTouched(Hit)
if not Debounce then -- Typical debounce stuff

local Chance = PickChance() -- Store the chance we got in this
local Player = game:GetService("Players"):GetPlayerFromCharacter(Hit.Parent) -- Get the player that touched the part

if Player then
local Parent = script.Parent.Parent

Debounce = true
script.Parent.Parent = game:GetService("ServerStorage")

coroutine.resume(coroutine.create(function()
wait(1)
script.Parent.Parent = Parent
Debounce = false
end))
end
end
end

script.Parent.Touched:Connect(OnTouched)
``````
4 Likes
``````local deb = false

local Minimum = 25
local Maximum = 700

script.Parent.Touched:Connect(function(hit)
if not deb then
if hit.Parent:FindFirstChild("Humanoid") then
if game.Players:GetPlayerFromCharacter(hit.Parent) then
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)

local chances = {
Cash = NumberRange.new(250,700),
Crystals = NumberRange.new(25,70)
}

local random = math.random(Minimum,Maximum)

for i, v in pairs(chances) do
if random >= v.Min and random <= v.Max then
print(i)
end
end

script.Parent.Parent = game.ServerStorage
deb = true
wait(1)
deb = false
script.Parent.Parent = workspace
end
end
end
end)
``````

Whatâ€™s now weird is that sometimes you donâ€™t even get anything. Neither cash or crystalsâ€¦

Try my code.

I wrote it for you

2 Likes