Below you will find various pieces
of documentation rescued from the (now defunct) bot
epidemic site where the CGF mod called home. Whilst
these documents are of excellent quality, it should
be noted, that although LTKTBM shares many common factors
with this mod, it uses an entirely different structure
for handling much of the AI.
Weapon AI is a prime example,
LTKTBM not only has the capability to choose the best
current weapon, it can also select the best initial
weapon for individual maps, the data for which is obtained
by a learning algorithm not discussed here, the documentation
for which is not available in the public domain. These
documents are provided entirely for reference purposes,
and the views and theories belong entirely to their
author.
You can also view the cgf
grenade handling and terrain
pdf's by the same author.
This page is converted from the
origonal page.
CGF (AI) Weapon Handling
Last update: November 22,
2000, by William.
Tactical shooter games typically
are designed to provide a large arsenal of realistic weapons,
each with their subtle but important characteristics.
Some weapons are great for close combat, but are ineffective
at long range. Others have great accuracy when firing
in 3 round burst. Another type of weapon offers a telescope,
but reloads slowly. Some have large recoil. Others feature
large clips, etc.
The differences in weapons are that large and important
that FAQ's for these tactical shooters typically need
multiple pages of text to explain when (not) to use
a specific weapon.
Thus, it is probably non-trivial for the AI to handle
these weapons realistically and smart...
A number of 'open' 1st person shooters
has been modified (mod-ed) by talented members of the
gaming community to offer great and immersive realistic
multi-player shooters. These mods have been programmed
on top of (often) multi-player or (less often) single-player
game logic provided by game developers.
Characteristic for these games and their game logic
is:
- the original AI isn't too
smart, and doesn't bother to think about differences
as subtle as in realistic mods (because the original
game allows 'respawn')
- the weapon implementation
solely keeps track of events important to the player
(when to make sounds, what animation to display, etc.)
In other words, the information
available in the game logic (either if-statements for
Q2 based games, or weapon classes for HL based games),
was never designed to assist the AI in figuring out
how to handle a weapon realistically.
This page documents the weapon model that enables the
CGF AI to handle the weapons 'tactically'.
In realistic shooters, the gamer
(and preferably the AI):
- aims at a threat, and optionally
fires the weapon
- selects the best weapon for
the job
- selects the best weapon mode
for the job
(semi-automatic / full auto / zoom ...)
- reloads a weapon that is empty,
if possible
- preloads weapons that aren't
full (or prematurely reloads weapons that might become
empty soon)
- drops a weapon to pick up
a better one
The actor (gamer or AI) takes a
lot into account when deciding to fire, switch weapons,
switch mode, (p)reload, etc.:
- ammo available in weapon
- ammo clips carried by the
AI
- distance to threat
- obstacles (thin walls, water)
between AI and threat
- threat visible or predicted
- weapon usage ('spray-n-pray',
snipe, suppress, 'zoom-n-scan-n-snipe')
- weapon capabilities (silenced,
recoil, zoom, clip size)
- other weapons in AI's arsenal
- aim (reticule size, errors
due to being hit)
- threat's awareness of being
aimed on
- ...
This list clearly is too long
to be dealt with by a couple of 'if-statements'. (And
if that were possible, it would be a nightmare to add
a new weapon).
To record and be able to reason about these factors,
we'd better make them explicit in our design.
To reason about the use of weapons,
the AI has explicit representations of all the important
'objects':
- The AI character is an Actor,
who holds ammo clips, and carriers a number of weapons.
The Actor carries multiple Weapons,
but has only one of them in his hands (selected).
- The Weapon solely
represents the state of a weapon carried by the Actor:
the weapon holds some ammo, is in a mode, may be engaged
in a burst. The Weapon is of a specific WeaponType.
- The WeaponType super-class
defines the possible characteristics of WeaponType.
All Weapons of a WeaponType have a certain
fitness for some usage, feature the weapon modes,
and have ideal burst lengths.
There sub-classes of WeaponType that define
the exact properties and fitness for usage (as a virtual
function), for example:
- the Hand Gun, which
features single shot and automatic mode, and does
not provide any restrictions on the burst length,
since it doesn't have a significant recoil.
- the Assault Rifle,
which features 3 round bursts, automatic mode
and a 3xzoom, and has some recoil (so it suggests
a restricted burst length).
- the Squad Automatic
Weapon, which only has 'automatic' mode, and
a significant recoil. It therefor is best fired
in 5 round bursts.
- The Threat is a potential
target to aim for.
- Aiming isn't done instantaneously
and perfectly (that wouldn't be realistic). Instead,
the Actor's aim depends on how well he sees
the Threat, how long he has been looking at
the Threat, etc. And if the Threat is
hidden for just a moment by an obstacle, the Actor
typically aims for the position the Threat
will going to move to next, or the position the Threat
will re-appear.
Instead of going through giant if-statements,
weapon selection has become easier to write and understand:
Weapon
Actor::SelectBestWeapon(distance, usage)
{
bestweapon = 0;
bestscore = 0;
for each weapon carried
{
clips = inventory[weapon->GetAmmoType()];
rounds = weapon->GetAmmo();
score = weapon
->GetWeaponType()
->GetFitnessForUsage(usage,
distance,
rounds, clips);
if ( score > bestscore )
{
bestscore = score;
bestweapon = weapon;
}
}
return bestweapon;
}
The real gain is not so much in the simple weapon selection
algorithm, but in the fact that we can take care of
all the specific weapon's pecularities in its own WeaponType
function (a member function overriding the virtual member
function in WeaponType): float
SquadAutomaticWeapon::GetFitnessForUsage
(usage,distance,
rounds, clips)
{
// not useful for anything
// but suppression and direct fire
if ( !(usage & (eDirectFire | eSuppression)
)
return 0;
// fitness great for nearby
// less for long distance
float fitness;
if ( distance < 100 )
fitness = 1.0;
else
{
fitness = 100 / distance;
// correct for low on ammo
// since reloading is slow
if ( rounds < 10 )
fitness *= 0.75;
// if not much ammo in total
// reduce fitness some more
if ( (clips == 0) && (rounds < 50) )
fitness *= 0.75;
}
return fitness;
}
Note that the method deals in
a simple and structured way with detailed properties
of a 100 round belt-fed heavy machine gun. You don't
run the risk of affecting other weapon's properties
by changing it. This same format, of having
a dedicated method per weapon, allows you to take different
matters into account when defining the fitness for a
bolt-action sniper rifle.
The actual CGF for AQ2 code
deals with more factors, including weapon add-ons (silencer,
laser sight), weapon modes (3 round burst or full-auto,
zoom levels), and game round duration (early in the
game round, ammo conservation isn't that important).
The CGF WeaponType class
also implements a lot more weapon properties, such as
aiming preferences (hand guns cannot penetrate body
armor, and should be aimed for the head or legs, sniper
rifles aim for the largest portion of the body (torso),
assault rifles on full auto aim for the feet since the
muzzle will be kicked up, etc.).
This weapon model also enables simple
and understandable weapon handling code:
Weapon
Actor::HandleWeapon(threattracking)
{
if ( !threattracking)
{ // no threat, take care of the weapons
Weapon otherweapon;
if ( SelectedWeapon()->IsEmpty()
)
SelectedWeapon()->Reload();
else
if ( otherweapon = GetWeaponNeedingReload()
)
{ // select now, reload when active
SelectWeapon(otherweapon);
}
}
else
{ // threat! so aim and fire unless empty
AimResult_t aim; // tells how the
aim and weapon is
// aiming also has bot turn towards
target
aim = SelectedWeapon()
->AimAndDecideToFire(threattracking);
// test for good aim that isn't
blocked
if ( eFire == (aim & (eBlocked
| eFire)) )
SelectedWeapon->Fire();
else
if ( aim & (eEmpty) )
ReloadOrSwitchWeapon();
else
if ( aim & (eAim)) // thus eAim
without eFire
{ // aims needs to improve or trigger
should
// be released to reduce
recoil (burst length)
/* do nothing but keep aiming
*/
}
}
}
By having the Weapon
and (not shown) the WeaponType handle the fire,
we again can handle the peculiarities of the weapon
in a single method. The code above suggests how a Squad
Automatic Weapon can be used without the recoil
growing too large. Probably every burstlength shots,
the Weapon just does not return the eFire bit,
and the Actor will ease of the trigger.
The actual CGF for AQ2 implementation
(as released in December 99) deals with a number of
other factors, including prediction of threat movement,
prediction of threat 're-appear locations', weapon mode
switching during the attack, scanning during sniping
operations. It also knows dirty tricks such as taking
the time to steady its aim when attacking a threat in
the back (since the threat won't attack immediately)...
Depending on the weapon aspects
being simulated, this design can be extended. Some extensions
are straightforward, but other extensions really result
in more complex designs.
Clips
Some mods (including AQ2) have the Actor carry clips,
not rounds. They reload clip by clip. Clips released
from the weapons take 'home' the remaining rounds in
that clip. Here, it makes sense to model the clips explicitly
(since they probably can be picked up), and do the ammo
computations with rounds in the weapon, and clip sizes.
Other mods (notably Counter-Strike)
have 'virtual clips', and just shuffle additionals rounds
(up to the clip size or ammo amount) into the weapon,
when 'reloading' (CS seems to inherit the basic HL weapons
code). Modeling the clips explicitly doesn't make that
much sense.
Reload Activities
Most weapons will require one single (short) activity
to reload it. There are, however, exceptions: (semi)-automatic
shotguns and bolt-action (sniper) rifles typically combine
internal ammo (round) storage with the ability to reload
individual rounds. In that case, two modes of reloading
are available: loading a single round, or loading a
series of rounds. At ease, the Actor typically prefers
loading a series of rounds, whereas in engaging a threat,
the Actor will want to fire as soon as possible (after
loading one single round).
Ammo Types
Some tactical shooters (notably R6: Rogue Spear) differentiate
between different kinds of ammo. Examples including
full metal jacket (FMJ) rounds that penetrate through
targets and walls, jacketed hollow point (JHP) rounds
that do not penetrate, subsonic rounds (less noise),
slug / buckshot shotgun rounds, and tracer rounds.
Here it makes sense to model
even the ammo types explicitly.
'Power up' Weapons / Long
reload times
In a few shooters, some (but not all) weapons need a
significant amount of time from the moment they are
selected to the time they can be fired. Examples included:
the gatling gun (HL TFC), heavy sniper rifles (R6 Rogue
Spear), and hand grenades for which the pin is to be
released first. Similarly, once a weapon is
being fired (i.e. the pin is pulled), it is important
to continue to aim and fire in the direction intended.
Again, for the AI to take these
into account, it is best to model these properties explicitly
as an attribute / function call of the Weapon.
In addition, the preferences for rapid weapon switching
and activation should be taken into account when trying
to select the best weapon (as an additional parameter
in 'GetFitnessForUsage').
'Twin Weapons'
Some game feature 'weapons' composed of two guns. The
AQ2 and CS akimbo pistols of course come to mind. These
akimbos can be treated as a single weapon with two clips
and twice the rate of fire. They do not cause the AI
problems in considering these guns. For combinations of an assault
rifle and grenade launcher (such as the M4/M203 in CGF),
or an assault rifle and shotgun (in Delta Force), things
get more complicated.
A rifle/grenade launcher in theory is capable of direct
(rifle / grenades) and arc trajectory (grenades, 'lobbed'
over obstables) fire. Reload times differ for the clip
and rifle grenade. A laser-sight and scope typically
apply solely to the rifle, and is of little assistance
in aiming the grenade launcher.
Thus actual fitness for a task depends very much on
the availability of (two different kinds of) ammo, and
whether rounds of these types are in the weapon.
I've tackled these twin weapons by taking into account
two types of ammo in all WeaponType and Weapon
instance interfaces (assuming weapons consuming yet
another kind of ammo won't show up in a game).
Arc Trajectory Weapons
Already briefly mentioned above, arc trajectory weapons
shoot projectiles that do not travel in an almost straight
line, but instead along an arc (due to their slower
speed). Examples include: hand grenades, throwing knifes,
and rifle grenades.
These weapons, compared to rifles
and hand guns, complicated matters by:
- having a range typically shorter
than the map's dimensions
- having the actual range (partially)
depending on the height difference between the attacker
and the target
- having a minimum range (due
to the damage radius) for rifle grenades and hand
grenades
- being able to seriously damage
the target when positioned several meters away from
the target's actual position (for grenades)
- being able to cause friendly
fire accidents (for grenades)
In other words, arc trajectory weapons
are complicated to aim. Whereas for 'normal' rifles holds
"what you see is what you can hit", trajectory weapons
require checks for the complete trajectory.
In addition, the Actor may be required to aim in
a direction different from the target: notably the pitch
(up / down) angle will be different, and to lob grenades
through a window to a spot near enough to the target,
the yaw (left / right) angle might be different as well.
Handling these trajectory weapons requires some special
provisions in the aiming and aim evaluation code. |