Ball or .Touched slows down after round ends

Hello! Welcome to my topic!

It’s about a bug/glitch that makes my soccer ball slow down when a round ends (2:30 mins).

I don’t know how this happens, but when a round of 2 minutes 30 seconds ends, when I touch the ball, it takes longer for the ball to shoot and sometimes it just does nothing, the more rounds that pass, the worse it gets. One time (today) I left my game on for pretty long. I tried to touch the ball and oh my I literally crashed because of it. Does anyone know how this happens? My game is almost done and I need this fixed ASAP since I want the game done by Febuary 1st.

Help would really be appreciated. Have a great day :slight_smile:

I would like to clear up a few things before people ask me:

A round is 2:30 minutes.
The ball uses .Touched.
There is nothing really changing the wait() functions in any script.

I can provide the scripts (ball and timer) if needed.

1 Like

Yes, please, provide your scripts. I think you don’t disconnect .Touched event and add another after round ends.

1 Like

I’ll send you the timer script and the ball script:

Ball script:

game.Players.PlayerAdded:Connect(function()
	local Services = {
		Players = game:GetService("Players"),
		Debris = game:GetService("Debris")

	}
	local Settings = {
		Kick_Cooldown = 0.5,
		Kick_Height = 0.15,
	}
	local Ball = script.Parent
	local KickSound = Ball:WaitForChild("Kick")
	local IgnoreTable = {}

	while true do
		wait(0.03)
		Ball.Touched:Connect(function(hit)
			local Character = hit.Parent
			
			local isPlayer = Character:FindFirstChild("Humanoid")
			
			if not isPlayer then
				return
			end
			
			if Character then
				if isPlayer then
					if hit.Parent.Name == "GoalkeeperRed" then return end
					if hit.Parent.Name == "GoalkeeperBlue" then return end
					script.Parent.Value.Value = hit.Parent
					local Kick_Force = Character.Power.Value
					local Player = Services.Players:GetPlayerFromCharacter(Character)
					local Humanoid = Character:FindFirstChildOfClass("Humanoid")
					local Root = Character:FindFirstChild("HumanoidRootPart")
					if not Player or not Humanoid or Humanoid.Health <= 0 or not Root or table.find(IgnoreTable, Player) then
						return
					end
					table.insert(IgnoreTable, Player)
					delay(Settings.Kick_Cooldown, function()
						if not Player then
							return
						end
						local Position = table.find(IgnoreTable, Player)
						if not Position then
							return
						end
						table.remove(IgnoreTable, Position)
					end)
					local Direction = Root.CFrame.LookVector
					if Direction.Magnitude < 0.001 then
						return
					end
					local Velocity = Instance.new("BodyVelocity")
					Velocity.Parent = Ball
					Velocity.MaxForce = Vector3.new(1, 1, 1) * math.huge
					Velocity.Velocity = (Direction.Unit * Kick_Force) + Vector3.new(0, Kick_Force *Settings.Kick_Height, 0)
					Services.Debris:AddItem(Velocity, 0.2)
					KickSound:Play()
					wait(0.03)
				end
			end
		end)
	end
end)

Timer script:

