Help optimizing code

hello, i am working on a script for a missile and it has to be serverside so it can’t be exploited. sometimes, this script can get really bad, and i don’t know how to optimize code that well

could i have some help on where i should go to fix things up?

local RS = game:GetService("RunService")

local MaxSpeed = 145
local Exploded = false
local Deployed = false

local Missile = script.Parent.Missile
local Part

local MainTarget = Missile.Target.Value

local startervelocity = Vector3.new(0,0,0)

PartConnection = nil

local function Touched(Target,part,perferredpos)

	
	if not perferredpos then
		if part then
			perferredpos = part.Position
		end
	end
	
	
	
	if Deployed == false then return end
	
	if not Missile then
		return
	end
	
	--if not Target:IsA("BasePart") then  end
	
	if Target:IsDescendantOf(script.Parent.Parent) then return end

	--if not Target then return end
	
	Exploded = true
	Deployed = false
	Missile.Transparency = 0
	wait()
	Exploded = false
	Deployed = false
	
	
	MainTarget = Missile.Target.Value
	
	if PartConnection then
		PartConnection:Disconnect()
	end
	
	



	

	
	if part then
	

		
		local Explosion = Instance.new("Explosion")
		Explosion.Position = perferredpos
		Explosion.Parent = workspace
		Explosion.BlastRadius = 30
		Explosion.BlastPressure = 0
		Explosion.ExplosionType = Enum.ExplosionType.NoCraters
		
		local radius = workspace:GetPartBoundsInRadius(perferredpos,30)
		
		for i, v in pairs(radius) do
			if v.Parent then
				if v.Parent:FindFirstChild("Humanoid") then
					local plr
					
					pcall(function()
						plr = game.Players:GetPlayerFromCharacter(v.Parent)
					end)
					
					if plr then
						if workspace:FindFirstChild(plr.UserId) then
							v.Parent.Humanoid.Health -= math.random(2,5)
						end
					end
					
				end
			end
			
			if v:IsDescendantOf(script.Parent.Parent) then
				continue
			end
			
			if not v:IsDescendantOf(workspace.Plots) then
				if v.Parent.Parent then
					
					if tonumber(v.Parent.Parent.Name) ~= nil then
						v.CanCollide = false
						
						if math.random(1,5) >= 2 then
							game:GetService("TweenService"):Create(v,TweenInfo.new(.3),{Transparency = 1}):Play()
							game:GetService("Debris"):AddItem(v,.3)
						else
							if v:IsA("BasePart") then
								v:BreakJoints()
							end
						end
					end
				end
			end
		end
		
		
		
		local quicknew = Instance.new("Part",workspace)
		quicknew.Transparency = 1
		quicknew.CanCollide = false
		quicknew.CanTouch = false
		quicknew.Anchored = true
		quicknew.Position = part.Position
		

		part.Explode:Clone().Parent = quicknew
		quicknew.Explode:Play()
		
		game:GetService("Debris"):AddItem(quicknew,1)

		
		part.Anchored = true
		part.Transparency = 1
		
		
		if part then
			
			game:GetService("Debris"):AddItem(part,.2)
		end
	end
		
	MainTarget = Missile.Target.Value


end




