Hello developers, I am currently working on a tower defense game and I was wondering how I can reduce the Recv usage when handling hundreds if not thousands of enemies? I was considering trying out client replication but my knowledge only knows so much lol. They don’t use humanoids so thats already a plus point.
My code:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local BezierPath = require(game.ReplicatedStorage.Modules.BezierPath)
local Enemies = ReplicatedStorage.Common.Enemies
local map = workspace.Map:FindFirstChild("TestMap")
local EnemyFolder = workspace.InGameAssets.Enemies
local nodesFolder = map:WaitForChild("Nodes")
local nodes = {}
for _, node in ipairs(nodesFolder:GetChildren()) do
if node:IsA("BasePart") then
table.insert(nodes, node)
end
end
table.sort(nodes, function(a, b)
return tonumber(a.Name) < tonumber(b.Name)
end)
local waypoints = {}
for _, node in ipairs(nodes) do
table.insert(waypoints, node.Position)
end
local path = BezierPath.new(waypoints, 100)
path:VisualizePath()
local function moveEnemy(enemy)
local root = enemy:WaitForChild("HumanoidRootPart")
local enemyStats = require(ReplicatedStorage.Common.Enemies.Stats[enemy.Name])
root.Anchored = true
local baseSpeed = enemyStats.BaseSpeed or 10
local pathLength = path:GetPathLength()
local duration = pathLength / baseSpeed
local sideOffset = Random.new():NextNumber(-0.8, 0.8)
local _, size = enemy:GetBoundingBox()
local heightOffset = size.Y / 3
local startTime = tick()
local connection
local UPDATE_INTERVAL = 1/30
local lastUpdate = 0
connection = RunService.Heartbeat:Connect(function(dt)
lastUpdate += dt
if lastUpdate < UPDATE_INTERVAL then return end
lastUpdate = 0
local elapsed = tick() - startTime
local progress = math.clamp(elapsed / duration, 0, 1)
local cframe = path:CalculateUniformCFrame(progress)
local offsetCFrame = cframe * CFrame.new(sideOffset, heightOffset, 0)
root.CFrame = offsetCFrame
if progress >= 1 then
connection:Disconnect()
enemy:Destroy()
ReplicatedStorage.Common.Remotes.EnemyDestroyed:FireAllClients()
end
end)
end
local function spawnEnemy(amount, delay)
for i = 1, amount do
local enemy = Enemies.Models.Undead:Clone()
enemy.Parent = EnemyFolder
enemy.HumanoidRootPart:SetNetworkOwner(nil)
ReplicatedStorage.Common.Remotes.EnemySpawned:FireAllClients()
task.spawn(function()
moveEnemy(enemy)
end)
task.wait(delay)
end
end
spawnEnemy(1000, 0.1)
This is the BezierPath module I used.
