Unreal Tournament 2003 AI for Level Designers
This document describes how to set up navigation networks in a level so that NPCs can efficiently navigate to any point in the level. It also describes AI actors and level issues specific to UT 2003. The intended audience is level designers.
Level designers place
PathNodes (a subclass of
in their levels on surfaces which NPCs can walk on, or in volumes which NPCs can
swim in. For PathNodes to connect, they should be less than 1000 Unreal units
PlayerStarts are also NavigationPoints, and they
perform the same navigation function. In addition,
are automatically placed at the location of every pickup in the level when
building paths (they are invisible, but you will be able to see path connections
to them). Having two NavigationPoints too close together (overlapping) can cause
AI problems and should be avoided. When placing PathNodes, the goal is to make
sure that every area of the level is covered by a PathNode or some other
NavigationPoint. An area is covered if an NPC could walk to some pathnode less
than 1000 units away completely unobstructed (i.e. without having to step around
After placing PathNodes, the level designer can build the connections between NavigationPoints by using the "Build AI Paths" option in the Build menu (or by doing a full rebuild). Once paths have been built, they can be seen in the various level view windows by using the "Show Paths" option under the View menu. Paths will be displayed as lines from one NavigationPoint to another. If NPCs can traverse the path in either direction, there will be two lines, with an arrowhead pointing in each direction. Otherwise, the line will show with an arrowhead in which direction the path can be traversed. Paths will be displayed in various colors, indicating important information about the path:
ForcedPathsarray of the source NavigationPoint (in the NavigationPoint properties sheet).
Even if the NPCs using the paths are small, it is always better to tweak the pathnode positions to make the connecting paths as wide as possible. NPCs will smoothly round corners, or strafe back and forth within a path, so larger paths will result in more natural looking movement.
Once a level has a large number of paths, it can take a while to rebuild all the paths. To tweak path placement, use the "Build changed paths" button in the build options menu. This will only rebuild paths between NavigationPoints which have been added, removed, or moved. Before saving and playing the level, however, a full path rebuild is required.
After building paths, a window may pop up in the editor with a list of pathing errors. Click on an error to take you to the offending NavigationPoint.
After the level is completely pathed and paths have been defined, use the 'Review Paths' option in the Tools menu. The following items are checked:
If a bot seems confused or is doing something funky, view it by using the ViewBot console command, and use the ShowAI console command to see what it's thinking and the path it is following. Each time you enter ViewBot, your view will switch to another bot in the level. You can also use ViewFlag to directly view flag carriers. To check navigation paths while in the level, use RememberSpot to mark a location. Then, using ShowDebug while viewing your own player will show you a continually updated path to the marked location.
An additional valuable tool for debugging/testing AI in your level is the console command SoakBots. After entering SoakBots in the UT console, any time a bot encounters a significant problem, the game is paused with the view shifted to looking at the bot, with debugging information about the bot's state displayed (including the error at the top). While this will catch many bot problems, it won't catch everything, so watching bots play is still vital.
Each PlayerStart has a TeamNumber option, which specifies what team can spawn at that start. TriggeredPlayerStarts toggle the PlayerStart bEnabled attribute whenever they are triggered. Also, whenever a player spawns at a playerstart, its event (if any) is triggered.
UnrealScriptedSequence (subclass of Keypoint->AIScript->ScriptedSequence)
UnrealScriptedSequence is the subclass of ScriptedSequence that should be used for all UT2003 scripted sequences (typically used as defense points around bases). It contains several defense script related attributes:
By default, an UnrealScriptedSequence makes a bot go to its location, and look in the direction specified by its rotation. In most cases, this is all you need, and no changes to the default properties are needed (except for tagging the script properly to associate it with a GameObjective, such as a FlagBase).
However, defense scripts can
assign a variety of actions to bots, and be linked together like any scripted
sequence. Note that the amount of time bots pause at a script can
be modified by changing the PauseTime in the second action (if using the
Note that the amount of time bots pause at a script can be modified by changing the PauseTime in the second action (if using the default actions).
UnrealScriptedSequences that are not associated with any GameObjective are Freelance scripts. Bots with orders to freelance, or playing deathmatch, will wander between these scripts when they have nothing else to do. This works best if there are several in the map – it's better to have none than to have less than 5 freelance scripts.
Door NavigationPoints should be placed in conjunction
with any mover that acts as a door (based on its position, it allows or blocks
movement between two areas). The Door should be placed in the center of the
affected area (typically, in the middle of the actual static mesh used for the
door - but low enough to touch the ground). There are also several important
properties of a Door NavigationPoint that should be updated as needed:
DoorTag- the tag of the mover with which this Door is associated.
DoorTrigger- if the door is triggered, this is the tag of the trigger actor which will open the door.
bInitiallyClosed- whether the default state of the mover allows movement (if false), or prevents it (if true, the default value).
bBlockedWhenClosed- if the mover is closed, there is no way for the NPC to open it. (false by default)
Movers have a
bAutoDoor property. If set to true, a Door
pathnode is automatically generated for that mover. This should work for most
Level designers will place one xRedFlagBase actor, and one xBlueFlagBase actor in their level for CTF games. CTF bases have the following important AI attribute, that should be set:
Level designers will place one xDomPointA actor and one xDomPointB actor in their level for Double Domination games. Just like with CTF Bases, each domination point should have its DefenseScriptTags property set to match the UnrealScriptedSequences used as defense scripts for this point.
Level designers will place on xBombSpawn actor in the center of their level, and two xBombDelivery actors for Bombing Run games. Just like with CTF Bases, each bomb delivery point, or goal, should have its DefenseScriptTags property set to match the UnrealScriptedSequences used as defense scripts for this point. xBombDelivery actors also have a couple of other important attributes. The Team property needs to be set for each goal. The TouchDownDifficulty property is used to modify whether bots are more likely to shoot goals or try to jump through (higher values make bots more likely to shoot).
For bots to shoot goals from a distance, the level designer will need to set up ShootSpots to identify locations bots should shoot from. Use a BlueShootSpot to mark where red team bots should shoot at the blue goal, and RedShootSpots to mark where blue team bots should shoot at the red goal. You can have several shootspots for each goal.
AssaultPaths are used to specify alternate routes for squads of bots attacking an objective (for example a CTF Base). The following attributes are important for setting up basic assault paths:
When a squad of bots attack a base that has associated Assaultpaths, they will pick an assault path at random (weighted by their priorities), and run to that point before proceeding to the base. AssaultPaths should therefore be positioned so as to make bots use all the alternative ways into the base. For example, the red flag base might have three ways in, and an assaultpath in each of these paths. The attacking squad of blue bots will pick one of the three assault paths (weighted by their priorities, and ignoring any with bReturnOnly=true), and invade the base by running to that AssaultPath, and then proceeding to the red flag base. Once a blue bot grabs the red flag, he will exit the blue flag base by randomly picking one of the red flag base assault paths (weighted by their priorities, and ignoring any with bNoReturn=true), and running to it, and from there back to the blue flag base.
It is important to use bNoReturn to prevent bots from using unsuitable AssaultPaths for leaving the base (for example a path which you had to jump down into the base from, or one that requires the use of translocators).
Most level designers will not need to put together more complex configurations of assault paths, so this section is intended for advanced users only. These properties were almost never used in the levels shipped with UT, and may cause problems if not used correctly.
When an attacking squad of bots starts off toward the enemy base, it will choose an AssaultPath to use from among those which are first in all their paths, using the AssaultPath priorities to weight them. Only paths with a lower position than any other path which shares any of their PathTags will be considered as initial paths. AssaultPaths are also used as gather points for the squads, so they shouldn't be too out in the open. Once the squad has reached an AssaultPath, it will pick from among the paths specified in the PathTag array, and proceed to the next path (next higher position) which has that PathTag. If several share the same PathTag and same Position, one will be randomly chosen using their Priority as weights.
UTJumpPad is the UT2003 version of JumpPads. JumpPads will throw any pawn touching them in a specified direction. JumpPads are set up by specifying a destination pathnode in the first entry of the ForcedPaths array of the JumpPad. The appropriate jump velocity is automatically calculated when paths are rebuilt. The JumpZModifier property of the JumpPad can be set if for any reason the automatically generated velocity is problematic.
JumpSpot is the UT2003 version of JumpDest. JumpDests should be used instead of PathNodes at any spot that is too high to jump up to, but is linked to paths below it. JumpSpots will be used by NPCs in low gravity, or if they have some kind of jump boost. The path from which the bot should jump to the JumpSpot should have the JumpSpot in one of its ForcedPath array entries. Jumpspots should be used as the destination at the top of jumps. They should never be used on the "bottom" side of a jump, unless the fall is so great that the bot should translocate down rather than taking damage. Unnecessary jumpspots should be avoided, since they cost slightly more to evaluate for the navigation AI.
JumpSpots have the following important properties:
TranslocZOffset - Used to adjust the point bots aim at to translocate, to fix any translocation problems you might find.
To review and debug the jumpspots in your level, use the
ReviewJumpSpots console command. To use it, start the level, and type ReviewJumpSpots
at the console before hitting fire to start the game (and don't hit fire).
It will spawn a bot who tries to reach every jumpspot using the following modes:
- double jump
- jumping with Speed combo enabled and impact jump
- low gravity jump
You can watch the bot attempt the jumps, plus it will write to the log the details of any jump that failed.
Mover used as a lift should never use the
StandOpenTimed instead). Movers used as lifts
have two types of NavigationPoints associated with them. A
should be placed on the lift at its center. A
should be placed at each exit from the lift (but far enough away so that an NPC
standing there will not interfere with the lift). Both the LiftCenter and
LiftExits have a
LiftTag property which must be set to the
tag of the Mover. In addition, if the lift is triggered, put the tag of the
triggering actor in the
LiftTrigger property of the
LiftCenter. LiftExits also have an optional property,
which can be set to the keyframe number of the mover when the liftexit can be
used. This may improve navigation by NPCs in some situations.
LadderVolumes must be oriented to face the wall being
climbed (by adjusting their
WallDir property, which is
displayed as a directional arrow when the LadderVolume is selected). In most
cases, level designers can allow Ladder NavigationPoints to be automatically
added when paths are built, at the top and bottom of the LadderVolume. However,
if there are any problems with the automatically placed ladders, level designers
can manually place the ladders after setting the LadderVolume
to false. The Ladder centers must be within the LadderVolume. The LadderVolume
should touch the floor at its bottom, and poke over the edge at the top by at
least the height of the largest NPC using the ladder.