local function resetRed()

	local children = workspace.RedTeam
	local parts = workspace.RedParts

	if #children:GetChildren() == 0 then
		print("No")
		return
	end

	local num = math.random(1, #parts:GetChildren())
	local randomplace = parts:GetChildren()[num]
	local randomplayernum = math.random(1, #children:GetChildren())
	local player1 = children:GetChildren()[randomplayernum]


	if workspace.RedTeam:GetChildren()[randomplayernum] and workspace.RedParts:GetChildren()[num] then


		if #parts:GetChildren() == 0 then
			randomplace.Parent = workspace.RedParts
			player1.Parent = workspace.RedTeam
			return
		end
		if #children:GetChildren() == 0 then
			randomplace.Parent = workspace.RedParts
			player1.Parent = workspace.RedTeam
			return
		end

		player1.PrimaryPart.CFrame = randomplace.CFrame

		children:GetChildren()[randomplayernum].Parent = game.Workspace.TPPlayersRed
		print("Still here")
		randomplace.Parent = game.Workspace.TPPartsRed
		print("Here")

		if #parts:GetChildren() == 0 then
			randomplace.Parent = workspace.RedParts
			player1.Parent = workspace.RedTeam
			return
		end
		if #children:GetChildren() == 0 then
			randomplace.Parent = workspace.RedParts
			player1.Parent = workspace.RedTeam
			return
		end

		if workspace.RedTeam:GetChildren()[randomplayernum] and workspace.RedParts:GetChildren()[num] then
			print("2")
			children = game.Workspace.RedTeam
			parts = game.Workspace.RedParts

			num = math.random(1, #parts:GetChildren())
			randomplace = parts:GetChildren()[num]

			randomplayernum = math.random(1, #children:GetChildren())
			player1 = children:GetChildren()[randomplayernum]
			player1.PrimaryPart.CFrame = randomplace.CFrame
			player1.Parent = workspace.TPPlayersRed
			randomplace.Parent = workspace.TPPartsRed
			if #parts:GetChildren() == 0 then
				randomplace.Parent = workspace.RedParts
				player1.Parent = workspace.RedTeam
				return
			end
			if #children:GetChildren() == 0 then
				randomplace.Parent = workspace.RedParts
				player1.Parent = workspace.RedTeam
				return
			end

			if children:GetChildren()[randomplayernum] and parts:GetChildren()[num] then
				print("3")
				children = game.Workspace.RedTeam
				parts = game.Workspace.RedParts

				num = math.random(1, #parts:GetChildren())
				randomplace = parts:GetChildren()[num]

				randomplayernum = math.random(1, #children:GetChildren())
				player1 = children:GetChildren()[randomplayernum]

				player1.PrimaryPart.CFrame = randomplace.CFrame

				randomplace.Parent = workspace.TPPartsRed
				player1.Parent = workspace.TPPlayersRed
				if #parts:GetChildren() == 0 then
					randomplace.Parent = workspace.RedParts
					player1.Parent = workspace.RedTeam
					return
				end
				if #children:GetChildren() == 0 then
					randomplace.Parent = workspace.RedParts
					player1.Parent = workspace.RedTeam
					return
				end
			end
		end
	end
end

local function resetBlue()
	local children = workspace.BlueTeam
	local parts = workspace.BlueParts

	if #children:GetChildren() == 0 then
		print("No")
		return
	end

	local num = math.random(1, #parts:GetChildren())
	local randomplace = parts:GetChildren()[num]
	local randomplayernum = math.random(1, #children:GetChildren())
	local player1 = children:GetChildren()[randomplayernum]


	if workspace.BlueTeam:GetChildren()[randomplayernum] and workspace.BlueParts:GetChildren()[num] then
		if #parts:GetChildren() == 0 then
			randomplace.Parent = workspace.BlueParts
			player1.Parent = workspace.BlueTeam
			return
		end
		if #children:GetChildren() == 0 then
			randomplace.Parent = workspace.BlueParts
			player1.Parent = workspace.BlueTeam
			return
		end
		player1.PrimaryPart.CFrame = randomplace.CFrame

		children:GetChildren()[randomplayernum].Parent = game.Workspace.TPPlayersBlue
		print("Still here")
		randomplace.Parent = game.Workspace.TPPartsBlue
		print("Here")

		if #parts:GetChildren() == 0 then
			randomplace.Parent = workspace.BlueParts
			player1.Parent = workspace.BlueTeam
			return
		end
		if #children:GetChildren() == 0 then
			randomplace.Parent = workspace.BlueParts
			player1.Parent = workspace.BlueTeam
			return
		end

		if workspace.BlueTeam:GetChildren()[randomplayernum] and workspace.BlueParts:GetChildren()[num] then
			children = game.Workspace.BlueTeam
			parts = game.Workspace.BlueParts

			num = math.random(1, #parts:GetChildren())
			randomplace = parts:GetChildren()[num]

			randomplayernum = math.random(1, #children:GetChildren())
			player1 = children:GetChildren()[randomplayernum]
			player1.PrimaryPart.CFrame = randomplace.CFrame
			player1.Parent = workspace.TPPlayersBlue
			randomplace.Parent = workspace.TPPartsBlue
			if #parts:GetChildren() == 0 then
				randomplace.Parent = workspace.BlueParts
				player1.Parent = workspace.BlueTeam
				return
			end
			if #children:GetChildren() == 0 then
				randomplace.Parent = workspace.BlueParts
				player1.Parent = workspace.BlueTeam
				return
			end

			if children:GetChildren()[randomplayernum] and parts:GetChildren()[num] then
				children = game.Workspace.BlueTeam
				parts = game.Workspace.BlueParts

				num = math.random(1, #parts:GetChildren())
				randomplace = parts:GetChildren()[num]

				randomplayernum = math.random(1, #children:GetChildren())
				player1 = children:GetChildren()[randomplayernum]

				player1.PrimaryPart.CFrame = randomplace.CFrame

				randomplace.Parent = workspace.TPPartsBlue
				player1.Parent = workspace.TPPlayersBlue
				if #parts:GetChildren() == 0 then
					randomplace.Parent = workspace.BlueParts
					player1.Parent = workspace.BlueTeam
					return
				end
				if #children:GetChildren() == 0 then
					randomplace.Parent = workspace.BlueParts
					player1.Parent = workspace.BlueTeam
					return
				end
			end
		end
	end
end

local rep = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local minutesvalue = rep:WaitForChild("Minutes")
local secondsvalue = rep:WaitForChild("Seconds")
local minutes = 2
local seconds = 30

while true do
	
	minutesvalue.Value = minutes
	secondsvalue.Value = seconds

	repeat
		if secondsvalue.Value <= 0 then
			minutesvalue.Value = minutesvalue.Value - 1
			secondsvalue.Value = 59
		else
			secondsvalue.Value = secondsvalue.Value - 1
		end
		wait(1)
		
		if secondsvalue.Value <= 0 and minutesvalue.Value <= 0 then
			game.Workspace.Ref.RefWhistle:Play()
			game.Workspace.Ref.GameOver:Play()

			game.Workspace.Ball.Position = Vector3.new(-2.5, 3.799, -4.5 )

			resetRed()
			resetBlue()

			local red = game.Workspace.RedPoints
			local blue = game.Workspace.BluePoints

			local redwin = red.Value > blue.Value
			local bluewin = blue.Value > red.Value
			local tie = blue.Value == red.Value

			if redwin == true then
				game.Workspace.RedPoints.Value = 0
				game.Workspace.BluePoints.Value = 0
				game.Workspace.RedWins:FireAllClients()
				
				for i, v in pairs(game.Teams.Red:GetPlayers()) do
					v:FindFirstChild("leaderstats"):FindFirstChild("Wins").Value = v:FindFirstChild("leaderstats"):FindFirstChild("Wins").Value + 1
				end
			end

			if bluewin == true then
				game.Workspace.BlueWins:FireAllClients()
				game.Workspace.RedPoints.Value = 0
				game.Workspace.BluePoints.Value = 0
				for i, v in pairs(game.Teams.Blue:GetPlayers()) do
					v:FindFirstChild("leaderstats"):FindFirstChild("Wins").Value = v:FindFirstChild("leaderstats"):FindFirstChild("Wins").Value + 1
				end
			end

			if tie == true then
				game.Workspace.RedPoints.Value = 0
				game.Workspace.BluePoints.Value = 0
				game.Workspace.TieGame:FireAllClients()
			end
		end
	until secondsvalue.Value <= 0 and minutesvalue.Value <= 0
end
4 Likes

Remove the infinite loop. You connect function to the event every 0.03 seconds. It means that after 1 second of this code running ball have 33 .Touched functions.

1 Like

Huh, why? This is not what I meant. It happens every 2:30 minutes.

Also the ball gets kicked, it waits another 0.03 seconds before the ball can be kicked again. So you can only kick it once, except for when its against a wall.

5 Likes

@GulgPlayer is correct. You only need to set up the Ball.Touched event once to achieve the functionality you are looking for. Once you have connected a function to Ball.Touched, that function will be called every time the ball is touched until the event is disconnected. Your code does not disconnect the event.

What your code is doing is adding an additional connection to the ball roughly ~33 times per second per player. This means that when your game starts, the function is called once every time the ball is touched. If ten players are in the game after ten minutes every time the ball is touched you are calling your function 19,800 times! This is the source of your lag.

To achieve the cooldown you are looking for, try using a debounce variable:

local debounce = false
local cooldown = 0.03
Ball.Touched:connect(function(hit)
    if not debounce then
        debounce = true
        task.delay(cooldown, function()
            debounce = false
        end)
        -- ball touched logic
    end
end)

Remember, you only need to declare the event connection once and it will fire the function every time the ball is touched.

3 Likes

Tocuhed is an event. When you call Touched:Connect you tell Roblox that every time when the ball get touched your functions should execute. When you call Tocuhed:Connect it connects twice and the function will be called twice.

1 Like

Alright I’ll try that, I understand what you 2 are talking about now.

But what does this have to do with the 2:30 minutes timer?
Every time it resets, the ball gets laggier

5 Likes

That’s probably cause at that point on time, it’s reached like a 1000+ touched connections.

Which is definitely something that’ll make you lag/crash.

1 Like

Most likely the lag has nothing to do with your timer.

game.Workspace.Ball.Position = Vector3.new(-2.5, 3.799, -4.5 )

This line of code in your round reset script teleports the ball, at which point it likely hits something, triggering the ungodly amount of .Touched connections you’ve built up (The .Touched event triggers anytime the ball touches any other part)

1 Like

I have removed the while true do loop. It seems to be working!

It hits the ground, but I don’t think that changes anything, since it’s laying on the ground the whole time.

3 Likes

If its laying on the ground but not moving, it wouldn’t trigger the touched event. Even if its rolling, as long as it maintains contact with the ground it likely still wouldn’t trigger the touched event. But when you teleport the ball this more than likely does trigger the touched event.

Keep in mind that the longer the game was going, the more connection debt you were building up, so teleporting the ball at the end of the round and having it hit the ground would trigger more lag than any time a player hit the ball during the round.

1 Like

You should also be able to remove the .Touched connection from the .PlayerAdded connection and just put it at the top-level of your script. If it is in the PlayerAdded connection, you are generating an additional connection each time a player joins. This is much better than generating an additional connection every 0.03s for every player, but still not ideal. After all, you only need 1 connection for the event to work.

1 Like

Will do, appreciate you for helping me out there, this really helped me with my game, I didn’t know it was lag building up, just thought it was instant (by the timer) :slight_smile:

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.