19,721
edits
(continuing rewrite) |
m (wording tweaks around chenille vs. supershield; is it true that Mutant Muro's supershield goes away if he switches away from his melee behavior?) |
||
| (16 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
An action game like Oni needs artificial intelligence-driven characters ("AIs" or "bots") and some sort of interaction amongst these characters and between them and the world. The goal is to make an AI act at least a bit like a human being. That means giving the AI abilities such as moving in the game world believably, and seeing, hearing, and reacting to events in the game world. Different games deal with these problems in various ways, but in this article, we will take a look at Oni and its AI. | An action game like Oni needs artificial intelligence-driven characters ("AIs" or "bots") and some sort of interaction amongst these characters and between them and the world. The goal is to make an AI act at least a bit like a human being. That means giving the AI abilities such as moving in the game world believably, and seeing, hearing, and reacting to events in the game world. Different games deal with these problems in various ways, but in this article, we will take a look at Oni and its AI. | ||
| Line 7: | Line 4: | ||
==Pathfinding and movement== | ==Pathfinding and movement== | ||
[[ | [[Image:Pathfinding grid.jpg|thumb|right|alt=Example of a pathfinding grid.|An example of a pathfinding grid.]] | ||
[[ | [[Image:Ai2 showastar2.png|thumb|right|alt=Example of an A*.|An example of the A* algorithm's work: nodes chosen as a path for AI are highlighted.]] | ||
Oni has two ways to make an AI move in a game world - pathfinding, and what could be called vector-based. | Oni has two ways to make an AI move in a game world - pathfinding, and what could be called vector-based. | ||
'''Pathfinding''' is used when AI-driven character needs to travel from one place to another. Examples of pathfinding movement are: | '''Pathfinding''' is used when AI-driven character needs to travel from one place to another. Examples of pathfinding movement are: | ||
:*patrol paths - AI-driven character moves in a pre-designed fashion (see [[PATR]]) | :*patrol paths - AI-driven character moves in a pre-designed fashion (see [[PATR]]) | ||
:*alarm running - AI character is requested to go to given console and use it, see section [[#Alarm behavior | :*alarm running - AI character is requested to go to given console and use it, see section [[#Alarm behavior|Alarm behavior]] | ||
:*pursuit of target - AI character loses direct sight of the enemy, see section [[#Pursuit | :*pursuit of target - AI character loses direct sight of the enemy, see section [[#Pursuit|Pursuit]] | ||
:*running to weapons in order to pick them up, see [[# | :*running to weapons in order to pick them up, see [[#Extra combat behaviors|Extra combat behaviors]] | ||
:Pathfinding utilizes an [[wikipedia:A*_search_algorithm|A* (A-star)]] algorithm to design routes for AI within the game world. | :Pathfinding utilizes an [[wikipedia:A*_search_algorithm|A* (A-star)]] algorithm to design routes for AI within the game world. | ||
| Line 48: | Line 45: | ||
==Vision and hearing== | ==Vision and hearing== | ||
[[ | [[Image:VisionFields.jpg|thumb|right|alt=Visualization of vision fields.|An example of a blue Striker's central and peripheral vision.]] | ||
[[ | [[Image:SoundSpheres.jpg|thumb|right|alt=Visualization of sound spheres.|Three examples of sound spheres.]] | ||
When emulating humans with AI, senses have to be taken into an account: sight, hearing, taste, smell, touch. Unfortunately, Oni emulates only sight and hearing. | When emulating humans with AI, senses have to be taken into an account: sight, hearing, taste, smell, touch. Unfortunately, Oni emulates only sight and hearing. | ||
| Line 56: | Line 53: | ||
:*Peripheral: an enemy seen by peripheral vision will raise the AI's alert level to low and the AI will go into pursuit of the enemy; see [[#Pursuit|Pursuit]] section | :*Peripheral: an enemy seen by peripheral vision will raise the AI's alert level to low and the AI will go into pursuit of the enemy; see [[#Pursuit|Pursuit]] section | ||
:Modding hints: the parameters of the vision fields are stored in ONCC, under '''<VisionConstants>'''. The central vision field distance has to be greater than the peripheral vision field distance, otherwise peripheral vision detection will somehow be broken (it will not detect). Since peripheral vision makes the AI pursue the enemy but not attack it, it can be set quite large in order to surprise lousy stealth players. But be warned: nobody likes cheating AI ^_^. | |||
Modding hints | |||
| Line 70: | Line 66: | ||
:For more info about AI alert levels, see section [[#Reactions and awareness|Reactions and awareness]]. These sound types are used by impact effects ([[ONIE]]), and a danger sound type can be set in a particle's as part of its "danger radius". | :For more info about AI alert levels, see section [[#Reactions and awareness|Reactions and awareness]]. These sound types are used by impact effects ([[ONIE]]), and a danger sound type can be set in a particle's as part of its "danger radius". | ||
:For a video illustration of AI hearing, see [https://www.youtube.com/watch?v=LxX5dbYGZow this video]. | |||
:Modding hints: The sound system and ONIE are mighty tools if a modder knows how to use them. Even doors can have attached to them a sound sphere of one of the types listed above, so a modder can create doors which draw the attention (sound type Interesting) of nearby AIs when those doors are used. | :Modding hints: The sound system and ONIE are mighty tools if a modder knows how to use them. Even doors can have attached to them a sound sphere of one of the types listed above, so a modder can create doors which draw the attention (sound type Interesting) of nearby AIs when those doors are used. | ||
:Another example is a workaround for AIs to get alerted by dead bodies: | :Another example is a workaround for AIs to get alerted by dead bodies: set the death particle in the ONCC to emit a custom impact effect. That impact effect will have no sound or effect attached, but will be set to be heard by AIs as gunfire within a large radius (say, 200 units). | ||
==Reactions and awareness== | ==Reactions and awareness== | ||
| Line 147: | Line 142: | ||
:Pursuit behavior greatly depends on the AI's level of alert. There are four parameters regarding alert levels in the CHAR profile: | :Pursuit behavior greatly depends on the AI's level of alert. There are four parameters regarding alert levels in the CHAR profile: | ||
:*Initial: the AI is spawned with the specified level of alert | :*Initial: the AI is spawned with the specified level of alert | ||
:*Minimal: the | :*Minimal: the minimum alert level this AI can have | ||
:*JobStart: the alert level of the AI when it starts some job (typically a patrol) | :*JobStart: the alert level of the AI when it starts some job (typically a patrol) | ||
:*Investigate: From the alert level specified here, and all greater alert levels, the AI will tend to pursue any suspicious sound it hears or any hostile peripheral contact it makes | :*Investigate: From the alert level specified here, and all greater alert levels, the AI will tend to pursue any suspicious sound it hears or any hostile peripheral contact it makes | ||
| Line 167: | Line 162: | ||
Modding hints: '''Pursuit mode complications and weird glitches''' | Modding hints: '''Pursuit mode complications and weird glitches''' | ||
:Watch [ | :Watch [https://www.youtube.com/watch?v=OMFK5iKcZ5Q this YouTube video]. Pursuit mode is quite buggy, so when setting pursuit behaviors, there are several important things a modder has to have in mind. | ||
:*The pursuit distance parameter in CMBT is important in deciding whether the character should be more of a pursuer or more of a guard. | :*The pursuit distance parameter in CMBT is important in deciding whether the character should be more of a pursuer or more of a guard. | ||
:*Within the pursuit distance, peripheral vision pursuit follows its own rules. When an AI sees an enemy with its peripheral vision, this AI always goes into weak awareness mode and either just glances in the direction of this enemy (alert level was below Investigate level) or moves to the spot and performs weak investigation pursuit behavior (alert level was at Investigate on higher). | :*Within the pursuit distance, peripheral vision pursuit follows its own rules. When an AI sees an enemy with its peripheral vision, this AI always goes into weak awareness mode and either just glances in the direction of this enemy (alert level was below Investigate level) or moves to the spot and performs weak investigation pursuit behavior (alert level was at Investigate on higher). | ||
| Line 194: | Line 189: | ||
In order to make the AI look more human, it is a good idea to grant it the ability to interact with the world the same way that the player does. In Oni, for example, that means giving the AI the ability to use consoles. | In order to make the AI look more human, it is a good idea to grant it the ability to interact with the world the same way that the player does. In Oni, for example, that means giving the AI the ability to use consoles. | ||
::[ | ::[https://www.youtube.com/watch?v=jnsGuZxqW9I Watch this YouTube video.] | ||
:BSL scripting provides a command to make an AI go and use a console: [[ai2_doalarm]]. This way, an AI can be told to use any console. But there is a method to make an AI use a console completely on it own. | :BSL scripting provides a command to make an AI go and use a console: [[ai2_doalarm]]. This way, an AI can be told to use any console. But there is a method to make an AI use a console completely on it own. | ||
:In order to utilize this mechanic, there is a need for a console which has the ALARM CONSOLE flag set (see [[OBD:BINA/OBJC/CONS]]). In XML this flag is called '''IsAlarm'''. Such a console then can be used by AI characters without scripting. | :In order to utilize this mechanic, there is a need for a console which has the ALARM CONSOLE flag set (see [[OBD:BINA/OBJC/CONS]]). In XML this flag is called '''IsAlarm'''. Such a console then can be used by AI characters without scripting. | ||
| Line 243: | Line 238: | ||
:*Another way of using alarm mechanics is to create a feeling of cooperation -- in order for the player to achieve something, an AI-driven sidekick must use a console. | :*Another way of using alarm mechanics is to create a feeling of cooperation -- in order for the player to achieve something, an AI-driven sidekick must use a console. | ||
:*In extreme cases, an AI can be even made to move through the level on it own, from one console to another. That can be used to create "chase" missions -- an AI wants to activate a certain number of consoles, while the player is required to stop it from doing so. Thanks to Alarm behaviors, the task of tripping consoles can be fully completed by the AI, no scripting needed. Such a setup is on the one hand prone to possible AI glitches, but on the other hand can add an element of randomness and increase replayability. | :*In extreme cases, an AI can be even made to move through the level on it own, from one console to another. That can be used to create "chase" missions -- an AI wants to activate a certain number of consoles, while the player is required to stop it from doing so. Thanks to Alarm behaviors, the task of tripping consoles can be fully completed by the AI, no scripting needed. Such a setup is on the one hand prone to possible AI glitches, but on the other hand can add an element of randomness and increase replayability. A demonstration of alarm behavior being used by an AI to complete all of Chapter 1 can be found [https://www.youtube.com/watch?v=CkzguNxjGEs HERE]. | ||
==Basic combat behaviors== | ==Basic combat behaviors== | ||
[[ | [[Image:combatRanges.png|thumb|right|alt=Example of combat ranges.|Combat ranges of an AI character.]] | ||
Of course, an action game like Oni is not complete without guns blazing and fists flying through the air. But combat in real life is usually very fickle and everything has to be considered. How can Oni's AI possibly deal with such a complex task? | Of course, an action game like Oni is not complete without guns blazing and fists flying through the air. But combat in real life is usually very fickle and everything has to be considered. How can Oni's AI possibly deal with such a complex task? | ||
| Line 269: | Line 262: | ||
OK, we have positioning down; now for the actual behaviors that an AI can be set to execute within these ranges. There are fourteen possible combat behaviors (in | OK, we have positioning down; now for the actual behaviors that an AI can be set to execute within these ranges. There are fourteen possible combat behaviors (in parentheses are the XML strings): | ||
:*None (None): simply nothing. | :*None (None): simply nothing. | ||
:*Stare (Stare): the AI stands and stares; it does not even rotate to face the enemy. | :*Stare (Stare): the AI stands and stares; it does not even rotate to face the enemy. | ||
| Line 288: | Line 281: | ||
::Again, the annoying "over 550" height check is present. | ::Again, the annoying "over 550" height check is present. | ||
:*Run for alarm (RunForAlarm): see section [[#Alarm behavior|Alarm behavior]]. | :*Run for alarm (RunForAlarm): see section [[#Alarm behavior|Alarm behavior]]. | ||
:*Mutant Muro melee (MutantMuroMelee): the AI is only allowed to melee, not fire weapons. This behavior places | :*Mutant Muro melee (MutantMuroMelee): the AI is only allowed to melee, not fire weapons. This behavior places the Daodan aura on the character irrespective of his/her HP as long as the character has <HasDaodanPowers> set to 1 in their [[ONCC]]. This aura effect does ''not'' grant the damage overpower attribute that Konoko has when she overheals. If the ONCC has both <HasDaodanPowers> and <HasSuperShield> set to 1, the chenille mode called by this behavior grants a [[supershield]]. | ||
:: | ::The supershield lasts forever if it is not terminated either via BSL or by the AI performing a TRAM which has a DisableShield flag. After a DisableShield move removes the supershield there is a 10 second interval and then it is turned back on. Another specialty of this behavior is an automatic backward-evasion move when about 35 points of damage or a throw are inflicted on the AI. The supershield is turned off if this AI switches to some other combat behavior because the enemy moved to another combat range. | ||
:*Mutant Muro thunderbolt (MuroThunderbolt): Upon initial contact, the AI turns on chenille mode and runs toward the enemy. If chenille mode is turned off then, until definite awareness of the enemy is lost, this behavior will not cast chenille mode again. This behavior also allows the AI to use a special long range attack: the character turns off chenille, goes into AnimState 69 - Thunderbolt, and loops a special TRAM animation of AnimState 69 - Thunderbolt and AnimType 231 - Muro_Thunderbolt. That lasts for 10 seconds. Then the AI stops the animation for 5 seconds and runs toward the enemy. If, after those 5 seconds, the AI is still executing Mutant Muro thunderbolt behavior, the AI resumes the looping TRAM between AnimType 231 and 69. | :*Mutant Muro thunderbolt (MuroThunderbolt): Upon initial contact, the AI turns on chenille mode and runs toward the enemy. If chenille mode is turned off then, until definite awareness of the enemy is lost, this behavior will not cast chenille mode again. This behavior also allows the AI to use a special long range attack: the character turns off chenille, goes into AnimState 69 - Thunderbolt, and loops a special TRAM animation of AnimState 69 - Thunderbolt and AnimType 231 - Muro_Thunderbolt. That lasts for 10 seconds. Then the AI stops the animation for 5 seconds and runs toward the enemy. If, after those 5 seconds, the AI is still executing Mutant Muro thunderbolt behavior, the AI resumes the looping TRAM between AnimType 231 and 69. | ||
::This behavior's special looping animation continues even when an enemy enters some another combat range, with the exception of Short range. If the enemy enters Short range while the looped animation is running, the loop is forced to stop and the AI starts using Short range behavior. | ::This behavior's special looping animation continues even when an enemy enters some another combat range, with the exception of Short range. If the enemy enters Short range while the looped animation is running, the loop is forced to stop and the AI starts using Short range behavior. | ||
| Line 301: | Line 294: | ||
:*Barabbas Shoot and Barabbas Melee behaviors have access to a healing ability which can be a great asset for introducing mutants or stronger enemy units. However, remember that Barabbas Shoot limits rate of fire to one shot per three seconds. | :*Barabbas Shoot and Barabbas Melee behaviors have access to a healing ability which can be a great asset for introducing mutants or stronger enemy units. However, remember that Barabbas Shoot limits rate of fire to one shot per three seconds. | ||
:*Barabbas Advance is the only behavior which allows an AI to fire a weapon in its secondary fire mode. However the behavior is quite glitchy (the AI often looks away and fires stray shots). Still, with the proper gun and proper setup it can be useable for boss fights. | :*Barabbas Advance is the only behavior which allows an AI to fire a weapon in its secondary fire mode. However the behavior is quite glitchy (the AI often looks away and fires stray shots). Still, with the proper gun and proper setup it can be useable for boss fights. | ||
:*Superninja's behaviors sound excellent for cunning enemy units, however the annoying check for a character's | :*Superninja's behaviors sound excellent for cunning enemy units, however the annoying check for a character's minimum allowed height from the world origin, and subsequent forced re-positioning, severely impact these behaviors' usefulness. With a level which is deliberately raised to the correct height, the behavior will not cause random AI character re-positioning. Then it can be used to its fullest. | ||
::One other important thing about these behaviors: if the AI does not have required the TRAMs in its [[TRAC]], the AI can get stuck if it uses these behaviors. | ::One other important thing about these behaviors: if the AI does not have required the TRAMs in its [[TRAC]], the AI can get stuck if it uses these behaviors. | ||
:*If there is no console with the ALARM CONSOLE flag within the Alarm search distance, then the behavior "Run For Alarm" will make an AI just stand and stare. Choose this behavior with caution, and consider using a workaround where Medium and Short combat ranges have very close radii, with Run For Alarm being the MediumRetreat behavior, so that the Run For Alarm behavior is executed only for a brief amount of time as the AI almost immediately switches to LongRetreat. Even one frame is enough, because if an alarm is found, the AI is requested to perform an alarm run which can override combat (see section [[#Alarm behavior|Alarm behavior]] for more info). | :*If there is no console with the ALARM CONSOLE flag within the Alarm search distance, then the behavior "Run For Alarm" will make an AI just stand and stare. Choose this behavior with caution, and consider using a workaround where Medium and Short combat ranges have very close radii, with Run For Alarm being the MediumRetreat behavior, so that the Run For Alarm behavior is executed only for a brief amount of time as the AI almost immediately switches to LongRetreat. Even one frame is enough, because if an alarm is found, the AI is requested to perform an alarm run which can override combat (see section [[#Alarm behavior|Alarm behavior]] for more info). | ||
| Line 311: | Line 304: | ||
==Extra combat behaviors== | ==Extra combat behaviors== | ||
Combat ranges and various AI combat | Combat ranges and various AI combat behaviors were discussed in the previous section. Even in terms of combat ranges, there are still other aspects of combat to cover: picking up weapons from the ground, melee overrides of weapons, behaviors if the character is unarmed, and, of course, firing weapons or using hand-to-hand combat. | ||
'''"Melee override" ([[CMBT]] profile)''' | '''"Melee override" ([[CMBT]] profile)''': Similar to the BSL command [[chr_dontaim]], this behavior urges the AI to use its hand-to-hand animation variant (see [[TRAM]]) and to switch from some other behavior to melee combat. This field was probably added to deal with conflicts when multiple AI behaviors are applied on a character. The possible values are (XML strings in parentheses): | ||
:*None (None) | :*None (None): no override is used. | ||
:*If Punched (IfPunched) | :*If Punched (IfPunched): melee override is applied when the AI is melee-attacked by its enemy. Does not work when the character is invincible. | ||
:*Cancelled | :*Cancelled: unfinished feature; does nothing. There remains only the question of what it was meant to be.... | ||
:*Short (ShortRange) | :*Short (ShortRange): Melee override is applied when the enemy is within Short range. | ||
:*Medium (MediumRange) | :*Medium (MediumRange): Melee override is applied when the enemy is within Medium or Short range. | ||
:*Always | :*Always Melee (AlwaysMelee): Melee override is applied within all combat ranges. | ||
:This override can affect: | :This override can affect: | ||
:*Alarm running | :*Alarm running: It is actually required if an alarm run is called via the no-gun alarm run behavior, otherwise glitches will appear. | ||
:*Retreating behavior - When | :*Retreating behavior - When the no-gun behavior is set as "Retreat", an unarmed AI will try to run away from its enemy. However, if enemy meets the Melee override parameter (for example getting into the Short range while the melee override is set to ShortRange), then this AI stops running away and starts attacking the enemy. | ||
:*Weapon firing | :*Weapon firing: If the distance between the AI and its enemy is smaller than the minimum shooting distance, the AI tries to backpedal away from its enemy till the distance between characters is greater than the minimum shooting distance. However, this backpedal behavior can be overridden by the melee override if all conditions are met; the AI then starts using melee (even with a loaded weapon in hand) for at least 10 seconds (hardcoded timer). After ten seconds, the AI tries to resume its previous behavior. If the enemy is still too close, the melee override is immediately applied again. | ||
:*Weapon pickup | :*Weapon pickup: if the AI is trying to pick up a weapon and an enemy crosses the range specified in MeleeOverride, then the weapon pickup behavior is overridden by melee. | ||
:*Maybe some other aspects of AI behavior? | :*Maybe some other aspects of AI behavior? | ||
''' | '''No-gun behavior ([[CMBT]] profile)''': This parameter tells the AI what kind of action it should take if it is unarmed or has an empty weapon and no spare clips. Possibilities are (XML strings in parentheses): | ||
:*Melee (Melee) | :*Melee (Melee): The AI attacks the enemy with hand-to-hand combat. | ||
:*Retreat (Retreat) | :*Retreat (Retreat): The AI runs away from its enemy (a bit glitchy, but works). | ||
:*Run For Alarm (RunForAlarm) | :*Run For Alarm (RunForAlarm): see section [[#Alarm behavior|Alarm behavior]]. Reminder: this alarm-running behavior requires the melee override to be set in ShortRange, MediumRange or AlwaysMelee, otherwise the alarm behavior gets glitched and the AI gets stuck. If no alarm console is found within the alarm search distance, the AI resorts to melee. | ||
[[ | [[Image:GoForGun.jpg|thumb|right|alt=Picture showing AI moving to a weapon.|AI moving towards a weapon.]] | ||
'''Weapon pickup behavior ([[ONCC]] file)''' | '''Weapon pickup behavior ([[ONCC]] file)''': When in combat mode, an unarmed AI can be told to move to a loaded weapon and pick it up or to swap a held, empty gun for a loaded gun which is lying on the floor. Overall, AIs can only register pickup-able weapons up to a distance of 60 world units (hardcoded). In the ONCC file, these parameters can be set to alter the gun pickup behavior (XML tags in parentheses): | ||
:*Chance for pickup (GoForGunChance) | :*Chance for pickup (GoForGunChance): percent chance of AI deciding to go and pick up a weapon. It seems that the weapon closest to the AI character is always chosen to be picked up. | ||
:*Running pickup (RunPickupChance) | :*Running pickup (RunPickupChance): percent chance of AI picking up the weapon by performing an evasion (melee dodge) move. | ||
'''Getting up after being knocked down ( | '''Getting up after being knocked down (ONCC file)''': If an AI is knocked to the ground, it stays on the ground for a while (a simulation of being stunned), then gets up. In the ONCC file there are two parameters regarding getting up (XML tags in parentheses): | ||
:*Knockdown | :*Knockdown minimum number of frames (DazedMinFrames): minimum number of frames that AI stays on the ground. | ||
:*Knockdown | :*Knockdown maximum number of frames (DazedmaxFrames): maximum number of frames that AI stays on the ground. | ||
:If | :If a knocked-down AI gets hit by melee, it gets up immediately after the hit. Being hit by weapons does not make AI character instantly get up. Standard get-ups are simple ones (the same result as if the knocked-down player hits a directional key). If the AI is in melee combat mode, its [[MELE]] profile has get-up attacks listed, and the enemy is within the required range, there is a chance that this AI will use a get-up attack instead of a simple get-up animation. | ||
'''Making sure enemy is dead ( | '''Making sure enemy is dead (ONCC file)''': Yes, even this is a part of Oni's combat AI. | ||
:When enemy is defeated in hand to hand fighting, AI | :When the enemy is defeated in hand-to-hand fighting, the AI stands over them for a while to decide if the enemy is dead. During this interval, the AI can utter a short victory speech if the corresponding sound slot in its ONCC is filled and the percent chance roll is successful. Also during the "check body" time interval, the AI can perform a taunt animation if that roll is successful. Here are listed all the related fields from the ONCC file (XML tags in parentheses): | ||
:*Investigate body (InvestigateBodyDelay) | :*Investigate body (InvestigateBodyDelay): Time period for which AI stands over its defeated enemy and stares at him/her. | ||
:*Dead taunt chance (DeadTauntChance) | :*Dead taunt chance (DeadTauntChance): Percent chance of performing a taunt animation. | ||
:*Check body sound probability (CheckBodyProbability) | :*Check body sound probability (CheckBodyProbability): Percent chance of playing a victory speech. | ||
:*Check body sound (CheckBodySound) | :*Check body sound (CheckBodySound): A link to an Oni ambient sound file ([[OBD:OSBD/OSAm|OSAm]]). | ||
:If the enemy is defeated by weapon, then AI | :If the enemy is defeated by weapon, then the AI keeps shooting this dead enemy for some extra time to make sure the enemy is dead, then comes close to investigate the body. No taunts, no win phrases. The parameters of this behavior are: | ||
:*Dead make sure (DeadMakeSureDelay) | :*Dead make sure (DeadMakeSureDelay): Time period for which the AI keeps shooting the dead enemy. | ||
:*Investigate body (InvestigateBodyDelay) | :*Investigate body (InvestigateBodyDelay): Same as the one listed above for melee. | ||
Modding hints - behaviors | Modding hints - the behaviors listed in this section can be combined to achieve quite impressive results. | ||
:* | :*Unfortunately, Oni does not provide any AI settings that deal with intelligent holstering and unholstering of weapons in their possession. Thus, melee overrides are the only way to make an armed AI somehow defend itself when the enemy gets too close to use its weapon. | ||
::Nevertheless, | ::Nevertheless, BSL does provide a function to make a character holster or unholster a weapon: [[chr_forceholster]]. In order to make a character holster a held weapon, this character has to be using a pistol or rifle animation variant (see [[TRAM]]). Since AI can use "walk_noaim" and "run_noaim" movement modes (which disable weapon variants, i.e., aiming with weapons), the weapon variant should be explicitly forced on via the BSL function [[chr_dontaim]]. Unholstering is easier: the character simply has to be be executing some aiming overlay-compatible animation at the moment when chr_forceholster is executed. That means standing, running, crouching, walking, and jumping are OK -- the function will succeed -- but attack animations or animations of getting hit are not OK and the function will fail. | ||
::*IMPORTANT NOTE: The AI | ::*IMPORTANT NOTE: The AI must be "active" all the time in order to perform BSL animation checks ([[chr_wait_animation]]/[[chr_wait_animtype|animtype]]/[[chr_wait_animstate|animstate]] checks). Remember that Oni was developed mostly in the '90s, so various tricks were used to save memory and enhance performance. One technique was to make unseen characters (behind a wall, closed doors, etc.) go into an "inactive" mode, which means they are only stored in RAM as a structure, but no physics, collision checks, or drawing functions are performed on them in order to save system resources (and yes, that means inactive characters can [https://www.youtube.com/watch?v=GC4HLDekxQI walk in mid-air and pass through walls]). On the other hand, when a character is active, it is fully operational, with physics working, collisions being checked, and character being ready in graphics memory to be drawn any time. To make sure a character stays active requires either applying [[chr_lock_active]] to each AI, or (since computers have a lot more memory these days) simply setting [[chr_all_active]] to 1 to force all characters active. | ||
::Here is a simple example of a | ::Here is a simple example of a holster behavior scripted in BSL. A character is given a gun, then the weapon is holstered. When this AI notices an enemy and plays its startle animation, then an unholster is called for. [https://www.youtube.com/watch?v=2WNMh8u5wBI This YouTube video] shows the script in action. | ||
#Setup of AI - gets spawned, forced to be always active, weapon gets holstered. | #Setup of AI - gets spawned, forced to be always active, weapon gets holstered. | ||
| Line 388: | Line 381: | ||
:* | :*A melee override can be used together with the "Go For Gun" behavior and a properly-set Short combat range to create AIs who go for a gun any time they have a chance, yet they are not allowing an enemy to land free hits in the process (if the enemy gets too close, the Short range melee override kicks in). | ||
:* | :*The no-gun behavior "Retreat" works in a rather simple manner: if unarmed, an AI is given a desire to run as far from the enemy as possible. This behavior can look a bit awkward, but is useful for making more life-like civilians. Combined with Melee override at "Short range" or "If punched", and a bit of BSL scripting to deliberately switch between "combatant" and "non-combatant", a modder can achieve impressive results without only a light load on the game engine. [https://www.youtube.com/watch?v=BTGQTAoU_1E See this YouTube video.] | ||
:*Setting short | :*Setting short get-up times is a good way to make an AI-driven character a formidable opponent in hand-to-hand combat. However, too-short get-up times can introduce problems. It is a good idea to experiment with get-up parameters till the character feels "natural". | ||
:* Don't | :*Don't over-extend the "Check body" and "Dead make sure" timers. It looks silly, and on top of that it makes AIs easy targets for a rear throw. | ||
== | ==Weapon combat behaviors== | ||
Back in 2001 Oni was highly praised for its mixture of shooting and hand to hand combat. Now what could AI designers | Back in 2001, Oni was highly praised for its mixture of shooting and hand-to-hand combat. Now what could the AI designers for Oni possibly do to make AI characters aim a gun, pull a trigger or avoid being hit by enemy gunfire? In this section, settings found in [[ONWC]], together with [[ONCC]] and [[PAR3]], will tell the story. | ||
:First let's look into | :First let's look into the ONCC file. In an XML export of this file, under <AIConstants>, there's a tag named <Flags>. In the original binary data it is a bitset, meaning that more than one flag can be active at a time. The XML strings for the flags are: | ||
:*noStartleAnim | :*noStartleAnim: disables the startle animation that can occur when the AI sees the enemy for the first time. | ||
:*EnableMeleeDodge | :*EnableMeleeDodge: enables firing spread/projectile dodging while the AI is in pathfinding mode or melee combat mode. | ||
:*RunAwayDodge | :*RunAwayDodge: enables firing spread/projectile dodging even while the AI itself is shooting a gun. The AI will stop shooting and try to move away from the danger area. | ||
:*ShootDodge | :*ShootDodge: enables firing spread/projectile dodging even while the AI itself is shooting a gun. The AI will keep shooting at its enemy while at the same time attempting to move away from the danger area. | ||
:*NotUsed | :*NotUsed: Some characters have this bit turned on, however it looks like it does nothing. | ||
[[ | [[Image:Firingspread.png|thumb|right|alt=Example of a firing spread.|Example of a firing spread.]] | ||
[[ | [[Image:Projectile.png|thumb|right|alt=Example of a particle with an AI projectile-dodge radius.|Example of a projectile with AI dodge radius (blue sphere).]] | ||
'''Gunfire dodging mechanics'''. Gunfire dodging mechanics | '''Gunfire dodging mechanics'''. Gunfire dodging mechanics are quite an interesting part of Oni's AI system -- interesting because the retail version displays little to no such behavior, which is sad because it adds challenge to the gunplay. In order to make an AI perform gunfire dodging, this AI must be in combat mode with an enemy. Without combat mode and some enemy, AI character won't dodge. Additionally, an AI will only perform a dodge when the character senses one of these two things: | ||
:* | :*Firing spread. This can be seen by using [[ai2_showfiringspreads]]. The firing spread has the shape of a prism (its dimensions set in ONWC) which can be created when a weapon is fired. Not every gun has a firing spread, as for some guns a firing spread is useless (e.g. the Scram Cannon and Super Ball Gun). If an AI can dodge gunfire and intersects with a firing spread, this AI character starts its gunfire dodging behavior. | ||
:*Projectile | :*Projectile. The epic win of Oni modders. In the retail version of Oni, projectile dodging is basically broken due to a couple of bugs in the code. Since the engine hackers/modders fixed this issue, AIs can now dodge projectiles properly. Visualize this feature with [[ai2_showprojectiles]]. AIs will dodge particles themselves if they are in combat mode with some enemy and the particle (e.g. the Screaming Cell Cannon's projectile) has <AIDodgeRadius> set to a positive non-zero value. | ||
:AI parameters regarding gunfire dodging are set in | :AI parameters regarding gunfire dodging are set in ONCC (XML tags in parentheses): | ||
:*Dodge reaction delay (DodgeReactFrames) | :*Dodge reaction delay (DodgeReactFrames): a delay, in number of frames, which makes an AI wait a bit inside a danger zone before starting its reaction to the firing spread/projectile. | ||
:*Dodge timescale (DodgeTimeScale) | :*Dodge timescale (DodgeTimeScale): how long the AI's gunfire dodging behavior should last. | ||
:*Dodge weight (DodgeWeightScale) | :*Dodge weight (DodgeWeightScale): how strong the desire (as a length of vector???) is for this AI character to dodge gunfire. The dodge weight can add together with other "vector" movements, and a sum of all vectors is the direction in which the AI will try to move. | ||
:Parameters of | :Parameters of firing spread in ONWC are (XML tags in brakets): | ||
:* | :*Firing spread length (FireSpreadLength) | ||
:* | :*Firing spread width (FireSpreadWidth) | ||
:* | :*Firing spread skew (FireSpreadSkew) | ||
: | :The parameter for projectile dodging in the particle system (PAR3) is the AI dodge radius (AIDodgeRadius). | ||
'''AI character's prowess with guns'''. Still in | '''AI character's prowess with guns'''. Still in the ONCC, there are settings for how skillful this AI should be with [[Quotes/Weapons|each weapon in the game]]. Weapons are indexed (starting from zero) as follows: | ||
:*w0_sec | :*0: w0_sec - only Bungie West employees know what this weapon was supposed to be. | ||
:*w1_tap | :*1: w1_tap - TCTF Automatic Pistol | ||
:*w2_sap ( | :*2: w2_sap - Syndicate Automatic Pistol (the SMG) | ||
:*w3_phr | :*3: w3_phr - Plasma Rifle | ||
:*w4_psm | :*4: w4_psm - Phase Stream Projector | ||
:*w5_sbg | :*5: w5_sbg - Super Ball Gun | ||
:*w6_vdg | :*6: w6_vdg - Van de Graaff Gun | ||
:*w7_scc | :*7: w7_scc - Scram Cannon | ||
:*w8_mbo | :*8: w8_mbo - Mercury Bow | ||
:*w9_scr | :*9: w9_scr - Screaming Cell Cannon | ||
:*w10_sni | :*10: w10_sni - Mukade's Devil Star (heat-seeking red ball) as an invisible weapon; probably a relic from game development. | ||
:*w10_ba1 | :*11: w10_ba1 - Barabas' gun, the Wave Motion Cannon. | ||
:*w11_ba2 | :*12: w11_ba2 - Barabas' gun; this one cannot be shot and is probably a development relic. | ||
:For each | :For each weapon, the ONCC defines these parameters (XML tag in parentheses): | ||
:*Recoil compensation (RecoilCompensation) | :*Recoil compensation (RecoilCompensation): how much the AI character compensates for the recoil (vertical stray) of the weapon. Setting this to 0.0 means no compensation, and setting this to 1.0 means full compensation. | ||
:*Best aiming angle (BestAimingAngle) | :*Best aiming angle (BestAimingAngle): in radians, but the question is whether it really affects aiming. | ||
:*Shoot group error (ShotGroupError) | :*Shoot group error (ShotGroupError): the random deviation of the AI's aim from the target spot. Incorporated to simulate human inaccuracy. Can be set higher than 1.0. | ||
:*Shoot | :*Shoot group decay (ShotGroupDecay): the random deviation of the target spot itself. The target spot is naturally based on the enemy's position. Can be set higher than 1.0. | ||
:*Shooting inaccuracy multiplier (ShootingInaccuracyMultiplier) | :*Shooting inaccuracy multiplier (ShootingInaccuracyMultiplier): also controls the degree that the AI's aim strays from the target, but it's not clear how much it really affects aiming. | ||
:* | :*Minimum shooting delay (MinShotDelay): minimum pause between reloading and resuming firing. | ||
:* | :*Maximum shooting delay (MaxShotDelay): maximum pause between reloading and resuming firing. | ||
'''Targeting and prediction''' of enemy's movement. | '''Targeting and prediction''' of the enemy's movement. Unlike the majority of other games, Oni's AI does not "cheat" by starting from 100% accuracy and then adding some degree of error (even though additive error is also present in Oni; see above). To the contrary, there's a bit of a problem making the AI a precise marksman ^_^. The AI is given input parameters such as the distance between itself and the enemy, the present velocity of its enemy (as a vector), and the velocity of their gun's projectile (as a number, not a vector). From this data, the AI logic computes a prediction of the enemy's location and the ideal aiming vector for hitting the enemy. | ||
: | :The ONCC parameters for targeting and prediction are (XML tags in parentheses): | ||
:*Predict amount (PredictAmount) | :*Predict amount (PredictAmount): some sort of multiplier for prediction mechanics. | ||
:*Predict position delay (PredictPositionDelay) | :*Predict position delay (PredictPositionDelay): in frames, the delay before prediction is applied, so that the AI always somewhat-outdated prediction. | ||
:*Predict delay frames (PredictDelayFrames) | :*Predict delay frames (PredictDelayFrames): in frames, the delay before prediction is computed. Must be set to at least 1.0. | ||
:*Predict velocity frames (PredictVelocityFrames) | :*Predict velocity frames (PredictVelocityFrames): this is a period of time in number of frames, but the meaning is not 100% clear. Maybe the enemy's velocity data is obtained and used for prediction algorithm during this period of time? Must be set to at least 2.0. | ||
:*Predict trend frames (PredictTrendFrames) | :*Predict trend frames (PredictTrendFrames): another period of time in number of frames that is not 100% clear. Maybe the distance ahead that extrapolation of the enemy's movement takes place? Must be set to at least 2.0. | ||
: | :The ONWC parameters for targeting and prediction are (XML tags in parentheses): | ||
:*Prediction speed (PredictionSpeed) | :*Prediction speed (PredictionSpeed): more precisely "projectile prediction speed". This value is taken by the prediction algorithm as the speed of a projectile fired with the corresponding fire mode of the ONWC weapon. Thus, when the actual PAR3 projectile's speed is changed, this prediction behavior produces misleading results (i.e., the AI is unable to hit moving targets). | ||
:* | :*Maximum inaccuracy angle (MaxInaccuracyAngle): maximum allowed deviation of aim from the enemy's pelvis while firing the weapon. If exceeded, the AI ceases fire and corrects its aiming, then resumes fire. The pelvis is considered to be the root point of the character, so without any modifications made to the targeting origin and vector (see ONWC), AIs always target the pelvis of the enemy. | ||
:*Aim radius (AimRadius) | :*Aim radius (AimRadius): no idea what this does. | ||
:*Ballistic projectile speed (ProjectileSpeed) | :*Ballistic projectile speed (ProjectileSpeed): a separate prediction method can be used if the weapon fires gravity-affected projectiles (e.g. grenades). The AI then adjusts its aiming in order to hit the enemy using the ideal (parabolic) ballistic curve. This is a horizontal speed component. | ||
:*Ballistic projectile gravity (ProjectileGravity) | :*Ballistic projectile gravity (ProjectileGravity): the vertical gravity component of the same projectile. | ||
:*Targeting direction (Direction) | :*Targeting direction (Direction): a vector with three components (x, y, z) which gives the orientation of a firing spread. When set to wrong values, the firing spread will not cover the area where the weapon actually shoots (it can even point backwards ^_^). Friendly advice: do not alter unless needed. | ||
:*Targeting origin (Origin) | :*Targeting origin (Origin): a vector with three components (x, y, z) which tells the AI where to fire in relation to the enemy's pelvis. When an armed AI is firing at an enemy, the AI searches for his/her pelvis (see [[TRIA]]), as the pelvis is the representation of the whole character in the AI system. The vector described in this parameter tells the AI how much and in which direction to deviate from the enemy's pelvis position. | ||
::So when the vector is set as (0, 0, -2), AI will aim | ::So when the vector is set as (0, 0, -2), the AI will aim two world units above the enemy's pelvis position. Here is the effect of setting each component positive and then negative, from the shooter's point of view: | ||
::*x - deviate forward/backward (does not have much of an effect) | ::*x - deviate forward/backward (does not have much of an effect when firing at someone on the same floor, as you would expect) | ||
::*y - deviate right/left | ::*y - deviate right/left | ||
::*z - deviate down/up (headshots, anyone?) | ::*z - deviate down/up (headshots, anyone?) | ||
'''Miscellaneous | '''Miscellaneous ONWC AI setup''' - there are a few more parameters in ONWC which affect AI behavior with a weapon. They are (XML tags in parentheses): | ||
:* | :*Minimum shooting distance (MinShootingDistance): defines how close the enemy can be to the AI that is firing. If the enemy comes closer than this distance, the AI stops shooting and tends to move backward (a vector-based movement; see [[#Pathfinding and movement|HERE]]) until the distance is again equal to or greater than the minimum shooting distance. Then the AI opens fire again. To witness this effect, watch an AI operating an SBG when its enemy is close to it. | ||
::'''IMPORTANT''' | ::'''IMPORTANT''': for some unknown reason, the value from this field is '''divided by 2'''. So when set to 100, the AI starts backing up when its enemy is 50 units away. | ||
:* | :*Maximum shooting distance (MaxShootingDistance): The opposite of the parameter described above, this limits how far away an enemy can be before the AI stops shooting and starts moving closer. Watch an AI shooting with the SMG at a distant enemy. | ||
:*Fight timer (FightTimer) | :*Fight timer (FightTimer): a bit similar to thetimer-based BSL command chr_dontaim. Defines in frames for how long should AI switch from a weapon variant (shooting) to a melee variant (hand-to-hand combat) if this firing mode was used (don't forget, a weapon can have two firing modes) and certain conditions were met. See below for ''KnockdownSwitcher'' and ''StunSwitcher'' flag explanations. | ||
:*basic parameters of a weapon (pistol or rifle | :*The basic parameters of a weapon (pistol or rifle, type of ammunition, etc.) can be set using various flags in the ONWC (<Flags> in XML). These three flags from among those affect AI behavior (XML tags in parentheses): | ||
:**NoHolster | :**NoHolster: apart from disabling the ability to holster the weapon, this flag also makes the AI ignore this weapon when lying on the ground. One exception is w10_ba1 when the AI has the Superammo flag (InfiniteAmmo in XML) set in its CHAR profile; then this AI character can pick up the WMC cannon. If an AI is given the weapon, it will still fire it. | ||
:**Stun switcher (StunSwitcher) | :**Stun switcher (StunSwitcher): if the enemy is within an armed AI's shooting range and was knocked down, stunned or blown up, the AI switches to melee for a time specified in the weapon's Fight timer (see above). This flag was designed specially for w6_vdg. | ||
:**Knockdown switcher (KnockdownSwitcher) | :**Knockdown switcher (KnockdownSwitcher): similar to Stun switcher, but only a knockdown or a blownup makes the AI switch to melee. Tailored for w4_psm, probably to avoid AI abuse of an unfair advantage that the PSP grants (the enemy cannot get up as long as she/he is being shot). | ||
Modding hints: Phew, what a long section. | Modding hints: Phew, what a long section. The described material has plenty of modding possibilities. Still, modders should be aware of a few things: | ||
:*Don't set too | :*Don't set too high of a dodge vector (DodgeWeightScale), and don't overdo it with the dodge timer (DodgeTimeScale) -- the smallest possible value is 0.4; lower is not registered. The delay before gunfire dodging (DodgeReactFrames) should be minimal, otherwise it can happen that the AI won't start dodging till the shooter's weapon is empty. | ||
::As a side note, there is a glitch in gunfire dodging. It is not a coding bug, but | ::As a side note, there is a glitch in gunfire dodging. It is not a coding bug, but a limitation of the simple vector-based movement. When the AI starts its gunfire dodge, it tries to get away from the source of danger (be it a firing spread or projectile). And because vector-based movement works as a "desire" to go in some direction, it can happen that the AI will express a "desire" to go into a wall. In such a case, the character stops until the desire to move into a wall stops -- in other words, until the enemy stops shooting at the AI. When an AI character is unarmed, it will try to switch between pathfinding movement (go towards the enemy and attacking him with melee) and vector-based projectile dodging movement, so it kind of looks like the AI is still trying to dodge the gunfire. If the weight of gunfire dodging is set to be smaller than the standard vector-based movement weight, then the AI does not even have to get stuck, as it will run in a zigzag pattern towards the armed enemy. | ||
:: | ::If the AI is armed with a loaded weapon, there is no point in the AI running towards enemy. That means if the AI starts dodging and meets a wall, this AI gets "stuck" until the enemy's gunfire stops. If this character has "ShootDodge" set in their ONCC, it will at least fire back at the enemy shooter. But in case the character has "RunAwayDodge" set, then it simply stands near the wall and stares and waits till the enemy's gunfire ceases. | ||
::From | ::From this explanation, it can be seen that the gunfire dodge parameters should be set to make the AI dodge, but to not make the dodge vector outweigh the vector for moving towards the enemy. | ||
:*AI's skills with weapons (in | :*An AI's skills with weapons (in ONCC) can be used to create anything from sharpshooters to rookies who cannot hold a gun properly. For example, by setting "ShootGroupError" to 10.0 for w1_tap, we create a total amateur whose hand shakes all over the place when he fires the Campbell Equalizer. You can experiment with different settings in realtime using the ai2_skill* functions on the dev console line. See [https://www.youtube.com/watch?v=cxTz30YOPhc this video] where ai2_skill_error is used to override a character's original grouping error setting with new values. | ||
:*Unless really | :*Unless really necessary, do NOT alter the ONCC prediction parameters. Bungie set them quite reasonably, and if they are messed with, the AI loses accurate predictive abilities. | ||
:*In | :*In ONWC, Prediction speed is used for a calculation of the AI's aim. This speed should be exactly the same as the speed of this weapon's projectile. A projectile's velocity is usually set in the emitter of the projectile particle (PAR3). The separate values means that the predicted speed and actual speed of a weapon's projectile may differ, the most significant case being w3_phr (plasma balls accelerate rapidly). | ||
::If Prediction speed is set lower than the speed of a projectile | ::If Prediction speed is set lower than the speed of a projectile, the AI will tend to shoot too far in front of an enemy moving left/right since it will assume the projectile is slower than it really is. On the other hand, setting this value higher means that the AI will shoot too directly at the moving enemy (probably missing), as the AI will think the projectiles are fast enough to hit the target. | ||
:*Similar to Prediction speed, there are Ballistic projectile speed and Ballistic projectile gravity. When these two are set non-zero, AI assumes ballistic | :*Similar to Prediction speed, there are Ballistic projectile speed and Ballistic projectile gravity. When these two fields are set to non-zero values, the AI assumes that the projectiles are ballistic (e.g. grenades), and tries to shoot along a parabolic arc (the solution with shortest travel time is always chosen). In order to make AI successfully hit an enemy's pelvis, these values again must correspond with the particle's (PAR3) speed and gravity attraction, but they can be used for modding purposes as well. For example, if a projectile's gravity attraction is 0.5, but in the ONWC, the Ballistic projectile gravity is set as 0.3, the AI will shoot projectiles at the enemy's feet as it will assume that the gravity attraction of the projectile is lower and it does not have to aim so high in order to hit the pelvis (credit to [[User:Gumby|Gumby]]). Remember: for the AI system, the pelvis is a representation of a whole character. | ||
:* | :*The targeting origin vector (ONWC) can be utilized to make the AI fire higher than the pelvis (with a negative "z" component), so the AI can score headshots. Currently, such a change does not have any purpose, as characters don't have separate damage coefficients for different body parts. But maybe in the future... or with Paradox's headshot mod... (see [[XML:BINA/ONIE#Extra_damage_for_head_hits|HERE]] for his material-dependent damage mod ideas). | ||
:*One thing | :*One thing purposely left out in our main discussion of weapons is that there is an option for AIs to perform "startle" misses -- when startled, the AI can fire in some random direction. The parameters for this behavior are in ONCC and ONWC, but overall this feature is so minor that it does not need any special modding attention. | ||
:*Remember: in | :*Remember: in the ONWC, Minimum shooting distance is '''divided by 2'''. The reason is unknown (maybe some bug in the code). | ||
:*Through modification of | :*Through modification of Minimum shooting distance in conjunction with BSL scripting, a modder can achieve pseudo-intelligent holstering behavior. If an enemy gets too close, the AI will start backing away. Since this backing away motion is almost never used by an armed AI (it usually moves side-to-side), it can be watched for using the BSL function chr_wait_animation, and used as a trigger for scripting code to make the AI holster his weapon. To unholster, a different animation has to be watched for, such as a taunt animation. In [[MELE]], a modder can set up a melee profile which makes the AI taunt only at a safe distance. | ||
:: | ::A drawback of this modification is that the enemy ''will not fire his weapon at point blank range'', and also it limits the Melee override in [[CMBT]] to be only None or IfPunched; otherwise, instead of backing away, the AI goes directly into melee. | ||
== | ==Melee combat behaviors== | ||
Ah yes. After all those OTHER things, we finally | Ah yes. After all those OTHER things, we finally get to how the AI system handles the core gameplay feature of this game, hand-to-hand combat. First things first. As usual, a player can see her/his enemy trying to perform some move and react to it. An AI, however, cannot see a thing because it does not have eyes, nor a human brain. Thus the first question is, How does the AI learn about incoming attacks? | ||
First things first. As usual, player can see her/his enemy trying to perform some move | [[Image:Melee zones.jpg|thumb|right|alt=Melee zones around a character|A rough illustration of melee zones.]] | ||
[[ | :The answer lies within the [[TRAM]] files. Each animation which can hurt somebody should have "extents". Extents are invisible boundaries which tell the AI about the range of enemy attacks. There are two types, horizontal and vertical, but the more important thing AI-wise is that, without extents, attack TRAMs will not be registered by AI characters as attacks, so AI will not try to block or dodge them. As long as the attack has extents data, then the AI will have the needed knowledge of the path of the attacking character's body parts (see attack part of [[TRAM]]). | ||
: | :This info is used by the melee part of AI for defensive purposes (deciding what kind of evasive move to use, and whether to crouch or not) as well as for offensive purposes -- an AI will not execute an attack move unless it sees that the enemy falls within its attack move's extents. | ||
:This info is used by melee part of AI for | |||
:Also, for hand to hand purposes engine recognizes roughly four zones around a character | :Also, for hand-to-hand purposes, the engine recognizes roughly four zones around a character (see picture on right). These zones correspond to positioning moves, so when a melee technique has, for example, CloseBack, then the only time this melee technique is listed for possible execution is when the enemy is in back of the AI. In all other cases (enemy in the left, right or front zone), this technique is NOT listed for use. The exception is when a technique has the GenerousDir flag set; see below for more info. | ||
Melee mode AI combat is handled via [[MELE]] profiles. A MELE profile is assigned to a spawnable character in its [[CHAR]] profile. When in melee mode, an AI uses vector-based movement. Unless otherwise specified, the AI is inclined to run towards its enemy. | |||
: | :A MELE profile always contains these parameters (XML tags in parentheses): | ||
:*Character class (CharacterClass) | :*Character class (CharacterClass): link to an [[ONCC]]. The importance of this parameter not known, but maybe it is necessary in order to allow for some attacks to be performed (engine checks being performed through the ONCC and its [[TRAC]]). | ||
:*Notice (Notice) | :*Notice (Notice): percent chance that AI will notice an incoming attack. In retail profiles, it is always set to 100. | ||
:*Dodge base (Base inside Dodge) | :*Dodge base (Base inside Dodge): percent chance that AI will try to use an evasion moves (if it has any in the evade section of its MELE profile) to avoid getting hurt. | ||
:*Dodge extra (Extra inside Dodge) | :*Dodge extra (Extra inside Dodge): extra chance to dodge. | ||
:*Dodge extra damage (ExtraDamageThreshold inside Dodge) | :*Dodge extra damage (ExtraDamageThreshold inside Dodge): amount of damage needed to activate the extra chance of dodging. | ||
:*Single block skill | :*Single block skill (Single inside BlockSkill): percent chance of an attempt to block an incoming attack. | ||
:*Group block skill | :*Group block skill (Group inside BlockSkill): percent chance of maybe of blocking more attackers??? | ||
:*Not blocked (NotBlocked) | :*Not blocked (NotBlocked): a multiplier which affects the weight of techniques which will not be blocked by the enemy under the current circumstances (such as a punch combo against an opponent who is running forward). | ||
:*Must change stance (MustChangeStance) | :*Must change stance (MustChangeStance): a multiplier which affects the weight of techniques which force the enemy to change stance (standing vs. crouching) in order to block them under the current circumstances (such as a leg sweep against a standing opponent). | ||
:*Blocked but unblockable (BlockedButUnblockable) | :*Blocked but unblockable (BlockedButUnblockable): a multiplier which affects the weight of techniques that have the "unblockable" flag set in their attack part (see [[OBD:TRAM/raw0x14|TRAM attack part settings]]). | ||
:*Blocked but has stagger (BlockedButHasStagger) | :*Blocked but has stagger (BlockedButHasStagger): a multiplier which affects the weight of techniques that would make the enemy stagger if the enemy does block them, that is, they have the "stagger" flag set in their attack part (see TRAM attack part settings). | ||
:*Blocked but has | :*Blocked but has block stun (BlockedButHasBlockStun): a multiplier which affects the weight of techniques that would trap the enemy in a blocking animation for longer than 20 frames, that is, they have the "block stun" flag set in their attack part settings (see TRAM attack part settings). | ||
:*Blocked (Blocked) | :*Blocked (Blocked): a multiplier which affects the weight of techniques that will definitely be blocked by the enemy under the current circumstances and will not stagger or stun the enemy. | ||
:*Throw Danger (ThrowDanger) | :*Throw Danger (ThrowDanger): something to do with throws, but only Bungie West knows the meaning of this field. | ||
:*DazedMinFrames, DazedMaxFrames | :*DazedMinFrames, DazedMaxFrames: These were documented by Neo, but the question is, Do these two parameters actually have any effect, since the get-up time is controlled from the ONCC? | ||
Our basic melee setup is done. Now the profile branches into an '''attack''' part, an '''evade''' part, and a '''maneuver''' part. Each part has a certain number of "melee technique" slots. A melee technique is a set of one or more melee moves. A melee move is any single element of hand-to-hand combat -- an attack, a throw, a positioning command, or some maneuver. The maximum number of techniques in one melee profile is 32. If this limit is exceeded, Oni crashes. Let's take a detailed look at all three parts of the MELE profile: | |||
:*Attack branch | :*Attack branch: techniques from this branch are executed when the AI is trying to attack and hurt its enemy. The attack branch contains not only attack techniques, but also maneuver techniques (more about this later). | ||
:*Evade branch | :*Evade branch: techniques containing moves which are used to evade an attack -- escape moves (as when the player presses crouch + some directional key) and/or various jumps/slides. These techniques are picked only when an AI is reacting to an incoming attack. | ||
:*Maneuver branch | :*Maneuver branch: techniques from this branch should be used by the AI to maneuver around, so as to not just move in a straight line towards the enemy, but also circle around him, retreat, or advance. Unfortunately, this branch is probably a development relic. The AI only starts performing techniques from this maneuver branch when the global BSL variable [[ai2_spacing_cookies]] it set to zero, but that means that the AI cannot execute attacks. | ||
::The idea was probably | ::The idea was probably that when the AI had run out of attacks to execute (each attack "eats" a cookie), the AI would use the maneuver branch for a bit until it got a new cookie, and so on and so on. But somehow this setup was abandoned (the question is whether MELE was really planned that way ^_^ ), and techniques from this branch are ''de facto'' never used. This means that all maneuvering is done via the Attack branch. | ||
Structure of a melee technique: | Structure of a melee technique: | ||
:*'''Name''' (debugging purposes only) | :*'''Name''' (for debugging purposes only) | ||
:*'''Flags''' | :*'''Flags''': the possibilities are: | ||
::*Interruptible | ::*Interruptible: this technique can "home in" on the enemy to some extent, and if the enemy gets out of its reach, the technique is ended prematurely. | ||
::*GenerousDir | ::*GenerousDir: this technique is listed for possible execution even when the AI's facing does not match the position move of this technique (e.g. the technique uses CloseLeft but the enemy is directly in front). If the technique is used, the AI positions itself in order to perform the technique (in our example, the AI would turn his left side to the enemy and perform the technique). | ||
::*Fearless | ::*Fearless: does this flag actually do something? | ||
:*'''Weight''' | :*'''Weight''': the basic weight of the technique. Techniques are chosen randomly, but with the "weight" of the technique taken into account. Techniques with higher "weight" are used more often than those with lower "weight". | ||
::Also, there are more factors which affect final weight of the technique. '' | ::Also, there are more factors which affect the final weight of the technique. The ''basic weight'' of the technique is, according to the combat situation (position of the enemy, effect of moves in the technique), multiplied by one of the MELE profile's multipliers (NotBlocked, BlockedButHasStagger, etc.), then it is also multiplied by some diminishing value which decreases the weight of the technique if it is used consecutively. And finally, the weight of the technique is multiplied by a special "orange tiles" multiplier, which weighs down techniques that would make the AI fall over an edge, that is, dive into a part of the pathfinding grid that would be visualized as an orange-tiled area. | ||
:::The equation is PROBABLY very | :::The equation is PROBABLY very roughly something like this: | ||
:::Final weight = | :::Final weight = basic weight * corresponding MELE profile setup multiplier * diminish multiplier * "orange tiles" multiplier | ||
:*'''"Importance"''' | :*'''"Importance"''': documented by Neo, but does it have any effect? | ||
:*'''RepeatDelay''' | :*'''RepeatDelay''': in frames, how long should the technique be unavailable after its use (to avoid predictability). | ||
:*'''Moves''' | :*'''Moves''': the possible types of moves are: | ||
::*Position | ::*Position: usually takes three parameters -- minimum distance, maximum distance, and tolerance range. The meaning of minimum/maximum distances is clear; the tolerance range specifies an extra distance (beyond the chosen TRAM's attack extents) over which the AI will chase the enemy till the enemy gets inside the extent range of the attack this AI wants to use. | ||
:::Some | :::Some positioning moves don't have any parameters (Crouch, StartToCrouch) and are used strictly for stance purposes -- to make the AI perform crouched or special attacks. Positioning moves are used to give the AI variety in their available attacks, as techniques are chosen based on the melee zone the enemy is in (see picture at the beginning of this section). [[OBD:BINA/OBJC/MELE/MoveList/Position|HERE is a list]] of all available positioning moves in melee combat. | ||
::*Attack | ::*Attack: no parameter, just an attack action. [[OBD:BINA/OBJC/MELE/MoveList/Attack|HERE is a list]] of all available attack moves in melee combat. | ||
::: | :::An attack move can be the only move in a technique (no positioning move). If that is the case, then this technique is put into a list of possibly techniques only when its prerequisites (positioning and stance) are met via other means. For example, Kick_forward can be used without a Position move, but since a move is evaluated only when the AI sees an enemy within its extents, the AI will have to get into the correct position for the attack by some other means (maybe another melee technique), otherwise the technique with Kick_forward will be labeled as MISSBOUNDS. | ||
::*Throw | ::*Throw: no parameter, just a throw move. [[OBD:BINA/OBJC/MELE/MoveList/Throw|HERE is a list]] of all available throw moves in melee combat. As with an Attack, a Throw can be standalone, to be used under the circumstances described above. | ||
::*Evade | ::*Evade: no parameter, just an evasive action. [[OBD:BINA/OBJC/MELE/MoveList/Evade|HERE is a list]] of all available evasion moves in melee combat. | ||
::* | ::*Maneuver: taking up to three parameters, these moves are used to make the AI move around (advance, retreat, circle left/right) or perform various movements (crouch, jump, taunt, use uncommon get-up moves etc.). [[OBD:BINA/OBJC/MELE/MoveList/Attack|HERE is a list]] of all available maneuver moves in melee combat. Almost all maneuver moves have a Duration ('''in seconds''') as a first parameter. | ||
: | :Melee techniques can be a mixture of melee moves. The very first move (which should be positioning or maneuvering) is evaluated to make sure if the technique can be performed with the current positioning of the AI and its enemy. However, throws and maneuvers are checked as well even if they are not the first technique, so if a technique contains Throw_punch_behind, for example, it will be listed for use only if the AI is behind its enemy. Surprisingly enough, pairing Kick_forward and Kick_back makes the AI kick forward when the position is correct for a forward kick, and then kick backward even though there is nothing to hit ^_^. The same goes for other directional attacks. | ||
Also there is one special condition to executing melee techniques. When there is | Also, there is one special condition to executing melee techniques. When there is a ledge in a level, it is usually covered in pathfinding grid by a series of special tiles going from blue (border) to orange (danger). As mentioned earlier, the engine seems to check if an attack TRAM's extents run into an area of orange pathfinding tiles and, if so, it decreases the weight of techniques which would make the AI end up in an orange field (which would mean going over the edge). Techniques which utilize jump positioning moves are excluded from this weight decrease, so there is a very limited and random possibility for AIs to jump across gaps in order to reach the enemy. | ||
: | :The code behind all this must be pretty complex; hats off to the Oni developers who managed to pull this off. | ||
Modding hints: Creating custom MELE profiles can be fun, but beware of a few pitfalls: | Modding hints: Creating custom MELE profiles can be fun, but beware of a few pitfalls: | ||
:* | :*Positioning moves can be followed by some other positioning moves, but generally after a positioning move an attack or throw move is expected. If an attack or throw is not present, this melee technique will be labeled as NOATTACKNOTHROW and will be unused. | ||
:* | :*Jump positioning moves can be used to make the AI sometimes jump across gaps. As explained above, the presence of orange tiles nearby will up-weight jumping moves a lot. Just don't forget to follow up the jump positioning move with some jumping attack move. | ||
:* | :*Special attacks (e.g. Rising Fury, Devil Spin Kick) use the StartToCrouch positioning move as a starter. | ||
:* | :*Any combo technique (for example, a three-punch combo) without the Interruptible flag will make the AI too vulnerable. | ||
:* | :*Rear throw techniques and side attack techniques should have a high weight to ensure they will be chosen and used the moment there is a chance. | ||
:*Set the distances in positioning moves reasonably so that the AI doesn't attempt to perform jumping or running attack moves at close distance. | |||
:*Always try to utilize a given class' strength. The Fury is fast, so give weight to combos. The Tanker is slower, so give weight to throws and running attacks. The Ninja is a beast; set whatever you want and it will be annoying to deal with anyway. | |||
[[Category: | [[Category:Engine docs]] | ||