Combat AI of various units
Some units in Gothic 2 (Classic) behave incorrectly. I'm playing on opengothic-v1.0.2207 using the Gothic 2 Classic Mod provided by the Steam installation.
E.g. consider a troll. In the original G2 troll behavior seems to be as follows:
- Not in combat yet AND target too far away => Growl a few times
- In combat AND target is not in front of the troll => turn around
- In combat AND target is in front of troll AND target too far away => Run towards target
- In combat AND target is in front of troll AND target is in range => attack In OpenGothic there's a difference:
- Not in combat yet AND target too far away => Growl a few times
- In combat AND troll gets attacked => attack
- In combat AND target is not in front of the troll => turn around
- In combat AND target is in front of troll AND target too far away => Run towards target
- In combat AND target is in front of troll AND target is in range => attack This makes fighting trolls rather trivial as attacking them from the side forces the troll to keep facing the direction that the troll is currently looking at and attack into the air. If I had to guess, I'd think it's some function that makes them skip their growl that forces them into attacking when hit or maybe a check for whether the target is in front of the troll is missing.
Minecrawlers run far back when they are hit in the original Gothic 2. In OpenGothic the distance they go back is quite a bit shorter.
(Dragon-)Snappers (and likely Wargs and Wolves) behave differently too. In the original they charge towards you and do a big bite, followed by a quick one. If the player keeps stepping back, they'd repeat. If the player stands in range and doesn't hit them, Snappers do their machine-gun-bite-series. In OpenGothic they do their charge, the big bite but don't follow up with another bite quickly. They also don't seem to machine-gun-bite if left unattacked and in range. Strangely, Goblins do their machine-gun hammering with their heavy sticks if you let them.
In OpenGothic Bloodflies often just fly towards the player and chill without attacking. In the original game, they attack a lot more frequently.
I've noticed more differences in combat with some npcs (and skeletons) but I'm not 100% sure on this so pls take this with a grain of salt. Most NPCs (with a weapon skill lvl above 30) do this in the original G2: If right in front of the player and NOT attacked by the player, then the NPC either:
- does main attack => (step back OR wait and parry)
- or does main attack => main attack
- or does left attack => right attack A step back would make them run around a bit. In OpenGothic the fight seems a lot less scripted. The NPCs seem to often just do one attack. They also run around and parry a lot less than in the original Gothic 2.
I think most of these happen, because Units don't chain their actions (like NPCs with their parries, Snappers with their bites, Minecrawlers with the back-steps etc.).
Hi, @Tate39!
E.g. consider a troll. In the original G2 troll behavior seems to be as follows
I'm sorry, but this is quite far away from how game works internally. Combat AI in gothic made of multiple parts:
-
C_FightAIdescriptors in script, defines up to 6 move options, for given situation -
ai_attackqueue - command, that script calls to queue-up single attack action - at execution time command engine need to pick correct
C_FightAIand select one of moves randomly.
Here is script example, from snapper AI:
// 18 - is fight tactics ID, from npc
INSTANCE FA_MY_W_FOCUS_18 (C_FightAI) // when in attack range wait or attack
{
move[0] = MOVE_ATTACK;
move[1] = MOVE_WAIT;
};
INSTANCE FA_MY_W_NOFOCUS_18 (C_FightAI) // when in attack range, but no combat focus
{
move[0] = MOVE_TURN;
};
Here full list of fight-AI descriptors:
phoenix::c_fight_ai enemy_prehit; // Enemy attacks me
phoenix::c_fight_ai enemy_stormprehit; // Enemy makes a storm attack
phoenix::c_fight_ai my_w_combo; // I'm in the combo window
phoenix::c_fight_ai my_w_runto; // I run towards the opponent
phoenix::c_fight_ai my_w_strafe; // Just take hit
phoenix::c_fight_ai my_w_focus; // I have opponent in focus (can hit)
phoenix::c_fight_ai my_w_nofocus; // I don't have opponent in focus
// 'G' - range
phoenix::c_fight_ai my_g_combo; // I'm in the combo window (not used in G2)
phoenix::c_fight_ai my_g_runto; // I run towards the opponent (can make a storm attack)
phoenix::c_fight_ai my_g_strafe; // not used in G2
phoenix::c_fight_ai my_g_focus; // I have opponent in focus (can hit)
// FK Range Foes (far away)
phoenix::c_fight_ai my_fk_focus; // I have opponents in focus
phoenix::c_fight_ai my_g_fk_nofocus; // I am NOT in focus of opponents (also applies to G-distance!)
// Range + Magic (used at each removal)
phoenix::c_fight_ai my_fk_focus_far; // Opponents in focus
phoenix::c_fight_ai my_fk_nofocus_far; // Opponents NOT in focus
phoenix::c_fight_ai my_fk_focus_mag; // Opponents in focus
phoenix::c_fight_ai my_fk_nofocus_mag; // Opponents NOT in focus
Picking correct C_FightAI is difficult part, as they are defined very loosely. For example 'G'-range is quite unclear. Priority is also unclear.
Some command tokens are also not clear:
MOVE_RUN
MOVE_RUNBACK
MOVE_JUMPBACK
MOVE_TURN // de-facto same as run, but why?
MOVE_STRAFE
MOVE_ATTACK // what about charge-attacks ?
MOVE_PARADE
MOVE_STANDUP // what ? unused by game script anyway...
MOVE_WAIT
Thank you for the indepth explanation! I must admit, I hadn't checked out the way the AI worked at all. I just tried finding a logical way to describe the behaviors I noticed.
Priority is also unclear.
Priority as in higher/lower chance that a specific move is chosen? Might explain the NPCs behavior. Then it might just be that combo attacks and parades have a lower chance in OpenGothic than they do in the original Gothic 2.
If you need video footage for comparison, I can provide that too as soon as I find the time.
The initiator of ReGoth shared his findings about engine behavior. For fight ai priority seems to be top to bottom in script file.
In G1 FAI script there's a comment that describes the ranges:
// W - weapon range (FIGHT_RANGE_FIST * 3)
// G - walk range (3 * W). Buffer for ranged attackers where they should switch to melee weapon
// FK - ranged attack range (30m)