M2TW AI Modification: An Interactive Essay


By CavalryCmdr

All information herein is from my own extensive research into the workings and modification capabilities of the Campaign AI and is in no way “official”. Nor has any of this information been taken from other sources without being tested by me. I have searched different forums on the internet and gathered bits from all over the place, due to the wide array of sources I am utterly unable to define what individual sources may have been. Nor do I claim anything as my own discovery, for the same reasons.

This is for M2TW version 1.2. Many options are not available in earlier versions. 1.3 is largely the same though the kingdoms.exe does allow some options that are not covered here.

There are four major files that contribute to the AI’s behavior, these effect how the AI “thinks”.

  • descr_campaign_ai_db.xml
  • descr_strat.txt
  • descr_faction_standing.txt
  • descr_diplomacy.xml

Two lesser files also exist that effect AI performance, without directly effecting how it “thinks”.

  • config_ai_battle.xml
  • descr_character.txt

I will start with the files that least effect the AI, so the last entry, also by far the longest, will be the most influential to the ai.

config_ai_battle.xml

There are really only two lines in this entire file relevant to the Campaign AI:

<sally-out-ratio>2.0</sally-out-ratio>

Self explanatory: this is the strength ratio of defender to attacker that is necessary for the AI to decide to sally forth rather then defend in a siege battle. This line quite literally means the defender’s strength must be twice that of the attackers. This is used both in the campaign and during battle to determine whether to defend or counter-attack.

<friendly-to-enemy-strength-ratio>0.8</friendly-to-enemy-strength-ratio>

Again the default explanation explains this line quite well. This is the selected armies strength to selected target’s strength to determine whether or not to attack. Like the other line this is used both in battle and campaign mode. In campaign it determines whether to initiate battle or not. In battle it determines whether a defending army will take the offensive. The default setting shown here (0.8) means the AI considers it’s self stronger even if they are really slightly weaker in calculated strength.

Sadly I have not found a way to influence these settings by whether the target is human or AI controlled.

descr_character.txt

This file has no bearing on how the AI “thinks” but still strongly influences how the AI performs. Again there are two lines of importance, though they both appear for every character type:

    starting_action_points80; default value for all characters 
    and pathfinding calculations

Basically the movement range on the campaign map. This has massive effect on performance, how it organizes/moves it’s armies, where it chooses to combine units to form an army, what it considers viable targets/threats, where it chooses to position defensive armies, pretty much everything. Different campaign maps would have different ideal settings, from my own research the ideal for vanilla map is 135; basically the average distance between settlements. In a perfect map (for AI performance) all settlements would be the same distance from any bordering settlements, and the action points would be just over that distance. Increasing this number would see AI factions in widespread areas (i.e. Russia) perform better while those in more compacted places (i.e. Europe) would have a hard time consolidating armies before initiating a siege. By lowering the number you would see those in widespread areas do virtually nothing while those in more compacted areas would perform well.

Important note: The individual settings for each character type does not work properly! For best results set all to the same as the default.

    wage_base200

This is the “upkeep cost” (like for units.) This effects the AI because it is not programmed (for whatever reason) to consider upkeep. Also on harder settings the AI will “spawn” generals, with each general costing 200
florins per turn, a lot of money will be spent on an uncontrollable situation. Keep in mind you also need to pay the upkeep for the general’s bodyguard unit! This means each general is really costing between 400 and 600 each turn. Princesses costs 250 while a diplomat costs only 50, so get princesses married off ASAP or lower this to a more reasonable number. (Princesses are slightly more useful then diplomats so I suggest 75-100)

In addition to aforementioned ridiculous upkeep costs the AI has a tendency to spam (recruit mass numbers) the various other agents, then have them do nothing but sit around. This creates serious strain on the AI’s economy, especially late-game when a powerful faction might have as many as 20 or more spies (that’s 2000 florins per turn!)
and as many assassins (4000 per turn) throw in however many priests they are able to recruit and several diplomats and it’s no wonder the AI cannot keep up with higher level settlement development. Personally I chose to modify these to what I considered more reasonable then scripted in a refund of half for AI factions. Seeing as how the AI will only ever use about half it’s agents effectively I consider this not to be cheating.

descr_diplomacy.xml

