Is Parallel Luau necessary? (Need advice on optimization)

I see alot of games have smart advanced npcs with alot of logic and calculations behind their AI, and I’m wondering, how do their games not lag?

When I made a smart NPC, having 2 of them would already significantly slow down both of them.

So I’m wondering if Parallel Luau helps? Or what other methods do they use to have that sort of AI not lag the server.

help

I am not the best at explaining things but I can share some things I know;

For parallel luau to be effective; calculating stuff in bulk is something I would do. You should spread your NPCs across multiple Actors and make use of BulkMoveTo in sync.

To prevent network lag; make as little steps as possible on the server; let the client fill in all of the predictable movements and let the server fill in all the unpredictable movements to replicate to all the clients. If there is a start and a goal position; you can predict all steps in between. If something follows the same path all the time; it is entirely predictable.

More things to take into consideration are streaming and part count. Less parts in an NPC will overall improve performance.
Less streamed-in NPCs means that any changes in these NPCs won’t automatically replicate.

You can make a collisiongroup that doesn’t interact with itself for the NPCs so they go through eachother without much physics going on inbetween them.

If your NPC is constantly moving, you can make use of UnreliableRemoteRequests that don’t require a packet handshake, lost packets aren’t bad if the NPC constantly updates.

Update less frequently towards users that are further away or don’t update at all to users that shouldn’t be able to see the NPC.

Compress your data using methods such as the quite new buffer type.

Try to make your code run well on native luau, this may improve the performance more. Test by running both scripts with and without —!native tag to see which is performing better. Make sure to include types to make it effective.

All these methods can help making a game better performing with NPCs, but in practice you will need to plan out what you want your NPCs to do before starting to implement anything.

Wow, thanks for all the info, it is so useful.

However I’m left wondering a few things:

  • What’s that about tags and buffers? I’ve never seen that once in my time programming.

  • Isn’t constantly firing RemoteEvents a bad thing?

  • I thought ideally there should be one central script controlling all of the npcs, so how would I use multiple actors? Is having one script inside every NPC not really a bad thing?

  • You mentioned letting the client handle alot of it, could you dive deeper into what do you mean by that? How could a client control an npc supposed to be seen by everyone?

Constantly firing remoteevents:
An object that is constantly in motion on the server is replicating its data towards the clients no matter what. Instead of the uncontrolled replication of data by moving it on the server; you can move it on the client. You can control how much data is being sent using remote events and remove unnecessary details. You often don’t need much of the details that Roblox would usually send over to the client.
Roblox replicates the position and orientation using CFrames, but rather than sending a CFrame you might only need to send an X and Y value with 16 bit precision if your case scenario allows that. For the orientation you would only need the Y axis; which can be applied with another 8 bit precision number.
Buffer values are useful for this kind of data compression.

I have a game where the head rotation is constantly being shared towards the server and from the server to all clients; rather than sending 3 CFrames, I send 2 bytes of data, two signed 8 bit integers for the X and Y vector of the camera relative to the head; the server adds an additional 8 bit player identifier to it and sends a buffer with 3 bytes of data for each player (which with just the CFrame replication was over 50 bytes) and the client can calculate the head rotation with enough precision and can identify the user whose headrotation it is.
Next to that; I don’t send the clients the data for all users constantly; I have separated it into 5 distance groups of which the closest are replicated each 2 heartbeats (0.033 seconds) and the furthest each 32 heartbeats. (~0.5 seconds)
Constantly sending data through remoteevents each heartbeat can be bad if you do it incorrectly.

The client handling most of it;
You can tell all clients at the same time what the destination for the NPC should be; then all clients can move the NPC to that position; all steps inbetween can go smoothly that way without need for replication.

