Tutorial for how I use Behavior Trees for my NPC

Yes, my npc can follow a target. I have that logic in a different behavior tree for the chase behavior. If you watch the video at [4:53]. You can see a glimpse of that logic. Its an older version, which is why there are not doors, but you can see what its doing based on the emoji above Pepe’s head.

:) state means pepe is going to random positions in a random room
>:) state means pepe is following target

The switching of these states is why behavior trees are so powerful.


To help you specifically, you need to update your targetPosition.
Store two variables:
target as a reference to the target instance e.g. the player
targetPosition as a reference to the last target position you are pathing to

Then you check the distance between targetPosition and target.Character.PrimaryPart.Position to see if its greater than say 5 studs. If it is, update targetPosition to the new value and repath. Else continue as normal.


The doors is alot more complicated to explain. But in concept. I’m using a combination of things:
1. collisiongroups to separate collision with assets like doors and the parts I use to clean the navMesh so its grouped by rooms via pathfindingModifiers and Labels.
2. using pathfindingLinks to do actions based the label. Also since my navMeshes are separated by rooms, it makes links much easier to use. The only thing that connects rooms are the links. So it must use that door to go next room.
3. referencing my objectserivce—which is my collection of objects my npc can use—to dynamically give me the specific door object class I need to call that door’s open/close function.

mmm ok… I have not worked with Navmeshes before … to get my door system working it was pretty complicated also, but I also wanted the door to collide with the NPC so that like if it was partially open by a player, they could not just go through it…

thanks again for the details…

Ahh, yes. Physics on doors is definitely harder. I tried that at first, but I found it was not important enough to our game to justify spending the time to solve that problem.
Glad I was able to help ya tho.

Do you know if there is a way of queueing waypoints, in that if it is going to say waypoint 2, you can already have waypoint 3 set up as the next priority , even if as it is going to waypoint 2 , it does not know about 3 yet? because there is no clear path to 3, until it gets to 2?

I was wondering also with the queueing if this might eliminate some of the delays (note I also read one of the other posts you were in about npc stuttering ) …

For this issue there 3 possible solutions I can give:

  1. The roblox method. What it seems like you are trying to do is implement your own PathfindingLink PathfindingLink | Documentation - Roblox Creator Hub. But I would recommend conforming to roblox and using it like this Character Pathfinding | Documentation - Roblox Creator Hub.

Links are specifically made to connect untraversable areas. So if you put a Link between 2 NavMeshes the internal roblox PathfindingService will know to go to your Link to reach the next area.

It will trust that the Action associated to that Link will be handled by you. So if its a ocean away: teleport to boat, tween to end position, teleport to land; ifs its a broken wall: play crouch animation, call humanoid:MoveTo(holeEndingPosition) or humanoid:Move(holeEndingPosition), ifs its a door: open door, humanoid:MoveTo(doorEndingPosition) or humanoid:Move(doorEndingPosition).

The choice of using Move() or MoveTo() will be determined by how traversable your in-between zone is.


  1. The custom way. You can ignore the roblox and make your own, which will potentially be harder and lead to more bugs. But essentially you set up a "trigger box" which will act as the Link. Using touched on this part is not advised for performance. Rather in your code have a table of all these trigger boxes and store functions for how your npc will use the trigger box to move locations.

When you want to use it, force the npc to go to walk to trigger box 1 and use the associated function to cross zones to trigger box 2. However, the real complexity arises when chasing a player and using it dynamically as npc attempts to follow a player across zones.

For this, you must check your target positions before trying to Path or else it will fail. Figure out where our npc wants to go. If its in the next area. Take control and move between zones. Then Resume letting the npc follow the player.

This is just one way to do it and I am probably over-looking some things as well in this implementation. But trust it will be hard.


  1. The dirty easy way. Waypoints are tables in an ordered array format. You can also have multiple Paths Path | Documentation - Roblox Creator Hub . Create waypointsTable1 and waypointsTable2. Then combine the waypoints where you want them. Overall this will get complicated QUICK tho.

