Script fires too many times

local Stages = script.Parent:GetChildren()

local StageDifferenceWarningEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("StageDifferenceWarning")

local StageNotificationEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("StageNotification")

local Config = {
	StageOnDeath = false;
	AntiCheat = true; -- Won't let a player stage on the stage after their next stage
	DoubleStagePass = 60560957;
	VIPExtraStageChance = 60750478;
}

local ExtraStageChances = {
	["Yes"] = 25;
	["No"] = 75;
}

local PlrsOnCooldown = {}

local mps = game:GetService("MarketplaceService")

local function ChooseAmountOfStageToSet(UserId)
	
	local TempChanceVerdictTable = {}
	
	local CurrentStagesToSet = 1
	
	
	if mps:UserOwnsGamePassAsync(UserId, Config.DoubleStagePass) then
		
		CurrentStagesToSet += 1
		
		if mps:UserOwnsGamePassAsync(UserId, Config.VIPExtraStageChance) then
			
			for choice, chance in pairs(ExtraStageChances) do
				
				for i = 1, chance do
					
					table.insert(TempChanceVerdictTable, choice)
					
				end
				
			end
			
			local ChosenVIPExtraStageVerdict = TempChanceVerdictTable[math.random(1,#TempChanceVerdictTable)]
			
			if ChosenVIPExtraStageVerdict == "Yes" then
				
				CurrentStagesToSet += 1
				
				return CurrentStagesToSet
				
			else
				
				return CurrentStagesToSet
				
			end
			
		else
			
			return CurrentStagesToSet
			
		end
		
	else
		
		if mps:UserOwnsGamePassAsync(UserId, Config.VIPExtraStageChance) then

			for choice, chance in pairs(TempChanceVerdictTable) do

				for i = 1, chance do

					table.insert(TempChanceVerdictTable, choice)

				end

			end

			local ChosenVIPExtraStageVerdict = TempChanceVerdictTable[math.random(1,#TempChanceVerdictTable)]

			if ChosenVIPExtraStageVerdict == "Yes" then

				CurrentStagesToSet += 1

				return CurrentStagesToSet

			else

				return CurrentStagesToSet

			end

		else

			return CurrentStagesToSet

		end
		
	end
	
end


for _, stage in pairs(Stages) do
	
	if stage:IsA("Model") then
		
		stage.Spawn.Touched:Connect(function(hit)
			
			if hit.Parent:FindFirstChild("Humanoid") then
				
				local player = game.Players:GetPlayerFromCharacter(hit.Parent)
				
				local plrhealth = hit.Parent.Humanoid.Health
				
				local CurrentStageNum = tonumber(stage.Num.Value)
				
				if player.leaderstats.Stage.Value < CurrentStageNum and not table.find(PlrsOnCooldown, player.Name) then
					
					if Config.StageOnDeath == false then
						
						if plrhealth > 0 then
							
							if Config.AntiCheat == true then
								
								local StageDifference = (CurrentStageNum - player.leaderstats.Stage.Value)
								
								if StageDifference == 1 then
									
									local AmountOfStagesToGive = ChooseAmountOfStageToSet(player.UserId)
									
									print(AmountOfStagesToGive)
									
									player.leaderstats.Stage.Value = (player.leaderstats.Stage.Value + AmountOfStagesToGive)

									StageNotificationEvent:FireClient(player, player.leaderstats.Stage.Value, AmountOfStagesToGive - 1)
										
										
								else
									
									StageDifferenceWarningEvent:FireClient(player)
										
								end
									
							else
									
								StageDifferenceWarningEvent:FireClient(player)
									
							end
							
						end
						
					else
						
						if Config.AntiCheat == true then

							local StageDifference = (CurrentStageNum - player.leaderstats.Stage.Value)

							if StageDifference == 1 then
								
								local AmountOfStagesToGive = ChooseAmountOfStageToSet(player.UserId)

								player.leaderstats.Stage.Value = (player.leaderstats.Stage.Value + AmountOfStagesToGive)

								StageNotificationEvent:FireClient(player, player.leaderstats.Stage.Value, AmountOfStagesToGive - 1)


							else

								StageDifferenceWarningEvent:FireClient(player)

							end

						else

							StageDifferenceWarningEvent:FireClient(player)

						end
						
					end
					
				end
				
			end
			
		end)
		
	end
	
end

Whenever a player touches the part from stage 1 it fires too many times making someone stage 15

I tried cooldowns but they dont work

1 Like

You can use debouncing, you can achieve this by putting a boolean variable called isUsed or whatever you want it to be called and set it to false, then, when the script is done you set it to true. Implementing into your code would look like this

(If you need more help with debouncing go to Debounce – When and Why


 local Stages = script.Parent:GetChildren()

local isUsed = false

if not isUsed then

local StageDifferenceWarningEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("StageDifferenceWarning")

local StageNotificationEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("StageNotification")


local Config = {
	StageOnDeath = false;
	AntiCheat = true; -- Won't let a player stage on the stage after their next stage
	DoubleStagePass = 60560957;
	VIPExtraStageChance = 60750478;
}

local ExtraStageChances = {
	["Yes"] = 25;
	["No"] = 75;
}

local PlrsOnCooldown = {}

local mps = game:GetService("MarketplaceService")

local function ChooseAmountOfStageToSet(UserId)

	local TempChanceVerdictTable = {}

	local CurrentStagesToSet = 1


	if mps:UserOwnsGamePassAsync(UserId, Config.DoubleStagePass) then

		CurrentStagesToSet += 1

		if mps:UserOwnsGamePassAsync(UserId, Config.VIPExtraStageChance) then

			for choice, chance in pairs(ExtraStageChances) do

				for i = 1, chance do

					table.insert(TempChanceVerdictTable, choice)

				end

			end

			local ChosenVIPExtraStageVerdict = TempChanceVerdictTable[math.random(1,#TempChanceVerdictTable)]

			if ChosenVIPExtraStageVerdict == "Yes" then

				CurrentStagesToSet += 1

				return CurrentStagesToSet

			else

				return CurrentStagesToSet

			end

		else

			return CurrentStagesToSet

		end

	else

		if mps:UserOwnsGamePassAsync(UserId, Config.VIPExtraStageChance) then

			for choice, chance in pairs(TempChanceVerdictTable) do

				for i = 1, chance do

					table.insert(TempChanceVerdictTable, choice)

				end

			end

			local ChosenVIPExtraStageVerdict = TempChanceVerdictTable[math.random(1,#TempChanceVerdictTable)]

			if ChosenVIPExtraStageVerdict == "Yes" then

				CurrentStagesToSet += 1

				return CurrentStagesToSet

			else

				return CurrentStagesToSet

			end

		else

			return CurrentStagesToSet

		end

	end

end


for _, stage in pairs(Stages) do

	if stage:IsA("Model") then

		stage.Spawn.Touched:Connect(function(hit)

			if hit.Parent:FindFirstChild("Humanoid") then

				local player = game.Players:GetPlayerFromCharacter(hit.Parent)

				local plrhealth = hit.Parent.Humanoid.Health

				local CurrentStageNum = tonumber(stage.Num.Value)

				if player.leaderstats.Stage.Value < CurrentStageNum and not table.find(PlrsOnCooldown, player.Name) then

					if Config.StageOnDeath == false then

						if plrhealth > 0 then

							if Config.AntiCheat == true then

								local StageDifference = (CurrentStageNum - player.leaderstats.Stage.Value)

								if StageDifference == 1 then

									local AmountOfStagesToGive = ChooseAmountOfStageToSet(player.UserId)

									print(AmountOfStagesToGive)

									player.leaderstats.Stage.Value = (player.leaderstats.Stage.Value + AmountOfStagesToGive)

									StageNotificationEvent:FireClient(player, player.leaderstats.Stage.Value, AmountOfStagesToGive - 1)


								else

									StageDifferenceWarningEvent:FireClient(player)

								end

							else

								
StageDifferenceWarningEvent:FireClient(player)

							end

						end

					else

						if Config.AntiCheat == true then

							local StageDifference = (CurrentStageNum - player.leaderstats.Stage.Value)

							if StageDifference == 1 then

								local AmountOfStagesToGive = ChooseAmountOfStageToSet(player.UserId)

								player.leaderstats.Stage.Value = (player.leaderstats.Stage.Value + AmountOfStagesToGive)

								StageNotificationEvent:FireClient(player, player.leaderstats.Stage.Value, AmountOfStagesToGive - 1)


							else

								StageDifferenceWarningEvent:FireClient(player)

							end

						else

							StageDifferenceWarningEvent:FireClient(player)

						end

					end

				end

			end

		end)

	end

isUsed = true
end
end
2 Likes

No I have an issue where when the player touches the stage it fires too much

1 Like

Its firing too much because you didn’t check if the player has already touched the "stage " part

2 Likes

Should I add the old to a table and remove them once db ends?

1 Like

The script fires multiple times because the character has multiple parts that hit the part that detects touches. You need to implement additional checks into your script.

1 Like