How to Optimize Humanoids

So the idea that characters which utilize humanoids are “laggy” has gained a lot of traction lately. It’s time to shed some light on this rumor because a lot of people are asking about it and most are confused.

Keep in mind I’m not an engineer, I just have free time to write this and I work with humanoids a lot. Feel free to share your findings in this thread or correct me if I’m wrong somewhere.

I. Are You Sure It’s the Humanoid Object Harming Performance?

Expand

I see tons of developers fall into a trap where they think the humanoid object is somehow causing their NPCs to perform badly. Such issues are more than likely caused by their own coding and/or setup.

Let’s be real. In most scenarios, it’s really easy to create resource-intensive NPCs, even without using the humanoid object. Simply making an NPC chase players suddenly opens a huge can of worms in regards to performance. When you have 50 zombies running around, each trying to chase one of your 30 players, even barebone optimization is important.

Before you blame humanoids for your game’s lackluster performance, analyze your code. Ask the kind people in Scripting Support if it can be improved. More than likely, it can be improved, and you will see significant performance boosts afterwards.

II. Why Are Humanoids Sometimes Bad for Performance?

Expand

If you’re certain your own code isn’t causing the performance issues you’re concerned about, you will need to look into optimizing humanoids. But before you can do that, you need to know what you’re fixing and why!

The biggest reason humanoids take up so many resources is basically because by default they make a lot of calculations (duh). It turns out, making an object with as many features as an NPC can be quite intensive, and getting that object to work expectedly for a developer means many of them need to be on by default. I was going to get more specific on the kind of calculations being done, but upon further research, it’s redundant (plus I couldn’t find anything informative enough and/or cool enough to include).

Also, the Humanoid Object supposedly uses a really old legacy code base, and by nature that is probably slow. No doubt this has been improved— otherwise we wouldn’t have massive 100 player games on the front page. However, many developers seem to insist that this alone is a good enough reason to avoid humanoids.

III. How Can I Optimize Humanoids?

Expand

Finally, the meat of this thread! A lot of the actual optimization you can do will depend on the game the humanoids are in. It’s hard to give specific advice without knowing how the game works, but there are plenty of things to look out for if you want your humanoids to be less demanding.

A) Disable Any Unneeded States
You probably don’t need to check if your NPC can climb something or if it’s in water all the time. Disable as many humanoid states as you can to help reduce its performance hit. If you are going to need some states, enable and disable them on the fly as they become necessary.

B) Handle Visuals on the Client
This is a suggestion that gets thrown around a lot, but it’s true. The server should handle all the NPC logic. You shouldn’t waste resources animating or handling other visuals of your humanoid on the server. It’ll get expensive really fast!

To take this idea a step further, some developers even avoid using Humanoid:MoveTo() and instead use TweenService to move their NPCs. The idea here is that the visualization of an NPC’s movement can be done on the client, removing significant overhead from the server. Plus, modules like @SteadyOn’s TweenService V2 make this process really easy.

Unfortunately, complete client-side visuals can be tricky to implement in some games (I speak from experience). It’s definitely worth the effort to try implementing though.

C) Optimize Your Humanoids’ Clothing
This tip is probably the least obvious on this thread, but many developers overlook it.

The fact is, sometimes clothing can take up a lot of memory. Roblox creates a single clothing texture for the entire humanoid based off what it’s wearing. More items and more textures (especially those with bigger file sizes) means more memory.

Make your clothing textures’ file sizes as small as possible, avoid using tons of items in one humanoid, and always try to reuse as many items as possible.

D) Make Your NPCs As Dumb As Possible
Upon my research, I stumbled upon this gem from @CompilerError:

This is really the overall mindset you should have when you implement any AI into your game. The more advanced it is, the more resources you’ll need. And it sums up the whole thread.

Allow me to share my own quote, which I often say when doing my schoolwork: Cut as many corners as possible. Follow that logic when you decide which humanoid features to keep and which to can.

IV. Do I Need to Use A Custom Humanoid?

Expand

No.

Yes, you read that right.

NO.

Unless you won’t be needing the vast majority of features already built into the default humanoid object, you will probably be better off keeping them around. They’re just far too useful. There’s no point in trying to reinvent the wheel in the name of “performance” when it’s already just a wheel, and pretty much as refined as possible.

Of course there are scenarios where a custom humanoid object makes sense, but if you’re only making one because you want your game to be faster, you’re probably doing something wrong.

Conclusion
This took two hours to write and my eyes are burning out of my head; plus, I’m not the most knowledgeable guy out there. I promise there’s more goodies when it comes to optimizing humanoids that aren’t described here.

I hope we can all work together to share further optimization practices for humanoids and clear some common misconceptions on this thread. Please tell me if I made any mistakes too!

