Path Nodes: Difference between revisions
Springheel (talk | contribs) |
|||
(20 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
''originally written by Springheel'' | ''originally written by Springheel'' | ||
For more information on pathfinding, see [[Pathfinding]]. | For more information on pathfinding, see [[Pathfinding]]. For pathfinding after teleport, see [[Teleporting entities]]. For more general info on getting your AI to patrol, see [[AI Patrol]]. | ||
= What are Path Nodes? = | = What are Path Nodes? = | ||
Line 30: | Line 30: | ||
''Note that if an AI reaches a node that targets pathnodes that are unavailable (because they are idle_only, and the AI is alert, for example), the AI will stop and no longer proceed.'' | ''Note that if an AI reaches a node that targets pathnodes that are unavailable (because they are idle_only, and the AI is alert, for example), the AI will stop and no longer proceed.'' | ||
== Positional Tolerance == | |||
A node whose placement defines a specific location for the AI to walk to (currently the only type like this is the path_corner) can have an '''"move_to_position_tolerance"''' spawnarg. This defines how close the AI has to be to the destination point (in the X/Y plane) to consider 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. Smaller numbers mean the AI must get closer, larger numbers are more forgiving. | |||
The following is likely true: | |||
* Negative values of move_to_position_tolerance means the standard bounding box will be used. | |||
* The default value is -1. | |||
* While move_to_position_tolerance can be set on other entities, it won't necessarily do anything. | |||
* If set on levers or buttons, it may affect AIs moving towards them. | |||
* The positional tolerance in the z direction is determined by the AI, not a node spawnarg. (Specifically, spawnarg '''"aas_reachability_z_tolerance"''' used in the *.def file. The default is 75 for humanoid AI. This value is applied differently depending on whether the target is above or below the AI.) | |||
== Triggering == | == Triggering == | ||
Line 107: | Line 110: | ||
== path_turn == | == path_turn == | ||
''(edit: I'm not sure why this node is useful, since path_wait can do the same thing) | ''(edit: I'm not sure why this node is useful, since path_wait can do the same thing. grayman: yes, it's useful for turning the AI to the correct angle when preparing to lie down or sit down, which doesn't necessarily involve a path_wait.)'' | ||
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: | 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: | ||
Line 123: | Line 126: | ||
== path_anim == | == path_anim == | ||
This is a behaviour node that makes the AI play an animation, once. When that animation is done, | This is a behaviour node that makes the AI play an animation, once, at the node's location. When that animation is done, the AI 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. Other possibilities include peering through a window, picking a carrot off a table and eating it, or running to a spot and cowering. | ||
The | The proper syntax is: | ||
anim [animation name] | anim [animation name] | ||
Line 135: | Line 138: | ||
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. '''This value appears to be necessary to make the animation work.''' | 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. '''This value appears to be necessary to make the animation work.''' | ||
Tip: Animation blending | ===Animation Blending=== | ||
''by Geep'' | |||
path_anim and path_cycleanim (next) have two spawnargs: "blend_in" and "blend_out". Only "blend_in" is actually used, and it affects only the torso. This blends the animation of joints in effect when reaching the node, with that given by the node. The integer value is the number of animation frames to be blended. The legs have a fixed regime: blend to the idle state over 4 frames, then synchronize to the torso of the new animation over 10 frames. | |||
To think of this in terms of time rather than frames, note that 25 frames per second is the usual play speed defined in the animation file. | |||
Tip by Springheel: Animation blending is minimalist, so AI often "snap" into position from walking to playing the animation. For a more natural look, add a path_wait of a few seconds first, so AI transition to their idle pose before playing the animation. | |||
When the animation (or animation cycle) is complete, the torso and legs blend to the idle state over 5 frames, then the AI addresses the next node in the path. | |||
== path_cycleanim == | |||
''by Geep'' | |||
This is used to endlessly play an animation - one designed for cycling - for a specified amount of time or until the AI is triggered. It shares the "anim" and "angle" spawnargs with path_anim, as well as animation blending features. Note that there is no blending when the animation cycles back to the beginning. | |||
The AI stays in place at the node and loops for the number of seconds given by the 'wait' property. As elsewhere, you can optionally define 'wait_max' with a value greater than 'wait', to give a randomized time from 'wait' to 'max_wait'. The looping may be interrupted and stopped early by triggering the AI, using an external mechanism, e.g., a timer. | |||
== path_lookat == | == path_lookat == | ||
Line 143: | Line 162: | ||
== path_sit == | == 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. | This is a behaviour node that, following a path_corner, makes the AI sit down at its current location. See [[Sitting Behaviour for AI]] for more information. | ||
== path_waitfortrigger == | == path_waitfortrigger == | ||
Line 151: | Line 170: | ||
The "path_waitfortrigger" basically operates like a wall, blocking the AI from proceeding until triggered. | The "path_waitfortrigger" basically operates like a wall, blocking the AI from proceeding until triggered. | ||
IMPORTANT: It is the AI that is the target of the trigger, '''not''' the path_waitfortrigger node. | |||
''Example.'' Let's say you want an AI to stand somewhere until a player triggers him, then you want him to walk to path_corner 1. | |||
1. Make a "path_waitfortrigger" pathnode, and have it target "path_corner_1". | 1. Make a "path_waitfortrigger" pathnode, and have it target "path_corner_1". | ||
Line 159: | Line 180: | ||
3. Create a trigger_once entity, and target the AI. | 3. Create a trigger_once entity, and target the AI. | ||
The AI will stand where they are at map start and behave as if there are no pathnodes set ( | The AI will stand where they are at map start and behave as if there are no pathnodes set (i.e., he plays idle animations and can be alerted). When the player goes through the trigger, the "path_waitfortrigger" is cleared and the AI will proceed to path_corner_1. | ||
See also use of this node in the "Making an AI Start a Path after Teleporting" section of [[Teleporting entities]]. | |||
== path_interact == | == path_interact == | ||
Line 170: | Line 193: | ||
target <next path entity (if any)> | target <next path entity (if any)> | ||
== path_hide == | |||
''path_hide, path_show, path_attack are as tentatively described here by Springheel and Fidcal without testing.'' | |||
Supposedly deactivates and stops rendering the AI. It turns out this doesn't work well with TDM...makes AI invisible but they still talk and occupy space. Better to teleport away (see [[Teleporting entities]]). To remove an AI from the map permanently, try grayman's method described further below. | |||
== 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, presumably for scripted sequences. Specifically, the AI will attack the character specified by the 'enemy' key. The AI will go to next path when the enemy dies or when activated. | |||
== path_flee_point == | |||
These are special purpose and discussed below under '''Flee Points'''. | |||
== path_follow_actor == | |||
''Added in 2024, as of TDM 2.12'' | |||
This tells the AI that targets this path to follow the actor (either another AI or the player) targetted by this path. The method used for setup depends on the choice of actor. | |||
=== Other AI as Actor === | |||
If you want an AI to follow another AI, you can do the following directly in DarkRadiant: | |||
# Create a leader AI and a follower AI | |||
# Create a path_follow_actor node | |||
# Make the 'follower' AI target the path_follow_actor node (either directly or indirectly at the end of a path node chain) | |||
# Make the path_follow_actor node target the 'leader' | |||
# When the follower AI gets to the path_follow_actor node, it will start following the leader AI. | |||
=== Player as Actor === | |||
If you wish an AI to follow the player, you cannot directly target the player entity. The following methods '''DO NOT''' work: | |||
* Making the path_follow_actor node target the player_start entity. This is because the player_start entity and the player entity in the game (player1) are not the same entity. | |||
* Manually adding a target spawnarg on the path_follow_actor node with the value 'player1'. This is because the path_follow_actor node is initialized before the player1 entity and any targets will end up empty. | |||
Instead, you must target the player entity at runtime. The following methods work: | |||
==== Using a script ==== | |||
Add the following to your <mapname>.script: | |||
void main() | |||
{ | |||
sys.waitFrame(); | |||
$path_follow_actor_1.addTarget($player1); | |||
} | |||
==== Using atdm:target_changetarget ==== | |||
You can use a atdm:target_changetarget entity to dynamically target the player entity from the path_follow_actor node: | |||
# Create a atdm:target_changetarget entity. Set the spawnarg 'add' with value 'player1' | |||
# Create a path_follow_actor entity | |||
# Make the atdm:target_changetarget entity target the path_follow_actor entity | |||
# Use any combination of path nodes to lead up to and target the path_follow_actor node | |||
That will add the required target to the path_follow_actor node. You will then want to set something up to trigger the atdm:target_changetarget entity. Examples of entities that could target the atdm:target_changetarget entity: | |||
* a path_corner node so it triggers when an AI reaches a certain point | |||
* a trigger entity | |||
* a door opening | |||
'''IMPORTANT''': The atdm:target_changetarget entity must be triggered BEFORE the AI reaches the path_follow_actor node or it won't work. The AI will just stand there and do nothing. | |||
= How to Make AI do Random Interesting Things (RIT) = | = How to Make AI do Random Interesting Things (RIT) = | ||
Line 198: | Line 280: | ||
= Switching from | = Switching from One Path Network to Another = | ||
== When Reaching a Path Node == | |||
Suppose you want to have an AI patrol outside a mansion for the first part of a mission, and then change his route to patrol in another location later? | Suppose you want to have an AI patrol outside a mansion for the first part of a mission, and then change his route to patrol in another location later? | ||
Line 216: | Line 299: | ||
'''Other ideas:''' | '''Other ideas:''' | ||
'''Doormen'''-- An AI (or the player) walks up to the door and knocks on it. AI inside is triggered to walk over to the door and open it, then go back to his regular duties. | * '''Doormen'''-- An AI (or the player) walks up to the door and knocks on it. AI inside is triggered to walk over to the door and open it, then go back to his regular duties. | ||
* '''Abandon ship!''' -- When triggered, all AI drop what they're doing and start running for the exits. | |||
* '''Lights out!''' -- At a specific time, all AI stop what they're doing and walk to their beds to go to sleep. | |||
* '''Re-use, recycle''' -- AI that are stuck back in a portion of the map the player won't be coming back to could be told to walk to a new portion of the map and assume some job there. | |||
* '''It's a trap!''' -- Player walks down a hall and hits a trigger that causes AI to quickly position themselves at the only exits. | |||
== Switching Immediately (TDM 2.08+) == | |||
''by Geep 2021, from [https://bugs.thedarkmod.com/view.php?id=5056 grayman]'' | |||
As discussed above, you can re-route an AI to a new path by changing a target on an upcoming path node. But the AI won't make the path change until hitting the path node that was changed. Alternatively, as of TDM 2.08, you can immediately stop the current patrol and switch the AI to a new path, by scripting with the AI event "stopPatrol", e.g.: | |||
$Robert.stopPatrol(); | |||
This stops Robert wherever he is, and he'll wait for subsequent commands to put him on his new path. For example, to immediately put Robert on his new path, use this in your script file: | |||
$Robert.stopPatrol(); | |||
sys.trigger($ChangeRobertsPatrol); | |||
where ChangeRobertsPatrol is an atdm:target_changetarget with spawnargs such as: | |||
"add" "path_corner_my_new_path" | |||
"target" "Robert" | |||
As usual, if you want Robert to run instead of walk to his new path, "path_corner_my_new_path" should have this set: | |||
"run" "1" | |||
If you want Robert to unsheathe his weapon while he runs to his new path, and patrol his new path with his weapon out, do this: | |||
$Robert.stopPatrol(); | |||
$Robert.setAlertLevel(1.6); | |||
sys.trigger($ChangeRobertsPatrol); | |||
$Robert.setKey("alert_idle", "1"); | |||
Robert is put into the Observant state by setAlertLevel(1.6). From there, at some point he'll drop back into Idle State, where a decision is made based on "I saw evidence of an intruder" as to whether to unsheathe the weapon or not. That evidence will be then forced by using Robert.setKey("alert_idle", "1"). | |||
= Flee Points = | = Flee Points = | ||
''updated by Geep, based mostly on [https://bugs.thedarkmod.com/view.php?id=3548 grayman's bugtracker entry 3548] and related Flee Points forum thread'' | |||
AI, e.g., civilians, will automatically flee if in danger. By default, they will flee to the furthest from danger they can reach by AAS pathfinding. Since this will not always result in believable behavior, you can provide "flee point" alternatives. | |||
Do NOT target the AI to a flee point; Just make available '''path_flee_point''' entities at suitable places where you would like your AI to flee to. | |||
An AI that is fleeing from you can be chased from one flee point to another. Conversely, once fled, when enough time elapses without further danger, the AI may return, unless you arrange otherwise (through teleport or removal). | |||
===Spawnargs=== | |||
These are optional but usually set: | |||
team ''<number>'' | |||
is_guarded 1 | |||
These influence where a fleeing AI goes. A flee point with "is_guarded 1" is considered ''Guarded''. But, of course, it is up to the mapper to actually provide a guard there; and a loitering guard will typically run towards the source of danger, rather than staying fixed near, say, a flee point. | |||
===Where the Fleeing AI Tries to Run=== | |||
Let's define here some further categorization, comparing the team of the fleeing AI with that set on any given flee point: | |||
* ''Friends''. Either the ''same'' team or one that is "friendly" (see [[AI Relations (Editing)]]) | |||
* ''Indifferent''. Either a team that is "neutral", or no "team" spawnarg given on the flee point | |||
* ''Hostile''. Otherwise. | |||
As of TDM 2.03, the AI will seek the existence of an accessible flee point in this order: | |||
# Guarded and Friends | |||
# Friends | |||
# Guarded and Indifferent | |||
# Indifferent | |||
If no such flee point is found, a spot as far away as possible (i.e., within the AAS area) is sought. | |||
With these constraints: | |||
* If there are multiple accessible flee points of the same priority group, prefer the nearest. | |||
* Avoid fleeing to any location where there are armed hostile AI. | |||
* If the fleeing AI is allowed to use elevators generally, it can also use them to flee. | |||
For reference, the wiki description of the pre-TDM-2.03 flee-choice algorithm is also provided (see button right). | |||
<div class="mw-collapsible mw-collapsed" data-expandtext="Show" data-collapsetext="Hide"> | |||
This is how the code works: | This is how the code works: | ||
Line 247: | Line 385: | ||
A problem occurs when the AI doesn't find any appropriate flee points but also no AAS area that is far away enough from the enemy. In this case, he will just stand there. Maybe he should either cower and be afraid in this case or just run around like a mad chicken? | A problem occurs when the AI doesn't find any appropriate flee points but also no AAS area that is far away enough from the enemy. In this case, he will just stand there. Maybe he should either cower and be afraid in this case or just run around like a mad chicken? | ||
</div> | |||
===When will a Civilian or Unarmed AI Flee?=== | |||
''Geep: summarized mostly from [https://bugs.thedarkmod.com/view.php?id=3317 here] and [https://forums.thedarkmod.com/index.php?/topic/14471-ai-dont-care-about-violent-deaths/&do=findComment&comment=305947 here].'' | |||
= | |||
An AI will perceive danger and flee: | |||
* upon spotting an enemy (e.g., the player), either | |||
** immediately, or | |||
** after becoming suspicious and searching | |||
* upon being attacked (e.g., by surprise but inconclusively) | |||
* upon hearing a warning bark from another friendly AI | |||
* if witness to a murder or KO of a friend or neutral (not necessarily seeing the attacker) | |||
* if finding a friend's body that was murdered or KO'd | |||
* if finding a body of a neutral that was murdered or KO'd | |||
** within 4 seconds of the murder/KO, or | |||
** later, with 50% flee probability, 50% ignore. | |||
===When will an Armed AI Flee?=== | |||
An Armed AI in a dangerous situation will flee if its health points drop to a certain level, as determined by its health_critical spawnarg. | |||
== | ===Kneeling and Barks=== | ||
If a civilian or unarmed AI finds a body (without witnessing the attack), there's a 50% chance it will kneel to inspect it. | |||
A fleeing AI will bark a warning, that varies on circumstances. A cry for help alerts other AI and conveys the last alert position. Consequently, armed guard would go to investigate to the right place whereas another civilian might also flee away from it. | |||
= Removing an AI from the Game = | |||
''method by grayman'' | |||
Suppose you want to get rid of an AI permanently at a certain place, e.g., near the end of its path, or a flee point. Here's how. | |||
* Create a '''func_remove''' with spawnarg: | |||
"target" "<AI's name>" | "target" "<AI's name>" | ||
* At the point where disappearance is desired, place a '''trigger_once_entityname''' with spawnargs: | |||
"entityname" "<AI's name>" | "entityname" "<AI's name>" | ||
"target" "<func_remove's name>" | "target" "<func_remove's name>" | ||
When the AI walks through the | When the AI walks through the '''trigger_once_entityname''', it recognizes that AI and triggers the '''func_remove''', taking the AI out of the game. | ||
''Springheel notes you can wrap the AI's final path corner in a trigger_once_entityname. If you forget the entityname spawnarg, the game will error out and tell you it's missing.'' | |||
{{tutorial-editing}} | {{tutorial-editing}} | ||
[[Category:AI]] | |||
[[Category:AI Tutorials]] |
Latest revision as of 15:07, 11 May 2024
originally written by Springheel
For more information on pathfinding, see Pathfinding. For pathfinding after teleport, see Teleporting entities. For more general info on getting your AI to patrol, see AI Patrol.
What are Path Nodes?
Path entities (or path nodes) are the things that you use to make your AI move (patrol) 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, path_wait, 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 a coloured box with an arrow in the editor (colour varies depending on config.)
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 path node 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 a colored 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
Variation and Randomness
It is also possible to target multiple nodes (using "target1", "target2" 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. The chances at any point must not add to greater than 1, or it won't work properly. For example, if a path_corner targets two different nodes, you could set "chance" ".75" on one and "chance" ".25" on the other. This will result in AI choosing the first path 3/4 of the time.
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). (for info on how to use Objectives to alter paths, see Objectives#Using_Objectives_Creatively)
Note that if an AI reaches a node that targets pathnodes that are unavailable (because they are idle_only, and the AI is alert, for example), the AI will stop and no longer proceed.
Positional Tolerance
A node whose placement defines a specific location for the AI to walk to (currently the only type like this is the path_corner) can have an "move_to_position_tolerance" spawnarg. This defines how close the AI has to be to the destination point (in the X/Y plane) to consider 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. Smaller numbers mean the AI must get closer, larger numbers are more forgiving.
The following is likely true:
- Negative values of move_to_position_tolerance means the standard bounding box will be used.
- The default value is -1.
- While move_to_position_tolerance can be set on other entities, it won't necessarily do anything.
- If set on levers or buttons, it may affect AIs moving towards them.
- The positional tolerance in the z direction is determined by the AI, not a node spawnarg. (Specifically, spawnarg "aas_reachability_z_tolerance" used in the *.def file. The default is 75 for humanoid AI. This value is applied differently depending on whether the target is above or below the AI.)
Triggering
These path nodes will trigger their targets when AI 'use' them (as of TDM v2.02):
- path_corner - triggers targets when node is reached
- path_turn - triggers targets when turn is done
- path_wait - triggers targets when wait is over
- path_sit - triggers targets when sitting anim is done, including any final turn
- path_sleep - triggers targets when lying down anim is done
- path_anim - triggers targets when anim is done
Kinds of Path Nodes
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_corners 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; TDM will randomly choose between the targeted nodes. Use the following syntax:
target path_corner_1 target2 path_corner_2
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.
Extra note: To make an AI run on patrol add the property/value : "run" "1" to a path_corner on the AI's patrol and the AI will run to it (then resume walking after it if the next path_corner does not have that property set.)
Note that an AI will continue on to their next path_corner after a failed search. If you do not have at least one path_corner, the AI will return to its original position when their search is complete.
Also note that if the AI is going to stop at a path_corner--perhaps to wait a spell--the path_corner origin should be kept at least 16 horizontal units away from monsterclip and worldspawn brushes. Otherwise, the stopping animation might not look right.
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. Important: If the angle is 0 make sure it is actually on the entity and not just default.
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
(edit: I'm not sure why this node is useful, since path_wait can do the same thing. grayman: yes, it's useful for turning the AI to the correct angle when preparing to lie down or sit down, which doesn't necessarily involve a path_wait.)
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.)
Adding a "wait" spawnarg to this node doesn't seem to do anything.
path_anim
This is a behaviour node that makes the AI play an animation, once, at the node's location. When that animation is done, the AI 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. Other possibilities include peering through a window, picking a carrot off a table and eating it, or running to a spot and cowering.
The proper syntax is:
anim [animation name]
You can see the list of animations names here: Animation List. 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. This value appears to be necessary to make the animation work.
Animation Blending
by Geep
path_anim and path_cycleanim (next) have two spawnargs: "blend_in" and "blend_out". Only "blend_in" is actually used, and it affects only the torso. This blends the animation of joints in effect when reaching the node, with that given by the node. The integer value is the number of animation frames to be blended. The legs have a fixed regime: blend to the idle state over 4 frames, then synchronize to the torso of the new animation over 10 frames.
To think of this in terms of time rather than frames, note that 25 frames per second is the usual play speed defined in the animation file.
Tip by Springheel: Animation blending is minimalist, so AI often "snap" into position from walking to playing the animation. For a more natural look, add a path_wait of a few seconds first, so AI transition to their idle pose before playing the animation.
When the animation (or animation cycle) is complete, the torso and legs blend to the idle state over 5 frames, then the AI addresses the next node in the path.
path_cycleanim
by Geep
This is used to endlessly play an animation - one designed for cycling - for a specified amount of time or until the AI is triggered. It shares the "anim" and "angle" spawnargs with path_anim, as well as animation blending features. Note that there is no blending when the animation cycles back to the beginning.
The AI stays in place at the node and loops for the number of seconds given by the 'wait' property. As elsewhere, you can optionally define 'wait_max' with a value greater than 'wait', to give a randomized time from 'wait' to 'max_wait'. The looping may be interrupted and stopped early by triggering the AI, using an external mechanism, e.g., a timer.
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. Note the focus entity must not be obscured by monsterclip.
path_sit
This is a behaviour node that, following a path_corner, makes the AI sit down at its current location. See Sitting Behaviour for AI for more information.
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.
The "path_waitfortrigger" basically operates like a wall, blocking the AI from proceeding until triggered.
IMPORTANT: It is the AI that is the target of the trigger, not the path_waitfortrigger node.
Example. Let's say you want an AI to stand somewhere until a player triggers him, then you want him to walk to path_corner 1.
1. Make a "path_waitfortrigger" pathnode, and have it target "path_corner_1".
2. Have the AI target the "path_waitfortrigger" pathnode.
3. Create a trigger_once entity, and target the AI.
The AI will stand where they are at map start and behave as if there are no pathnodes set (i.e., he plays idle animations and can be alerted). When the player goes through the trigger, the "path_waitfortrigger" is cleared and the AI will proceed to path_corner_1.
See also use of this node in the "Making an AI Start a Path after Teleporting" section of Teleporting entities.
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. However, this could be used to make AI turn on lightswitches, open mechanical doors, etc.
You need to add these spawnargs to the path_interact entity:
ent <name of entity to be frobbed by AI>
target <next path entity (if any)>
path_hide
path_hide, path_show, path_attack are as tentatively described here by Springheel and Fidcal without testing.
Supposedly deactivates and stops rendering the AI. It turns out this doesn't work well with TDM...makes AI invisible but they still talk and occupy space. Better to teleport away (see Teleporting entities). To remove an AI from the map permanently, try grayman's method described further below.
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, presumably for scripted sequences. Specifically, the AI will attack the character specified by the 'enemy' key. The AI will go to next path when the enemy dies or when activated.
path_flee_point
These are special purpose and discussed below under Flee Points.
path_follow_actor
Added in 2024, as of TDM 2.12
This tells the AI that targets this path to follow the actor (either another AI or the player) targetted by this path. The method used for setup depends on the choice of actor.
Other AI as Actor
If you want an AI to follow another AI, you can do the following directly in DarkRadiant:
- Create a leader AI and a follower AI
- Create a path_follow_actor node
- Make the 'follower' AI target the path_follow_actor node (either directly or indirectly at the end of a path node chain)
- Make the path_follow_actor node target the 'leader'
- When the follower AI gets to the path_follow_actor node, it will start following the leader AI.
Player as Actor
If you wish an AI to follow the player, you cannot directly target the player entity. The following methods DO NOT work:
- Making the path_follow_actor node target the player_start entity. This is because the player_start entity and the player entity in the game (player1) are not the same entity.
- Manually adding a target spawnarg on the path_follow_actor node with the value 'player1'. This is because the path_follow_actor node is initialized before the player1 entity and any targets will end up empty.
Instead, you must target the player entity at runtime. The following methods work:
Using a script
Add the following to your <mapname>.script:
void main() { sys.waitFrame(); $path_follow_actor_1.addTarget($player1); }
Using atdm:target_changetarget
You can use a atdm:target_changetarget entity to dynamically target the player entity from the path_follow_actor node:
- Create a atdm:target_changetarget entity. Set the spawnarg 'add' with value 'player1'
- Create a path_follow_actor entity
- Make the atdm:target_changetarget entity target the path_follow_actor entity
- Use any combination of path nodes to lead up to and target the path_follow_actor node
That will add the required target to the path_follow_actor node. You will then want to set something up to trigger the atdm:target_changetarget entity. Examples of entities that could target the atdm:target_changetarget entity:
- a path_corner node so it triggers when an AI reaches a certain point
- a trigger entity
- a door opening
IMPORTANT: The atdm:target_changetarget entity must be triggered BEFORE the AI reaches the path_follow_actor node or it won't work. The AI will just stand there and do nothing.
How to Make AI do Random Interesting Things (RIT)
by Sotha
You can use the above to make individual AI seem to do Random Interesting Things (RIT) when entering a room. Note that it will work with basic dendritic AI, so you could have multiple AI's running in several rooms doing things.
1) Build a room with RITs. A statue. A few chairs. Maybe a lit fireplace.
2) On each RIT place the necessary interaction path_nodes to make an AI interact with them: path_corner to walk over to them; path_sit on each of the chairs, path_anims for warming hands at the fireplace and standing in front of the statue and pondering, etc (A, B & C in image).
3) Place two path_waits (1 & 2 in image) on the ceiling of the room. (They could be anywhere in the room, but it is easiest to manage if they are in the ceiling.)
4) Name one of the path_waits "enter_room_decide_what_to_do." (1) From that path_wait target each of the RIT path_corners. Set the path_wait "wait 0". so AI won't stop there. The idea is to use the path_wait as a simple decision making node. Be sure that the path_wait has no angle-spawnarg. If it does, the AI will turn towards the angle each time he targets the node.
5) Name the other path_wait "exit_room_decide_what_to_do." (2) Make each RIT final path_node target this path_wait. Make the path_wait target other rooms with similar decision making path_waits.
6) Done.
AI will come into the room, select A, B or C at random, and then leave. Next time they enter, they'll again pick at random.
This could be used to make servants to run around a mansion, cleaning, making food, taking sitting breaks, visit the toilet, etc. You could build room decision making network separately for different AI. Servants clean, cook and take breaks. Guards patrol, make random deviations once in a while, and of course take breaks. Controlling the RIT path_corner chance-spawnarg gives you control what RITs the AI do more likely.
Please see the dedicated RIT network article for more details. RIT Networks
Switching from One Path Network to Another
When Reaching a Path Node
Suppose you want to have an AI patrol outside a mansion for the first part of a mission, and then change his route to patrol in another location later?
It is possible to change the "target" property on a path_corner by using atdm:target_changetarget.
Target the atdm:target_changetarget entity at the pathnode you wish to alter. Use the following spawnargs:
"add" "[new path_corner]" and/or "remove" "[old path_corner]"
Then add a trigger that targets the atdm:target_changetarget.
When triggered, the new path_corner will be added and the old removed, sending the AI to a new path network. This no doubt has vast potential for variation and creativity that has yet to be explored. One simple example would be a "changing of the guard" moment, where some guards leave their posts and go to their barracks to sleep, while others take over for them.
Other ideas:
- Doormen-- An AI (or the player) walks up to the door and knocks on it. AI inside is triggered to walk over to the door and open it, then go back to his regular duties.
- Abandon ship! -- When triggered, all AI drop what they're doing and start running for the exits.
- Lights out! -- At a specific time, all AI stop what they're doing and walk to their beds to go to sleep.
- Re-use, recycle -- AI that are stuck back in a portion of the map the player won't be coming back to could be told to walk to a new portion of the map and assume some job there.
- It's a trap! -- Player walks down a hall and hits a trigger that causes AI to quickly position themselves at the only exits.
Switching Immediately (TDM 2.08+)
by Geep 2021, from grayman
As discussed above, you can re-route an AI to a new path by changing a target on an upcoming path node. But the AI won't make the path change until hitting the path node that was changed. Alternatively, as of TDM 2.08, you can immediately stop the current patrol and switch the AI to a new path, by scripting with the AI event "stopPatrol", e.g.:
$Robert.stopPatrol();
This stops Robert wherever he is, and he'll wait for subsequent commands to put him on his new path. For example, to immediately put Robert on his new path, use this in your script file:
$Robert.stopPatrol(); sys.trigger($ChangeRobertsPatrol);
where ChangeRobertsPatrol is an atdm:target_changetarget with spawnargs such as:
"add" "path_corner_my_new_path" "target" "Robert"
As usual, if you want Robert to run instead of walk to his new path, "path_corner_my_new_path" should have this set:
"run" "1"
If you want Robert to unsheathe his weapon while he runs to his new path, and patrol his new path with his weapon out, do this:
$Robert.stopPatrol(); $Robert.setAlertLevel(1.6); sys.trigger($ChangeRobertsPatrol); $Robert.setKey("alert_idle", "1");
Robert is put into the Observant state by setAlertLevel(1.6). From there, at some point he'll drop back into Idle State, where a decision is made based on "I saw evidence of an intruder" as to whether to unsheathe the weapon or not. That evidence will be then forced by using Robert.setKey("alert_idle", "1").
Flee Points
updated by Geep, based mostly on grayman's bugtracker entry 3548 and related Flee Points forum thread
AI, e.g., civilians, will automatically flee if in danger. By default, they will flee to the furthest from danger they can reach by AAS pathfinding. Since this will not always result in believable behavior, you can provide "flee point" alternatives.
Do NOT target the AI to a flee point; Just make available path_flee_point entities at suitable places where you would like your AI to flee to.
An AI that is fleeing from you can be chased from one flee point to another. Conversely, once fled, when enough time elapses without further danger, the AI may return, unless you arrange otherwise (through teleport or removal).
Spawnargs
These are optional but usually set:
team <number> is_guarded 1
These influence where a fleeing AI goes. A flee point with "is_guarded 1" is considered Guarded. But, of course, it is up to the mapper to actually provide a guard there; and a loitering guard will typically run towards the source of danger, rather than staying fixed near, say, a flee point.
Where the Fleeing AI Tries to Run
Let's define here some further categorization, comparing the team of the fleeing AI with that set on any given flee point:
- Friends. Either the same team or one that is "friendly" (see AI Relations (Editing))
- Indifferent. Either a team that is "neutral", or no "team" spawnarg given on the flee point
- Hostile. Otherwise.
As of TDM 2.03, the AI will seek the existence of an accessible flee point in this order:
- Guarded and Friends
- Friends
- Guarded and Indifferent
- Indifferent
If no such flee point is found, a spot as far away as possible (i.e., within the AAS area) is sought.
With these constraints:
- If there are multiple accessible flee points of the same priority group, prefer the nearest.
- Avoid fleeing to any location where there are armed hostile AI.
- If the fleeing AI is allowed to use elevators generally, it can also use them to flee.
For reference, the wiki description of the pre-TDM-2.03 flee-choice algorithm is also provided (see button right).
This is how the code works:
- The AI tries to determine the nearest friendly (their team specified) guarded flee point and flee to it.
- If there is no friendly guarded flee point, the AI tries to find the nearest friendly flee point (on friendly team) and run to it.
- If this also fails, the AI tries to find an AAS area far from the enemy and run there.
- If the enemy is still visible when the AI reaches his destination, he chooses the farthest friendly guarded flee point to run to,
- if this fails, the farthest friendly flee point,
- and if this also fails falls back to choosing an AAS area far from the enemy to run to.
- So neither the priority nor the target spawn arg have any function here, it is not possible to weight the flee points. The AI will choose one automatically.
A problem occurs when the AI doesn't find any appropriate flee points but also no AAS area that is far away enough from the enemy. In this case, he will just stand there. Maybe he should either cower and be afraid in this case or just run around like a mad chicken?
When will a Civilian or Unarmed AI Flee?
Geep: summarized mostly from here and here.
An AI will perceive danger and flee:
- upon spotting an enemy (e.g., the player), either
- immediately, or
- after becoming suspicious and searching
- upon being attacked (e.g., by surprise but inconclusively)
- upon hearing a warning bark from another friendly AI
- if witness to a murder or KO of a friend or neutral (not necessarily seeing the attacker)
- if finding a friend's body that was murdered or KO'd
- if finding a body of a neutral that was murdered or KO'd
- within 4 seconds of the murder/KO, or
- later, with 50% flee probability, 50% ignore.
When will an Armed AI Flee?
An Armed AI in a dangerous situation will flee if its health points drop to a certain level, as determined by its health_critical spawnarg.
Kneeling and Barks
If a civilian or unarmed AI finds a body (without witnessing the attack), there's a 50% chance it will kneel to inspect it.
A fleeing AI will bark a warning, that varies on circumstances. A cry for help alerts other AI and conveys the last alert position. Consequently, armed guard would go to investigate to the right place whereas another civilian might also flee away from it.
Removing an AI from the Game
method by grayman
Suppose you want to get rid of an AI permanently at a certain place, e.g., near the end of its path, or a flee point. Here's how.
- Create a func_remove with spawnarg:
"target" "<AI's name>"
- At the point where disappearance is desired, place a trigger_once_entityname with spawnargs:
"entityname" "<AI's name>" "target" "<func_remove's name>"
When the AI walks through the trigger_once_entityname, it recognizes that AI and triggers the func_remove, taking the AI out of the game.
Springheel notes you can wrap the AI's final path corner in a trigger_once_entityname. If you forget the entityname spawnarg, the game will error out and tell you it's missing.