Extreme lag caused by some functions

I’m working on a game that has an injure function, carry function, and execute function in my characterhandler script which used to work fine. I don’t know when it started, but these functions started causing immense amounts of lag especially when spammed. The ping reaches up to 1000ms in these cases and goes back down a couple seconds after it’s stopped, but the rate does not slow down. It’s my first time genuinely scripting on roblox so I don’t know exactly how to prevent lag, I’ve made sure that most loops aren’t left running for no reason and everything is deleted after it’s done being used so I’m not sure what could be causing this.

function injure()
	if not actionCheck() and not character:FindFirstChild("Injuring") and not character:FindFirstChild("Gripping") and not character:FindFirstChild("Carrying") then
		local target
		
		target = sortKnocked()
		
		if target ~= nil and liveFolder[target]:FindFirstChild("Knocked") and liveFolder[target].Humanoid.Health ~= 0 then
			local gettingInjuredTrack = liveFolder[target].Humanoid.Animator:LoadAnimation(Anims["BeingGripped"])
			gettingInjuredTrack.Priority = Enum.AnimationPriority.Idle
			gettingInjuredTrack.Looped = true
			if liveFolder[target]:FindFirstChild("Knocked") and liveFolder[target].Humanoid.Health ~= 0 then
				if not character:FindFirstChild("HeavyStunned") then
					local heavyStun = Instance.new("Folder")
					heavyStun.Name = "HeavyStunned"
					heavyStun.Parent = character
				end
				if not character:FindFirstChild("Injuring") then
					local injureFolder = Instance.new("Folder")
					injureFolder.Name = "Injuring"
					injureFolder.Parent = character
				end
				if not character:FindFirstChild("BeingInjured") then
					local beingInjuredFolder = Instance.new("Folder")
					beingInjuredFolder.Name = "BeingInjured"
					beingInjuredFolder.Parent = liveFolder[target]
				end
				if not liveFolder[target]:FindFirstChild("HeavyStunned") then
					local heavyStun = Instance.new("Folder")
					heavyStun.Name = "HeavyStunned"
					heavyStun.Parent = liveFolder[target]
				end
				
				liveFolder[target]:FindFirstChild("Knocked"):Destroy()
				liveFolder[target].HumanoidRootPart.CFrame = CFrame.new(liveFolder[target].HumanoidRootPart.Position.X, character.HumanoidRootPart.Position.Y, liveFolder[target].HumanoidRootPart.Position.Z)
				liveFolder[target].HumanoidRootPart.Orientation = Vector3.new(0, liveFolder[target].HumanoidRootPart.Orientation.Y, 0)
				
				gettingInjuredTrack:Play()
				injureTrack:Play()
				
				character.HumanoidRootPart.CFrame = CFrame.new(liveFolder[target].HumanoidRootPart.Position)
				character.HumanoidRootPart.CFrame = CFrame.lookAt(character.HumanoidRootPart.Position, liveFolder[target].HumanoidRootPart.CFrame.Position + -(liveFolder[target].HumanoidRootPart.CFrame.LookVector * 10))


				local injureConstraint = Instance.new("AlignPosition", character.HumanoidRootPart)
				injureConstraint.Name = "InjureForce"
				injureConstraint.Attachment0 = character.HumanoidRootPart.RootAttachment
				injureConstraint.Attachment1 = liveFolder[target].HumanoidRootPart.RootAttachment
				injureConstraint.RigidityEnabled = false

				liveFolder[target].HumanoidRootPart.CFrame = CFrame.new(liveFolder[target].HumanoidRootPart.Position.X, character.HumanoidRootPart.Position.Y, liveFolder[target].HumanoidRootPart.Position.Z)
				liveFolder[target].HumanoidRootPart.Orientation = Vector3.new(0, liveFolder[target].HumanoidRootPart.Orientation.Y, 0)
				
				
				humanoid.AutoRotate = false
				
				local function stop()
					injureConstraint:Destroy()
					humanoid.AutoRotate = true
					if injureTrack.IsPlaying then
						injureTrack:Stop()
					end
					if gettingInjuredTrack.IsPlaying then
						gettingInjuredTrack:Stop()
					end
					if character:FindFirstChild("Injuring") then
						character.Injuring:Destroy()
					end
					if character:FindFirstChild("HeavyStunned") then
						character.HeavyStunned:Destroy()
					end
					if liveFolder[target]:FindFirstChild("HeavyStunned") then
						liveFolder[target].HeavyStunned:Destroy()
					end
					if liveFolder[target]:FindFirstChild("BeingInjured") then
						liveFolder[target].BeingInjured:Destroy()
					end
					if not liveFolder[target]:FindFirstChild("Knocked") then
						local knock = Instance.new("Folder")
						knock.Name = "Knocked"
						knock.Parent = liveFolder[target]
						game:GetService("Debris"):AddItem(knock, 15)
					end
					return
				end
				
				character.ChildAdded:Connect(function(child)
					if child.Name == "Stunned" then
						if character:FindFirstChild("Injuring") then
							character.Injuring:Destroy()
						end
					end
				end)
				game.Players.PlayerRemoving:Connect(function(leftPlayer)
					if leftPlayer.Name == target then
						if character:FindFirstChild("Injuring") then
							character.Injuring:Destroy()
						end
					end
				end)

				character.ChildRemoved:Connect(function(child)
					if child.Name == "Injuring" then
						stop()
					end
				end)


				injureTrack:GetMarkerReachedSignal("StartInjure"):Connect(function()
					liveFolder[target].HumanoidRootPart.Bonebreak:Play()
					local hit = liveFolder[target].HumanoidRootPart.Hit:Clone()
					hit.Parent = liveFolder[target].Torso
					hit.Enabled = true
					game:GetService("Debris"):AddItem(hit, 0.3)
				end)
				injureTrack.Stopped:Connect(function()
					tagTarget(target, 15)
					stop()
				end)
			end
		end
	elseif character:FindFirstChild("Injuring") then
		character.Injuring:Destroy()
	end