Deploy = function()
	if not Missile then
		return
	end
	
	if not Missile:FindFirstChild("Target") then
		return
	end
	MainTarget = Missile.Target.Value
	
	--print(Deployed, Exploded)
	
	if Deployed == true then
		return
	end
	
	if not MainTarget then
		return
	end
	
	if not script.Parent:FindFirstChild("Base") then
		return
	end
	
	local missiles = 0
	
	for i, v in pairs(workspace:GetChildren()) do
		if v.Name == "Missile" then
			missiles += 1
		end
	end
	
	if missiles >= 6 then
		local userid = script.Parent.Parent.Name
		local plr

		for i, v in pairs(game.Players:GetPlayers()) do
			if v.UserId == tonumber(userid) then
				plr = v
			end
		end
		
		if plr then
			game.ReplicatedStorage.Events.Notifications.Notify:FireClient(plr,"Too many missiles in airspace.")
		end
		return
	end
	
	local ray = Ray.new(MainTarget.Position,Vector3.new(0,-18,0))
	local targettime = tick()+(math.clamp(script.Parent.Config.ActivationTimer.Value,.1,99999999)/20)
	
	local objecthit, hitposition,normal,material = workspace:FindPartOnRayWithWhitelist(ray, {workspace.Terrain}, false, false)
	
	startervelocity = script.Parent:FindFirstChild("Base").Velocity
	
	if objecthit then
		if objecthit.Name == "Terrain" then
			local userid = script.Parent.Parent.Name
			local plr
			
			for i, v in pairs(game.Players:GetPlayers()) do
				if v.UserId == tonumber(userid) then
					plr = v
				end
			end
			
			if plr then
				game.ReplicatedStorage.Events.Notifications.Notify:FireClient(plr,"Target is too close to the ground.")
			end
			return
		end
	end
	
	Deployed = true
	
	Part = Missile:Clone()
	
	Missile.Transparency = 1
	
	MainTarget = Part.Target.Value
	Part.Parent = workspace
	
	script.Parent.Base.CanCollide = false
	--script.Parent.Release:Play()
	Part.Anchored = false
	
	if Part:FindFirstChild("Starter") then
		Part.Starter:Destroy()
	end
	

	
	
	repeat wait() until tick() >= targettime
	
	Part.Beam1.Enabled = true
	Part.Beam1.Enabled = true
	
	Part.AngularVelocity.Enabled = true
	Part.LinearVelocity.Enabled = true
	
	Part.Engine:Play()
	
	local c = 0
	local t = tick()
	

	Part.Touched:Connect(function(h)
		if Part then
			if script.Parent:FindFirstChild("Base") then
				if (Part.Position-script.Parent:WaitForChild("Base").Position).Magnitude > 25 then
					PartConnection = Touched(h,Part,Part.Position)
				end
			end
		end
	end)

	
	if MainTarget == nil then
		Part.Target.Value = workspace.TARGET
		MainTarget = workspace.TARGET
	end
	
	
	if MainTarget.Parent then
		if MainTarget.Parent:FindFirstChild("Base") then
			if MainTarget.Parent.Base:FindFirstChild("SurfaceGui") then
				local tr = Instance.new("BoolValue",MainTarget.Parent:WaitForChild("Base").SurfaceGui.CallSign)
				tr.Name = "WarningVal"
				game:GetService("Debris"):AddItem(tr,7)
			end
		end
	end
	
	Part.Release:Play()
	
	game:GetService("Debris"):AddItem(Part,25)
	
	local waittime = 5
	
	while not Exploded do
		if tick()-t > 25 then
			break
		end
		if Part then
			if Part:FindFirstChild("Target") then
				MainTarget = Part.Target.Value
				
			
				
				
				if c > 100 then
					waittime = .3
				end
				

				game:GetService("TweenService"):Create(Part,TweenInfo.new(waittime),{CFrame = CFrame.lookAt(Part.Position, MainTarget.Position) * CFrame.Angles(math.pi,0,0)}):Play()
			
				
				Part.LinearVelocity.VectorVelocity = startervelocity + (-Part.CFrame.LookVector * (MaxSpeed+c))
				
				

				
				
				if (MainTarget.Position-Part.Position).Magnitude <= 25 then
					PartConnection = Touched(MainTarget,Part)
				end
			end
			
		else
			break
		end
		
		c += 4
	
		RS.Stepped:Wait()
		RS.Stepped:Wait()
	end
	
	if tick()-t < 25 then
		if Part then
			PartConnection = Touched(MainTarget,Part)
		end
	end
	
	
	if Part then
		game:GetService("Debris"):AddItem(Part,.5)

		Part = nil
	end

	Deployed = false
	Exploded = false
	Missile.Transparency = 0
end


script.Parent.Deploy.OnServerEvent:Connect(Deploy)
1 Like

What was the original recommendation you were going to give?

1 Like

I was making a recommendation but I accidentally pressed ctrl+enter or something that automatically sent it

here was the thing I was going to recommend


you put a lot of gaps between code so I had removed it
also another thing you did is rode if statements

if x then
	--no variable,function,loop declared between ifs
	if y then

we can replace this with

if x and y then

same with the returns

if x then
	return
end
--nothing declared between statements 
if y then
	return
end

can be

if x or y then
	return
end

RS.Stepped will only be called if there is a part
so we can flip the if statement so it can be
and then you will realize that now that