This influences diplomacy, primarily between the human and AI, but to a lesser degree AI-AI as well. Here is a quick rundown of how the file works.

    <item name="offer_payment">
    <cost modifier="1.0"/>
    <faction_standing modifier="0.0"/>
    <global_standing modifier="0.0"/>
    </item>

“Item name” is pretty much understandable, it’s fairly easy to figure out the diplomatic option it’s referring to. Note that you cannot add or delete items.

“Cost modifier” This is the relative “value” the AI will place on the item, while the exact value is a abstract that also considers how much the AI wants something (not really moddable,) this at least allows you to influence
“relative” value. Note: the AI will never offer something with a value of 0 or lower. Also keep in mind “value”
also means cost while some items such as “offer_payment” is rather obviously increases value and “demand_payment”
costs you, some such as “offer_ceasefire” can be either +/- depending on whether the AI wants a ceasefire.

“faction_standing modifier” and “global_standing modifier” these values do not directly effect the displayed “value”
of a transaction, but do influence the chances of the AI accepting the offer. “faction_standing” is how much the AI likes you, so a positive value here means the AI is more likely to accept if they like you more while putting a negative value means they are more likely to accept if they like you less. “global_standing” is your factions reputation, so a positive number means the AI is more likely to accept the better your reputation.

    <diplomacy_text_fields>

The above are quite simply translations of a numerical value to the displayed text for things such as relations, reputation, wealth and power.

I am not familiar enough with the “demeanour_entry” section to make educated statements regarding it. Though by playing with the numbers herein I have managed to increase the AI’s likelihood of counter-offering.

descr_faction_standing.txt

As the document title suggests this is the file that controls how your actions effect your relations with other factions as well as your global reputation. This is a basic trigger controlled document such as those for traits and ancillary. I won’t be getting into triggers, what they are and what they mean here, it is far too extensive a subject that is adequately covered elsewhere. However an important note here is that the conditions “FactionIsLocal”
and “not FactionIsLocal” (“local” meaning human controlled) is applicable in this file, allowing actions to have different effects when committed by a human versus when done by the AI.

For post length I will simply clarify the intro section of this file that explains it’s usage.

    min_faction_standing-1.0
    max_faction_standing1.0

Obviously this sets the minimum and maximum value for relations, I suggest NOT editing this because the values are used in various other locations, modifying all of them would be rather tedious.

    relations_improved_thresholds
    {
    0.25
    0.4
    0.6
    }

    relations_worsened_thresholds
    {
    -0.8
    -0.4
    -0.25
    }

When these values are reached the appropriate message pops up, they trigger a message event, nothing more.

Basically, after reading the intro post, the only thing that may be difficult to understand is:

    normalise [target_faction_standing] [divisor] --> for each 
    affected faction standing, 
    add (target_faction_standing - faction_standing)/divisor

an example is

    FactionStanding target_faction normalise -1.0 20

    [target_faction_standing] = -1.0
    [divisor] = 20

The exact meaning of this line can be a bit difficult to decipher, so I’ll just explain it in the most basic manner I can.
The difference between current faction standing and target faction standing divided by the divisor. So, with the example, lets say current faction standing is 0.2 we know the target faction standing is -1.0, so the difference is -1. -1.2/20 = -0.06. This number is added to the current faction standing (0.2)+(-0.06)=(0.14) so after this trigger is fired and calculations done, the resulting calculation is 0.14. This means the closer your current standing is to the target faction standing the less effect the triggering event will have.

That’s the best I can explain it. Sorry if it does not clarify.

descr_strat.txt

Aside from the starting faction standings dictated at the bottom of this document, the format for which are pretty self-explanatory so I wont get into, there are two major lines for each faction that greatly influences the AI.

    factionengland, balanced smith

As seen in Rome I think this best describes what this line means:

These control a set of AI production personalities, which contribute a bias towards building and training (but not retraining or repairing). This bias is fairly small compared to game-generated factors such as “the enemy is attacking me with lots of cavalry, build me some spearmen”. Explaining the weighting system which drives the production AI in full is beyond the scope of this document as it would take several days to write.

