Server script activity very high when using spell move?

Hello, I am developing a element type game with my friends and I played around with loops and I suddenly realized that the loop is causing intense server lag if many people use the move, which is a problem because it’s meant for many people to be in a server and i don’t want it to lag and the players having a bad experience. When one person uses it the activity goes up to something like 6% which is not ideal with many players. The lag is coming from line 92.

The lag disappears after the spell but it still will get laggy when alot of players does moves too

But if i do the move again the activity goes higher then the first time i used the move

local Debris = game:GetService("Debris")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local Connection4
local Connection5
local Connection6
game.ReplicatedStorage.Fire.Events.Move2.OnServerEvent:Connect(function(Player)
	local function GetMouse()
		local MS
		local Num = math.random(1,10)..math.random(1,10)..math.random(1,10)..math.random(1,10)
		game.ReplicatedStorage.GetMouse:FireClient(Player,Num)
		game.ReplicatedStorage.GetMouse.OnServerEvent:Connect(function(Player,M,N)
			if N == Num then
				MS = M
			end
		end)
		repeat wait() until MS
		return MS
	end 
	local AlreadyHit = {}
	local Burning = {}
	local FlamePart = Instance.new("Part")
	local Duration = true
	local Anim = Instance.new("Animation",Player.Character)
	Anim.AnimationId = "rbxassetid://10545496514"
	Anim = Player.Character.Humanoid.Animator:LoadAnimation(Anim)
	Anim:Play()

	FlamePart.Parent = workspace.Debris
	FlamePart:SetNetworkOwner(Player)
	FlamePart.Size = Vector3.new(1,1,1)
	FlamePart.Anchored = true
	FlamePart.CanCollide = false
	FlamePart.Transparency = 1
	local HitPart =  Instance.new("Part")
	HitPart.Parent = workspace.Debris
	HitPart.Anchored = true
	HitPart.Transparency = 1
	HitPart.CanCollide = false
	HitPart.Size = Vector3.new(4.5,4.5,40)
	HitPart.CFrame = CFrame.new((Player.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-2)).Position,GetMouse()) * CFrame.new(0,0,-(HitPart.Size.Z/2 + 2))
	local Sound = game.ReplicatedStorage.Fire.SoundEffects.Flamethrower:Clone()
	Sound.Parent = Player.Character.HumanoidRootPart
	Sound:Play()
	HitPart.Touched:Connect(function(t)
		if t.Parent:FindFirstChild("Humanoid") then
			if table.find(AlreadyHit,t.Parent) == nil and not t:IsDescendantOf(Player.Character) then
				table.insert(AlreadyHit,t.Parent)
				table.insert(Burning,t.Parent)
				for i, v in pairs(t.Parent:GetChildren()) do
					if v:IsA("Part") or v:IsA("MeshPart") then
						coroutine.wrap(function()
							for l,k in pairs(game.ReplicatedStorage.Fire.ParticleEmitters.BurningEffect:GetChildren()) do
								k = k:Clone()
								k.Parent = v
								k.Enabled = true
								coroutine.wrap(function()
									wait(3)
									for i, v in pairs(Burning) do
										if v == t.Parent then
											table.remove(Burning,i)
										end
									end
									for i, v in pairs(AlreadyHit) do
										if v == t.Parent then
											table.remove(AlreadyHit,i)
										end
									end
									k.Enabled = false
									Debris:AddItem(k,1)
								end)()
							end
						end)()
					end
				end
 				coroutine.wrap(function()
				     while true do
						wait(.5)
						if table.find(Burning,t.Parent) ~= nil then
							t.Parent:FindFirstChild("Humanoid"):TakeDamage(4.5783)
						end
						if Duration == false or table.find(Burning,t.Parent) == nil then
							break
						end
					end
				end)()
			end
		end
	end)
	coroutine.wrap(function()
	 Connection4 = RunService.Stepped:Connect(function()
			if HitPart ~= nil then
			HitPart.CFrame = CFrame.new((Player.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-2)).Position,GetMouse()) * CFrame.new(0,0,-(HitPart.Size.Z/2 + 2))
			else
				Connection4:Disconnect()
			end
	    	end)
	end)()
	for i, v in pairs(game.ReplicatedStorage.Fire.ParticleEmitters.Flamethrower:GetChildren()) do
	    v = v:Clone()
		v.Parent = FlamePart
		v.Enabled = true
		spawn(function()
			wait(5)
			v.Enabled = false
		end)
	end
	coroutine.wrap(function()
	Connection5 = RunService.Heartbeat:Connect(function()
	 if Duration == true then
		FlamePart.CFrame = CFrame.new((Player.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-2)).Position,GetMouse())
	end
	end)
	end)()
	spawn(function()
	wait(5)
	Connection4:Disconnect()
	Connection5:Disconnect()
	Anim = nil
	Debris:AddItem(FlamePart,1)
	HitPart:Destroy()
	HitPart = nil
	Duration = false
	end)	
end)


It’s recommended to do effects on client and hitboxes on server, also you should disconnect that GetMouse OnServerEvent connection after it’s used

You have numerous nested loops, of course your code is going to lag. Essentially each loop runs the loop inside it multiple times and so on. Unnest your loops or combine them if you can. Have your code run as few times as possible to reduce the lag you are having.

How would other players see the effects though

Remote event to every client then add the effects there

Alr thanks ill look into it tomorrow

You’re creating hundreds of alternate threads via coroutine.wrap. This entire script needs rewriting.

I did this rn moved all the effects on the client but other players don’t see the fireball when i use the move, and when i check the position of the fireball on another client the fireball is under the map. Am i doing something wrong?

What do i use then spawn(function()?

I just found out that mouse.Hit is for some reason nil for other players

What i mean is you should make the base part on server then send it to every player via remote event and have the players add particles themselves. Also you should get rid of most of those loops like others said.

Ah i found out but i have no idea how to fix the fireball that was fired by the 1st user going to the 2nd user’s mouse cursor when he fires his fireball : /

Send the owner’s mouse position through the remote event

i tried that too but ima try to rewrite that part a little