if tick()-t > 25 then
	break
end
if not (Part or Part:FindFirstChild("Target")) then
	break
end

are next to eachother we can apply the same rule for return

if tick()-t > 25 or not (Part or Part:FindFirstChild("Target")) then
	break
end

replacing this with

if tick()-t > 25 or not (Part or Part:FindFirstChild("Target")) then
	break
end
MainTarget = Part.Target.Value
if c > 100 then
	waittime = .3
end
TweenService:Create(Part,TweenInfo.new(waittime),{CFrame = CFrame.lookAt(Part.Position, MainTarget.Position) * CFrame.Angles(math.pi,0,0)}):Play()
Part.LinearVelocity.VectorVelocity = startervelocity + (-Part.CFrame.LookVector * (MaxSpeed+c))
if (MainTarget.Position-Part.Position).Magnitude <= 25 then
	PartConnection = Touched(MainTarget,Part)
end
c += 4
RS.Stepped:Wait()
RS.Stepped:Wait()

these aren’t all optimizations but
here is the final code

local RS = game:GetService("RunService")
local TweenService=game:GetService('TweenService')

local MaxSpeed = 145
local Exploded = false
local Deployed = false

local Missile = script.Parent.Missile
local Part

local MainTarget = Missile.Target.Value

local startervelocity = Vector3.new(0,0,0)

PartConnection = nil

local function Touched(Target,part,perferredpos)
	if not perferredpos and part then
		perferredpos = part.Position
	end
	if Target:IsDescendantOf(script.Parent.Parent) or not (Deployed or Missile) then
		return
	end
	Exploded = true
	Deployed = false
	Missile.Transparency = 0
	wait()
	Exploded = false
	Deployed = false
	MainTarget = Missile.Target.Value
	if PartConnection then
		PartConnection:Disconnect()
	end
	if part then
		local Explosion = Instance.new("Explosion")
		Explosion.Position = perferredpos
		Explosion.Parent = workspace
		Explosion.BlastRadius = 30
		Explosion.BlastPressure = 0
		Explosion.ExplosionType = Enum.ExplosionType.NoCraters
		local radius = workspace:GetPartBoundsInRadius(perferredpos,30)
		for i, v in pairs(radius) do
			if v.Parent and v.Parent:FindFirstChild("Humanoid") then
				local plr=game.Players:GetPlayerFromCharacter(v.Parent)
				if plr and workspace:FindFirstChild(plr.UserId) then
					v.Parent.Humanoid.Health -= math.random(2,5)
				end
			end
			if v:IsDescendantOf(script.Parent.Parent) then
				continue
			end
			if not v:IsDescendantOf(workspace.Plots) and v.Parent.Parent and tonumber(v.Parent.Parent.Name) then
				v.CanCollide = false
				if math.random(1,5) >= 2 then
					TweenService:Create(v,TweenInfo.new(.3),{Transparency = 1}):Play()
					game:GetService("Debris"):AddItem(v,.3)
				elseif v:IsA("BasePart") then
						v:BreakJoints()
				end
			end
		end
		local quicknew = Instance.new("Part",workspace)
		quicknew.Transparency = 1
		quicknew.CanCollide = false
		quicknew.CanTouch = false
		quicknew.Anchored = true
		quicknew.Position = part.Position
		part.Explode:Clone().Parent = quicknew
		quicknew.Explode:Play()
		game:GetService("Debris"):AddItem(quicknew,1)
		part.Anchored = true
		part.Transparency = 1
		if part then
			game:GetService("Debris"):AddItem(part,.2)
		end
	end
	MainTarget = Missile.Target.Value