Happy optimizing!

187 Likes

This exactly, thanks for writing! Building a custom-humanoid from scratch not only eliminates useful features (properties, events, inbuilt functions, even clothing), but can consume a significant amount of time to develop.

Custom-humanoids can be worth-while and evidently do provide performance benefits, but for the general population of developers optimising the existing humanoid is considerably the best approach.

Tldr and additional tricks

  • Disable all HumanoidStates. These consume memory through constant raycasting.
  • Anchor the HRP and use TweenService to move the character. This reduces the burden on the physics engine. Consider using SteadyOn’s TweenService V2 to do this.
  • Disable collisions. Add all BasePart descendants to a CollisionGroup and set collision to false. No collisions means less physics calculations and greater performance.
  • Set the RenderFidelity to Automatic and CollisionFidelity to Box of all MeshParts within the character. This reduces the polygon count of the character, therefore reduced physics burden.
  • Optimise your clothing. Clothing textures can take up a lot of memory, so make your file sizes as small as possible or remove the clothes entirely.
  • Display and handle the NPCs on the client. This eliminates ‘judders’ caused by latency and reduces the burden of the server.
  • Dumb down your NPCs. Recursive, intensive functions, multiplied by hundreds of NPCs is going to slightly kill your computer. Implement actions as efficiently as you can. ComplierError explains this in greater detail here.
  • Filter out NPCs. If the player is not viewing and interacting with the character, simply parent it out of workspace.

Obviously you may not be able to use all techniques for your situation, so select and use accordingly.

83 Likes

Thanks for the great advice! Commenting to save for later.

2 Likes

Would using Clothes Humanoids result in better performance? using Surface Guis instead.

I am not entirely sure how it’s done but I’ve seen it often around.


Your guide seems to be about NPCs with Humanoids but how does it address the problem of having 100+ Players in a single server?

1 Like

In my experience with my NPCs, which are certainly not dumb by any means, the bulk of poor performance seems to come from the logic involved in calculating all the humanoid physics when there’s 100+ NPCs, and then replicating all of the logic to the client. Custom humanoids would probably alleviate this to a degree, but it’s not worth the development time.

The reality is that humanoids are severely limiting, and modifying them to suit individual use cases, especially for NPCs, is ridiculously tedious. I could go on forever about all the gripes I have with humanoids, and all the ways in which they’ve wasted my time.

For reference, the script activity of my NPC handler is about 3%, and the micro profiler seems to say the most intensive thing my script is doing is raycasting, and yet the network absolutely dies when there’s a large number of NPCs.

2 Likes

Assuming you’re using R15 and putting 6 SurfaceGuis on each body part (excluding the head), that’s 84 SurfaceGuis being rendered. That’s probably not the best for performance.

I don’t know if I explained it well enough in the thread, but Roblox automatically bakes all the textures in your humanoid into one. This means that pretty much any alternative clothing method is probably going to be more expensive than the one built in.

I wouldn’t avoid shirts and pants for performance reasons. Instead, I’d optimize the shirts and pants I already have so they can be baked efficiently.

I’m sorry about the bias. I work with NPCs more than players.

Nevertheless, the same practices apply. Make sure your programming is efficient and scalable, disable unneeded features, and have the client handle as many visuals as possible. 100 player servers are definitely maintainable, even when using the default humanoid object.

@Shardwielder
I completely agree that humanoids are way too limited and way too taxing. However, just from what I read, you could probably optimize your code. Definitely look into that raycasting.

3 Likes

I’m currently making a RPG and humanoids will be in abundance, so I will definitely be bookmarking this

this is also what I came up with on my own thinking of ideas before I found this thread

I’m implementing custom zones (zoning characters) and despawning the enemies if no character is in said zone and respawning when a character enters the zone

Do you disable HumanoidStates on client, server or both?

Just for consistency and to obtain expected results, I would do both. At least one state I know of needs to be disabled on the client and server to work properly (the death state, unless this changed).

3 Likes

Thank you for this advice, it is appreciated.

This advice does make me feel like the best npc would be a simple block part that vaguely looks like a character. Especially the ‘make them dumb’ advice. Can Roblox seriously do nothing?

Well this was many years ago and there are ways to make NPCs without using humanoids that are way more performant.

Your statement about a simple block being the most performant is true on every platform, since it has barely any geometry.

haha true.

thanks for the link

streaming enabled and OOP approach also seems to make more complex npcs feasible i found in other topics, which boosted my spirits

No problem, if you have other questions about optimization feel free to make a topic or even message me. I try to stay up to date with things regarding performance.

Best of luck with your game.

1 Like

thanks. i actually might take you up on that