How do I optimize td enemies?

Hello developers,
I am getting a lot of lag from a tds game I am helping develop.


How do I fix this?
Code:

local waypoint = game.Workspace.POINTS
local rrr = require(game.ReplicatedStorage._requirements)--just a module
local r = game.ReplicatedStorage.enemies.ExplosiveCrawler
local c = 1
local s = r:FindFirstChild("ADDPOS")
if s then s = s.Value end
r:SetPrimaryPartCFrame(workspace.Map.ENEMIESSPAWN.CFrame)
local oldhealth = r.Humanoid.Health
for i,v in pairs(r:GetDescendants()) do
	if v:IsA("BasePart") then
		v.CanTouch = false
		v.CanCollide = false
		v.CanQuery = false
		--v.Transparency = 1
	end
end
r.Parent =  workspace.WAVE
local hum = r.Humanoid
hum.Changed:Connect(function()
	if oldhealth > hum.Health then
		for i,e in pairs(game.Players:GetPlayers()) do
			pcall(function()
				e.leaderstats:FindFirstChildOfClass("IntValue").Value += 2
			end)
		end
		oldhealth = hum.Health
	end
end)
local oldr = r
-- DO NOT REMOVE GETTOUCHINGPARTS() AS THIS WILL BREAK THE FUNCTION CHECK
local function GetTouchingParts(part)
	local connection = part.Touched:Connect(function() end)
	local results = part:GetTouchingParts()
	connection:Disconnect()
	return results
end
local function check(model)
	local checkpart1 = GetTouchingParts(model["Left Leg"])
	for i,v in pairs(checkpart1) do
		if v.Name == "BasePartIg" then
			return true
		end
	end
	local checkpart2 = GetTouchingParts(model["HumanoidRootPart"])
	for i,v in pairs(checkpart2) do
		if v.Name == "BasePartIg" then
			return true
		end
	end
end
local function splitformathround(e)
	local two = string.split(tostring(e),".")[2]
	if not two then return e end
	local a = string.sub(two,1,1)
	local b = string.sub(two,2,two)
	local done = tostring(a.."."..b)
	return tonumber(string.split(tostring(e),".")[1].."."..math.round(tonumber(done)))
end
r.HumanoidRootPart.Anchored = false
r.HumanoidRootPart:SetNetworkOwner(nil)
r.HumanoidRootPart.Anchored = true
if r:GetScale() > 0.5 then
	while check(r) do
		r.PrimaryPart.CFrame = CFrame.new(Vector3.new(r.PrimaryPart.Position.X
			,r.PrimaryPart.Position.Y + 0.1,r.PrimaryPart.Position.Z))
		task.wait()
	end
end
local new = false
task.spawn(function()
	repeat
		task.wait()
		local czas = ((waypoint:FindFirstChild(tostring(c)).Position - r.HumanoidRootPart.Position).Magnitude/2)/2 / r.Speed.Value
		local pos = waypoint:FindFirstChild(tostring(c)).Position
		local newpos = Vector3.new(pos.X,splitformathround(r.HumanoidRootPart.Position.Y),pos.Z)
		r.PrimaryPart.CFrame = CFrame.new(r.PrimaryPart.Position, newpos)
		--local CFRAME = CFrame.new(r.PrimaryPart.Position, newpos)
		local oren = r.HumanoidRootPart.Orientation
		oren = Vector3.new(0,oren.Y,oren.Z)
		r.HumanoidRootPart.Orientation = oren
		local test
		local cframe = (CFrame.new(CFrame.new(newpos).Position)
			* (r.HumanoidRootPart.CFrame.Rotation))
		local tween = rrr.TweenService:Create(r.HumanoidRootPart,{czas, Enum.EasingStyle.Linear, Enum.EasingDirection.In}, {
			CFrame = cframe
		})
		tween:Play()
		tween.Completed:Wait()
		c += 1
		if r:FindFirstChild("Humanoid") == nil then 
			break
		end
		local oren = r.HumanoidRootPart.Orientation
		oren = Vector3.new(0,oren.Y,oren.Z)
		r.HumanoidRootPart.Orientation = oren
	until c == #waypoint:GetChildren() + 1 or r.Humanoid.Health == 0  or r.Humanoid.Health <= 0
	if c == #waypoint:GetChildren() + 1 then
		game.ServerScriptService.Function:Invoke(r.Humanoid.Health)
		r:Destroy()
	end
end)

All help is appreciated!

2 Likes

I mean for starters, it seems like you’re spawning an enormous chunk of enemies. I’m not going to suggest that you should do this but if y’all wanted to, you could have beefier enemies (enemies with more health).

From this line right here, I can assume that this is a server script.

The server would use a bunch of resources compared to if the client were to do it. You should instead store positions for enemies on the server and then let the client do the calculations. Make sure you’re optimizing the data you’re sending so that you’ll be able have more enemies!

And so I’d like to introduce you to this post which does a better job at explaining what I’ve said (and more):

4 Likes

You could try to make a system, that holds every enemy on server like data-table, and replicates this data (like position of NPC or his health) to every player, and then player`s client draws every NPC like a model with animations, movement and etc.

2 Likes

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