Any optimalization tips? (Managed about 1500 NPCs mostly without lag.)

This is more suited to Code Review than Scripting Support, although your code seems to be working fine - 1500 NPCs without lag is generally a sign of decent scripting; I’m not certain that there are any non-trivial improvements to be made here.

2 Likes

How many FPS is your Computer maintaining with 1000 NPCs?

You are using Roblox R6 Humanoid, Disabling some HumanoidStates and Anchoring the Rootpart when it’s not moving right?

I did the same but I was using R15 and didn’t Anchor the RootPart, my Computer maintained 60 FPS with 200 NPCs Moving and Animated at the same time.

5 Likes

Even at 3000 NPCs I still have 60 FPS most of the time.

The root is anchored when the NPC isn’t moving indeed and visual effects such as animation and appearance is clientside.

I use Roblox R6 humanoids, a lot of the states are disabled except the ones I truly need.

Though I would like to know if there are more ways top optimize to even get the limit to 10000 NPCs possibly.

I have no idea, I’m still trying to figure out how you manage to maintain 60 FPS with 3000 NPCs with Roblox Humanoid while most of the DevForum members would recommend to not use Roblox Humanoid and Rendering Characters on the Client.

So let me get this right;

You are using Only Roblox Humanoid with R6 rigs with most States disabled and RootPart Anchored and you can maintain 3000 NPCs at 60 FPS with no other special gimmick?

My hypothesis is that with 3000 NPCs you’ll have a total of at least 21000 (3000x7) parts

Roblox struggles while handling 500 moving sphere parts at once so moving all of those NPCs at once would be too much for the Engine (in extreme cases)

So if you have a Max cap of 150 moving NPCs at once that’s 1050 (150x7) parts max at any given moment

Since you are using a Humanoid few parts are forced to be CanCollide = true, although most of the NPCs aren’t moving thus Anchored.

So if you want to have 10000 NPCs which is 70000 (10000x7) parts, you should figure out if Roblox can handle at least 70000 parts in a game in a small space



If you don’t mind me asking what is your computer’s spec?

My Laptop Specs

Alienware 17 R5

OS: Windows 10 Pro


GPUs:

  • NVIDIA GeForce GTX 1080
  • Intel® UHD Graphics 630

I believe that Computer’s specs plays a role but I would say that Roblox Studio has it’s limits and inefficiencies so theoretically you could have a Super Computer but Roblox Studio might not be able to perform above it’s limits.

The zombies are handled on the client.
On the server I have 2 parts with a humanoid welded together (Torso and Head, nothing more), the client renders the arms, legs, etc and does the animations.
the humanoid has ALL states disabled except Dead and Running(NoPhysics).
And zombies that are not moving or active are anchored, I check their velocity and then anchor and set them inactive if they aren’t doing anything and unachored when actively doing something. That’s how I did it.
3000 NPCs worked even.

Edit: Oh oops hadn’t read.
I play on a pretty decent gaming laptop.
Has about 16 GB RAM, Intel core i7 (Quad) and a Nvidea GTX 1050.

Back to humanoids.
Humanoids really aren’t that bad as some may think.
What really causes most lag is physics and unused states such as climbing (which does a lot of raycasts just to see if it can climb a ladder).
I literally only use states I actually need, I even disable the jumping state if not needed and the ragdoll state.
Only Dead and Running are enabled.

1 Like

I have used almost the same method

I get around 35 FPS with 13 HumanoidStates Disabled and 27 FPS without any HumanoidStates Disabled for 250 NPCs moving around without Animations played while also using CollisionGroups to disable collisions between all of the NPCs, however some NPCs will Teleport if I SetNetworkOwner to nil (Server).

Although from doing some testing at 200 NPCs Disabling HumanoidStates and Collision doesn’t make any difference but does when going beyond 200+ NPCs

These are full Server-Sided NPCs nothing is done on the Client.



I have made a system without using a Humanoid nor Parts on the Server-Side and maintained 40 FPS with 400 NPCs moving and animated at once in a 512, Y, 512 space, goes back to 60 FPS when they stop moving

That honestly is strange.
Im not entirely sure why I can run 1500 NPCs and you only 250.
it’s a experiment I did and results turned out to be better than I actually expected.

Maybe it’s so optimized because I literally use 1 single script to run 1500 NPCs?

