Hi, thanks for reading this topic, this one will be a long one. Let’s start, I’m making a game that has ALOT of coroutines. ALOT. and for every player, say there are 6 coroutines, but that’s not all. on average, there are about 3 players in my game, since it’s pretty small and is in beta, but there is no actual low fps, my system for the game is using loops, which wait a said amount of time based on a predefined number, and then increment a certain value based on that same number. Almost like manual tweening. all of those loops i have though, are in a coroutine. One of them looks like this:
There’s another one of these, which looks like this:
-- xp handling
task.spawn(function()
while wait(xpcooldown) do
if #xps:GetChildren() < xpcount then
local newxp = createmodule.createXP(heightfactor, false)
end
end
end)
Here’s the script that it’s running:
function module.createXP(heightfactor, isFeed)
local xp = game.ServerStorage.XP.XP:Clone()
local value
if isFeed then
local feedtag = Instance.new("BoolValue", xp)
feedtag.Name = "IsFeed"
feedtag.Value = true
value = 5
else
value = xpminsize + (math.random(spawnsmoothness * (xpmaxsize - xpminsize)) / spawnsmoothness)
end
xp.Position = Vector3.new(math.random(-border*spawnsmoothness, border*spawnsmoothness)/spawnsmoothness, 0, math.random(-border*spawnsmoothness, border*spawnsmoothness)/spawnsmoothness)
xp.Color = Color3.new(math.random(0, 255), math.random(0, 255), math.random(0, 255))
xp.Parent = game.Workspace.XP
xp.Size = Vector3.new(value * heightfactor, math.sqrt(value/6.25), math.sqrt(value/6.25))
xp.XP.Value = value
return xp
end
Here’s the thing, will this create lag?
There’s also another coroutine running, it looks like this:
-- virus handling
task.spawn(function()
while wait(1) do
if #viruses:GetChildren() < viruscount then
local virus = createmodule.createVirus(heightfactor)
wait(viruscooldown - 1)
end
end
end)
And the module function it’s running
function module.createVirus(heightfactor)
local virus = game.ServerStorage.Virus.Virus:Clone()
virus.Parent = game.Workspace.Viruses
virus.CFrame = CFrame.new(Vector3.new(math.random(-border*spawnsmoothness, border*spawnsmoothness)/spawnsmoothness, 0, math.random(-border*spawnsmoothness, border*spawnsmoothness)/spawnsmoothness)) * CFrame.Angles(0, 0, math.rad(-90))
return virus
end
Also, in THE EXACT same script, i’m doing this:
event.OnServerEvent:Connect(function(plr, circle, mousepos, campos, smoothness, _split, _feed)
if not circle then return end
if not circle:FindFirstChild("IsAlive") then return end
local speedradius = 1
local stopradius = .1
local function getRayPlaneIntercept(rayPoint, planePoint, rayDir, planeNormal)
return rayPoint + (rayDir * -(rayPoint - planePoint):Dot(planeNormal)/rayDir:Dot(planeNormal))
end
local function handleOverlap(unit1, unit2)
if (unit1.Position - unit2.Position).Magnitude + overlapnum < unit1.Size.Z/2 + unit2.Size.Z/2 then
local bgr = (unit1.Size.Z >= unit2.Size.Z) and unit1 or unit2
local smlr = (unit1.Size.Z >= unit2.Size.Z) and unit2 or unit1
local overlap = ((unit1.Position - unit2.Position).Magnitude) - ((unit1.Size.Z/2) + (unit2.Size.Z/2))
local unitvector = (smlr.Position - bgr.Position).Unit
local mid_pos = (overlap > overlapmaxnum) and bgr.Position:Lerp(smlr.Position, .5) or bgr.Position + (unitvector * (bgr.Size.Z/2))
local bgrpos = mid_pos - ((bgr.Size.Z/2 * unitvector)) -- - (unitvector * (overlapnum * spawnoverlapnum))
local smlrpos = mid_pos + ((smlr.Size.Z/2 * unitvector)) -- + (unitvector * (overlapnum * spawnoverlapnum))
bgrpos = Vector3.new(math.clamp(bgrpos.X, -border, border), 0, math.clamp(bgrpos.Z, -border, border))
smlrpos = Vector3.new(math.clamp(smlrpos.X, -border, border), 0, math.clamp(smlrpos.Z, -border, border))
bgr.Position = bgrpos
smlr.Position = smlrpos
end
end
local intPosition = getRayPlaneIntercept(campos, Vector3.new(0, height, 0), (mousepos - campos).Unit, Vector3.new(0, 1, 0))
-- move each unit with vel
for _, v in pairs(circle.Units:GetChildren()) do
local diff = (intPosition - v.Position)
local distance = diff.Magnitude
local clampedunitvector = diff.Unit
local clampeddistance = math.min(distance / (v.Size.Z/2), speedradius)
if distance / (v.Size.Z/2) <= stopradius then clampeddistance = 0 end
local endpos = (clampedunitvector + v._Velocity.Value) * clampeddistance
local tr_endpos = (endpos * v.Speed.Value) / smoothness
local x_pol = (v.Position.x >= 0) and 1 or -1
local z_pol = (v.Position.Z >= 0) and 1 or -1
local x = ((v.Position.X + tr_endpos.X) > border or (v.Position.X + tr_endpos.X) < -border) and ((border * x_pol) - v.Position.X) or tr_endpos.X
local z = ((v.Position.Z + tr_endpos.Z) > border or (v.Position.Z + tr_endpos.Z) < -border) and ((border * z_pol) - v.Position.Z) or tr_endpos.Z
local clampedtr_endpos = Vector3.new(x, 0, z) -- clamp y also
v.Position += clampedtr_endpos
-- split and feed
if _split then
if v.XP.Value >= minsplitxp and #circle.Units:GetChildren() < maxunitcount then
split(circle, v, clampedunitvector, false)
end
end
if _feed then
if v.XP.Value >= minfeedxp then
feed(v, clampedunitvector)
v.XP.Value -= feedxp
end
end
v._Velocity.Value -= (v._Velocity.Value * slowdownfactor) / smoothness
end
-- average out position and set root
local unitcount = #circle.Units:GetChildren()
local sumposition = Vector3.new()
for _, v in pairs(circle.Units:GetChildren()) do
sumposition += v.Position
end
local circlepos = sumposition/unitcount
circle.RootPosition.Value = circlepos
-- overlap
local all_table = {}
for _, v in pairs(circle.Units:GetChildren()) do
table.insert(all_table, v)
end
for _, v in pairs(circle.Units:GetChildren()) do
table.remove(all_table, table.find(all_table, v))
for _, w in pairs(all_table) do
if v:FindFirstChild("CanMerge") and w:FindFirstChild("CanMerge") then
if (not v.CanMerge.Value) or (not w.CanMerge.Value) then
handleOverlap(w, v)
else
if isColliding(w, v) or isColliding(v, w) then
if w.Size.Z >= v.Size.Z then
w.XP.Value += v.XP.Value
v:Destroy()
else
v.XP.Value += w.XP.Value
w:Destroy()
end
end
end
end
end
end
end)
And that’s running SIXTY TIMES PER SECOND for EVERY SINGLE PLAYER IN THE GAME. But there’s no lag. Now, I’m pretty sure there IS lag, but it’s not local, it’s serversided. I recorded the script activity for this script, and it’s 13%. That doesn’t sound good.
Maybe the solution is to separate them into different scripts?
Or maybe just not use coroutines?
Maybe what i’m doing in the first place is just extremely taxxing in general, and there’s no way around it?
Someone, please help me, I’m having trouble with this.