I’m trying to make ‘smart’ AI, like how Theme Park Tycoon and Restaurant Tycoon’s AI work. I’ve never worked with AI, so this is becoming a real challenge for me to not only well code the AI, but then get them to follow path systems, stop at certain points, etc.
I’ve looked around youtube videos, places, the wiki, etc. And atm I’ve just got the AI to spawn at random intervals and walk randomly along the players base. Problem I am starting to face however is around 80-100 AI it starts to become a bit laggy. And if we times that by 6 for 6 bases, it’d be insanely laggy, and add to the fact I want like 200 AI characters per player base.
Are there any techniques to dramatically decrease lag from large AI numbers. ATM I have Animation and movement scripts inside each AI separately, so not sure if maybe making that a single script would speed things up? And not sure how I would get the movement to work for each individual AI without it being inside the AI itself.
I haven’t touched a AI since years, but for 200 AI, you’ll need to optimize it in all ways possible :
I’ve done a very quick check on the games you mentionned
Theme Park Tycoon
You’ll notice their animation stops completely if you’re too far from the NPC or the player’s camera is too far from them.
you said ‘Smart AI’ like ‘these games’, but i think in this game, all it uses is a MoveTo: to random position including a few exceptions & action, the script are made exclusively to uses the minimal data possible in a second.
Restaurant Tycoon
This game is even more obvious, The uses of R6 and minimal animations (basically walking, eating & cooking) already reduce a considerable amount of details. just watching the trailer shows you almost all the game can offer in terms of gameplay.
Overall, for supporting this much AI, your game need to looks less than simple.
Both games have solutions that works just fine, so you’ll normally won’t have much issue if your Pathfinding is as simple as the following games mentionned. and if you do, perhaps reduce it to 100 instead.
As for the no moving when the cameras far away or your far away etc. That would cause issues with AI giving the player money (with AI spending money at vendors and stuff) so i’d just have to make it so you get no money when your far away from the AI?
Humanoids themselves do use a lot of resources – it’s recommended to make your own custom humanoids instead. As long as you don’t do anything stupid, they should be noticeably more efficient.
However, if you’re not very experienced in the physics area of Roblox, it’s maybe not a good idea to make your own custom humanoids (if you need them done quickly). If your NPCs are all on a flat surface, then woohoo, you won’t need to do much in this area.
I’m going to have a go at some basic custom humanoids soon for my game (200+ humanoid NPCs currently, server = dead), and I know EgoMoose has been doing something real cool.
The animations should be entirely visual. They shouldn’t have any effect on gameplay at all. Also, since the money giving should hopefully be server-side, client-sided things such as animations should not have any effect on what happens anyway.
But like them moving around is server side, their animations yea thats fine, but for them actually moving. But if I just made them stand still then their character wouldn’t be getting to their destination, they wouldnt be giving the player money, etc
Just to be clear, a Animation is just a additional visual to make the game more dynamics, the NPC will move and give the player the money whenever he have a animation playing or not.
Mm, but if you made them stand still server-side, they’ll stand still for all players. Kenami also said why this isn’t an issue, also. Effectively, all of this doesn’t do anything on the server, so don’t worry about this particular optimisation
I wouldn’t give each AI entity their own set of scripts. I would imagine 200 AI trying to run their own logic would become dreadful. I’ve mentioned in a separate thread on how I achieved a large number of NPCs with little backlash performance wise. The way I went about it is by having a single server and local script designated with handling different things regarding your AI
Before all of that…
The method I’m talking about is what I used for civilians walking around to random nodes I serialized to CollectionService…
Avoid Humanoids as much as you can. Like what everyone has been saying above me :). But if you cannot live without them (For clothing), I’d advise setting their HumanoidState to Physics. It will reduce the number of resources they eat quite a bit. In my case, I went with no Humanoid and simply placed ImageLabels on the body for clothing and used AnimationControllers.
Server Side
For each AI entity, they are represented by a single 1 x 1 x 1 brick that is anchored. I can still use PathfindingService with this so it works out well. Next, I insert StringValues and BoolValues inside the part for the client to be able to read. Like for instance, what type of model is it, its current state, etc etc. Afterwards, once I spawn the Entity I do some math to offset it from the ground and begin Pathfinding. I’d advise Tagging the Entity into CollectionService so if you spawn Entities at random intervals it will be a breeze. Afterwards, I simply CFrame each Entity to their next waypoint, keeping their offset from the ground using the position of the waypoints. Since they just walk around and interact with random things, a simple logic check is quick! Although if you want to get more advanced with the logic you can. I run through the CFrame Update randomly for each object I get too in the Tagged list If I recall correctly. Helps visually keep them from all moving from node to node at the same time. Realism!!!
Client Side
The client is simply responsible for spawning the humanoidless model. Of course, in order for them to have clothes I had to use ImageLabels (still having nightmares about that). Basically, I had the client set up a few events to each entity to get real-time updates about the entity (change in logic/position). Once the Position event fires, I run a Tween using TweenService to tween the model to the updated position. Of course, you’ll have to time it with when the server updates the part (pretty easy). To top it off, another Event to listen to a StringValue (AnimationState or whatever you want to call it) that tells the client to play a specific animation.
Finally, you type too much Dysplexus…
I never went beyond the threshold of 175 NPCs with this method of mine, however, it never really gave me a problem in terms of performance. Perhaps it is my rig? I’ve tested 90 on an older PC and it handles surprisingly well… unless I’m bugging.
Would recommend reading this. SurfaceGuis have a major performance hit which might be worse than just using Humanoids with performance-intensive states disabled.
@OP:
As for humanoids performing badly, this is most likely due to collision and ray detection. When Humanoids’ climb state is enabled, they raycast forward constantly to look for ladders. Disabling this state helps with performance. You can also use CollisionGroups to disable collisions between all of the NPCs, which helps out a lot too. In general, I would recommend Humanoids once you disable collisions/climbing – spending 90% of your development time writing custom movement controllers is a waste.
I wanted to add something too, since I am too curious about topics that is AI included.
Now that’s absolutely right, but depends on what you really want to do. A single server script could decrease performance when I think of my experiences. Instead, multiple scripts which each leads like 30-50 NPCs would work better. To give example, think of Total War series, group of soldiers intend to move together but each can think of itself when it comes to danger. In these cases, script would do something more that would reduce performance(I don’t know about what you are planning to do, but if you are planning seperate events for seperate NPCs that is in a group…) And let’s think about 200 NPCs. Even if 30-40 of them encounters seperate events that would decrease performance momentarily.
About clothing, humanoids with removed features sounds better as they say above.
Good luck with your project!
I have done some testing with the Method you suggested Disabling HumanoidStates and Collision
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
I am unsure of how it will perform on Lower-End Devices