So in short, the building construction personalities are these: (ranked highest to lowest)

  • Balanced – biases towards growth, taxable income, trade level bonuses (roads), walls and xp bonus buildings
  • Religious – biases towards growth, loyalty, taxable income, farming, walls and law
  • Trader – biases towards growth, trade level, trade base, weapon upgrades, games, races and xp bonus buildings
  • Comfort – biases towards growth, farming, games, races, xp bonus and happiness
  • Bureaucrat – biases towards taxable income, growth, pop health, trade, walls, improved bodyguards and law
  • Craftsman – biases towards walls, races, taxable income, weapon upgrades, xp bonuses, mines, health and growth
  • Sailor – biases towards sea trade, taxable income, walls, growth, trade
  • Fortified – biases towards walls, taxable income, growth, loyalty, defenses, bodyguards and law

These biases are towards building properties, rather than buildings themselves. The game does not know what a “Blacksmith” is, for example, it only knows that it is a building which provides a weapon upgrade, and hence a Craftsman AI would be more likely to build it than another AI personality type.

These are then combined with a troop production personality, as follows:

  • Smith – exactly level
  • Mao – biased towards mass troops, light infantry
  • Genghis – biased towards missile cavalry and light cavalry
  • Stalin – biased towards heavy infantry, mass troops and artillery
  • Napoleon – biased towards a mix of light and heavy infantry, light cavalry
  • Henry – biased towards heavy and light cavalry, missile infantry
  • Caesar – biased towards heavy infantry, light cavalry, siege artillery

The same system as for the buildings applies. Troop category and class are combined at the time the unit database is loaded to give a unit production type, and the likelihood of the AI choosing to produce a given unit type which can be produced is then modified by the unit type weighting. There is also a random element in the choosing of which building or troop type to produce next, so the effect of the bias is a statistical thing. Another factor that is applied over the top which may obscure the bias is a tendency towards producing troop mixtures (according to what is already in the garrison) and a weighting according to unit strength.

