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
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.
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
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.
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.
@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.
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.
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)
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.
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.
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)