Path Nodes
originally written by Springheel
For more information on pathfinding, see Pathfinding.
What are Path Nodes?
Path entities (or path nodes) are the things that you use to make your AI move around the map. Placing path nodes can take a little getting used to; hopefully this article will help (I'm far from an expert, but here's what I've discovered so far).
There are lots of different kinds of path nodes. It can sometimes help to think of them as "travel nodes" (nodes that AI will travel to) and "behaviour nodes" (nodes that tell AI how to behave at a certain point).
Although path nodes have a directional arrow in the editor, it has no impact on most nodes. Rotating the node does add a corresponding "angle" property to the entity (matching the direction of the arrow). Certain nodes (path_anim and path_turn, for example) are affected by the "angle" property, but most will ignore it.
How to use Path Nodes
Path nodes are placed like any other entity (RMB and select "add entity", then scroll to "paths"). They show up as an orange box in the editor.
Path nodes are useless if they are not linked to another entity (either an AI or another node). In order to link them, you use the "target" property. This tells the AI what pathnode they should go to (or act on) next. If you type "target" "path_corner_1" in your AI property list, then your AI will walk to "path_corner_1" when the map starts. Without a "target" property, your AI will not go anywhere. Once you add a "target" property to either your AI or another node, you should see an orange line connecting the two entities.
Behaviour nodes activate behaviour in order. In other words, if you want an AI to reach a path_corner, then turn to face a direction, then wait for a time, then play an animation, you need to link the nodes in that order.
path_corner ---> path_turn ----> path_wait ----> path_cycleanim -----> next path_corner
It is also possible to target multiple nodes (using "target_1", "target_2" etc. spawn args). In this case, the AI will choose one of these nodes with equal probability. If the "chance" spawn arg (between 0 and 1) is set on a node, it defines the probability for the AI to choose this path node next when multiple path nodes are targetted.
There are now two new spawnargs, "alert_idle_only" and "idle_only" that can be set on path nodes. The nodes are then only chosen when the AI is in that state. For example, if you set a path_corner as "idle_only", then the AI will no longer go to that path node when it has been alerted. This allows the mapper to set a complete set of alternate patrols and actions for AI who have been alerted (like sending them to guard important areas).
Nodes that make the AI walk to a specified location (currently the only one that does this is the path_corner) can have an "accuracy" spawn arg, which defines how close the AI has to be to the destination point to determine the position as reached. Normally, the AI considers the position reached as soon as it is inside its bounding box (most of our humanoid AI are using aas32, so the point would need to be within 16 units from the AI's origin). This is not always accurate enough, for example when a path_corner is placed in front of a chair where the AI is supposed to sit down, making the AI place half of their back next to the chair. Setting the accuracy spawn arg will change the horizontal size of the bounding box used for checking. If the accuracy is set to negative values (default is -1), the standard bounding box will be used as before.
path_corner
Probably the most common path node, this is a "travel node". AI will walk from their current position to this node in as straight a line as possible. This node must be on the ground and in an area AI can reach. See Pathfinding for more information on how to help AI go from one node to another.
To make AI patrol an area, each path_corner node can target the next one in sequence. If AI reach a node that does not target anything, they will stop there and no longer move without player interaction. It is possible for two path_nodes to target each other, which means the AI will walk from one to the other and back again endlessly.
A single entity (path node or AI) can target more than one path_corner; D3 will randomly choose between the targetted nodes. Use the following syntax: (actually this syntax needs to be double checked)
target path_corner_1 target_2 path_corner_2
(At the moment, targetting more than 2 path_corners from the same entity does not seem to work (possibly a DR bug).
In the example below, both A and B are path_corner nodes. On map start, the AI will walk to A, then turn and walk to B, then stop.
Note that an AI will return to a path_corner (does it choose the nearest or most recent?) after a failed search. If you do not have at least one path_corner, the AI will stop wherever they are when their search is complete.
path_wait
This is a behaviour node. It does not tell an AI to move anywhere. This node tells an AI to wait in an idle state for a given amount of time. Once that time is up, the AI will proceed to whatever the next target is (a path_wait with no target is pretty pointless).
A path_wait node appears as a small orange box. It has a directional arrow, but that has no affect on which direction the AI faces in the first place. However, you can set the angle key on the path either by rotating the entity or by setting the key directly to make the AI turn and face this direction before starting to wait.
A path_wait node should have a "wait" property, with the number of seconds the AI should wait there before proceeding. It can also have a "wait_max" property which will vary the repeat time. So for example...
* wait 30 * wait_max 40
...will cause the AI to wait between 30 to 40 seconds before proceeding. If wait_max is set to 0, the AI will always wait exactly the time specified in wait before proceeding. If you set wait to 0, the AI will wait between 0 seconds and the time specified in wait_max. Default values are 2 seconds for wait, and 0 seconds for wait_max, so the AI will always wait exactly 2 seconds.
In the following example, A and B are path_corners, and the small orange box is a path_wait entity. On map start, the AI will walk to A and wait there for the required amount of time, then turn and proceeds to B.
Note that it does not matter where the path_wait node is placed. The AI does not actually follow the orange lines (this is not really intuitive, I know). The example below would cause the exact same behaviour as the example above--in both cases the AI will walk directly from A to B.
Another useful example for path_wait is that of the stationary guard who turns to look in different directions periodically. This can be schematically represented (arrows indicate target links) as:
AI -> path_corner1 -> path_wait1 -> path_wait2 -> path_corner1
Example properties for the path_wait are:
wait: 5 (minimum time to wait on action) wait_max: 10 (maximum time to wait on action) angle: 0 (Important: this property is essential for proper function even if the angle is 0)
The AI walks to or stands at the path_corner. The next action is to do what is indicated by the first path_wait. In this example, it tells the AI to face a particular direction for a certain period of time. This then targets a second path_wait which has the AI face a different direction for a certain period of time. To complete the cycle, the second path_wait then targets the original path_corner. The path_corners are necessary because again, the path_wait doesn't contain pathing or location information. Without the path_corner, if the AI is caused to wander (e.g. becomes alerted), it might not return to the original standing spot, and instead will do the look angles right where it stands. The path_corner assures the AI returns to its original position.
path_turn
This behaviour node tells an AI to turn in place to face a chosen direction. It does not make the AI walk anywhere. This is the one node where the directional arrow does seem to matter--the AI turns to face the same direction as the arrow. Alternately, you can use the property "angle" and the values below:
- 0 = East (X)
- 90 = North (Y)
- 180 = West (-X)
- 270 = South (-Y)
- 360 = East(X)
(Actually, to be more accurate, rotating the entity automatically adds the "angle" property to the entity. If you just leave the arrow facing the way it is when you create the entity, there will be no "angle" property, and therefore the AI will not turn.)
path_anim
This is a behaviour node that makes the AI play an animation, once. When that animation is done, it proceeds to the next target (if any). This could be used to make an AI walk over to a bookshelf and play a 'reaching out' animation, for example.
The syntax proper syntax is:
anim [animation name]
You can see the list of animations names in the AI's def file. Do not use the name of the actual animation file.
A path_anim can have only one animation, but it is possible for a single entity to target more than one path_anim. The AI will pick one of the path_anim nodes at random and play that animation.
When you first create the path_anim entity, the directional arrow is meaningless. However, if you rotate the entity, the "angle" property is added to the entity and is updated based on which direction the arrow is pointing. That property indicates the direction the AI will face while playing the animation.
Issues: Currently there are two problems with path_anim nodes. First, the animation seems to be played only on the torso channel (ie, it will not affect the AI's legs). Secondly, a random idle animation can interrupt the path_anim. Not only will this cut off the desired animation, but the AI will not proceed to the next target (pretty serious). [edit: this latter issue should be fixed now]
path_sit
This is a behaviour node that makes the AI sit down at its current location. See Sitting Behaviour for AI for more information.
Untested Nodes
I have not personally tested the following, so I'm just going by their editor descriptions. They may or may not work as described.
path_cycleanim
The AI stays in place and loops the selected animation, either for a specified amount of time (using the 'wait' property) or until triggered. Syntax needed.
path_lookat
This does not stop the AI, but they will turn their head and look somewhere specific as they walk to their next target. For the next wait seconds, turn head to look at the entity given by the focus spawnarg (defaults to looking at the path_lookat entity itself). This is useful if you want to make sure an AI is looking at a specific spot (or away from a certain spot) during their patrol.
path_waitfortrigger
Waits at a given place until triggered, then proceeds to the next target. This is useful if you want some control over exactly where the AI is when the players first see it.
path_hide
Deactivates and stops rendering the AI. Used to remove "ambient AI" from the map when they have served their purpose (ie, AI that are just there for flavour, like a messenger leaving the room and disappearing).
path_show
Starts rendering the AI. I would assume this one would be linked to a path_waitfortrigger, to create AI that spawn when triggered. This could be used to create the effect that an AI just came through a doorway or around a corner.
path_attack
Used to script AI attacking a particular enemy, for scripted sequences I guess. AI will continue on to the next path entity if it kills the enemy.
Questions: How do you define who the AI attacks?
[Fidcal]: Just found this - "Character will attack the character specified by 'enemy' key. Character will go to next path when enemy dies or when activated." Not tested.
path_interact
This lets the AI interact with an entity (for example a button) in a similar way to frobbing. This will only work for buttons etc, not for inventory items and moveables. The AI will stop and look at the entiy while interacting, but not walk to it, so a path_corner next to the entity is required. AI will use normal doors and elevators without needing a path_interact (confirmation needed). However, this could be used to make AI turn on lightswitches, open mechanical doors, etc.
Questions: what is the synatx for targetting the entity to interact with? How close does the AI need to be?