A simpler example is a door.
If you have a door that opens and closes; a script entirely on the server would have to handle the state and tell the client each step of the opening and closing process; each step between it being entirely closed and entirely open is being replicated to the client.
Now if you do it partially on the client; the client only needs to know when it’s opened or closed; hypothetically the server would only need 1 bit of data (in practice due to how sending data works, it is a few bytes rather than a singular bit) to share the opening and closing of the door rather than the hundreds of bytes. Plus the door opens more smoothly since you will be able to animate the door each frame on the client rather than at each arrived packet.

It would look like this in situation 1:
Data arrived > 20% open (tells the client how the door is oriented and what its position is each time)
Data arrived > 40% open
Data arrived > 60% open
Data arrived > 80% open
Data arrived > 100% open
In situation 2:
Data arrived > Tween the door smoothly from 0 to 100% on the client (with just the data telling the state, open or closed)

Multiple Actors isn’t bad as it spreads the load across multiple threads, that way you’re not putting the load on one and causing the rest to lag behind.

Edit: You should read this for more info!

1 Like

Tags are really useful if you want to identify a group of something very quickly and efficiently. Adding the tag “NPC” to each NPC is faster than scanning all of the contents in workspace that match with the needs to be an NPC model.
And no matter what location they’re in; they will keep functioning.
Tags are essential for client sided scripts that support streaming. The client can easily get an instance added signal and instance removed signal.

1 Like

I can feel my brain capacity expanding as I’m reading all this, I have one more question tho.

If I move the NPC on the client only, and then the NPC is required to perform an action like launching an attack, the position of the hitbox will be different than what the players see since in the server the NPC did not move, correct?

But If I calculated the attack on the client then exploiters could just manipulate it, right?

So,

Is Parallel Luau necessary?

No, Parallel Lua is not required to make an efficient system, nor its it a easy solution to solve inefficient or process heavy calulations, you are still responsible for cleaning up and compressing your code, which how most people solve the issue of heavy lag to their game.

It can help, but that entirely depends on the system you are making, such as terrain generation, or hundreds of NPC’s at a time, if 2 of them are already causing issues to your game, you have some serious optimizing to do.


As with all things, it really depends on the task as already stated, because while you can multithread to get rid of lag related issues, your primary focus should be to be optimizing your code to work with hundreds of NPC’s before you consider multi-threading your system. This ensure you have the best system possible for whatever you need.

(Fairly oversimplified, but it still is relevant to what im talking about)
Take Minecraft as an example, its a heavily optimized game, attempting to load all its textures, creating 3D Perlin Noise using a seed, and Create Chunks for said Perlin Noise. Something to that scale would be horrible for your computer to swallow, so they had to optimize their game, they made it so the insides of blocks are excluded so the game doesnt have to process that information, created a efficient lighting system, and converts the map into a giant mesh. All of these techniques and challenges eventually has a solution, which is how we have the game today. Is the system perfect? No, but its better to not borrow NASA’s computer to run 4 chunks of the game.

Its the same way of how you can use OOP to organize your code, but just because you can use OOP to do that, it isnt a solution to janky, and bloated code. Its still your responsibility to clean that code up.


Thats still a bad thing as you are having more scripts, thus more threads running at the same time, thus more memory usage. You centralize your code to ensure the NPC’s have the same functionality and are doing the same thing, it allows you to make easy changes that apply to all of them unlike what multiple scripts would allow you to do.

Multiple scripts have your Pro’s too, but you would need to heavily optimize them too, if you have to see of of them to their fullestr potential.

Thats if you leave it open to attacks.

Typical systems run a calculation on the Client to confirm whatever they are doing, then they check in with the Server which validates the Clients claims, this is known as a sanity check, and is a effective way to increase your codes security if done correctly.


So in short, its your responsibility to ensure your code is the best that it can be while running efficiently and smoothly, while you can multi-thread, it isnt a solution to unoptimized code, and still is your resposibility as the programmer to ensure that its running the best that it can with or without it.

2 Likes

I see, that makes sense.

Minecraft was kind of a bad example because my PC can’t run minecraft but I get your point
(Also how is a game that loads blocks with full detail even if they are 20 chunks away heavily optimized?)

