Master of Orion

Master of Orion

Not enough ratings
Understanding AI Fleets and Blueprints
By vaaish
A guide to modding how the MOO:CTS AI builds ships and decides which ships it wants to build.
   
Award
Favorite
Favorited
Unfavorite
Introduction
First off I want to thank WhatIsSol for his help in understanding what the AI does. It's been indispensable in learning how to get the AI to build ships more like a player might. Without his input, much of what I'm covering here wouldn't be possible.

So let's get started! If you're here and reading this guide, you probably want to get the AI to build better ships or, at least, different from stock ships and put those into fleets that are challenging to fight. To effectively do this, you'll need to work within yaml files. If you don't know what that is or haven't read it yet, check out Spud's excellent primer on modding MOO:CTS before you continue with this guide. From here out I'm expecting you have a passing understanding of the basics.

This guide will cover two things, Al Fleets and AI Blueprints. To begin, I'll explain how the AI decides which blueprint to build and how to influence that. This is what controls the AI fleet design. Then, in the second part of the guide, we'll cover the basics of ship blueprints. Last of all, we'll touch on some advanced concepts to give more specific control over what the ai puts on its ships.
AI Fleet Building 101
When the AI builds a fleet, total command points (CP) are divided between different ship sizes (CP cost). This allocation is weighted by the value set by heavyArmy. The AI then looks at the blueprints available to it and prioritizes ships that have bombs. If multiple ships of the same size have bombs, it selects the one with the higher attack value to build first. If there are multiple blueprints for a ship size, the AI will build all of them (we'll come back to this). It will then build ships in order of priority to fill each CP group and continues doing this until all CP are used.

So how do we influence this process? To do that we'll have to delve into the yaml files. Much of the AI fleet composition is controlled by the raceTypes.yaml file. In this file are entries for each race in the game. Most of this you don't need to worry about as it controls aspects outside of the AI fleet preferences. What we're interested in here are the blueprints available and the race personality.

Within the race personality, the heavyArmy setting primarily controls the fleet composition. It can be set from 1-10 with lower numbers placing more emphasis on building smaller ships while higher numbers shifts fleets to build bigger ships. We don't have granular control to select and exact number or size of ships the AI wants to build, but adjusting this number will have a significant effect on what you see in the game.

Further control of the AI fleet composition is controlled by the blueprints section of the raceTypes.yaml. This section determines what the AI can actually build. Any blueprint that's not here won't be built by the AI, even if you give them the tech and there's a blueprint for how to build the ship. This is important because you can limit access to specific ship types to give the AI more variety between races or you can include multiple blueprints for the same ship to create alternate builds and roles for the same type of ship.
Basic Blueprints
Having blueprints listed in raceTypes lets the AI know what it's allowed to build, but it's not much use if they don't actually have a good blueprint to build. To do that, the game looks in the ShipBlueprintTemplates.yaml for the blueprint design specified in raceTypes. This section will overview what makes up a blueprint and how to use them to design ships.

Let's start of with a simple example of a ship blueprint. This is a simple design for an Alkari frigate. It has all of the components for more complex blueprints but it's pretty easy to understand:

- key: design_frigate_alkari name: SHIP_DESIGN_FRIGATE hull: hull_frigate profile: blitzer baseSystems: armor: shipslot_armor drive: shipslot_drive computer: shipslot_computer shield: shipslot_shield pointDefense: shipmodule: shipmodulesubtype_cannon quantity: 2 bombPayload: shipmodule: shipmodulesubtype_bomb quantity: 1 weaponSlots: - slot: shipmodulesubtype_cannon prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_continuous_fire_lasers - modifier_auto_fire - modifier_enveloping - modifier_heavy_mount specialSystems: maxSlots: 4 moduleList: - shipmodule_battle_pods - shipmodule_inertial_nullifier - shipmodule_inertial_stabilizer - shipmodule_hard_shield - shipmodule_hyperx_capacitors # Fallback Specials in order of desirability for race - shipmodule_augmented_engines

As you can see the blueprint is divided into several different sections that define the basic attributes for the ship, what weapons it caries, and what special systems it equips. Going from the top to bottom, here's what all this means:

- key: design_frigate_alkari
The key is what the game uses to find this blueprint. It has to be unique and it has to be listed in the race's availableBlueprintTemplates section of the raceTypes.yaml for the game to use it. I tend to follow the pattern used here, but you can call it whatever you want.

name: SHIP_DESIGN_FRIGATE hull: hull_frigate profile: blitzer
These lines tell the game what the ship's name is, what hull type to use, and what AI profile to give the ship in combat. You can type anything you like for the name, but if you want to allow other players to translate the name to other languages, keep what's there.

Hull tells the game what attributes the ship has. Hull types are defined in ShipHullTypes.yaml, but for our purposes the options are:

hull_frigate
hull_destroyer
hull_cruiser
hull_battleship
hull_titan
hull_doomstar

Profile is the same as setting a profile in game with the blueprint designer. This just tells the game how the ship should behave in tactical. If you don't want a profile at all, you can remove this line.

baseSystems: armor: shipslot_armor drive: shipslot_drive computer: shipslot_computer shield: shipslot_shield
The next section covers what basic systems the ship mounts. Mostly this should be left alone unless you want to ignore one of these. These are generic names and the game will upgrade the slot as better equipment becomes available. The game adds these to the ship before determining space available for weapons

pointDefense: shipmodule: shipmodulesubtype_cannon quantity: 2
This section tells the game what kind and how many point defense weapons to put on the ship. It's a straight number unlike weapon slots and it's added to the ship before weapons.

bombPayload: shipmodule: shipmodulesubtype_bomb quantity: 1
This section tells the game what kind and how many bombs to put on the ship. It's also a straight number added to the ship before weapons like point defense.

weaponSlots: - slot: shipmodulesubtype_cannon prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_continuous_fire_lasers - modifier_auto_fire - modifier_enveloping - modifier_heavy_mount
WeaponSlots is the meat of the ship design. This is how the game determines what weapons to put on the ship and how many. Each design can have as many weapons added as you like, but the game will only put as many weapons on a ship as the ship has slots for weapons. Each weapon definition contains multiple properties:

- slot: shipmodulesubtype_cannon
Determines the type of weapon and can be a specific weapon. If left generic, the game will upgrade the slot as new weapons become available. We'll cover what you can put here a bit later.

prioritizeMods: true
Value can be true or false Tells the game to use an older weapon that has the desired mods available rather than use a newer weapon without mods. Depending on the weapon, this can result in weaker designs. UCP disables this control via globals.yaml.

sizePriority: 1
This value us used by the game to determine how much space to allocate to a weapon slot. In our example, we only have one weapon so the value has no effect. WhatIsSol determined that the formula used to figure out how much space each slot gets is this:

(1/(sum all sizePriority))* weapon sizePriority = % of space allocated to slot

Let's look at an example to see how this plays out:
First, the game adds any point defense, bombs, and specials to the ship. The remaining space is used for weapons, let's say 50 space remains. In this example, we have two weapons. One with sizePriority: 1, and one with sizePriority: 2.

We add up the total of both weapon's sizePriority giving us 3 and divide one by the result. That makes each "share" worth 33% of the available space. Weapon one then gets 33% while weapon two gets 66% resulting in approximately 16.5 space for weapon one 33 space for weapon two. The then attempts to fill each slot with as many weapons as will fit in the space.

slotCount: 1
Buggy and removed with UCP.

facing: front
Determines the weapon facing on the ship. Valid options are front, rear, sides, any. Leaving this out will result in weapons facing any direction.

mods: - modifier_continuous_fire_lasers - modifier_auto_fire - modifier_enveloping - modifier_heavy_mount
Determines which mods the AI wants to add to the weapon. If prioritizeMods is true then it will add the first weapon that matches all of the desired mods. The available mods for each weapon type are defined in ShipModuleModTypes.yaml.

specialSystems: maxSlots: 4 moduleList: - shipmodule_battle_pods - shipmodule_inertial_nullifier - shipmodule_inertial_stabilizer - shipmodule_hard_shield - shipmodule_hyperx_capacitors # Fallback Specials in order of desirability for race - shipmodule_augmented_engines
The last section of the blueprint determines which special systems the ship will try to mount up to the number listed in maxSlots. maxSlots can't be higher than the number of slots on a hull type, but it can be lower. Specials are mounted going down the list from top to bottom skipping items that aren't available. As they become available, the ship will drop any items lower on the list past the maxSlots limit. Specials are added before allocating space to weapons.
Weapons Types
Each slot in a blueprint contains the definitions for one weapon type or weapon. There are different options and mods for the weapons but the valid types are cannon, beam, missile, torpedo, and fighter. The AI considers the weapon with the highest research point cost to be the "best" when upgrading generic weapon slots.

- slot: shipmodulesubtype_cannon prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_continuous_fire_lasers - modifier_auto_fire - modifier_enveloping - modifier_heavy_mount
This is an example for a cannon entry. The game will put the best cannon weapon that meets the criteria in this slot.

- slot: shipmodulesubtype_beam prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_continuous_fire_beams - modifier_auto_fire - modifier_enveloping - modifier_heavy_mount
This is an example for a beam weapon entry. It functions identically to the cannon entry. The game will put the best beam weapon that matches the criteria in this slot

- slot: shipmodulesubtype_missile prioritizeMods: true sizePriority: 1 slotCount: 1 mods: - modifier_heavy_armor - modifier_eccm - modifier_fast - modifier_mirv
Missile entries do not have facing indicators but function the same as cannons or beams.

- slot: shipmodulesubtype_torpedo prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_enveloping - modifier_overloaded - modifier_fast - modifier_semi_guided
Basic torpedo entry, the game will fill this slot with the latest torpedo that matches the criteria.

- slot: shipmodulesubtype_fighter sizePriority: 1 slotCount: 1
Fighters or drones are the simplest weapon entry. These entries have no mods or facing and only need a sizePriority set.
Dynamic Blueprints
While letting the game fill a weapon slot with any weapon within a subtype is useful for some blueprints, it may not give enough control in all situations. This section will cover ways to create designs that swap weapons entirely, shift as tech becomes available, or even organically upgrade to as specific weapon preference. This is where most of the magic happens to create more dynamic and interesting ships for the AI to use.

Lets go back to our basic frigate example from the start of this guide. We'll be modifying this design using different methods to make a dynamic load out. Each method has its place and not all are useful for all ship types.

Method one: add more weapons than weapons slots
Each hull has a limited number of weapon slots available to put weapons on the ship. Point defense and bombs take these slots first so including both on a design will reduce the available weapon slots by two. In the example of our frigate, using the 5x mod, we will have two slots left to put actual weapons in. We can use this to our advantage to change the ship loadout as the game progresses.

The game will fill weapons slots from top to bottom. It will skip weapons entries that aren't unlocked or there are no remaining slots to put them in. Lets update our weaponSlots section to look like this:

weaponSlots: - slot: shipmodulesubtype_torpedo prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_fast - slot: shipmodulesubtype_cannon prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_auto_fire - modifier_heavy_mount - slot: shipmodulesubtype_missile prioritizeMods: true sizePriority: 1 slotCount: 1 mods: - modifier_mirv
This is now a design that starts the game with cannons and missiles but switches to torpedoes and cannons when torpedoes are unlocked. We can further extend this by putting an entry for beams above torpedoes making a ship that eventually uses just beams and torpedoes. This method works great when you either have a limited number of weapon slots, such as with the frigate, or your weapons spread over multiple slots allowing you to "push" out a slot or two at the end of the list. Order is important here so make sure the weapons at the end of the list are ones you want to change.

Method Two: using size priority
Our second method takes advantage of how the game uses sizePriority to calculate the space available for a weapon. It's pretty simple: if there's not enough space left, the game won't mount a weapon so if we make one weapon take all the space, then we'll only get that weapon on the ship. Our frigate's weapon section now looks like this:

weaponSlots: - slot: shipmodulesubtype_beam prioritizeMods: true sizePriority: 2000 slotCount: 1 facing: front mods: - modifier_auto_fire - modifier_heavy_mount - slot: shipmodulesubtype_torpedo prioritizeMods: true sizePriority: 1000 slotCount: 1 facing: front mods: - modifier_fast - slot: shipmodulesubtype_cannon prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_auto_fire - modifier_heavy_mount
This will change our design in two ways. First of all, if either beams of torpedoes are unlocked, our ship won't mount cannons at all. Secondly, if both beams and torpedoes are unlocked the design will give twice as much space to beams as it does torpedoes. This method is useful if you want to switch to weapons that will be unlocked later in the game and you don't want to keep any of the original weapons.

Method Three: target specific weapons using mods
Due to all weapons having the same mods available in the base game and 5x, this method won't work unless you also change the mods each weapon is allowed to use. We'll be targeting the Graviton Cannon by changing it's modifiers to only allow Continuous Fire and Heavy Mount:

- key: weapontype_graviton_beam modifiers: - modifier: modifier_continuous_fire_lasers - modifier: modifier_heavy_mount

Here's what our weapons section now looks like:

weaponSlots: - slot: shipmodulesubtype_cannon prioritizeMods: true sizePriority: 1 slotCount: 1 facing: front mods: - modifier_continuous_fire_lasers - modifier_heavy_mount
The effect here is that the game will upgrade the ship as new cannons are unlocked until it reaches the Graviton Cannon. This happens because prioritize mods is set to true and the mods selected are a unique combination to the Graviton Cannon. Since no weapon past this point has both of these mods, no newer weapon will be mounted. If you're building a mod that adjust the weapons used in the game, this method is probably the best option to give different races preferences for which weapons they want to use. Keep in mind that doing this could cause subpar designs with the base weapons in the game.

Method Four: Specific weapons
Each slot on a ship doesn't need to have a subtype specified. Instead you can list a specific weapon to go in the slot. Doing this as the only weapon on the design will result in no weapon being taken until the specified weapon is unlocked. I can't really recommend this in most circumstances, but occasionally it can be useful to ensure specific late game weapons are used.

weaponSlots: - slot: shipmodule_gauss_cannon prioritizeMods: true sizePriority: 1000 slotCount: 1 facing: front mods: - modifier_auto_fire - modifier_heavy_mount - slot: shipmodulesubtype_cannon prioritizeMods: false sizePriority: 1 slotCount: 1 facing: front mods: - modifier_continuous_fire_lasers - modifier_heavy_mount
Our resulting design will use the last unlocked cannon until Gauss Cannons are unlocked at which point it will switch to those exclusively. Again, this is an option that is most useful if you're weapons are different from the base game. However, the same principle can be applied to bomb and point defense selection letting you add bombs to ship designs later in the game when shields are stronger.
Variant Blueprints
Congrats, you made it! This final section will talk about using blueprint variants to create more diversity within the AI fleet. Hopefully this guide will help you build more interesting and challenging ships and fleets to fight against.

Back at the start of this guide, we discussed how the AI selects ships to build. One important aspect of adding variety to AI fleets is variant blueprints. For a player, this might mean creating different designs for specific jobs in your fleet for the same size ship. An example might be a cruiser with lots of torpedoes to take down slow targets or static defenses quickly versus a cruiser with lots of cannons or beams to take down faster ships. Both use the same hull but have different jobs.

Since the AI can't do this itself, we have to cheat to help it add the illusion of intelligence. To do this we turn to variant blueprints. These can be as simple as duplicating your cruiser design and giving it a different key name or as complex as building different templates for the same hull with appropriate roles defined.

First of all here's how this works in the game. Once the AI has decided how many of a hull it wants (hull defined as same command point cost), it checks for available blueprints. If you have three different blueprints, the AI will split the number of ships between the number of blueprints and starting with ships that have bombs. If it wants to build 9 frigate size ships and you have three blueprints for them, it will build three of each blueprint.

You can see how the more blueprints you have the less useful this becomes. Too many ships with different roles means you don't get that many of what you actually need. It might not matter if you're just looking to randomize the behavior of the AI ships you fight so some cruisers rush in, others play sniper, and some act more like brawlers. Combined you can manipulate otherwise rudimentary AI into creating a complex and variable tactical situation.

Variants can also be useful in providing a way to adjust fleet balance of ships with certain roles. Going back to our first example, you probably don't want a lot of torpedo only ships as they won't work well against fast targets. If we've only got two variant blueprints, you can expect half of the ships to be torpedo only. We can fix this by duplicating the design of the the other cruiser types and giving them different key names:

design_cruiser_alkari_torpedo
design_cruiser_alkari_a
design_cruiser_alkari_b
design_cruiser_alkari_c

The result here is that the AI will have 25% of the cruisers as torpedo only while the other 75% are another design. The down side is, this might cause issues with squadrons.

Final Thoughts
MOO:CTS has a fairly simple design system and basic tactical AI. While we can't do a lot about that, we can find ways to manipulate the system we have to make interactions and designs appear more complex and challenging. Hopefully this guide will give you some ideas and pointers on how to do just that. If you have any questions, pop me a message and I'll try to answer what I can. Thanks for reading!