end

Is the injure tag firing every time the player gets injured/is it firing many times?

The injure function alone is:
Checking multiple values, loading animations, enabling values, adding MULTIPLE instances at once, CFraming parts, changing orientations, adding constraints and attaching them, adjusting CFrame again, destroying parts, playing audio, starting debris to destroy some items after 15 seconds, creating a function, connecting a function to ChildAdded, playersremoving, childremoved, getmarkerreachedsignal, and stopped.

Basically: You’re connecting the same functions again that were already connected, creating multiple functions, and doing many if statement checks on multiple values/changing cframes/adding multiple instances. I might be wrong but I’m going to assume thats going to cause some lag regardless of how you go about it. I’m also going to assume that it fires every time the player gets injured? If so, you’re gonna have to move those functions that are inside connecting things out since its being constantly added ontop of eachother leading to possible memory leaks if you aren’t careful.

Along with that of the many additions of many instances and parenting them.

1 Like

Forgive me if I misunderstood, but this function is for injuring another player, like stomping on them while they’re down to break their leg or arm. There’s currently no injuries in the game, I just created this for later.

Wait so is this function not being fired or is it being fired?

Also to clarify:

Are you purposely spamming the function to test it or is something firing the function?

1 Like

This function fires when the player presses M while they’re not stunned or occupied, and if an unconscious target is found by the sortKnocked() function inside then it will run the rest of the function.

if not actionCheck() and not character:FindFirstChild("Injuring") and not character:FindFirstChild("Gripping") and not character:FindFirstChild("Carrying") then		
		target = sortKnocked()
		
		if target ~= nil and liveFolder[target]:FindFirstChild("Knocked") and liveFolder[target].Humanoid.Health ~= 0 then

If a player just presses M to fire the function it will bring the script’s rate up to about 200-400/s without causing noticeable server lag.

When a player spams M (however they can only do it after they’re done injuring them which takes about 2 seconds) on an unconscious player or NPC it will cause temporary extreme server lag.

Make a server debounce, if they aren’t in the table, shove them in the table right in the beginning of the function running so that way, it cant be spammed multiple times. Once the function finishes, remove them from the table ending the debounce allowing it to be fired later on. Repeat vice versa.

1 Like

The problem is that I want the function to be able to be spammed, just without causing this lag. The function should be able to be used as many times as the player wants as long as they aren’t stunned or occupied by anything and they have a target.

Hmm, then start it slow and move out things that don’t need to be repeated in the function, for example:
The functions that are connecting toward playerremoving/childadded/childremoved/etc can be moved outside or “debounced” in its own right to prevent multiple stack ups on the connections.

It also doesn’t look like you’re disconnecting them so they’re gonna constantly cause a memory leak leading to the graph you see above. By putting them outside, they only fire “once” and once is all that is needed.

Create all the folders/constraints beforehand and reference them later down the line rather than creating them on the spot every time they get injured.

Other than that, thats all I can think of from getting a quick look.

1 Like

I realized that the lag was caused by the ragdoll function, which is called by 3 functions including the injure function, so I’m going to make a new ragdoll script. I also moved all the functions outside as well as the constraint which helped reduce the lag but not completely.