Due to M2TW’s separation of castles and cities, without the AI being adequately modified to cope, it is important to note that effectively the AI will be producing twice the siege equipment and light infantry that their personality calls for. Basically, eliminate any personality that calls for siege equipment, and only use ones that call for light infantry for factions with very good militia (i.e. Scotland and the Italian factions. This is what’s left for general usage:

  • Genghis – biased towards missile cavalry and light cavalry
  • Henry – biased towards heavy and light cavalry, missile infantry

with

  • Mao – biased towards mass troops, light infantry
  • Napoleon – biased towards a mix of light and heavy infantry, light cavalry

being reserved for factions with better then average militia troops. HOWEVER there are some exceptions that make no sense. For example Denmark recruits admirably well with “smith” while almost all other factions will spam militia and siege weapons. (“smith” is the default for all factions, as everyone knows with the default settings the AI is notorious for “stupid” armies.)
The personality prefix is basically a personal preference thing, trial and error and beginning settlements being deciding factors. For example “sailor” doesn’t make a whole lot of sense for the mostly landlocked HRE, but with the abundant mine able resources “craftsman” it does. Spain on the other hand has a good amount of mine-able resources and almost all their settlements until late game will be coastal, so either would work well.

    ai_label catholic

This is the ai_label within the descr_campaign_ai_db.xml that this faction uses to determine it’s behaviour.

Now it’s time for the biggest section.

descr_campaign_ai_db.xml

This file is massively powerful, and not nearly used to it’s fullest potential, especially when combined with the other files I mentioned. I am simply going to go through the intro section and clarify:

<trusted_ally_fs_threshold float="0.5"/> // min threshold for how much we like the target faction to consider them a trusted ally
<trusted_ally_target_fs_threshold float="0.5"/> // min threshold for how much the target faction likes us to consider them a trusted ally
<trusted_ally_target_human_fs_threshold float="0.0"/> // min threshold for how much the target (human) faction likes us to consider them a trusted ally
<trusted_ally_gs_threshold float="-1.0"/> // min threshold for how trustworthy we are to consider the target faction a trusted ally
<trusted_ally_target_gs_threshold float="-0.1"/> // min threshold for how trustworthy is the target faction to consider them a trusted ally
<trusted_ally_enemy_auto_war bool="false"/> // flag to indicate if a faction automatically goes to war with a trusted allies enemy

Pretty well explained, however, I disagree with how they use this. “trusted ally” is the only third party reference available within this file such as “trusted_ally_enemy” and “trusted_ally_protectorate” This means it is impossible to get allies who do not fall within the “trusted_ally” threshold to cooperate. I use the
“trusted_ally” for this purpose while vanilla and other mod’s use it only to identify whether the target faction is a “trusted_ally” which you can simply do by matching these same priorities into a single decision entry. By doing so they totally eliminate any third party reference, while I have it available to create more interaction.

<invade_priority_fs_modifier float="-400.0"/> // modifies the final invade priority for new faction targets by += (faction_standing * modifier) {makes factions more likely to start war with disliked targets}
<invade_priority_gs_modifier float="0.0f"/> // modifies the final invade priority for new faction targets by += (global_standing * modifier) {makes factions more likely to start war with untrustworthy targets}
<invade_priority_assistance_offset int="200"/> // modifies the final invade priority for new faction targets where military assistance has been asked by += (offset) {makes factions more likely to start war with military assistance targets}

All pretty self-explanatory, however it is important to note that the “fs” and “gs” modifiers are not fired when the factions are already at war. This is a good thing as they shouldn’t really, and it would have made me far more comfortable using them if they had noted that in their explanation. I am not sure if the assistance offset is fired while “AtWar” or not, but I don’t think so.

    <use_cheat_overrides bool="true"/> // determines if cheat 
    overrides (force peace with ai, force attack with humans) are 
    applied

This is big, basically all the references to “hard coded” within the file are enabled (“true”) or disabled
(“false”) the only way to make a truly reasonable AI is to make this “false”.

Now for min and max_entry thresholds. If you do not know and cannot figure out what min_entry and max_entry stand for, find a new hobby. I’m sorry if that sounds rude or harsh, but it’s just that if you do not have the capability to figure that out on your own your talents lay elsewhere and it is a waste of both our times for me to try explaining it.

I will explain that each faction calculates every other faction as a “target” every turn before making it’s moves. The AI will then attack those factions it has the highest “invade_priority” for, with one exception
(invade_opportunistic) which I will get into later.

    frontline_balance="0.0" :: ratio of factions frontline military 
    strength vs the target

At first glance this appears fairly straight forward, a value of “2.0” should be twice the strength on border regions and for the most part it is. However the LTGD log (I’ll cover that later) tells some interesting tales. Most importantly it is vital to specify “is_neighbour” when using this, secondly when units are on-board a fleet they create an unreadable frontline balance (ranging from 0.000001 or less to 100000.0 or more!) So an AI faction may have a frontline balance greater then 2.0 but actually have almost no troops in the border region, the higher
“frontline_balance” being the result of troops on-board a fleet half way around the world. Therefore it is also very important to specify a min and max_entry generally I use 1000.0 and 0.001 as these numbers will never realistically be met with any significant meaning to them but will be met often and mean absolutely nothing but
“frontline_balance” cannot effectively be read. “frontline_balance” cannot be used with non-neighbouring factions, it will either be 1.0 or an unreadable and meaningless number.

    military_balance="0.0" :: ratio of factions overall military 
    strength vs the target

Perfectly straightforward and explained, however keep in mind that naval forces are considered in this equation.

    production_balance="0.0" :: ratio of factions overall production 
    strength vs the target

Straightforward enough, but the AI’s production is so erratic I suggest only having it cause minimal effect.

    target_num_enemies="0" :: the number of enemies the target has
    num_enemies="0" :: the number of enemies the faction has

Straightforward right? WRONG! This I have yet to fully comprehend, a faction can be “AtWar” with no-one and have 2 or 3 “enemies” while another faction can be “AtWar” with 2 or 3 factions and have no “enemies”. In general however it is usable, just don’t let it have too much influence.

    has_alliance_against="false" :: is the faction part of an 
    alliance against target

This is a bit misleading. Most people (myself included) assume this is a diplomatic agreement to attack a faction. IT’S NOT. Quite simply it’s a rough look at the current world political situation, “I have allies that are not allied to this faction?” would be “has_alliance_against="true"“. It’s a very basic outlook, but can be used effectively.

    military_balance_plus_enemies="0.0" :: ratio of factions overall 
    military strength vs the target (plus all of its enemies)

This means exactly what the description says and, more importantly, does not what the description does not say. It is a balance of military force that considers the target factions enemies but not the considering factions. Use with care.

    alliance_military_balance="0.0" :: ratio of factions (plus its 
    allies) overall military strength vs the target

Same as above only it does not consider the target faction’s allies.

    strongest_neighbour="false" :: is the target the factions 
    strongest neighbour

Means exactly what you probably assume.

    most_desirable="false" :: is the target the factions most 
    desirable target

I have no idea how the AI decides who the “most_desirable” is. I know it’s not “who has the richest lands”, it’s not “target faction for victory”, it’s not “the most powerful” and it’s not “the weakest”. It may or may not be a neighbour. Basically, I HAVE NO IDEA.

faction_standing="-1.0" :: how much does the faction like the target
target_global_standing="-1.0" :: how trustworthy is the target to the rest of the world
target_faction_standing="-1.0" :: how much does the target faction like this faction
global_standing="-1.0" :: how trustworthy is this faction to the rest of the world

Self explanatory (especially if you read the section and have looked at and understand the
descr_faction_standing.txt file.)

    target_religion="catholic" :: the religion of the target (see 
    descr_religions.txt)

Pretty self-explanatory.

    enemy_excommunicated="false" :: is the target excommunicated
    excommunicated="false" :: is this faction excommunicated

Again self-explanatory. Note, non-catholic factions will always be “false”.

num_turns_allied="0" :: the number of turns since the faction agreed to an alliance with the target
num_turns_ceasfire="0" :: the number of turns since the faction has agreed to a ceasefire with the target (-1 for no agreement)
stance="Allied" :: diplomatic stance with the target (Allied, Neutral, AtWar)
target_faction="england" :: target faction label (see descr_sm_factions.txt)
target_human="false" :: is the target a human player

These are all straight-forward in their meaning.

    target_is_shadow="false" :: is the target this factions shadow faction

This is often considered many different things. Most usually short campaign victory conditions. It’s not anything you may have been told elsewhere. It’s a rollover from Rome Total War: Barbarian Invasion relating to “Eastern Roman Empire” and “Rebel Eastern Roman Empire” or whatever they were called. As of now it’s not used in M2. This will never be a “true” condition unless some ambitious modders decide to re-introduce shadow factions. (I believe all the necessary workings still exist, they just need to be implemented.)

turn_number="0" :: the game turn number (starting at 0)
is_protectorate="false" :: is the target our protectorate
is_protectorate_of_catholic="false" :: is the target a protectorate of a
non-excommunicated catholic faction

Self explanatory.

free_strength_balance="0.0" :: ratio of factions free military strength
vs the target

This is exactly what you might hope. It’s a relative strength after considering nearby enemy armies for both the considering and target factions. Keep in mind, however, this does include the slave faction as an enemy so use with care early in the game when the slave faction is still quite powerful.

borders_all_our_regions="false" :: does the target border on all the factions region groups
target_weakest_neighbour="false" :: is the faction the targets weakest neighbour
has_ceasehostilities="false" :: does the faction have a cease hostilities mission against the target from the papal faction
is_neighbour="false" :: does the target neighbour on any of the factions regions
trusted_ally="false" :: is the target a trusted ally (they like us more than fs_thresh, and their global standing > gs_thresh, and they are allied)

These are all self explanatory.

trusted_ally_enemy="false" :: is the target an enemy of a trusted ally
trusted_ally_protectorate="false" :: is the target a protectorate of a trusted ally

This, I mentioned earlier. These are the only third party considerations available (aside from the rather vague “has_alliance_against” and “is_protectorate_of_catholic”) If you want allies to cooperate, lower the “trusted_ally” thresholds and use these extensively.

    num_settlements="0" :: how many settlements does the faction own

Self explanatory

    rand="0.0":: a random value

A random number is generated each turn for each target faction. The number is between 0.0 and
1.0 however there is no limit to the decimal value. 0.00000127 is as likely to occur as 0.2 This effectively means you can use it to simulate any random number variant. For example:

    max_entry rand="0.333333333"

Would be a 1 in 3 chance. You could follow this with:

    min_entry rand="0.333333334"
    max_entry rand="0.666666666"

And another decision using:

    min_entry rand="0.666666667"

Thus creating a random number from 1-3 with each having an equal chance. Personally I generally use it as a percentile. Keep in mind that only 1 random number is generated for each target faction each turn so make sure you have a defined use for it.

Now for “faction_attitude” or the decision used if the min and max requirements are met. I’ll go through all the other ones first then go through each “invade” and “defend” setting independently.

defend_priority="0" :: The defensive priority of achieving stance against this faction
(NOT USED AT PRESENT) (additive with previous decisions this turn)

Unfortunately “not used at present” means it has no use and cannot be used.

invade_priority="0" :: priority of achieving invasion against this faction (additive with
previous decisions this turn). Compared with priority for decisions against all other factions
to choose highest. Value modified internally by faction standing.

This is likely to be the most important factor. This determines who the AI will attack and how much of it’s resources it will dedicate to that attack. The closer to the “invade_priority_max” setting, the more resources dedicated. Keep in mind that the AI is capable of attacking multiple opponents if their
“invade_priority” is close, and will try focusing it’s local resources rather then it’s total resources. With care you can create an effective multi-tasking AI. Also if “invade_priority” is less then the
“invade_priority_min” setting, the AI will not attack that faction (unless “invade_opportunistic” is used, more on that later.)

    at_war="false" :: are we at war with this enemy

A very strange option. Effectively if used in an earlier setting in combination with the continue="true" option you can have the AI consider its “stance” to be “AtWar” even if it’s not. This will not change the actual stance. (i.e. if the faction does not attack and it is allied to the target, they will still be allied.)

    want_peace="false" :: do we want to be at peace with this faction

Does the AI want to offer or accept a “ceasefire”? Unfortunately, we are at present unable to assign a “value” to this, only a straight yes/no answer.

    want_ally="false" :: do we want to ally with this faction

This setting has effectively been replaced with:

pts_alliance="0" :: points total for measuring how much we want to be allies with these
people (additive with previous decisions this turn)

Which is self explanatory. And yes, this does effect the “value” of an alliance in the diplomacy scroll.

want_be_protect="false" :: do we want to be a protectorate of this faction
want_offer_protect="false" :: do we want to offer protectorate status to this nation

Self explanatory, allows you to dictate whether the AI will offer/accept protectorate status from/toward the target. Again, as yet we are unable to assign a “value”.

    force_invade="false" :: must we invade now

If set to “true”, the AI will attack with whatever is available immediately regardless of the odds, it also bypasses “invade_priority”. Use with care.

alliance_against="0" :: how much do we want to have an alliance against this nation (additive
with previous decisions this turn)

Kind of a third party reference. If the AI has a positive number here it is added to the “pts_alliance”
to any faction that is not allied with the faction they want an alliance against. I’m not sure if negative numbers are usable or effective. Update: it is cumulative turn-turn which can result in crazy high (as in 100’s) numbers which in turn will cause am uncontrolled and often undesired, number of alliances as everyone tries to form an alliance against everyone else.
Use with caution.

pts_desire="0" :: points total for measuring our desire for this faction's territory (additive
with previous decisions this turn)

