Jump to content

AI: Difference between revisions

327 bytes removed ,  21 December 2015
finishing rewrite; adjusting statement about dodging per Loser's correction -- it was only projectile dodging that was fixed, not firing spread dodging
(continuing rewrite; correcting statement that gunfire dodging was only fixed for particles -- I am pretty confident it was fixed for firing spreads too)
(finishing rewrite; adjusting statement about dodging per Loser's correction -- it was only projectile dodging that was fixed, not firing spread dodging)
Line 1: Line 1:
==Foreword==
Motivational video: http://www.youtube.com/watch?v=8Okn7u_-oVs
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 147: Line 144:
: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 alert level this AI can have
:*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 301: Line 298:
:*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 minimal 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.
:*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 324: Line 321:
:*Alarm running: It is actually required if an alarm run is called via the no-gun alarm run behavior, otherwise glitches will appear.
:*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 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.
:*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: If the distance between the AI and its enemy is smaller than the minimal shooting distance, the AI tries to backpedal away from its enemy till the distance between characters is greater than the minimal 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 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: 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.
:*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?
Line 344: Line 341:


'''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):
'''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 minimal number of frames (DazedMinFrames): minimal number of frames that AI stays on the ground.
:*Knockdown minimum number of frames (DazedMinFrames): minimum number of frames that AI stays on the ground.
:*Knockdown maximal number of frames (DazedmaxFrames): maximum number of frames that AI stays on the ground.
:*Knockdown maximum number of frames (DazedmaxFrames): maximum number of frames that AI stays on the ground.


: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.
: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.
Line 413: Line 410:
'''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:
'''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.
:*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. 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.
:*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.
 
Projectile dodging is the epic win of Oni modders. In the retail version of Oni, projectile dodging is mostly broken due to a couple of bugs in the code. Since the engine hackers/modders fixed this issue, AIs can now [https://www.youtube.com/watch?v=aEuAu7jLQQI execute proper gunfire dodging].




Line 455: Line 450:
:*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.
:*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): also controls the degree that the AI's aim strays from the target, but it's not clear how much it really affects aiming.
:*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.
:*Minimal shooting delay (MinShotDelay): minimum pause between reloading and resuming firing.
:*Minimum shooting delay (MinShotDelay): minimum pause between reloading and resuming firing.
:*Maximal shooting delay (MaxShotDelay): maximum pause between reloading and resuming firing.
:*Maximum shooting delay (MaxShotDelay): maximum pause between reloading and resuming firing.




Line 494: Line 489:
:*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):
:*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: 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.
:**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): 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.
:**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): 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).
:**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).




Line 528: Line 523:




