How would I go about reducing lag for humanoids? For my NPCs, I disabled a lot of states, disabled collisions, and even had each NPC controlled by one script. Doing these things I have helped increase my NPC count without major lag from 40 to about 200. But is there any other ways to help reduce lag further? My main goal is to get around 400 NPCs without substantial lag.
Using async programming (coroutines) may be helpful, they are usually a very good solution to lag.
Other possible solutions could be to:
A) Reduce the frequency of operations. For example, zombies are pretty dumb and making them make a decision every heartbeat isn’t necessary.
B) Stagger calculations. Instead of calculating all NPC’s actions at the same time you could constantly calculate a smaller amount of them. Combining this with the previous solution may give you some better performance, since the previous solution would cause a large amount of load every X seconds (or however often you chose).
I haven’t tried these, but these should hopefully give you some form of start.
Could you explain B) with more detail please? I’m kind of confused.
For example, let’s say you chose to implement B) by doing something along the following:
while task.wait(1) do
-- Decision code
end
This would cause all 400 something NPC’s to calculate their actions at once. What you could do is spread it out over a longer time, for example dividing it into 100 segments and doing one segment every 4th loop.
local npcSegments = {
[1] = {
-- Lots of NPC's
},
[2] = {
-- Lots of NPC's
},
[3] = {
-- Lots of NPC's
},
[4] = {
-- Lots of NPC's
}
}
local currentGroup = nil
while task.wait(.25) do
currentGroup = next(npcSegments, currentGroup)
if currentGroup == nil then -- We are past the last one.
currentGroup = next(npcSegments) -- Get the first one
end
makeDecision(npcSegments[currentGroup]) -- Pass in a segment of NPC's
end
This would hopefully cause a little less lag, as a smaller portion of resources is used at a time. Instead of calculating all 400 actions at once you calculate 100 actions. Another solution could be to just do something like this:
local currentNpc = nil
while task.wait() do
currentGroup = next(npcs, currentGroup) -- npcs is a list of NPC's
if currentGroup == nil then
currentGroup = next(npcs)
end
makeDecision(npcs[currentNpc])
end
I believe the above should be good enough, since you give the server some breathing room between each NPC. These may not be the best implementation of the idea, but hopefully it gets the idea across.
Thanks, I’ll be sure to try that now.
I have done this and the NPC cap was bumped up by about 40, which is pretty good. Thanks.
Yes I’m researching and have done something similar to you my tips would be to consider making the parts of the npcs massless except the humanoidrootpart reducing the collission fidelity of R15 rigs to box, making sure the meshparts are not double sided when not neccessary. and turning off autojump enabled.