Not sure about this one, I’d assume it’s connected to the “most_desirable” setting, but I honestly have not tried using it.

can_force_invade="true" :: can naval or forced invasion settings overwrite invade parameters

When set to false it will cancel all invasions not directly ordered within this file. In addition it will not allow naval invasions against the target, even if an invasion is ordered within this file. Best used in very limited instanced IMHO. Naval invasions are influenced by “invade_priority” (again with the exception of “invade_opportunistic”.)

continue="false"/> :: do we stop evaluating decision entries (false) or continue

The single biggest improvement of version 1.2 IMO. The AI will cease consideration for the current target and move to the next target as soon as a decision_entry is found that has it’s min and max entries met, unless continue="true" is used on that decision entry. This option allows to add the results of different settings without needing to include them all within one decision.

Now for the (IMO) second most important, “invade=” decisions.

    invade_buildup

Pretty much what it sounds, the AI will attempt to unite units into a larger force and attack. Unfortunately the AI does initiate attack prior to combining the armies, so they may engage before uniting. Also the AI cannot
“buildup” naval invasions effectively.

    invade_immediate

This is your basic invade order. The AI will attack as soon as possible but will try to be “stronger” than their target army (as per descr_ai_battle.xml settings described earlier.)

    invade_raids

Again, fairly straightforward, the AI will attempt attacking without getting involved in a pitched battle. This involves blockading ports, one-round sieges and spreading devastation. Can be useful but keep in mind that the AI will not even attempt to form a large army, so is very vulnerable to a decisive counter-attack.

    invade_start

