So I’m making this type of tower defense and was trying to code stuff, until i noticed that my recv is going up. Within a few entities gets me up to 100 KB/s of recv. The script that moves the entities use lerp then CFrame replication, and as in server side is a basepart then the client side is the model of the character. I’m dumb enough to fix it, but i found one in the script that moves the entities, and the remote that plays the animation from server to local side.
Tried to test on 20 enemies, and GOD my game lagged, and got 150-200 KB/s of recv.
So here’s the script. Messy stuff i have to fix @_@
NPCSYSTEM
local System = {}
System.CurrentFunctionRunnin = {}
System.ClientFunctionRunnin = {}
local RS = game:GetService('RunService')
local Util = require(game.ReplicatedStorage.Utilities)
local Store = game.ReplicatedStorage.StoreRunninSystem
function System.MoveTo(obj,pos) -- Moves the part, just like humanoid MoveTo
pos = Vector3.new(pos.X,pos.Y,pos.Z)
for i,v in pairs(System.CurrentFunctionRunnin) do
if i:find(obj.Name,1,true) then
System.CurrentFunctionRunnin[i] = nil
end
end
local nam = obj.Name..math.random(-9999,9999)
System.CurrentFunctionRunnin[nam] = true
local Values = require(obj:WaitForChild('Stats'))
local durTimer = 0
local startPos = obj.Position
local duration = (pos - startPos).Magnitude / Values.walkspeed
local dir = (pos - startPos).Unit
local curDir = obj.CFrame.LookVector
local durMult = 1 / duration
local hb
hb = RS.Heartbeat:Connect(function(dt)
if (not System.CurrentFunctionRunnin[nam] or System.CurrentFunctionRunnin[nam] == nil) or startPos == pos then
hb:Disconnect()
return
end
durTimer += dt
if durTimer >= duration then
durTimer = duration
System.CurrentFunctionRunnin[nam] = nil
hb:Disconnect()
end
local ratio = durTimer * durMult
local pos = startPos:Lerp(pos,ratio)
obj.CFrame = CFrame.new(pos,pos + curDir:Lerp(dir,math.min(durTimer * 10,1)))
end)
end
function System.ClientModelConnect(obj,part,offsetpos) -- Attaches client model to a part
local function Show(inst,bool)
for i,v in ipairs(inst:GetChildren()) do
if (v:IsA('Part') or v:IsA('MeshPart')) and v.Name ~= 'HumanoidRootPart' then
v.Transparency = bool and 0 or 1
end
end
end
for i,v in pairs(System.ClientFunctionRunnin) do
if i:find(obj.Name,1,true) then
System.ClientFunctionRunnin[i] = nil
end
end
local nam = obj.Name..math.random(-99999,999999)
System.ClientFunctionRunnin[nam] = true
local objpos = obj.PrimaryPart.Position + offsetpos
local x, y, z = obj.PrimaryPart.CFrame:ToEulerAnglesYXZ()
local camera = workspace.CurrentCamera
local hb
hb = RS.RenderStepped:Connect(function(dt)
objpos = objpos:Lerp(part.Position + offsetpos,dt * 10)
local x2, y2, z2 = part.CFrame:ToEulerAnglesYXZ()
x,y,z = Util.Lerp(x,x2,dt * 10),Util.Lerp(y,y2,dt * 10),Util.Lerp(z,z2,dt * 10)
obj:SetPrimaryPartCFrame(CFrame.new(objpos) * CFrame.Angles(x, y, z))
local vector, onScreen = camera:WorldToScreenPoint(obj.PrimaryPart.Position)
if onScreen then Show(obj,true) else Show(obj,false) end
if not System.ClientFunctionRunnin[nam] then
hb:Disconnect()
end
end)
end
function System.StopClientModel(obj)
for i,v in pairs(System.ClientFunctionRunnin) do
if i:find(obj,1,true) then
System.ClientFunctionRunnin[i] = nil
end
end
end
function System.IsMoving(obj)
for i,v in pairs(System.CurrentFunctionRunnin) do
if i:find(obj.Name,1,true) and v then
return true
end
end
return false
end
function System.StopMoving(obj)
for i,v in pairs(System.CurrentFunctionRunnin) do
if i:find(obj.Name,1,true) then
System.CurrentFunctionRunnin[i] = nil
end
end
end
return System
I also think the playing animation in enemy/unit entity script can cause that too. The remote event fires from serverside to client side, and worse it’s executed repeatedly. Honestly I’m too dumb to implement an optimization of it.
local animation = {
Idle = {'Idle',false,0.5,0.2},
Run = {'Run',false,0.5,0.2},
Attack = {'Attack',false,0.15,0.2},
SpecAttack = {'SpecAttack',false,0.15,0.2}
} -- name, isplaying, playfade, stopfade
-- ignore the isplaying, i tried to optimize using that bool and couldn't make it so when the anim ends it set to false. (due to remote optimization)
local animstring = 'Run'
function updateAnim(string)
local ent = isEnemy and workspace.Enemy or workspace.Unit
for i,v in pairs(animation) do
if i ~= string then
ClientModelEvent:FireAllClients('stopAnim',stats.ClientModelName,{Parent = ent,animName = animation[i][1],fadetime = animation[string][4]})
end
end
ClientModelEvent:FireAllClients('playAnim',stats.ClientModelName,{Parent = ent,animName = animation[string][1],fadetime = animation[string][3],force = false})
end
There are some Roblox built in functions that are deprecated (i think). So please mention it!