Making a Better AI: some ideas and suggestions

First, I want to thank your commitment to updating the game. Just a few years ago I wouldn’t have though it possible for the game to receive any updates. I might make a few references to this ai:

Currently the ai has many flaws, a major one is a bug that disallows it from using trade posts on trade routes. There are also bugs with the card systems, with certain cards never being added to the ai deck, such as svea lifeguard for the swede ai.

the ai also has a strange system for managing its eco/military balance based on econ/mil percent. this econ/mil percent system should not exist and be done away with entirely, instead using resource priorities, game time, ai strategy and other contexts to consider when and what to prioritize something. Econ/mil percent should both be set to 1.0 or removed from the script, it hurts more than it helps.

Another thing that should be separate from any other variable is settler production. ai should always maintain settler production except when close to aging up or at settler cap, and these settler targets should always be based on settler limits and not any other variable. It should be unchanging between civilization, current age, and ai strategy. just as a skilled player will never cease settler production to add one more musket, neither should the ai. Settler targets need to be 100% prioritized all time except when age up is imminent. Ai should always use the current settler cap for all settler units, as it can change dynamically depending on allies, techs, access to trade posts, and spc triggers.

The fishing/navy manager is also lacking and needs to be reworked. Whenever the ai is in a viable water map and it approaches a body of water, the ai needs to have a high priority in exploring and fishing it regardless of location, even if it means sneaking a villager past the enemy team for a backdoor port. ai should always have minimum 8 fishing boats if fish nodes allow regardless of strategy pursued and try to monopolize every whale node up to a dynamic maximum based on need. This fishing manager must never be turned off if there is a viable body of water on the map that has resources or is unexplored. When resources are exhausted the ai either uses idle fishing boats to explore unseen sections that may contain resources or delete them. if ai scouts no enemies in one body of water but sees enemies in another, it should delete navy units on the empty side if it doesn’t have enough to contest. The ai should always be ruthless and unrelenting in its control of water, always seeking out enemies and monopolizing resources. Even if its defeated, it should always make a new plan to take back water control. This is something I attempted to implement, and I’m sure you guys can do it even better.

Age up time/priority should also be simply based on game time and strategy, with increasing priority as the ai starts to lag behind, until it increases to a maximum value threshold after staying in an age for too long, such as staying in age 2 past 12 minutes. An ai that doesn’t compete in aging up isn’t a challenge, as the economic, unit and shipment advantage makes it a non-factor.

And all of this should be separate from difficulty. Eco management is critical to the game, and new players will often imitate the ai. when the original ai splits its villagers into wood cutting, mining and berry gathering instead of hunting in age 1, it’s a terrible teacher. Even in sandbox, villager production needs to be maintained and allowed to reach the cap. The same thing can be said for decks, banks, trade posts, town centers and factories. Its fine if gather rates/military production are limited, but the ai should never be suboptimal in its handling of the economy.

Unit Compositions:

The ai needs to have civ specific default units and a unit counter system for all types of variables it encounters. Its not difficult or time consuming, I’ve built one basically from scratch with minimal coding knowledge and the payoff is well worth it.

Each civ needs to have a default army composition with a minimum weight that will perform well in many situations for each age. For example, many European civs such as French, Portuguese, Spanish, and British should default to a roughly 80% musketeer 20% hussar composition in age 2. This default composition is then modified by the counter unit system, which adds to and replaces this default composition as more enemy units are spotted. This removes the problem of random and ineffective units such as spies being built by the ai for no reason.

having the ai count what type of units the enemy has and making those counts into unique factor values for the civ so that it can build the appropriate unit greatly helps the ai be competitive with human players on a composition front. For example, having the Spanish ai count each hand cavalry that is not a lancer the enemy target has for a hand cavalry count, then using a unique espada factor of 2 means that for every hand cavalry the ai sees, it will have a weight of 2 rodeleros to add to its default composition. This factor can overlap with a tercio count/factor for pikes, which is the same as a hand cavalry count except it is reduced with the presence of enemy ranged units. These factors can than be selectively enabled/disable In each age, so that rodeleros are replaced with dragoons past age 4, pikes/crossbows are disabled after age2, and aennas replaced by forest prowlers in age 3, meaning the ai is never outclassed when it comes to the units it chooses to build its army around. These factors can also be influenced by biases, such as an infantry bias increasing every infantry factor by 50% to say, 3 rodeleros per 1 hand cavalry.