Basically a combination of “buildup” and “raids”.

    invade_none

Very useful believe it or not, the AI will follow it’s defend command, as I will explain shortly, certain
“defend=” commands use “invade_priority” so can make this setting very effective for building up for invasion.

    invade_opportunistic

The trickiest and most powerful invade command. This allows targeting of weak points as well as diversionary tactics. Like “immediate” the AI will always attempt to be “stronger” then it’s target. A major downfall is it ignores “invade_priority” even if the priority is lower then minimum, and even if another faction has 10 times the priority attached to it. Used with care, however, this is a very powerful weapon indeed.

Now, IMO even more important then “invade” types, our “defend=” options!

    defend_minimal

Use is limited. I suppose useful for early game and against the “slave” faction which will never attack anyway. With this setting the AI will not even attempt to intercept enemy armies and is more likely to march off on attack with a nearby settlement under siege.

    defend_normal

Most commonly used. With this setting the AI might even garrison it’s settlements, and will attempt to intercept/lift sieges, etc. Overall probably the most rounded defence. However, it’s really only useful in combination with “invade_immediate” and “invade_buildup”, as there is no real “set” defensive point a “set”
invasion point is necessary for this setting to “lead” to anything.

    defend_raid

Quite possibly even more useless then “minimal” this setting will see large numbers of 1 or 2 unit armies running around one’s own lands.

    defend_frontline

