For loop not going through the amount of times needed

what is the variable “rewardWeight”

1 Like

does it print???

A table with the weight (chances) for each function.

For example, the function I showed in the post has a 75% (750 is for 75.0) chance of running.

@ZINTICK

I would consider rereading :slight_smile:

1 Like

wait maybe now that I notice it is because you are not adding a “return” at the end of your function, try that :slightly_smiling_face:

Wait a sec…

It’s not getting past the wait(1)…

A wait(.5) did not help.

wait is the problem ??? D you mean it dosent print after wait

Yeah I put a print statement before and after the wait but the after wait did not print…

I know this question might be redundant but did you wait 1 second?

Yep. It’s for the messaging system that is fired in the function because it needs a debounce and if it didn’t wait, it would mess things up.

2 Likes

This code doesn’t look problematic, so the next thing to look at is the reward function being called. Reading through the posts, I’ve gathered that the wait isn’t being reached which means that the problem is with the code in the iteration itself.

Is the if statement being reached at least? If the if statement is being reached and the condition is truthy, then your iteration is being halted by the function. Until the function completes, the if statement block doesn’t finish execution so any code after it yields as well.

What is the exact content of the called function when the for loop stops iterating?

1 Like

just to make sure, the “print” is right before the wait and right before the after right?

try commenting the reward part usually scripts stop when there’s a problem maybe that’s the thing that’s not allowing the script to reach the wait()

there is no error outputed. Therefore it isnt erroring the function

1 Like

some times script do not error like in this case

1 Like

Wat a second just to make sure, at calling the function do you have a PCALL? Pcalls gather errors meaning that if you remove it for a second it will output the error and make it easeir to solve

1 Like

@colbert2677 The following code shows the functions, weights, and for loop.

local rewards = {
	[1] = {
		function(plr)
			if plr.EXP.Level.Value == 2 then
				plr.leaderstats.Meteorite.Value += 2
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 meteorite! (Bronze Tier Level 2)")
			elseif plr.EXP.Level.Value == 1 then
				plr.leaderstats.Crystals.Value += 2
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 crystals! (Bronze Tier Level 1)")
			elseif plr.EXP.Level.Value == 3 then
				plr.leaderstats.Crystals.Value += 2
				plr.leaderstats.Meteorite.Value += 3
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 crystals and 3 meteorite! (Bronze Tier Level 3)")
			elseif plr.EXP.Level.Value >= 4 and plr.EXP.Level.Value < 7 then
				plr.leaderstats.Crystals.Value += 5
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 5 crystals! (Bronze Tier Level 4-6)")
			elseif plr.EXP.Level.Value >= 7 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 4
				plr.leaderstats.Crystals.Value += 7
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 7 crystals and 4 moltenite! (Bronze Tier Level 7-9)")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 10
				plr.leaderstats.Crystals.Value += 20
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 20 crystals and 10 moltenite! (Bronze Tier Level 10+)")
			end
		end,
		750
	},
	[2] = {
		function(plr)
			if plr.EXP.Level.Value == 1 then
				plr.leaderstats.Crystals.Value += 5
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 5 crystals! (Silver Tier Level 1)")
			elseif plr.EXP.Level.Value == 2 then
				plr.leaderstats.Meteorite.Value += 5
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 5 meteorite! (Silver Tier Level 2)")
			elseif plr.EXP.Level.Value >= 3 and plr.EXP.Level.Value < 7 then
				plr.leaderstats.Moltenite.Value += 5
				plr.leaderstats.Crystals.Value += 8
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 8 crystals and 5 moltenite! (Silver Tier Level 3-6)")
			elseif plr.EXP.Level.Value >= 7 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 8
				plr.leaderstats.Crystals.Value += 15
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 15 crystals and 8 moltenite! (Silver Tier Level 7-9)")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 15
				plr.leaderstats.Crystals.Value += 30
				plr.leaderstats.Meteorite.Value += 20
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 30 crystals, 15 moltenite, and 20 meteorite! (Silver Tier Level 10+)")
			end
		end,
		175
	},
	[3] = {
		function(plr)
			if plr.EXP.Level.Value >= 1 and plr.EXP.Level.Value < 5 then
				plr.leaderstats.Moltenite.Value += 2
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 moltenite! (Gold Tier Level 1-4)")
			elseif plr.EXP.Level.Value >= 5 and plr.EXP.Level.Value < 8 then
				plr.leaderstats.Moltenite.Value += 5
				plr.leaderstats.Crystals.Value += 15
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 15 crystals and 5 moltenite! (Gold Tier Level 5-7)")
			elseif plr.EXP.Level.Value >= 8 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 20
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 20 moltenite! (Gold Tier Level 8-9)")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 50
				plr.leaderstats.Crystals.Value += 80
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 80 crystals and 50 moltenite! (Gold Tier Level 10+)")
			end
		end,
		70
	},
	[4] = {
		function(plr)
			if plr.EXP.Level.Value >= 1 and plr.EXP.Level.Value < 5 then
				plr.leaderstats.Moltenite.Value += 15
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 15 moltenite! (Diamond Tier Level 1-4)")
				game.ReplicatedStorage.RemoteEvents.Sound:FireClient(plr, "Legendary")
			elseif plr.EXP.Level.Value >= 5 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 50
				plr.leaderstats.Crystals.Value += 100
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 100 crystals and 50 moltenite! (Diamond Tier Level 5-9)")
				game.ReplicatedStorage.RemoteEvents.Sound:FireClient(plr, "Legendary")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 200
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 200 moltenite! (Diamond Tier Level 10+)")
				game.ReplicatedStorage.RemoteEvents.Sound:FireClient(plr, "Legendary")
			end
		end,
		5		
	},
}
local amountweights = {[1] = {70}, [2] = {22}, [3] = {8}}