==Combat behavior part 4 : "Everybody was kung fu fighting..."==
==Melee combat behaviors==
Ah yes. After all those OTHER things, we finally got to how AI system handles the core gameplay feature of this game, hand to hand combat.
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, so player can then react. AI character cannot see a thing beacuse it does not have human eyes nor human brain. Thus the first question is how the AI knows about incoming attacks?
[[File:Melee zones.JPG|thumb|right|alt=Melee zones around a character|A rough illustration of melee zones.]]
[[File:Melee zones.JPG|thumb|right|alt=Melee zones around a character|Rough idea 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]]).
:Answer lies within [[TRAM]] files. Each animation which can hurt somebody should have EXTENTS. Extents are invisible marks which tell AI character how the attack's ''trajectory'' looks. There are two types, horizontal and vertical, but 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 them or dodge or attack with the [[TRAM]] animation properly. But if the attack has extents, then AI gets a complete knowledge of a whole path of attacking bodyparts of this enemy's attack (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 defense purposes (deciding what kind of dodge move to choose and whether to crouch or not) and for attack purposes - position move in melee techniques are used to give general info about the melee technique's positioning, but AI character will not execute the attack move of the technique till enemy is within chosen attack move's extent range.




:Also, for hand to hand purposes engine recognizes roughly four zones around a character, see picture on right. These zones are then corresponding with position moves, so when melee techique has for example CloseBack, then the only time this melee techique is listed for possible execution is when enemy is in the back of the AI character. In all other cases (enemy in left, right or front zone), this techique is NOT listed for use. Exception is a technique with GenerousDir flag, see below for more info.
: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.




Fistfighting AI mode is handled via [[MELE]] profiles. MELE profile is assigned to the spawnable character in its [[CHAR]] profile. When in melee mode, AI character uses vector type of movement. Unless specified otherwise, AI character is made to run towards its enemy.
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.
:[[MELE]] profile always contains these parameters (xml tags in parentheses):
:A MELE profile always contains these parameters (XML tags in parentheses):
:*Character class (CharacterClass) - Link to an [[ONCC]] class. Level of importance of this parameter not known, but maybe it is neccessary in order to allow for performance of some attack moves (engine checks referenced [[ONCC]] class and its [[TRAC]]).
:*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) - percentual chance that AI will register incoming attack. In retail profiles it is always set 100.
:*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) - percentual chance AI will try to use one of '''evade''' moves (if it has any in evade section of MELE profile) to avoid getting hurt.
:*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) - extra chance to dodge
:*Dodge extra (Extra inside Dodge): extra chance to dodge.
:*Dodge extra damage (ExtraDamageThreshold inside Dodge) - amount of damage for activation of extra dodge
:*Dodge extra damage (ExtraDamageThreshold inside Dodge): amount of damage needed to activate the extra chance of dodging.
:*Single block skill - (Single inside BlockSkill) - percentual chance of attempt to block incoming enemy's attack
:*Single block skill (Single inside BlockSkill): percent chance of an attempt to block an incoming attack.
:*Group block skill - (Group inside BlockSkill) - percentual chance of ???. Not sure, maybe of blocking more attackers?
:*Group block skill (Group inside BlockSkill): percent chance of maybe of blocking more attackers???


:*Not blocked (NotBlocked) - Multiplier which affects weight of techniques which will not be blocked by the enemy under current circuumstances (punch combo against opponent who is running forward).
:*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) - Multiplier which affects weight of techniques which force enemy to change stance (standing, crouching) in order to block it under current circuumstances (leg sweep against standing opponent).
:*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) - Multiplier which affects weight of techniques that have "unblockable" flag in its attack part, see [[OBD:TRAM/raw0x14|TRAM-attack part]].
:*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) - Multiplier which affects weight of techniques that makes enemy stagger if the enemy blocks the technique. Depends on TRAM attack part settings (BlockStagger), see [[OBD:TRAM/raw0x14|TRAM-attack part]].
:*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 blockstun (BlockedButHasBlockStun) - Multiplier which affects weight of techniques that lock enemy in a blocking animation for longer than 20 frames. Depends on TRAM attack part settings (BlockStun), see [[OBD:TRAM/raw0x14|TRAM-attack part]].  
:*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) - Multiplier which affects weight of techniques that will be certainly blocked by the enemy under current circuumstances and will not stagger nor stun the enemy.
:*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) - Something with throws, but only Bungie West knows what's the meaning of this field.
:*Throw Danger (ThrowDanger): something to do with throws, but only Bungie West knows the meaning of this field.


:*DazedMinFrames, DazedMaxFrames - documented by Neo. Question is - do these two parameters actually have effect, since getup time is controlled from ONCC?
:*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?