Also the studder is a network ownership issue. Animations not should be played over the server. Rather be handled on client side.
The reason why it happens is because when something is owned by the server, the npc body must wait to replicate all physics aka motion to all clients. Which causes that brief moment of non-movement which stops the animation.

Once an owner is set to a cilent, animations will smooth for that person. Others will probably see the stutter still. This can also be relived by extending the waypoint distance or entirely fixed by making your own animation script that will just play regardless of physics.

mm, ok some more things for me to research.

for option 3, if the door has collide on for everyone, and the door is closed, I thought then the NPC will not know about any way point inside of the room when the door is closed…

but anyhow, great info, to me it seems a custom combined system is needed to get through all the various logic

hmm, I thought I saw people were setting the npc network ownership to nil… how is it set to the client, and then what if there are multiple clients around the npc, does every client then get the ownership?

Depends how you set up PathfindingModifiers and CollisionGroups. You can still have collisions on the door, but have `PathfndingModifer’ that say yes you can still pass through this door. The NPC will walk into it now regardless of the door.

Right, but then it does not collide with the door… which I wanted it to , like if the door is being opened it pushed the NPC, and or if the door is open like at a 90 deg, it has to walk around it… it would look goofy if it walked through it when it was open at 90 deg…

I messed around with the way roblox say do to it, like you say and it just walk though it , unlike a player… which would not be cool to players if it was a pvp shooter or even anything… like if the player is in the room, cannot see the npc and it walks though the door…

and ya, what you need then is a trigger system like you have…but if the npc is coming along the wall parrell to the door, and it triggers the door open, then it would walk through it as it opens?.. or when you trigger it could turn a second part the size of the door to collide on, then perhaps the NPC has to recompute around the door… then if the door is closed, turn collide off on the second part and the npc can stilll compute into the room…

that might work…

the other challenge with above, is that then the npc is opening the door sometime when it is not really near enough to open the door… which I have seen in other non roblox games and that again if goofy looking… so you could have a trigger point with a slight delay…

(and wow roblox just said I cannot do more then 3 replies in a row, until I get a reply, so I have to edit the last one)

and now I lost my train of thought… which was doors that slide open…not open out or inward…

Network Ownership is derived from all BaseParts BasePart | Documentation - Roblox Creator Hub . Here is some info on it: Network Ownership | Documentation - Roblox Creator Hub

By setting it to nil you are overriding automatic ownership to explicitly use the server as the owner. Which will cause the issue. You can do this if you want, but you MUST make a custom client animation script that fires signals to all clients on which animation to play for the npc on their screen. This may be the easier solution you may want.
Edit: The stutter occurs when you have server animation but a client takes ownership. Causing the server to wait for physics updates from the client, producing the stutter.

  1. To fix this either dedicate to pure server logic by setting ownership nil, but I HIGHLY RECOMMEND making a custom client animation script that fires signals to all clients on which animation to play for the npc on their screen. Animations are a heavy process.
  2. Or create your own auto ownership system to pass the ownership between clients. It is okay to have the server handle physics but be mindful of the stress your game puts on the server and how it affects your core gameplay. You ought to minimize your server work to only wants needed for fast performance. So it still HIGHLY RECOMMEND create a custom client animation script.

To set to a client, give it the player instance. But as you noticed too, it becomes difficult to say who should get the best physics. This is a problem beyond Roblox and is a general Server/Client issue across all networked games. This is why in games in general you can float out of cars when its moving fast.

I don’t know a good solution for this, but it is common to go by closet proximity or who ever is prioritized, say the player its chasing.

Also remember! Network Owner is for all BasePats so make sure to iterate through your entire npc and set all basePart's ownership.

hmm, I’ll have to look at one of my npc codes… I could have sworn that’s what people were saying to do,

what happens to the NPC if you give to the nearest client and the player dies? does it automatically revert to something else?

Ah yes, you are right. So that means you definitely want your navMesh to take into account the doors position, so it can walk around or open when its closed. And if thats the case, then you need something like a link or trigger box to say these areas are still traversable when the door is closed.

This is the post I was reading where you are in the last comment Pathfinding NPC stuttering - #15 by F0xBirdmansBFF

and yes the dude you replied to says to set the networkownership to the client and then the guy below the guy you replied to says to do it on the server… and the original poster was setting it to nil…

ah good times…

well thanks for the chat and info… I shall now mosey off to bed and dream of npcs getting stuck at a door… but you and I have fixed that issue… somewhat…

Oh oh oh my mistake, I was partially wrong here. It does get confusing. I missed remembered. This was all a lot of info dumping at one time lol.

Context: this was issue before that post.
So for me, I got the stutter consistently after 1 min in game. Which baffled me, because it looked clean and stutter-free before 1 min.

The issue was caused by default roblox ownership being is set to auto. So as a player stays in the game their domain of ownership expands, taking objects from the server as it grows. Which for me happend around the 1 min mark.

At the time, my npc was instantiated on server and used server animations. Which worked great when the Server had ownership from auto. But the moment the client owned it, it lagged, because nowww the server to needs to wait for the cilent to handle the physics.

Sorry, for the wrong info before. Sooooooo
Setting to ownership to nil, will make it work.
You are forcing physics to be handled server side. But be wary as your server will lag if you have too many npcs relaying on server physics and animations. Which is why you still want a make a client animation script. In general animations should never be played on the server, its alot to handle.

By doing so you will let your server focus on more core gameplay elements like door physics, or precise bullet hit detection.

If the player is nil, thats the same as explicitly saying set owner to nil.
Also it uses the Player Instance, rather than the Character. So there is no dying, only leaving the game.

This is getting very specific and its difficult to know exactly what you did. So I’ll show you my door. Apologies to those who are color blind.
[Reference A - Hinge]


Standard roblox HingeConstraint setup with an attachments in Hinge part and Door Mesh

[Reference B - NavModifiers]

  • NavDoorway - a part with a collision group set to NavMesh, CanCollide true, and PathfindingModifier with Passthrough false and Label set to DoorWay. This is necessary to create a division between rooms so the PathfindingService will always use the link.
  • NavInside - a part with a collision group set to NavMesh, CanCollide true, and PathfindingModifier with Passthrough true and Label set to DoorInside. Passthrough is true this time so npc can walk through these parts.
  • NavOutside - a part with a collision group set to NavMesh, CanCollide true, and PathfindingModifier with Passthrough true and Label set to DoorOutside.

[Reference C - Attachments]

  • Door - actually mesh with collision group set to GeoDoor, CanCollide true, and PathfindingModifier with Passthrough false and Label set to Door. This forces the NavMesh to continue the block pathing based on the door’s position. So if its open it will go around. Also my GeoDoor collision group is set to collide with players and npcs. As opposed to NavMesh collision group which collides with nothing.
  • Prompt Attachment - used to make prompt appear on door knob
  • NavInside/NavOutside Attachments - correspond to respective point for the link to use.
  • LinkDoor - IsBidirectional true, Label set to Door

With a NavMesh setup like this you can place this door between rooms and it will separate Room’s NavMeshes. As you can see this room’s nav which is Labeled as Small.

Code-wise when you set up your Humanoid.MoveToFinished signal make sure to check the `waypoint.Action == Enum.PathWaypointAction.Custom and waypoint.Label == “Door”. If true do the open door action. Else continue like any other waypoint. Here is my src code but it may not be easy to use off the bat. There are many wrappers I create to make this modular and recursive-able. Enjoy!

Most excellent, I will review all the details. Thanks!

Hey, can I load pepe and have him do the same stuff on the client? Or must it be done on the server