I have a table containing all NPC.
When a NPC spawns I do

npcs[npc].mainfunction = function()
--I do my stuff here
end

--Then I do this.
spawn(npcs[npc].mainfunction)

That way I could run 1500 NPCs with 1 single script.
Take a good look at the code I posted, that’s literally the entire AI.

Just quickly looking through your code, you seem to be creating new threads for no reason at all.

Both of your delays are unneeded as they’re at the end of another thread anyways, so it wouldn’t block any code from executing. 2/3 spawns also do this. Any connection will run on another thread, unless you actually have multiple things that need to run you don’t need to create new threads in this case.

Not sure how much it would impact performance.

I guess it also kind of depends on what you do in those threads really.

I’m also using only one Script to control all of the NPCs, although they are Server-Sided.

Don’t forget that they are R15 Rigs so that’s twice the amount of Parts of a R6 Rig

I took at look at your Script several times, you are doing quite a few things differently than the place I linked but I can see that the major performance gain is from anchoring RootParts.

While using one script can be performant, I can see that even though you are using 1 script to control all of the NPCs they have their own Threads.

So again, if you want to run 10000 NPCs we’ll have to answer the question of whether or if Roblox can handle 70000 anchored parts in any given space.



How big is that space shown in the OP?

I’m going to assume that it’s bigger than 2048, Y, 2048

When talking about ur pc specs, you should really include clock speeds for Processor and GFX Card. He has a 2.9GHz processor, which is most likely why his pc struggles. I personally won’t buy anything with less than 4GHz

Sorry forgot to inculde that.
Here is a screenshot of my processor.

https://gyazo.com/77ea749ff9c2adad885b99ad88a1d2e8

I remember watching crazyman32 do a similar approach to this before for his game but rendering only visible NPCs. I think he managed to get over 1500 NPCs at 60 FPS, but I’m not too sure on the NPC count. If I find the video I’ll link it.

So as AMD said, you could render only visible NPCs, as well as distant ones (basically any that is shown on screen). Don’t really see a use case for rendering non visible ones.

1 Like

If it isn’t processing power, what else could limit NPCs?
I personally think it’s mostly physics and such that limit NPCs.
But don’t really know what to optimize futher.
I actually want more NPCs to move at the same time.
I kind of limited the amount of NPC that are allowed to move at the same time to prevent all 1500 of them to move at the same time.

I don’t think it’s possible at this time to achieve that but until Roblox Upgrades it’s Software and Server-Hardware to be more performant and/or powerful you are stuck with it’s current limits.

We don’t have the technology yet basically, or more accurately Roblox.



Oh, alright.
3000 NPCs was the highest I’ve tested but noticed that 1500 is more stable.
The server can handle 3000 NPCs, however for patato PCs 1500 NPCs already is pretty heavy.
NPCs are rendered clientside mostly, the server only does hitboxes, targetting, movement, thinking in general, etc.


I made AI for 1500 NPCs and there is no lag at all (they are cubes)
so i think having alot of NPCs will only lag your game because of the amount of parts not because they are humanoid or AI

The two scripts that control them only have 2-3% script activity altogether.

5 Likes

I don’t think it’s the parts mainly.
Mainly physics and hit boxes/touch events that make it laggy.
I was wondering…
Is there a way to turn off the touched event for parts so NPCs touching each other won’t trigger it?
But players and ray-casts hitting the parts should still work.
I could do a lot with that knowledge.
I’ve heard of collision service but never used it before in all honestly.
Even my current 1K AI game doesn’t use collision service.
The NPCs quite literally just use a few parts and a lot is rendered client side. Touched events are still triggered when they hit each other.

3 Likes

Have you tried shifting network ownership of npcs close to players?
It could take some of the physics load off of the server, since the players would be handling physics instead of the server.

I haven’t thought about that actually.
But wouldn’t this result in really choppy movement if the NPCs target suddenly switched on a laggy server?
But I’ll keep this in mind, thank you, perhaps this could help a lot in games
that need to handle a lot of zombies at once.

If I can make a full functional, hyper-optimized zombie AI
and have 2000 zombies walk around I could perhaps make a game
like Deadrising in Roblox.

I’d be cool to have players literally bulldoze through tons of zombies with vehicles or weapons, I’m pretty excited about that idea.

4 Likes