Quite useful, can be used with “invade_opportunistic”, “invade_immediate” and “invade_buildup” with great effect. As it implies the AI will attempt to match up against the target faction on the frontline. Army size determined by invade type and nearby enemies. This decision type uses “invade_priority” to determine whose frontline to line up on. Note: One weakness is it will not “recall” these troops to intercept/lift siege unless they can arrive in one turn. DO NOT use against non-neighbouring factions.

    defend_fortified

Very useful unless the AI builds a fort. Like “frontline” in many respects, including using “invade_priority”
to decide whose border to line up on except more flexible, compatible with nearly any invasion type and more likely to “recall” when the factions settlements are at risk. Additionally this setting often will see armies garrisoning settlements if a threatening army is nearby. However there is one MAJOR downfall. IF the AI builds a fort that army is very likely to “freeze” additionally the AI, for some incredibly stupid reason, will prefer to garrison forts over settlements, if a threatening army is nearby, even to the extent of allowing their last settlement to fall.

    defend_deep

This is your basic “last stand” setting. The AI will keep it’s armies immediately adjacent to it’s settlements and jump inside if a threatening army approaches. Three major downfalls: first the AI is only interested in defending it’s settlements and will never intercept. Second, it’s not really compatible with any invasion type. Finally the AI might not be able to move the army inside the settlement before an enemy attacks.

Then theres the LTGD log, this is a “log” option available that records all information and decisions used by the
descr_campaign_ai_db.xml file. To enable it add:

    [ai]
    ltgd_logging = true

    [log]
    to = logs/system.log.txt
    level = ai.ltgd trace

To your M2 preference file (or aplicalble mod.) This is excellent for troubleshooting.

Note: In the begining of the descr_campaign_ai_db.xml it says this.

Additionally, the ai_labels can be tested through event conditions and set through
// a script command, potentially allowing ai behaviour to be changed dynamically in
game depending on current game state.

Meaning you can script in a change to a faction’s ai_label. An example would be:

    link_faction_ai england default

Which means an AI England would use the ai_label “default” from that point on. This command does work, however, in the LTGD log is will still note the faction as using the ai_label given in the descr_strat regardless of what label it is actually using.

That’s about it. Feel free to ask questions or make observations or suggestions in the
dedicated forum thread.