1 Introduction
Mafia III is a third person action-adventure game set in Vietnam War Era America. The protagonist Lincoln Clay, an orphan and war veteran, fights to take power away from the Italian mob in the city of New Bordeaux, a fictional version of 1968 New Orleans. But this chapter is not about Lincoln, it is about the hundreds of nameless enemies he fights to get to the mob controlling the city.
The open world has plenty to offer; encounters and player interaction abound. Lincoln can be subtle and lure gangsters from safety, or more direct by getting into fire fights or police chases. These situations occur systemically throughout New Bordeaux while leaving designers the freedom they crave to work both within and outside of the bounds of these systems.
The whole system is made of numerous individual pieces which create the illusion of deadly gangsters and fearless police officers. This chapter is a broad survey of the most important systems that went into creating Mafia III’s AI such as perception, position selection and the cover system. While we use a behavior tree as the main decision-making structure, it is these supporting systems that provide the essential information used by the behavior tree to make sensible decisions. For more detail on behavior trees, see [Simpson 14] or [Colledanchise 18].
2 Enemy design
When the player dives into the world of Mafia III, they find themselves in a city rich in detail and era-accuracy. The player can hear the great music of the ‘60s, ladies walk down the street wearing dresses or slim fit pants, low-heeled shoes, and carrying small rectangular bags; men wear suits or just shirts with a tie and suspenders – all to create an immersive recreation of 1968 New Orleans. The enemies in such a realistic setting have to be believable as well. They have to look like, behave, and be as mortal as humans.
Realistic enemies means realistic perception, abilities and properties. They have limited lifespans because when a human enemy gets shot in the head, everybody expects him to die immediately.
We knew from the beginning that creating such enemies would require a lot of iteration, which demands flexible, data-driven systems. The data-driven approach largely eliminates engineering and game compilation time from the iteration cycle through techniques such as in-game configuration reload.
We decided to break the enemy design down into modular parts to improve data sharing and overall system maintainability. NPCs all have an archetype which provides data on the appearance and behavior of the NPC, in particular the tactics it can use. A tactic defines decision trees and scoring functions used in battle decisions such as position selection, target selection, in-cover behavior, etc.
2.1 Archetype
An archetype is a description of an NPC type, and contains data such as the list of usable tactics, configuration for senses and voice, weapons, reactions to the player, animation set, etc. Each archetype can have multiple variations and supports inheritance of the settings. At the root of the inheritance hierarchy lies a basic configuration for all archetype variants. This base configuration would have some (or all) of its members overridden in each variant.
The triggerman is an example of one such archetype. In the base configuration the triggerman is equipped to throw Molotov cocktails, but in a variation the triggerman might throw grenades instead.
2.2 Tactics
Tactics define how the NPC behaves in combat. The tactic itself is broken down into these basic blocks:
Position selection – where the enemy should stand or take cover
Target selection – who to shoot
Movement style – how to move into selected position
Cover action – what to do while staying in a cover position
Open space action – what to do while staying in open space
Reload behavior – when to reload
Each of these blocks is another data description which lives in a separate file and the tactic references it. One description of the target selection can be used in many tactics. The position selection and target selection are lists of scoring functions for the utility system described later. The movement style, cover action, open space action and reload behavior are authored as decision trees [Colledanchise 18].
3 AI systems
This section describes systems used either as inputs for the behavior layer - perception, archetype definition, position selection or decision trees – or consumers of the output such as shooting. The general overview of the systems connections is displayed on Figure 1.
Figure 1 The AI systems are glued together by the behavior tree.
3.1 Perception
What would an NPC be without its senses? Pedestrians, policemen and gangsters all need to be able to see and hear the player when he decides to wreak havoc. The expectation is that we see civilians fleeing in panic, police officers trying to eliminate the threat to public safety and gangsters protecting their turf.
All sight and hearing properties are data driven. They form yet another block of configuration data stored in a separate file referenced by the archetype definition. Designers can change everything from how far away the NPC is able to see, to how far the footstep sounds travel. Every variable is exposed for editing. If a property is defined as a function, it is authored as a piecewise linear graph.
3.1.1 Sight
Sight in Mafia III is used for detection of any event that the AI should react to when there is a clear line of sight between the NPC and the event. Every NPC in the game has a sight detector attached to its head and can detect any sight event within range. The player is constantly emitting the “Player” event which can be detected by enemies. The system is not limited to player detection. It is used, for example, to detect melee fight in progress by emitting the “melee” event on both participants of the fight. NPCs detect dead bodies, pedestrians react when seeing a weapon in the players hand, etc.
The core of the sight engine in Mafia III uses a vision cone check combined with raycasts to multiple points on the player, similar to systems in other third person action games, namely in the Tom Clancy’s Splinted Cell Blacklist [Walsh 15]
The Mafia III sight engine uses five detection points which can be either data driven, or attached to specific bones. The points are attached to the head, elbows and knees by default, but points are defined by designers for most animation states. Figure 2 shows the designer authored detection points for the player hiding in a cover position. Using predefined positions instead of animation bones plays better when the player is in stealth mode and it provides better protection during battle.
Figure 2 Detection points are moved closer to the chest and collisions to give the player better protection.
When the enemy detects the player, he does not attack immediately. He uses the event as an impulse that something is in his field of view and he starts recognizing it. The speed of recognition is influenced by many factors. We measure the following properties:
Distance to the event
Angle between direction to the event and the direction the enemy is looking
How well the object and NPC are lit
The object speed
Number of visible points
The influence of each property is defined in a configuration file as a piecewise linear function and the time needed for a full recognition is given by the Equation 1.
(1)
3.1.2 Hearing
Enemies sometimes need to be able to react to events that they cannot see as well. For that purpose, any sound which is critical for the AI is registered with the AI hearing engine and propagated to all NPCs within range. In Mafia III the AI hearing engine is completely independent of the audio engine. Any NPC can have a detector registered with the system. When the game emits any AI relevant sound, we notify all detectors within range of the event. The propagation distance is different for each sound. For some events, such as the shooting, we react immediately and we switch the NPC into battle behavior. For others, such as footsteps, we react only when we get a certain number of events during a short time span.
3.1.3 Awareness
Once the player is recognized, NPCs can be in one the five states shown in Figure 3. These states are tied to the enemy behavior. Most situations go through all the states as displayed, but there are exceptions.
Figure 3 AI uses a state machine for transitioning between recognition states.
Each of these states can use different sight and hearing settings. For example, an unaware enemy will not notice the player as far away as an enemy in active combat.
3.2 Stealth tools
The player has several options when it comes to stealth.
We adopt the common convention that when the player crouches and moves slowly, they are being stealthy and are harder for enemies to detect. The sight detection points on the player are moved lower in the crouch animation and his steps make no sound while he moves slowly. On top of that, when the player hides in a cover position, the speed of recognition is even slower.
During the development of Mafia III, the speed of recognition was also slower when the player was sneaking, but we removed this later on because it didn’t feel right. A big guy crouching in the middle of street is not harder to notice than a standing one. The change of detection points position still gives the player better chances to hide behind objects.
To give the player better chances to sneak through the enemy hideout, the game offers different ways to distract the enemies.
Whistle: Whistle is a powerful ability to distract one of the enemies and lure him out. The crucial part of this ability is the enemy targeting for which we used player driven, screen space targeting. We used a scoring function for choosing the NPC close to the player and close to the center of the screen. Equally important is to have an appropriate reaction for the remaining NPCs in the group we are luring enemies from. [Ocio 18]