This count/factor system can be further iterated on, as each faction can use counts of mercenaries to decide if to build spies/ninjas, counts of artillery to decide if it makes sense to make culverins, enable unit factors if certain techs/cards are researched (grenadiers=>hand mortars/mercenaries/revolutions), mortar count/factors for forts/strongholds/walls, all which have a maximum unit limit allowed before the factor is disabled, and more. Also, a separate spc list so that every ai can build spc units if allowed.

Here is a short example for a Spanish default comp and tercio/hussar count/factor:

kbUnitPickSetPreferenceFactor(gLandUnitPicker, gLandPrimaryArmyUnit, 0.5);
kbUnitPickSetPreferenceFactor(gLandUnitPicker, gLandSecondaryArmyUnit, 0.3);
kbUnitPickSetPreferenceFactor(gLandUnitPicker, gLandTertiaryArmyUnit, 0.2);

if (kbGetCiv() == cCivSpanish)
if (kbGetAge() == cAge2)
gLandPrimaryArmyUnit = cUnitTypeMusketeer;
gLandSecondaryArmyUnit = cUnitTypeMusketeer;
gLandTertiaryArmyUnit = cUnitTypeHussar;

float LancerCount = kbUnitCount(enemyToCounter, cUnitTypeAbstractInfantry, cUnitStateAlive);

float TercioCount = kbUnitCount(enemyToCounter, cUnitTypeAbstractHeavyCavalry, cUnitStateAlive) +
kbUnitCount(enemyToCounter, cUnitTypeCuirassier, cUnitStateAlive) -
kbUnitCount(enemyToCounter, cUnitTypeAbstractLancer, cUnitStateAlive) -
kbUnitCount(enemyToCounter, cUnitTypeAbstractRangedInfantry, cUnitStateAlive);

float TercioFactor = TercioCount * 2 / totalEnemyCount;
float LancerFactor = LancerCount * 1 / totalEnemyCount;

case cCivSpanish:
if (kbGetAge() < cAge3)
kbUnitPickSetPreferenceFactor(gLandUnitPicker, cUnitTypePikeman, TercioFactor);
kbUnitPickSetPreferenceFactor(gLandUnitPicker, cUnitTypeHussar, heavyCavalryFactor);
kbUnitPickSetPreferenceFactor(gLandUnitPicker, cUnitTypePikeman, TercioFactor * 0);
kbUnitPickSetPreferenceFactor(gLandUnitPicker, cUnitTypeHussar, heavyCavalryFactor*0);
kbUnitPickSetPreferenceFactor(gLandUnitPicker, cUnitTypeLancer, LancerFactor);

if (kbTechGetStatus(cTechDEHCREVCharros) == cTechStatusActive)
kbUnitPickSetPreferenceFactor(gLandUnitPicker, cUnitTypedeREVVaquero, MerclightInfFactor * 1.5);

And if using artillery factors doesn’t work out, you can just cheat and create a dynamic maintain plan for them.

While this system is much better than what we have currently, it’s not good enough. It’s too rigid and unadaptable and has many flaws. I’m sure you guys can come up with something better so that every time we see the units the ai makes, we aren’t automatically reminded that yes, we are facing a dumb and un-adaptive machine.

Ai should also adapt units into its compositions based on politicians: mamelukes for ottomans, jaegers for swedes.

One improvement could be the addition of a global array, by allowing the ai to directly check what units it can build and use the array to decide which units makes the most sense. These would have weights depending on the value of each units i.e. musket infantry over hand infantry, rifle infantry over archers, lancers over hussar, dragoons over cav archers and so on. Techs researched/sent can also influence the points of units, such as old han increasing the value of chu-ko-nu and qiang pikes, or caballero’s vs rifling when dealing with heavy infantry.

The upside of this method is that if a scenario, tech or mod changes what the ai can build, it can still adapt and make the most effective units possible, rather than building veteran pikes/xbows in the imperial age.

If it is not possible for the ai to check what units are enabled directly, then the tech tree can be changed so that every tech that enables a unit directly calls a specific tech the ai can check. Instead of age0dutch enabling skirms it activates a tech called “enableskirmishers” and so on.