local rewardWeight = {}
local amountWeight = {}

local function weightInsert(tab, inserted, partOfTab)
	for i, v in pairs(tab) do
		for p = 1, v[partOfTab] do
			table.insert(inserted, #inserted+1, i)
		end
	end
end

weightInsert(rewards, rewardWeight, 2)
weightInsert(amountweights, amountWeight, 1)

local folder = script.Parent.Parent
local deb =  false

local function egg(plr, times)
	print(times)
	plr.EasterEvent.Eggs.Value += times
	for i = 1, times do
		print(i)
		local reward = rewardWeight[math.random(1,#rewardWeight)]
		if rewards[reward] then
			rewards[reward][1](plr)
		end
		print("before")
		wait(0.5)
		print("after")
	end
end

As I said in an earlier reply, the after wait did not print. I forgot to mention that the before wait did in fact print.

If you would like the exact content of the called function, look in table rewards.

@STORMGAMESYT7IP No I do not. I will most likely try it unless I fix it before I do.

Thanks for the extended code. I ran it in Studio with some parts omitted (specifically anything to do with instances) and it ran as expected. The only thing I noticeably changed was the “weights” from being in the hundreds to single digit numbers.

Output:
image

Code:

local rewards = {
	[1] = {
		function()
			print("rew1")
		end, 3
	},
	[2] = {
		function()
			print("rew2")
		end, 2
	}
}

local amountweights = {[1] = {70}, [2] = {22}, [3] = {8}}

local rewardWeight = {}
local amountWeight = {}

local function weightInsert(tab, inserted, partOfTab)
	for i, v in pairs(tab) do
		for p = 1, v[partOfTab] do
			table.insert(inserted, #inserted+1, i)
		end
	end
end

weightInsert(rewards, rewardWeight, 2)
weightInsert(amountweights, amountWeight, 1)

local function egg(plr, times)
	print(times)
	--plr.EasterEvent.Eggs.Value += times
	for i = 1, times do
		print(i)
		local reward = rewardWeight[math.random(1,#rewardWeight)]
		if rewards[reward] then
			rewards[reward][1](plr)
		end
		print("before")
		wait(0.5)
		print("after")
	end
end

egg("bro", 4)

So even with this extended information, there’s still no problem and your code does run. Perhaps maybe the problem is how you’re handling weights? After all, what you have isn’t exactly a real weighting system but rather you’re inserting several hundreds of entries into a table. Probably not a good idea from a memory and technical standpoint in several ways.

You might want to look into some existing resources or articles about how to do weighted chance so you can get this down better. Here’s a good article you can read up on that deals with weighted chances and the math behind it:

If you’re looking for a resource that deals with weighted chance whether to study from or to try applying it into your project, check out LootPlan.

1 Like

Part of the reason why it is in the hundreds is partly because one of the chances has to be 0.5%, and can you really do 0.5? I’m going to try making the last chance 1 and divide the rest of the weights by 5 (5 / 5 = 1).

EDIT: That didn’t work so I tried it with single digits. Capture1
It still isn’t getting past that darn wait! (The crossed out is a print statement for when I touch the egg) Nothing is stopping that wait for some reason… I’m very confused right now.

You can still do values less than 1% if you use weighted chance properly without inserting hundreds of entries into a table before selecting them. Frankly I’m not sure why your code specifically refuses to work when evidently I ran the same code without issue.

I would highly recommend changing your approach if you can’t figure it out. Weighting is meant to automatically handle all percentage based stuff for you through math and without any of the extra hassle that may come with it (other than setting up the weighting of course). Weights aren’t meant to be a literal percentage, rather the frequency of an occurrence.

If you decide that you want to use LootPlan rather than creating your own implementation, then you can essentially assign the rewards ids and execute those functions accordingly if they’re pulled. I think it’s a much simpler approach to the issue, plus you can take advantage of a readily made resource.

local LootPlan = require("LootPlan")
local EggRewardsPlan = LootPlan.new("single")

local REWARDS = {
    [1] = {
        Weight = 0.5,
        Handler = function(player)
            print("Reward 1", player)
        end
    },
    [2] = {
        Weight = 700,
        Handler = function(player)
            print("Reward 2", player)
        end
    }
}

for id, data in ipairs(REWARDS) do
    EggRewardsPlan:AddLoot(id, data.Weight)
end

local function egg(player, times)
    player.EasterEvent.Eggs.Value += times

    local rolledRewards = {}
    -- Roll all rewards first so functions don't have to finish
    -- In order for us to roll again if times > 1
    for i = 1, times or 1 do
        local rewardId = EggRewardsPlan:GetRandomLoot()
        table.insert(rolledRewards, rewardId)
    end

    for _, rewardId in ipairs(rolledRewards) do
        local reward = REWARDS[rewardId]
        if reward then -- Guaranteed? Not needed really
            reward.Handler(player)
        end
    end
end

I decided to reroute my approach to this as you recommended.

local rewards = {
	[1] = {
		function(plr)
			if plr.EXP.Level.Value == 2 then
				plr.leaderstats.Meteorite.Value += 2
				return {{Cry = 0, Met = 2, Mol = 0}, "Bronze Tier Level 2"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 meteorite! (Bronze Tier Level 2)")
			elseif plr.EXP.Level.Value == 1 then
				plr.leaderstats.Crystals.Value += 2
				return {{Cry = 2, Met = 0, Mol = 0}, "Bronze Tier Level 1"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 crystals! (Bronze Tier Level 1)")
			elseif plr.EXP.Level.Value == 3 then
				plr.leaderstats.Crystals.Value += 2
				plr.leaderstats.Meteorite.Value += 3
				return {{Cry = 2, Met = 3, Mol = 0}, "Bronze Tier Level 3"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 crystals and 3 meteorite! (Bronze Tier Level 3)")
			elseif plr.EXP.Level.Value >= 4 and plr.EXP.Level.Value < 7 then
				plr.leaderstats.Crystals.Value += 5
				return {{Cry = 5, Met = 0, Mol = 0}, "Bronze Tier Level 4-6"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 5 crystals! (Bronze Tier Level 4-6)")
			elseif plr.EXP.Level.Value >= 7 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 4
				plr.leaderstats.Crystals.Value += 7
				return {{Cry = 7, Met = 0, Mol = 4}, "Bronze Tier Level 7-9"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 7 crystals and 4 moltenite! (Bronze Tier Level 7-9)")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 10
				plr.leaderstats.Crystals.Value += 20
				return {{Cry = 20, Met = 0, Mol = 10}, "Bronze Tier Level 10+"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 20 crystals and 10 moltenite! (Bronze Tier Level 10+)")
			end
		end,
		150
	},
	[2] = {
		function(plr)
			if plr.EXP.Level.Value == 1 then
				plr.leaderstats.Crystals.Value += 5
				return {{Cry = 5, Met = 0, Mol = 0}, "Silver Tier Level 1"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 5 crystals! (Silver Tier Level 1)")
			elseif plr.EXP.Level.Value == 2 then
				plr.leaderstats.Meteorite.Value += 5
				return {{Cry = 0, Met = 5, Mol = 0}, "Silver Tier Level 2"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 5 meteorite! (Silver Tier Level 2)")
			elseif plr.EXP.Level.Value >= 3 and plr.EXP.Level.Value < 7 then
				plr.leaderstats.Moltenite.Value += 5
				plr.leaderstats.Crystals.Value += 8
				return {{Cry = 8, Met = 0, Mol = 5}, "Silver Tier Level 3-6"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 8 crystals and 5 moltenite! (Silver Tier Level 3-6)")
			elseif plr.EXP.Level.Value >= 7 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 8
				plr.leaderstats.Crystals.Value += 15
				return {{Cry = 15, Met = 0, Mol = 8}, "Silver Tier Level 7-9"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 15 crystals and 8 moltenite! (Silver Tier Level 7-9)")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 15
				plr.leaderstats.Crystals.Value += 30
				plr.leaderstats.Meteorite.Value += 20
				return {{Cry = 30, Met = 20, Mol = 15}, "Silver Tier Level 10+"}
				--game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 30 crystals, 15 moltenite, and 20 meteorite! (Silver Tier Level 10+)")
			end
		end,
		35
	},
	[3] = {--not done with this yet
		function(plr)
			if plr.EXP.Level.Value >= 1 and plr.EXP.Level.Value < 5 then
				plr.leaderstats.Moltenite.Value += 2
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 2 moltenite! (Gold Tier Level 1-4)")
			elseif plr.EXP.Level.Value >= 5 and plr.EXP.Level.Value < 8 then
				plr.leaderstats.Moltenite.Value += 5
				plr.leaderstats.Crystals.Value += 15
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 15 crystals and 5 moltenite! (Gold Tier Level 5-7)")
			elseif plr.EXP.Level.Value >= 8 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 20
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 20 moltenite! (Gold Tier Level 8-9)")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 50
				plr.leaderstats.Crystals.Value += 80
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 80 crystals and 50 moltenite! (Gold Tier Level 10+)")
			end
		end,
		14
	},
	[4] = {
		function(plr)
			if plr.EXP.Level.Value >= 1 and plr.EXP.Level.Value < 5 then
				plr.leaderstats.Moltenite.Value += 15
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 15 moltenite! (Diamond Tier Level 1-4)")
				game.ReplicatedStorage.RemoteEvents.Sound:FireClient(plr, "Legendary")
			elseif plr.EXP.Level.Value >= 5 and plr.EXP.Level.Value < 10 then
				plr.leaderstats.Moltenite.Value += 50
				plr.leaderstats.Crystals.Value += 100
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 100 crystals and 50 moltenite! (Diamond Tier Level 5-9)")
				game.ReplicatedStorage.RemoteEvents.Sound:FireClient(plr, "Legendary")
			elseif plr.EXP.Level.Value >= 10 then
				plr.leaderstats.Moltenite.Value += 200
				game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, "You got 200 moltenite! (Diamond Tier Level 10+)")
				game.ReplicatedStorage.RemoteEvents.Sound:FireClient(plr, "Legendary")
			end
		end,
		1		
	},
}
local amountweights = {[1] = {70}, [2] = {22}, [3] = {8}}

local rewardWeight = {}
local amountWeight = {}

local function weightInsert(tab, inserted, partOfTab)
	for i, v in pairs(tab) do
		for p = 1, v[partOfTab] do
			table.insert(inserted, #inserted+1, i)
		end
	end
end

weightInsert(rewards, rewardWeight, 2)
weightInsert(amountweights, amountWeight, 1)

local folder = script.Parent.Parent
local deb =  false

local timesToOther = {
	[1] = "Single",
	[2] = "Double",
	[3] = "Triple"
}

local function egg(plr, times)
	print(times)
	plr.EasterEvent.Eggs.Value += times
	local things = {Cry = 0, Met = 0, Mol = 0}
	local tier = "null Tier Level null"
	local text = "You got 0 crystals, 0 meteorite, and 0 moltenite! (null Tier Level null, Single Egg)"
	for i = 1, times do
		print(i)
		local reward = rewardWeight[math.random(1,#rewardWeight)]
		local tab = nil
		if rewards[reward] then
			tab = rewards[reward][1](plr)
		end
		things.Cry += tab[1].Cry
		things.Met += tab[1].Met
		things.Mol += tab[1].Mol
		tier = tab[2]
	end
	text = "You got "..things.Cry.." crystals, "..things.Met.." meteorite, and "..things.Mol.." moltenite! ("..tier..", "..timesToOther[times].." Egg)"
	game.ReplicatedStorage.RemoteEvents.MessageGui:FireClient(plr, text)
end

It seems to work well but I could shorten the text by removing the 0’s. Also, you could get a Bronze Tier as well as a Silver Tier, but it shows the last one. I could live with that, but I would still like an alternate for getting the tier(s).