A guide to modding how the MOO:CTS AI builds ships and decides which ships it wants to build.
Introduction
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
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
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:
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:
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.
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.
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
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.
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 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:
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.
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.
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:
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.
Buggy and removed with UCP.
Determines the weapon facing on the ship. Valid options are front, rear, sides, any. Leaving this out will result in weapons facing any direction.
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.
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
This is an example for a cannon entry. The game will put the best cannon weapon that meets the criteria in this slot.
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
Missile entries do not have facing indicators but function the same as cannons or beams.
Basic torpedo entry, the game will fill this slot with the latest torpedo that matches the criteria.
Fighters or drones are the simplest weapon entry. These entries have no mods or facing and only need a sizePriority set.
Dynamic Blueprints
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:
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:
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:
Here’s what our weapons section now looks like:
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.
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
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.
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!