Anywhos, how could I optimize NPCs? I’m sure less updates per frame would help alot, but wouldn’t that leave me with inaccurate NPCs? (For example if chasing the player)

The short of it is that yes, multi-threading will improve performance. In fact, actors were designed to work as top-level models so that you can easily swap out the “Model” instance for an “Actor” instance for all of your NPCs or whatever else. Multi-threading isn’t needed for the majority of things, but it’s definitely useful when handling a large number of tasks what you want to complete simultaneously.

But exactly as @DasKairo said, your issue seems to be more of how your NPCs are coded. Multi-threading will help regardless, but it’s not the core issue. You should always try to optimize as much as possible before looking for an easy solution. Modern games have this issue where they rely on things like DLSS instead of actually optimizing their games, and this is not a good future.

4 Likes

Minceraft is doing this for millions of blocks, chunks are about 16x16x256 on older versions, but 16x16x320 on newers version, assuming youa are on newer versions, each chunk as about 81,920 blocks to calulate, if your render distannce is 20 chunks, 20x20 is 400 possible chunks the game could load at a time, multiply that by how many blocks each chunk has, you are loading about 32,768,000 blocks.

Keep in mind, this is assuming that the terrain is loaded in like a square, however most cases its loaded in as a circle picking the chunks that are within it, so take whatever I say here with a grain of salt.

It may not seem like a lot at first, but games like minecraft are heavily optimized and sacrifice a lot of things handle that specific task, just for you to appreciate its looks and features, which is why people consider the game to be a techical feat.

1 Like

I see, It’s like trying to cover a wound instead of actually healing it.

Wow that’s alot of blocks.

Why do we have mods like Distant Horizons or Iris then? and why does everyone on reddit say Mojang’s coding is terrible?

What exactly are you having your NPCs do? If an NPC is chasing the player, it likely doesn’t need pathfinding, it can just move directly towards the player. You really only need pathfinding if the NPC loses direct line of sight. Pathfinding is also an expensive calculation that you definitely do not want to be calling very often.

To add on to what @DasKairo was saying, Minecraft has a lot of smart optimization going on. The original 16x16x256 is because a byte could store a value between 0 and 255 or 1 and 256, and half a byte could store 0-15 or 1-16, which means a block position in a chunk can be stored with only two bytes. You also only need to store changes to the world rather than every single block. When rendering, it also only renders faces that you can see, and it uses greedy meshing or something similar. There’s a lot more that Minecraft does than this. I find this pretty interesting and one of my side projects has been creating a Minecraft inspired experience on Roblox with as few compromises as possible, and I have to say that this is no easy feat, but a challenge I enjoy when I’m in the mood.

1 Like

Distant Horizons introduces a LOD system, which essentially creates a Low quality impostor mesh to simulate what it would look like far away, you wouldn’t notice it if you were very far away which is the intended purpose of LOD. Minecraft doesnt do this, and continues to load the blocks as high quality and does load any of the terrain outside of the Render distance.

Using the LOD system, people were able to create and visualize the entire Minecraft world (60,000,000x60,000,000x320, btw) which shows how far you are able to optimize those kinds of systems, and those kinds of games.

The way they did it isnt exactly the best, and it leaves room for more optimizations, but its still a heavily optimized game, allbeit not the most perfect game.

1 Like

Yea, pathfinding was called alot, I guess I could raycast to check line of sight, and only pathfind when player is out of sight and if necessary.

(Would that work?)

That would be ideal, but you should keep pathfinding calculations to a minimum even when out of line of sight. There are also other ways of optimizing pathfinding that may be less accurate but more efficient. It also depends on what you want out of your NPCs, or rather, how much you actually need. There are a lot of inaccuracies in games, but you don’t need full fluid simulation just to have water physics (as an example).

1 Like

I see, that’s very interesting, anyway we’re getting off track haha.

Thanks @CodeProto, @DasKairo, @MightyDantheman for all the help, I learnt alot!

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.