Basic melee setup is done. Now the profile branches into '''attack''' part, '''evade''' part and '''maneouver''' part. Each part has a certain number of "melee techniques". Melee technique is a compound of one or more melee moves. ''Melee move'' is a simple element of hand to hand combat - attack, throw, positioning command or some maneuver. Maximal amount of techniques in one melee profile is 32. If this limit is exceeded, Oni crashes. Let's have detailed look at all three mentioned parts of [[MELE]] profile:
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 - Techniques from this branch are executed when AI is trying to attack and hurt it enemy. Attack branch contains not only attack techniques, but also maneuver techniques as well (more about this later).
:*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 - Techniques contain moves which are used to evade attack. That means escape moves (SHIFT + some direction) and/or various jumps/slides. These techniques are picked only when AI character reacts on incoming enemy's attack.
:*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 - Techniques from this branch should be used by AI to maneuver around, in order to move not only in a straightforward fashion towards the enemy, but also circle around, retreat or advance. Unfortunately, this branch is probably a development relic. In order to see these techniques performed, global [[BSL]] variable '''ai2_spacing_cookies''' has to be set zero (0). That means AI cannot execute attacks. Only then AI starts performing techniques from this 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 to make the AI execute a certain number of attacks (each attack "eats" a cookie), then make the AI maneuver a bit and so on and so on. But somehow this setup was abandoned (question is whether MELE was really planned that way ^_^ ) and techniques from this branch are de-facto never used. That means all maneouvring is done via Attack branch.
::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''' - possibilities are:
:*'''Flags''': the possibilities are:
::*Interruptible - This technique can "home" to some extent and if enemy gets away from its reach, technique is ended prematurely.
::*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 - This technique is enlisted for possible execution even when facing of the AI does not match position move of this technique (technique uses CloseLeft, enemy is directly in front). If technique is used, AI character positions itself in order to perform the techique (in our example case, AI chracter turns left side towards enemy and perform the technique).
::*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 - does this flag actually do something?
::*Fearless: does this flag actually do something?
:*'''Weight''' - Basic weight of the technique. Techniques are chosen randomly but with "weight" of the technique taken into account. Techniques with higher "weight" are used more often than those with lower "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. ''Basic weight'' of the technique is according to combat situation (position of the enemy, effect of moves in the technique) multiplied by one of MELE profile setup multipliers (NotBlocked, BlockedButHasStagger etc.), then it is also multiplied by some dimnishing value which decreases weight of the technique if it is used consencutively. And finally, weight of the technique is multiplied by some special "orange tiles" mutiplier, which downweights techniques that would make the AI "fall over the edge", aka dive into orange tiled area.
::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 roughy something like this:
:::The equation is PROBABLY very roughly something like this:
:::Final weight = Basic weight * corresponding MELE profile setup multiplier * dimnish multiplier * "orange tiles" multiplier
:::Final weight = basic weight * corresponding MELE profile setup multiplier * diminish multiplier * "orange tiles" multiplier
:*'''"Importance"''' - documented by Neo. Does it have any effect?
:*'''"Importance"''': documented by Neo, but does it have any effect?
:*'''RepeatDelay''' - in frames, how long should be the technique unavailable after its use (to prevent from predictability). For this time the technique is not enlisted in a list of performable techniques.
:*'''RepeatDelay''': in frames, how long should the technique be unavailable after its use (to avoid predictability).
:*'''Moves''', possible types of moves are:
:*'''Moves''': the possible types of moves are:
::*Position - usually takes three parameters: minimal distance, maximal distance, tolerance range. Meaning of Minimal/Maximal distances is clear, tolerance range specifies extra distance (beyond chosen TRAM attack's extents) where AI chases the enemy till the enemy gets inside the extent range of the [[TRAM]] attack this AI charater wants to use. Then AI uses the TRAM attack ^_^.
::*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 position moves don't have any parameters (Crouch, StartToCrouch) and are used strictly for stance purposes - to make AI perform crouched or special attacks. Position moves are used to give the AI general sorting of available attacks, so based on the melee zone the enemy is in (see picture at the beginning of this section) only corresponding techniques are taken into account as "possible to be used" and the rest is ignored. [[OBD:BINA/OBJC/MELE/MoveList/Position|HERE is a list]] of all available position melee moves.
:::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 - no parameter, simply some kind of attack action. [[OBD:BINA/OBJC/MELE/MoveList/Attack|HERE is a list]] of all available attack melee moves.
::*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.
:::Attack move can be the only move of a techique (no position move). If that is the case, then this techique is put into a list of possibly used techniques only when its prerequisities (positioning and stance) are met via other means. For example Kick_forward can be used without a Position move, but then it is evaluated only when the AI character gets within the extent range of its Kick_forward [[TRAM]] move. Then the AI chracter has to somehow get into correct position within extent range of the Kick_forward's TRAM (maybe via other melee techniques), otherwise the technique with Kick_forward is labeled as MISSBOUNDS. When all that is OK, this a melee technique is listed for possible use.
:::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 - no parameter, simply some throw. [[OBD:BINA/OBJC/MELE/MoveList/Throw|HERE is a list]] of all available throw melee moves. Again can be standalone, under circuumstances described above.
::*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 - no parameter, simply some evasive action. [[OBD:BINA/OBJC/MELE/MoveList/Evade|HERE is a list]] of all available evasion melee moves.
::*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.
::*Maneouver - up to three parameters, these moves are used to make AI character move around somehow (advance, retreat, circle left/right) or perform various movements (crouch, jump, taunt, use uncommon getup moves etc.) [[OBD:BINA/OBJC/MELE/MoveList/Attack|HERE is a list]] of all available maneuver melee moves. Almost all maneouver moves have a Duration ('''in seconds''') as a first parameter.
::*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.
:In melee techniques there can be a mixture of melee moves. Very first move (shuold be position or maneouver) is evaluated to make sure if the technique can be performed under current positioning of the AI character and its enemy. However, throws and maneuvers are checked as well even if they are not the first tehnique, so if technique contains Throw_punch_behind, it will be listed for use only if the AI is in theback of its enemy. Surprisingly enough, pairing Kick_forward and Kick_back makes AI character kick forward when position is correct for kick forward move, then it kicks back even tough there is nothing to hit ^_^. Same with other directional attacks.
: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 an edge of a platform nearby it is usually covered in pathfinding grid as a seires of special tiles from blue (border) to orange (danger). Engine seems to check if [[TRAM]] attack's extent extends into orange pathfinding tiles and according to it it decreases weight of such techniques which would make AI character end in orange field (i.e. going over the edge and falling down). Techniques which utilize jump position moves are excluded from weight decrease, so there is some very limited and random possibility for AI characters to jump aross gaps in order to reach the enemy.
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.
:Code behind all this must be pretty complex, hands down before Oni developers who managed to pull this off.
: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:
:*Position moves can be followed by some certain other position moves, but generally after position move an attack or throw move is expected. If attack or throw is not present, this melee technique will be albeled as NOATTACKNOTHROW and will be unused.
:*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 position moves can be used to make AI at least "somehow" jump across gaps. Oni registers special pathfinding grid tiles (edge tiles and danger tiles) which are registered by AI character even she/he is in melee mode. And orange tiles upweight jumping moves a lot. Just don't forget to follow jump position move with some jump attack move.
 
:*Special attack (Rising fury, Devil spin kick) use StartToCrouch position move as a starter.


:*Any combo techique (for example three punch combo) without Interruptible flag makes AI character too vulnerable.
:*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.


:*Rear throw techniques and side attack techniques should have high weight to ensure they will be chosen and used the moment there is a chance.
:*Special attacks (e.g. Rising Fury, Devil Spin Kick) use the StartToCrouch positioning move as a starter.


:*Set distances in position moves reasonably so AI character doesn't attempt to perform jump attack techniques or run attack techniques at close distance.
:*Any combo technique (for example, a three-punch combo) without the Interruptible flag will make the AI too vulnerable.


:*Always try to utilize given class's strength - Fury is fast, so upweight combos. Tanker is slower, upweight throws and run attacks. Ninja is a beast, set whatever you want and it will be annoying to deal with anyway.
:*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.


<div style="text-align: center;">[http://www.youtube.com/watch?v=XeymFlbQuNg|'''THE END...''']</div>
:*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:Modding information]]
[[Category:Modding information]]