Is there any way I can optimize this code?

Is there any way I can optimize this code? It seems to be causing a rather high % rate in the “script performance” tab (4-7%).

Code
local lasthrpcf = nil
	function self.step(dt)
		if not self.rendering then return end
		local hrpcf = nil
		local lastfollowpos = self.currentfollowpos
		if not self.attacking then
			local char = p.Character
			if char then
				local hrp = char:FindFirstChild("HumanoidRootPart")
				if hrp then
					--if hrp.CFrame ~= lasthrpcf then
						local fpos = self.getfollowpos()
						if hrp and fpos then
							self.currentfollowpos = (hrp.CFrame * fpos)
						end
						
					--end
					hrpcf = hrp.CFrame
				end
			else
				self.currentfollowpos = nil
			end
		end
		if self.circle then
			self.circle.toggle(self.attacking)
		end
		if self.model then
			if self.attacking then
				if self.circle then
					self.circle.UpdatePosition()
				end
				if self.circleline then
					self.circleline.update()
				end
			end
			local hum = self.humanoid
			if hum then				
				local closeto = false
				if not self.attacking then
					local hrp = self.hrp
					if hrp and self.currentfollowpos and self.currentfollowpos ~= lastfollowpos then
						local distance = (self.currentfollowpos - hrp.Position)
						local dist = (distance.Magnitude)
						if dist <= 3 then
							closeto = true
						end
						local xzdist = Vector3.new(distance.X, 0, distance.Z)
						if xzdist.Magnitude >= 120 or distance.Y >= 100 then
							self.refresh()
						end
					end
				end
				local upg = GetPlayerUpgrade(self.player, "Speed")
				local boost = 0
				if upg then
					boost = upg["Amount"] or 0
				end
				local walkspeed = 16
				local walkspeed2 = 16
				local char = self.player.Character
				if char then
					local hum = char:FindFirstChild("Humanoid")
					local hrp = char:FindFirstChild("HumanoidRootPart")
					if hum and hrp then
						walkspeed2 = ((hrp.Velocity * Vector3.new(1, 0, 1)).magnitude > 1 and hrp.Velocity.magnitude or 16)
					end
				end
				walkspeed2 = self.attacking and 16  or walkspeed2 
				local ws0 = 16
				if not closeto and not self.attacktarget then
					walkspeed = math.min(ws0 * (walkspeed2 / ws0),math.floor((walkspeed2) * 0.999))
				else
					walkspeed = math.min(ws0 * (walkspeed2 / ws0), 50)
				end
				if hum.WalkSpeed ~= walkspeed then
					hum.WalkSpeed = walkspeed
				end
				if not self.attacktarget then
					if self.currentfollowpos and self.currentfollowpos ~= lastfollowpos then
						MoveTo(self.currentfollowpos, hum)
					end
				else
					local hrp = self.attacktarget:FindFirstChild("HumanoidRootPart")
					if hrp then
						local positionOnCircle = self.getattackpos()
						MoveTo(hrp.CFrame * positionOnCircle, hum)
					end
				end
			end
			
			if self.hrp then
				local walking = nil
				local dir = self.hrp.Velocity
				local vel = Vector3.new(dir.x, 0, dir.z)
				if math.abs(vel.magnitude) > 0.66 then
					walking = true
				end
				if not walking then
					if hum.AutoRotate then
						hum.AutoRotate = false
					end
					if self.hrp then
						local bodyGyro = self.bodyGyro
						if bodyGyro then
							local hrp = self.attacktarget
							if not hrp then
								local char = p.Character
								if char then
									hrp = char:FindFirstChild("HumanoidRootPart")
								end
							end
							if hrp then
								local cf = CFrame.new()
								if hrp == self.attacktarget then
									local hrp = self.attacktarget:FindFirstChild("HumanoidRootPart")
									if hrp and self.model ~= nil then
										if self.hrp ~= nil then
											hrp = hrp
											cf = CFrame.new(self.hrp.Position* Vector3.new(1, 0, 1), hrp.Position* Vector3.new(1, 0, 1))
										end
									end
								else
									cf = hrp.CFrame
								end
								if bodyGyro.CFrame ~= cf then
									bodyGyro.CFrame = cf 
									bodyGyro.MaxTorque = Vector3.new(40000, 40000, 40000)
								end
							end
						end
					end
				else
					if not hum.AutoRotate then
						hum.AutoRotate = true
					end
					if self.hrp then
						local bodyGyro = self.bodyGyro
						if bodyGyro then
							bodyGyro.MaxTorque = Vector3.new()
						end
					end
				end
				if self.attacking and self.attacktarget ~= nil and not self.removed then
					local hrp = self.model:FindFirstChild("HumanoidRootPart")
					local hrp2 = self.attacktarget:FindFirstChild("HumanoidRootPart")
					local hrp3 = nil
					local char = self.player.Character
					if char then
						hrp3 = char:FindFirstChild("HumanoidRootPart")
					end
					if hrp and hrp2 and self.attacktarget ~= nil then
						local hum = self.attacktarget:FindFirstChild("Humanoid")
						if hum then
							local dist = 0
							if hrp3 then
								dist = math.abs((hrp2.Position - hrp3.Position).Magnitude)
							end
							if hum.Health <= 0 or dist >= 200 then
								self.retreat(true)
							end
						end
						local v = Vector3.new(1, 0, 1)
						local attackpos = self.getattackpos()
						if attackpos then
							self.closetoattack = math.abs(((hrp2.CFrame * attackpos * v) - hrp.Position * v).magnitude) <= 1
						else
							self.closetoattack = false
						end

						if p == Player and self.attacktarget ~= nil then
							local clientsided = self.attacktarget:FindFirstChild("ClientSided")
							if clientsided then
								clientsided = clientsided.Value
							end
							if self.closetoattack and not clientsided then
								local mob = GetMobFromModel(self.attacktarget)
								if mob then
									local model0 = mob["model0"]
									if model0 then
										startattack("attacking", self.num, model0)
									end
								end

							else
								startattack("attacking", self.num, nil)
							end
						end
					end
				else
					if p == Player then
						startattack("attacking", self.num, nil)
					end
					self.closetoattack = false
				end
			end
		end
		lasthrpcf = hrpcf
	end

I can’t dissect it completely because it’s a lot of code to digest, but I can already tell there are a ton of if-then statements! If-then statements can be taxing, especially if there are a ton of them nested within each other.

You might need to find a way to run code without depending on whether certain instances contain something or not. That’s just my suggestion!

You’re creating a new Vector3 value every time these lines are run. Consider creating them only once, and store and reuse them.

It’s pointless to create a Vector3 value only to get a magnitude of it. Operations like this require squareroots which are very expensive. If you think outside of the box, you can exclude squareroots and the Vector3 construction entirely:

if distance.X*distance.X + distance.Z*distance.Z >= 120*120 or distance.Y >= 100 then
1 Like