end
Deploy = function()
	if Deployed or not (Missile or Missile:FindFirstChild("Target") or script.Parent:FindFirstChild("Base")) then
		return
	end
	MainTarget = Missile.Target.Value
	if not MainTarget then
		return
	end
	local missiles = 0
	for i, v in pairs(workspace:GetChildren()) do
		if v.Name == "Missile" then
			missiles += 1
		end
	end
	if missiles >= 6 then
		local userid = script.Parent.Parent.Name
		local plr
		for i, v in pairs(game.Players:GetPlayers()) do
			if v.UserId == tonumber(userid) then
				plr = v
			end
		end
		if plr then
			game.ReplicatedStorage.Events.Notifications.Notify:FireClient(plr,"Too many missiles in airspace.")
		end
		return
	end
	local ray = Ray.new(MainTarget.Position,Vector3.new(0,-18,0))
	local targettime = tick()+(math.clamp(script.Parent.Config.ActivationTimer.Value,.1,99999999)/20)
	local objecthit, hitposition,normal,material = workspace:FindPartOnRayWithWhitelist(ray, {workspace.Terrain}, false, false)
	startervelocity = script.Parent:FindFirstChild("Base").Velocity
	if objecthit and objecthit.Name == "Terrain" then
		local userid = script.Parent.Parent.Name
		local plr
		for i, v in pairs(game.Players:GetPlayers()) do
			if v.UserId == tonumber(userid) then
				plr = v
			end
		end
		if plr then
			game.ReplicatedStorage.Events.Notifications.Notify:FireClient(plr,"Target is too close to the ground.")
		end
		return
	end
	Deployed = true
	Part = Missile:Clone()
	Missile.Transparency = 1
	MainTarget = Part.Target.Value
	Part.Parent = workspace
	script.Parent.Base.CanCollide = false
	--script.Parent.Release:Play()
	Part.Anchored = false
	if Part:FindFirstChild("Starter") then
		Part.Starter:Destroy()
	end
	repeat wait() until tick() >= targettime
	Part.Beam1.Enabled = true
	Part.Beam1.Enabled = true
	Part.AngularVelocity.Enabled = true
	Part.LinearVelocity.Enabled = true
	Part.Engine:Play()
	local c = 0
	local t = tick()
	Part.Touched:Connect(function(h)
		if Part and script.Parent:FindFirstChild("Base") and (Part.Position-script.Parent:WaitForChild("Base").Position).Magnitude > 25 then
			PartConnection = Touched(h,Part,Part.Position)
		end
	end)
	if MainTarget == nil then
		Part.Target.Value = workspace.TARGET
		MainTarget = workspace.TARGET
	end
	if MainTarget.Parent and MainTarget.Parent:FindFirstChild("Base") and MainTarget.Parent.Base:FindFirstChild("SurfaceGui") then
		local tr = Instance.new("BoolValue",MainTarget.Parent:WaitForChild("Base").SurfaceGui.CallSign)
		tr.Name = "WarningVal"
		game:GetService("Debris"):AddItem(tr,7)
	end
	Part.Release:Play()
	game:GetService("Debris"):AddItem(Part,25)
	local waittime = 5
	while not Exploded do
		if tick()-t > 25 or not (Part or Part:FindFirstChild("Target")) then
			break
		end
		MainTarget = Part.Target.Value
		if c > 100 then
			waittime = .3
		end
		TweenService:Create(Part,TweenInfo.new(waittime),{CFrame = CFrame.lookAt(Part.Position, MainTarget.Position) * CFrame.Angles(math.pi,0,0)}):Play()
		Part.LinearVelocity.VectorVelocity = startervelocity + (-Part.CFrame.LookVector * (MaxSpeed+c))
		if (MainTarget.Position-Part.Position).Magnitude <= 25 then
			PartConnection = Touched(MainTarget,Part)
		end
		c += 4
		RS.Stepped:Wait()
		RS.Stepped:Wait()
	end
	if tick()-t < 25 then
		if Part then
			PartConnection = Touched(MainTarget,Part)
		end
	end
	if Part then
		game:GetService("Debris"):AddItem(Part,.5)
		Part = nil
	end
	Deployed = false
	Exploded = false
	Missile.Transparency = 0
end
script.Parent.Deploy.OnServerEvent:Connect(Deploy)

Thank you so much. Just wondering, how does optimizing code make it lag less and run faster?

well
first you have to run an if statement

if x then
return
end
if y then
return
end

you ran the if statment twice slowing it down.
so which is why if x and y then is better
because using the and is alot faster than running it twice, you have to check for true twice

the x and y means
if x is true then it’ll use y
so its basically
if y then
also Im prettysure in an ASM it will use less jumps and less resources.

1 Like

Hey! Sorry for coming back, but I still experience some lag spikes with the code. Do you know anything else I could do to help this?

probably because of this, just put a task.wait or a RS.Stepped:Wait()
just before the break.

1 Like

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