If you’re adamant to sticking with humanoids, you can try disabling HumanoidStates that you wouldn’t necessarily need.
You can also attempt to hide your NPCs whenever they’re too far, keep in mind that occlusion culling is a thing.
..nevermind, occlusion culling currently doesn’t work for avatars (which I’m assuming means humanoids)
However, there is another method that is commonly used for real-time strategy (RTS) games that involve a buuunch of units – it’s where you ditch serversided humanoids, and instead opt to have the server…
figure out the positions of each NPC (and their pathfinding)
– you can look into modules like FastFlow which use the concept of “flowfields” to avoid pathfinding for each individual NPCs
send this position data to clients
– be smart about how often you send data, “too frequent” can be really laggy – especially with a ton of NPCs. You can look into modules like BridgeNet2 or ByteNet which can really lessen your bandwidth
and the client..
render the NPCs and handle all the magic (animations, sounds, etc.)
– since you’d be loading animations on the client, you can also look into workspace.ClientAnimatorThrottling which throttles animations depending on their distance
There are a ton of genuinely helpful resources for this method, definitely look into these: