Parallel luau NPCs

Henlo, im working on an NPC system that involves using 1 script to control multiple NPCs. This uses coroutines and can be abit slow when you have more than 30 NPCs. How would i go about using parallel luau on this as i am only using 1 script to control multiple AI agents?

2 Likes

For future reference, look up keywords like parallel lua into Google, more specifically the Roblox docs, this forum, and YouTube.

Side note, as of right now you can only have at max 3 Actors really for a process.

Ive read the documentation on this and watched the video but it didnt really have what i wanted exactly. This involves putting scripts under actors. What i have sadly is 1 script that controls all AIs agents in the game environment that i can’t put under an actor similar to Y3llowMustangs NPC systems. Im trying to find if theres any way to apply multithreading to a single script controlling multiple AI agents without having to revert to putting 1 script under every NPC that i have.

image

1 Like

In another thread @XenoDenissboss1 spoke about parrell stuff, maybe they can jump jump in here.

Sorry, I thought you didn’t try the other stuff first, and I’m not sure if that’s possible.

1 Like

Thank you very much anyway, i’ll see what i can do about my code.

it can be rather complex, the jist is

the npc is typically initialized in a serial context

parallelism is only used for modular functions i.e. lets assume a facet of the NPC is Fog Of War visualization (i.e. determination of what nodes the npc can/cannot see)

assume this visibility requires .stepped checks for as long as the npc exists; and can encompass .magnitude, dotproducts, and raycasting (not always all 3)

in serial context, this can be quite burdensome in large amounts of npcs… though I’m surprised you are having problems with mere 30… you should elaborate on what you are doing for these npcs that you cannot even run 30.

in any case, parallelism seeks to granularize tasks for parallel execution within the given frame time and so if we had 1000 npcs doing the visualizer functions, it won’t bog up the execution at all (assuming correct implementations)

you’d call a controller or something that handles a request to add/create an actor plus code executor or simply request for our npc to be added to a pre-existing worker actor

this is absolutely complicated and I would defer you to actually investigate why you are having problems serially with very little npcs…

1 Like

I dont know exactly what happens at 30, this is my first time working with coroutines at this scale lol. But this is what it looks like. The NPCs start feeling sluggish and slower the more they spawn. My guess is that since theyre serialized the server is trying to move them one by one every time so it runs slower the more entities the server has to deal with? I only really came across this problem after i started testing large amounts of enemies.

I guess its also worth noting that im using SimplePath for this.

Uh… Which post if you dont mind me asking?

I have to ask first… Control in what way exactly? Like do you have one main script that involves changing states and giving these npc’s some sort of “destination” for them to walk to? Or do these npc’s run mostly independently of one another but they just do within multiple coroutines inside that one script?

I have one Script in ServerScriptService that controls all NPCs tagged through CollectionService. It controls everything each NPC does from movement to health to, well everything.

Just don’t render NPCs on the server. Most of the time, NPCs are rendered on the client and client only. The server simply runs calculations like pathfinding or calculating where the NPC will move next. The client is the one responsible for creating the NPC model and then playing animations on that NPC model. You can use this idea to skip the entire “using multi-threading for NPCs” idea and still have performant NPCs in your game.

For more information, please view this tutorial by SuphiKaner. https://www.youtube.com/watch?v=JyMxrcqEzu8&ab_channel=SuphiKaner

1 Like

Right. well, this sorta complicates things for parallelism. For parallelism to really be effective, you firstly need to let all npc’s be independent rather than entirely tied to a singular controller script. This isnt to say that you wont be able to control them IF they were to make all npc’s independent but so far you cant really do much with parallelism here with your current setup.

If you want proper parallelism then NPC’s will have to be running mostly on their own from individual actors. Again, you can still control them with a singular primary controller script but ultimately most of the actual “work” should be done by the actual parallel npc code. Said work being like letting npcs compute their own paths, get the closest player and have them walk said paths.

Do note that parallelism isnt about simple throwing NPC code into an actor and calling it a day. Parallel luau works very differently and is insanely easy to misuse and destroy its performance.
Here are some things to note about it:

  1. Actors do NOT have access and CANNOT see, write or modify the changes within modules of other Actors and Serial. For data management, you’ll need to either make sure the server specifically already has all the correct information or simply send back the new information from all actors to the server.
  2. Parallel luau is all about crunching numbers. It can work well for that getClosestPlayer() function and creating new paths. However updating instances will require you leave the parallel phase (via task.synchronize). Make sure that the serial phase is ONLY activated when absolutely needed! (Like when you have all the numbers ready to be applied and actually used)

But right now, i recommend you look into optimizing the code you already have. Defering a million heartbeats isnt exactly a good thing to do considering that these heartbeat events will all run in serial. A dirty fix for this would be to just make a singular Heartbeat loop on the server and have the npcs listen to a “fire” event instead. You can use a signal library to help you with that firing event functionality. This should get rid of that weird overhead from defering all those heartbeats.
Secondly, you could perhaps look into optimizing that getClosestPlayer() function. If everything is getting sluggish from just a handful of NPC’s then its likely youll need to look into getClosestPlayer() and see if you arent spending compute resources on way too many things.
Dont really know what simplePath is. Im guessing its a path finding library so im not sure how much i can really help you with that specifically.

2 Likes

parallel lua is likely not worth the effort, the overhead is huge which negates almost all benefit’s and the available threads on the server is limited by server size and from what i remember seeing recently in forum posts parallel lua might not be working at all on the server anyways right now.

Apparently the issue with everything getting laggy from just a couple of NPCs was a stupid vestigial line of code for an AlignOrientation object that i put in to control where the NPCs were facing. There are still some optimization issues in the way (slight jittering and pathfinding just being slightly off when there are more than 100 npcs) so il work on ironing those out with your directions. Thank u

1 Like

The overhead will universally be lesser compared to any piece of code running 100 npcs. It all really depends on the implementation. But i do have to agree that parallel potential here, as implied in my other post, is not exactly super great.

Also i believe servers are all locked with like two workers regardless (whenever its one core with two threads or two cores i dont know). The only thing that gets influenced by server size is its actual memory.

1 Like

a forum post i read a month or so ago was about why parallel lua wasn’t using more than 1 thread on the server (i think it was server) and a roblox employee responded that they aren’t happy with their system that dynamically allocates server threads and have effectively disabled it for now, they initially said it would be based on player count which was then later clarified by them to be max server size. this is all i can remember, I’m not gonna go look around for sources.

1 Like

This one:

I didn’t understand much of it, but I gathered that you’re knowledgeable on the topic and have used Actors a fair bit. :sweat_smile:

1 Like

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