The ai can use mortars, and it should have them enabled. There is code in the ai that allows them to do so called siegeWeaponManager and I would love to see you guys create a better version that allows the ai to utilize mortars and other obscure units that it currently cannot.

More general changes:

The ai needs to make competitive decks, utilizing techs that enable their civs unique strength, and consistently utilize powerful cards such as Castrametation/national redoubt, tulip speculation/guild artisans, Caballeros/Genitours and fencing/riding school. Decks should be effective for human players to copy and avoid trap cards, such as pets, hand infantry upgrades/units, and infinite age2/3 crates. Decks need to be viable regardless of difficulty, so new players can copy them and succeed.

The ai should also tell you when its aging up, what strategy it is pursuing, what units it is making, and proactively feed you resources once it is in age 5, has a surplus, and your score is lower.

Factory/dojo tactics needs to be looked at. The ai switches to cannons far too soon when it should be generating resources. And the dojo tactics are random and make strange choices, such as yabusame/samurai over ashiguru.

The ai is too hesitant in upgrading its units, having a far too large threshold for when to prioritize unit upgrades. Artillery units should be upgraded when at least 2 are on the field, and 5 for regular units. Unique church shipments need to have a higher priority, there is fun in seeing the Dutch use muskets, or the British utilize skirms.

The ai needs to tc boom asap regardless of difficulty. It needs to prioritize building town centers, and it needs to spread them out all over the map without distance limits on important resource nodes such as mines or multiple hunts. The tower turtle manager needs to be removed and replaced with a lower priority map control manager that instead puts towers/forts on these important nodes all over the map.

The ai on higher difficulties needs to forward base with a war hut or tower in age 2 on the opponent’s natural hunts/expansion and make full-fledged military bases around strategic and valuable resource nodes/trade posts as the game goes on. Rather then a compact and constrained single base, the ai should instead have a sprawling and map wide empire with several bases it can fall back to.

The ai should always pick the fort/stronghold politicians and all fort/stronghold cards and use them to create a zone of control on the player, an overlapping wall of forts and towers that tighten on the player as the ai expands to consume the map. If a fort goes down, the ai needs to promptly retake control over the lost area and use its explorer/musketeers to rebuild the fort. trade posts need to be heavily contested, if the ai cannot build a trade post due to proximity of a players tc, the ai should make that town center an extreme priority to take down so it can control that trade post. it also needs to trigger monopoly as often as possible.

The ai needs to constantly scout and raid. Currently too many units have the LogicalTypeScout tag that should not, such as spahis, mercenaries, dayimo, and doppelsoldners. LogicalTypeScout should be reserved for expendable and low population units, such as natives, muskets, archers, and pikes. The ai also needs to be more rigorous and smarter when scouting, dividing the map into a grid and sending units to patrol each grid it doesn’t control. The more resources an area has, the more units the ai assigns to patrol and the smaller the grid. If it scouts a defensive structure it should modify the patrol to avoid it and mark the structure as a potential attack target to regain map control. If it sees unprotected units and buildings such as shrines, it needs to create a high priority raid plan to destroy them, preferring cavalry for villagers and heavy infantry for buildings. Increased focus should be put on constantly scouting hunts, mines and unexplored areas, just as with human players. No human player should be able to hunt for long without the ai finding them and making note of the defenses in place. Ai should also be able to tech into spies and cease scouting once the map is fully explored.

Ai attacks need to be more coordinated with each other. When one ai does a base attack, it needs to call other ai to join in the attack as a united force. Rather than attack in waves, Armies should instead converge on a forward base point before moving into the attack goal together. ai should only attack the wall in its path and ignore other wall points, utilizing mortars to aid in its push. Ai should always focus on units instead of buildings, and in later ages bring in villagers to create forward bases to keep resupplying its push. Base attacks also need to happen earlier and be more brutal.

Politian/wonder choices should be more linear and optimal: merc contractor age 5, merc contractor for ottomans/swedes age 3, fort logistician age 4, agra/torri/summer palace age 2, and so on.

Some game changes that would greatly help the ai (and new players):
Remove hand attacks from petards/healers.
Change decay from .75 to .1 resource a second.
LogicalTypeScout tags only on units that should have it.
Creating of a light infantry tag for skirms/archers. Replace shock infantry tags with cavalry tags.
Allow the ai to know the start location of players.