|
|
|


 (Unreal Tournament) AI & Gameplay for Level
Designers 
AI & Gameplay for
Level Designers by Steven
Polge
Porting Unreal I maps to Unreal Tournament
Unreal I content is automatically replaced by Unreal
Tournament content if you run an Unreal I DM map with one of the Unreal
Tournament gametypes. However, we recommend that you manually replace
the Unreal I inventory items in your level with their UT equivalents and
release an updated version of the map. Otherwise, both the Unreal I and
UT versions will be loaded on the content, which will cause swapping on
clients with low amounts of memory.
The Navigation
Network
Creating the Navigation Network
Unreal Tournament bots use a system of waypoints to
navigate the level. Using waypoints allows UT to minimize the CPU
cycles used by the AI, and gives level designers maximum control
over how the AI navigates their levels.
These waypoints are
defined by placing actors which are subclassed from
NavigationPoint in the level. This includes actors such as
PlayerStarts and Teleporters which designers will
place to make their level playable. Certain NavigationPoints,
such as InventorySpots and WarpZoneMarkers are
automatically placed when the designer "defines"
the paths (described below). Other NavigationPoints are
intended for Unreal I style single player situations and are not
used at all in UT. These include AlarmPoints,
ButtonMarkers, PatrolPoints, QueenDests,
SpawnPoints, Transporters, and TriggerMarkers.
Once the level geometry is complete, the level designer
should fully map the level into the navigation network using
PathNodes. Place PathNodes at intersections and turns
so that there is as much clearance as possible from corners (at
least 50 world units if possible). Paths need a line of sight to
each other, clear to the width of the maximum width (2 *
collisionradius) of creatures which will use this path.
PathNodes should not be placed more than 700 units apart.
Since PlayerStarts and Inventory will be placed on the
navigation network, the designer can (and should) not place
PathNodes where these other NavigationPoints can
substitute. On stairs and ramps, the PathNodes should only be
350 units apart. The objective should be to use a minimum number of
PathNodes to completely cover a level.
To navigate
around the level, bots will first find the nearest reachable
NavigationPoint, and move to it. They will then move toward
their destination, going from NavigationPoint to
NavigationPoint. It is important that some
NavigationPoint is reachable (there are no obstructions in
the way) from any location a bot may reasonably get to in the level.
If a bot can't find a valid path, either because it can't find a way
to get on the network, or there is no valid way to get from the
network to its destination, or the path on the network is broken,
then the bot will wander (walking) around its current area.
The final step in setting up the navigation network is
performing a PATHS DEFINE. This can
be done by typing PATHS DEFINE into the UnrealEd console, or
pressing the "Paths Define" button in the lighting section of the
rebuild window. The designer can examine the network generated in
any of the UnrealEd world view windows by selecting "Show Paths"
from that window's "View" menu. NavigationPoints which are
successfully connected will have either blue or red lines between
them. Bots will use either blue or red paths, but blue paths are
preferable - they indicate a cleaner, more obstruction free path.
Each time geometry is changed or NavigationPoints are added
or moved (including inventory, since paths are generated from
inventory items), a PATHS DEFINE should be performed.
There are several common problems that result from
assumptions and approximations made by the AI to minimize CPU
overhead. Make sure that all NavigationPoints are separated
by at least 50 world units. If two pathnodes are too close together,
a bot may get stuck on them. The editor log window will display
warnings during a PATHS DEFINE if paths are too close
together. This problem commonly occurs with InventorySpots,
which are automatically placed near all inventory items. Don't place
PathNodes too near to inventory.
In some situations,
bots may get stuck on the edge of a ledge where it runs into a wall.
This occurs because of a threshold problem. Bots won't jump off
ledges until the angle of their destination is greater than 45
degrees from the ledge direction. If they run into a wall right
around this threshold, they may get confused. The solution is to
adjust the NavigationPoint they were trying to reach, or add
an intermediate PathNode.
Bots will have problems if
the NavigationPoints are too high off the ground. Make sure
that the NavigationPoint is no more than 1.5x the bot's
CollisionHeight off the ground. This will normally be the
case automatically, but in a few situations (such as very steep
ramps), the level designer may need to manually adjust the Z
position of the NavigationPoint.
PathNodes for
the bots to use while swimming must be in the water. Placing
paths above the water's surface will result in bots bobbing at that
spot, attempting unsuccessfully to levitate to the PathNode's
location.
WarpZones should be at least 70 units deep
to allow the AI to handle them properly. Adding Support
for Lifts
There are two special NavigationPoint classes
used to help bots understand how to use lifts, LiftCenters
and LiftExits. Give the lift a unique Tag. Place a
LiftCenter on the lift, and set its LiftTag attribute
to be the tag of the lift. At each exit from the lift, far enough
away so that bots standing at that spot won't interfere with the
lift, add a LiftExit. Each LiftExit should have its
LiftTag set to the tag of the lift.
The default state
for movers is BumpOpenTimed. Do not use this
state for lifts! Bots misinterpret movers that are
BumpOpenTimed as being doors. Instead, use the
StandOpenTimed state for most lifts. Bots will also
understand triggered lifts (TriggerOpenTimed,
TriggerToggle, etc.). In many cases, they will use triggered
lifts without any further help. However, for certain complex
situations, such as when a delayed dispatcher is used to control the
lift, bots may need a hint. In these cases, set the
LiftCenter's LiftTrigger attribute to the Tag
of the trigger the bot should use to control this lift.
There are two other configurable LiftCenter
attributes of interest. These should be modified only if absolutely
necessary. MaxZDiffAdd, which defaults to 0, specifies an
additional allowable difference in height between the bot and the
LiftCenter for the bot to consider that LiftCenter
reachable. This is useful if the bot must stand below the lift (down
stairs or a ramp) while waiting for it. MaxDist2D is the
maximum distance between the bot and the LiftCenter. It
defaults to 400 world units. NavigationPoint
Attributes
The only configurable NavigationPoint attribute
that should be modified is bOneWayPath. bOneWayPath
can be set to true so that paths will only be valid in the direction
the NavigationPoint is facing. Turn on the
bDirectional attribute of the NavigationPoint to
adjust the direction it faces. Special Purpose
NavigationPoints
Several special purpose NavigationPoints exist to
provide tactical or game specific positions or to provide support
for special movement modes such as using translocators and
jumpboots. Game specific NavigationPoints will be described
in the section of this document devoted to that game type.
- PlayerStarts specify allowed spawning locations for
players and bots. There are two relevant configurable attributes
in PlayerStarts. The TeamNumber attribute specifies
which team is allowed to spawn at that PlayerStart in
teamgames where team specific PlayerStarts are enforced.
The bEnabled attribute, which is true by default, can be
toggled to enable or disable the PlayerStart by triggering
the PlayerStart.
- AmbushPoints are used to specify good camping spots.
They are directional and should be pointed in the direction the
bot should be looking while using that AmbushPoint.
AmbushPoints have two configurable attributes,
SightRadius and bSniping. SightRadius
specifies how far out the bot should be looking for enemies when
camped at the AmbushPoint. bSniping specifies that
bots using this AmbushPoint should stay at this point and
snipe after acquiring an enemy, rather than chasing after the
enemy.
- DefensePoints are a subclass of AmbushPoint used
in team games. DefensePoints have three additional
configurable attributes, Team, Priority, and
FortTag. The Team attribute specifies which team
should use this DefensePoint (0=Red, 1=Blue, 2=Green,
3=Gold). The Priority attribute is used in team games to
determine which DefensePoints will be manned first (higher
priorities are manned earlier). The FortTag attribute is
used in Assault games to associate a DefensePoint with a
particular FortStandard.
- BlockedPaths are used to keep bots from attempting to
follow routes which are initially blocked (such as a bridge which
must be lowered). . When triggered, the BlockedPath is
unblocked. Once unblocked, a BlockedPath cannot be
re-blocked. If using a BlockedPath, make sure that there
aren't any path connections which bypass the BlockedPath
and render it useless. AS-Mazon has some good examples of the use
of BlockedPaths.
- TranslocDests are a special type of LiftCenter
which are not associated with a mover. TranslocDests are
used to define places that bots can use a translocator to cut a
route short. A LiftExit should be placed at the spot where
the bot should stand a use his translocator, and a
TranslocDest should be placed where the Translocator Target
should be thrown. Another LiftExit should be placed near
the TranslocDest, as an "exit" from this "lift". The
LiftExits and the TranslocDest should be given the
same LiftTag.Bots will assume that any LiftExit with
the same LiftTag as a TranslocDest can be directly
reached from the TranslocDest, without any special action
on the bot's part. If the bot must use the translocator to get
from the TranslocDest to one of the LiftExits,
replace that LiftExit with a TranslocStart.
- JumpSpots are similar to TranslocDests, and are
also placed in conjunction with LiftExits all given the
same LiftTag. Bots understand that in low gravity areas, or
in JumpMatch, or if they have JumpBoots, they can
also jump to reach JumpSpots. In addition, if the
bImpactJump attribute of the JumpSpot is true,
higher skill bots will impact jump (using the impact hammer) to
reach the JumpSpot. If the bAlwaysAccel attribute is
true, bots will use air control to reach the JumpSpot (try
this only if they are failing without it).
- Teleporters send any pawn which touches them instantly
to their destination teleporter, as specified by their URL
attribute. If the URL attribute is empty, the teleporter acts only
as a teleporter destination. If it contains the same string as the
tag of another teleporter in the level, that teleporter will be
the destination. If it contains a string in the form of
LevelName/TeleporterName, it will teleport to a different level on
this server (single player only). If it contains a string in the
form of
Unreal://Server.domain.com/LevelName/TeleporterName, it
will teleport to a different server on the net.
If a
teleporter's bEnabled attribute is false, then it will not
teleport pawns which touch it, although it can still act as a
teleporter destination. The bEnabled attribute is toggled by
triggering the teleporter. If the bChangesYaw attribute is
true, pawns arriving at this teleporter will have their yaw changed
to the teleporter's yaw. If the bChangesVelocity attribute is
true, pawns arriving at this teleporter will have their velocity set
to the teleporter's TargetVelocity. Tweaking and
Debugging the Navigation Network
After placing and "defining" the navigation network, the
level designed should tweak and debug it by watching bots play the
level. The designer should the game as a spectator, and add first
one and then later several bots to the level. The designer can watch
them play, advancing through the bot cameras using the fire button,
and looking for problem areas. If the bot currently being viewed
seems to be acting strangely, using the console command "verbose"
will indicate what it is thinking. After the play session, reviewing
the log file may also provide insight to problems.
If the
bots don't seem to understand how to get to a certain destination,
the designer can use the "rememberspot" and "showpath" console
commands to look for breaks in the navigation network. When the
rememberspot command is used, the current location is saved.
Subsequent showpath commands will cause the best visible
NavigationPoint on the path to the remembered location to
become visible. If no NavigationPoint becomes visible, there
is no valid path to the remembered location.
If a player
cannot fit in the position specified by a PlayerStart, then
the player cannot properly enter the game and will either wander as
a spectator or the game will crash. The log file for that play
session will have information on which PlayerStart caused the
failure. UT Game Types
The Unreal Tournament team games require special actors to
be placed in the level.
Domination
Domination requires ControlPoints, which are a
type of NavigationPoint, to be placed at strategic locations
in the level. As with all NavigationPoints, these must not be
placed too close to another navigation point, and they must be
placed at ground level or bots will be confused by them.
ControlPoints have several editable attributes of
interest. When a player gains control of a ControlPoint (by
touching it), the optional event related to the player's team is
triggered. These events are specified by the RedEvent,
BlueEvent, GoldEvent, and GreenEvent
attributes. The bSelfDisplayed attribute specifies whether
the ControlPoint mesh (which depends on which team controls
it) is visible. The PointName attribute gives a human
readable name to the ControlPoint. The ControlSound
attribute specifies the sound to be played when control of the
ControlPoint changes. Capture the Flag
Capture the Flag requires FlagBases, which are a
type of NavigationPoint to specify the home location of the
flag for each CTF team. There can only be two CTF teams, and each
can only have one FlagBase. The team attribute of the
FlagBase specifies to which team the FlagBase is
associated, with 0=Red, and 1=Blue.
AlternatePaths
are used to indicate alternate routes that bots can use to enter an
opponent's base. The AlternatePath's team attribute should be
the same as the team of the FlagBase for which the
AlternatePath is pointing out a route. The
AlternatePath's SelectionWeight is used to modify the
likelihood of bots using that path. Bots use AlternatePaths
by first moving along the shortest route to the AlternatePath
they have chosen, and then moving along the shortest route from
their to the FlagBase. If the AlternatePath is set up
so that the shortest route to the AlternatePath involves
running right by the FlagBase, bots will do that (a bad
thing!). The location of AlternatePaths may need to be
adjusted to provide the desired results. AlternatePaths with
the bReturnOnly flag set true are used by bots with the same
team number returning to their base with a
flag. Assault
The FortStandard is used to define the objectives
in the Assault map. There can be multiple FortStandards in a
map. The bFinalFort attribute if true specifies that when the
FortStandard is destroyed, the level is completed even if
there are other FortStandards still active. The
DefensePriority attribute specifies the order in which the
FortStandards should be defended, with the highest
DefensePriority FortStandards defended first. The
NearestPathNodeTag attribute should always be used to provide
bots a hint about how to get to the FortStandard. Set it to
the tag of the nearest reachable PathNode. The optional
FallBackFort attribute specifies which fort defenders should
fallback to if the FortStandard is destroyed (set the
FallBackFort to the Tag of the desired
FortStandard). The bTriggerOnly attribute specifies
that the FortStandard should be triggered (using a trigger or
by touching it) rather than shot.
The bSelfDisplayed
attribute specifies that the FortStandard is visible (using
its mesh). This is typically turned off and the FortStandard
is displayed with level geometry. The bFlashing attribute
specifies that the FortStandard should flash when it is
damaged. The bSayDestroyed attribute specifies that bots
should announce when they have destroyed this FortStandard
(turn this off if the FortStandard marks a strategic
location, and not a visible objective). If the
DestroyedMessage is not empty, it will be displayed on
everyone's HUD when the FortStandard is destroyed. The
DamageEvent[] and DamageEventThreshold[] arrays are
used to specify events which occur when the FortStandard has
incurred specific amounts of damage.
The ChargeDist
and bForceRadius attributes are advanced AI tweaks used to
determine how aggressively bots will go after a FortStandard,
when they feel they don't have adequate backup.
One of the
FortStandards in the level should have the DefenseTime
attribute (the total time the base needs to be defended) set. Also,
one FortStandard should have the EndCamTag attribute
(the Tag of the SpectatorCam to use when the game
ends).
The TeamCannon can be placed in Assault levels
to support defenders. The MinigunCannon is a minigun version
of the TeamCannon.
Every Assault level must have an
AssaultInfo somewhere in it. The AssaultInfo contains
the text (in the ObjDesc[] array) and screenshots (in the
ObjShots[] array) which describe the objectives for the
level. The NumObjShots should be se to the number of
text/screenshot elements.
The AssaultRandomizer can
be used to force bot attackers to vary their entry routes randomly.
Place an AssaultRandomizer in a spot along the shortest path,
making sure there are no connections around it along that path. Set
the ToggledCost attribute to an appropriate value to increase
the distance cost of that path. The use a trigger to toggle the
AssaultRandomizer on and off as desired, causing the path to
appear longer or shorter. Never use a negative value for the
ToggledCost. The Level Info
The LevelInfo contains several properties which
should be set to describe the level, including the Title
string, the Author string, and the IdealPlayerCount
string. Import a screenshot and set it as the ScreenShot
texture.
RecommendedEnemies,
RecommendedTeammates, and the LevelEnterText are not
used.
The LevelInfo is the default ZoneInfo for
zones that don't have their own ZoneInfo. See the section on
ZoneInfos below. Trigger
The Trigger actor is used to trigger events. When a
Trigger is activated, it broadcasts its event to all other
actors in the level. Any actors whose Tag matches this event
will be triggered.
The TriggerType of a Trigger
specifies what situations will cause a trigger to activate. The
possible settings of TriggerType are:
- TT_PlayerProximity: Trigger is activated by player
(or bot) proximity.
- TT_PawnProximity: Trigger is activated by any
pawn's proximity.
- TT_ClassProximity: Trigger is activated by actor
of the class specified by the Trigger attribute
ClassProximityType.
- TT_AnyProximity: Trigger is activated by any actor
in proximity.
- TT_Shoot: Trigger is activated by player shooting
it. The optional DamageThreshold attribute specifies the
minimum damage required for triggering (instantaneous, not
cumulative).
The attribute ReTriggerDelay specifies
the minimum time before a trigger can be triggered again. The
bTriggerOnceOnly attribute, when true, specifies that the
trigger should only activated once and then go dormant.
There
are several possible states for the Trigger actor. The desired
state is set using the InitialState attribute (in the
Object section of the Trigger properties). The alternate
states are used for Trigger actors that are turned on or off by
other triggers, in conjunction with the bInitiallyActive
property. If bInitiallyActive is false, the Trigger will
be disabled initially. The possible states for the Trigger
actor are:
- NormalTrigger: Triggering the Trigger has no
effect.
- OtherTriggerToggles: When triggered, the Trigger
will toggle its bInitiallyActive property on and off.
- OtherTriggerTurnsOn: When triggered, the Trigger
will turn be come active.
- OtherTriggerTurnsOff: When triggered, the Trigger
will turn be come inactive.
RepeatTriggerTime, if set
to a value greater than zero, causes the trigger to send out its
Event at an interval of RepeatTriggerTime seconds while
the triggering actor remains within the trigger's radius.
Special Trigger Types
The TimedTrigger is not triggered by being
touched like other triggers. Rather, it triggers at a fixed interval
after the level starts, specified by its DelaySeconds
attribute. If its bRepeating attribute is true, the
TimedTrigger will continue to trigger at every
DelaySeconds interval.
The TeamTrigger is only
activated by pawns which do not belong to the team specified
by its Team attribute. Triggers
Classes which are subclassed from Triggers, but are
not subclassed from Trigger, are recipients rather than sources
of trigger events.
The SpecialEvent has several
possible states. The desired state is set using the
InitialState attribute (in the Object section of the
SpecialEvent properties).
- DisplayMessage: Just displays the message in the
Message attribute.
- DamageInstigator: Damages the instigator who triggered
this event. The Damage attribute specifies the amount of
damage. The DamageType and DamageString attributes are
also relevant for this state.
- KillInstigator: Kills the instigator, using the
DamageString for his death message if the DamageType
is SpecialDamage.
- PlaySoundEffect: Plays the sound specified by the
Sound attribute at the SpecialEvent's location.
- PlayersPlaySoundEffect: All players play this sound
effect at their location on the client side (so they hear it at full
volume).
- PlayAmbientSoundEffect: Places the SpecialEvent's
AmbientSound on the instigating player.
- PlayerPath: Sends the instigating actor on a spline path
through the level as specified by InterpolationPoints placed
in the level.
If the Message string is not empty, it
will be sent to the instigating player, unless bBroadcast is
true in which case it will be broadcast to all players. This will
happen in any SpecialEvent state.
TBD: TriggerLight, DistanceViewTrigger,
Kicker, Dispatcher,
Counter ZoneInfos
This section describes the attributes of ZoneInfos
which are relevant to gameplay. For more information on the importance
of properly zoning your level for rendering performance, review Unreal
Zones. Every zone can optionally include a ZoneInfo which
specifies special attributes of that zone. Zones with no
ZoneInfo in them use the LevelInfo's zone attributes.
There are several pre-defined ZoneInfo classes which
should be used when possible, including WaterZones,
LavaZones, and SlimeZones. The relevant attributes for
these ZoneInfo classes are already properly set. While any zone
can be filled with water simply by setting its bWaterZone
attribute to true, the zone will not have all the normal
characteristics of WaterZones, such as entry and exit splashes.
Several ZoneInfo attributes affect physics within the
zone. These include WaterGravity (for which only the Z
component is relevant), ZoneGroundFriction (used for walking),
ZoneFluidFriction (used for swimming in water zones),
ZoneVelocity (constant velocity added to moving actors in this
zone), ZoneTerminalVelocity (which specifies the maximum
falling velocity), and bWaterZone (which causes the zone to be
filled with water if true). If a zone has a ZoneVelocity, the
bMoveProjectiles attribute specifies whether this velocity
should be imparted to projectiles and effects. Zones with
bWaterZone true can also specify an EntrySound, an
ExitSound, an EntryActor (such as a splash effect), and
an ExitActor.
Zones can be set to damage actors that
enter them by setting the bPainZone attribute to true, and
specifying a DamagePerSec value and a DamageType.
Setting the bDestructive attribute to true will prevent
fragments and gibs from hanging around in the zone, while settingthe
bNoInventory attribute to true will prevent dropped inventory
items from hanging around in the zone. The actual damage inflicted on
a pawn depends on the DamagePerSec value and how much of the
pawn is immersed in the zone. If the DamageType is
SpecialDamage, then the DamageString will be used to
describe deaths.
Zones with bKillZone set to true will
instantly kill any pawn that enter them. Pawns will not take damage in
zones with bNeutralZone set to true.
The
ZonePlayerEvent is triggered whenever a player enters the zone.
The ZoneName (in the LocationStrings section of
the ZoneInfo properties) is used to identify the location of
teammates on the scoreboard or when giving orders to bots. In large
zones, a level designer can place LocationID actors in the zone
to provide a finer granularity of location descriptions. The
CollisionRadius of the LocationID (in world units)
determines the area in which the LocationID's
LocationName will supercede the zone's ZoneName.
The ZoneTag is used to tag a zone which is to be
triggered by a ZoneTrigger. WarpZones can be triggered
to sequence through an array of destinations specified in their
properties. Other zones will toggle the bPainZone attribute on and off
when triggered.
The ViewFog and ViewFlash
properties (in the ZoneLight section of the ZoneInfo
properties) allow the level designer to change the player's display
color/fogging while the player is in that zone. ViewFog is used
to color the screen. It is a vector whose components are RGB values
between 0 and 1.
As ViewFog increases the brightness of
the screen, ViewFlash should be used to keep it from
over-brightening. ViewFlash is a vector whose components should
be between 0 and -1 (for example (-0.5, -0.5, -0.5). It reduces the
brightness of the screen. Typically, all the components will have the
same value, which should have a magnitude about the same as the
average magnitude of the ViewFog components to keep the screen
from changing brightness.
Special Zone Types
When a player enters a TeleporterZone, he is
teleported by the associated teleporter (specified by the
TeleporterZone's TeleporterTag).
TBD: PressureZone, VacuumZone,
WarpZone AI Difficulty
Differences
Unreal Tournament has 8 AI skill levels, along with a
continuous range of intermediate skill levels. Skill levels 0 to 3 are
called "novice" skills, because bots at these skill levels move more
slowly than players and their weapons do less damage than player
weapons. Bots with skill levels between 4 and 7 move at the same speed
as players and their weapons do the same amount of damage.
Lower skill bots turn more slowly, and take longer to acquire
an opponent. They also have worse peripheral vision. Higher skill bots
have better aim, and do a better job of leading opponents. Higher
skill bots are also better able to strafe, or to move toward an
objective while firing at an enemy at the same time. Low skill bots
move much more slowly when strafing. Higher skill bots are less
disoriented when hit, and tend to fire their weapons faster (although
never faster than players can).
High skill (non-novice) bots
also understand the special moves with weapons, including the shock
rifle combo move, the sniper rifle headshot, and impact jumping with
the impact hammer. Back to the Documentation
Table
of Contents
|