Adding a new unit

There are multiple ways to add new units to the game:

  • Modify the stats of an existing unit – You change the data for an existing object while leaving the underlying behavior and visuals alone.
  • Modify the visuals of an existing unit – You change out the model for the unit but leave the behaviors alone.
  • Add a completely new unit – You are creating a new unit from scratch to add to the game.

We have covered modifying stats above. This section will cover #2 and #3. Note that these are advanced modding techniques, and will require the modification of multiple files.


Changing a Unit's Model

This guide assumes that you are already familiar with the format for ALO files and the associated animation sets.

Step 1: Choose the Unit to Edit

Find a unit that you wish to edit; it is assumed that you are changing units of the same type (for example, infantry-for-infantry). If you looking to change one unit into a new type entirely, then you are better off adding an entirely new unit. Each unit in the game will have its own unique XML file.

Step 2: Find the Correct Component

The ActorAnimationComponent contains the model data for each unit. Within that component, the AssetName XML tag will contain the ALO model file name for the unit. You can change this to your new model. NOTE: This component also contains the animation template name for the unit. This name does not always match the model since animation rigs can be shared across multiple models. In general, it is best not to change this unless you are very familiar with editing the anim template system.

Step 3: Test

Save the XML file and run the game. If you have done everything correctly, the next time you build that unit, it should be using your new model.


Adding a New Unit to the Game

Adding a new unit is a fairly complex operation that spans several files and dependencies. Before you start, you need to have the following in mind:

The type of unit you wish to add

Your level of difficulty will vary depending on the unit type you want to add. For example, adding a new infantry type is relatively easy at the unit level but requires a lot of hierarchy setup. Adding a tank has less hierarchy but has added complexity in the unit since it uses hard points for weapons.

The hierarchy of GWWF (Unit to Company to Corps to Faction)

All units in the game fall into a hierarchy. There are individual units (such as a soldier or tank) that are part of a company (the item you build in tactical combat). That company is part of a corps (the object you move on the world map). Remember that a company cannot be made up of multiple types of units, but corps can be made up of multiple types of companies.

Where your unit falls on the hierarchy

If you are going to add your unit and its company to an existing corps, that is less work than creating a completely new corps.

For this example, we will be adding a new infantry unit: the French Foreign Legion soldier. It will be added to a brand new Africa Corps, so it will require its own company and corps data.

Step 1: Create the Unit

The best way to create a new unit is to find a unit that is similar to what you want that already exists. We want the Foreign Legion soldier to be an elite infantry unit and it will fly the French flag, so using Unit_INF_French_Elite_00.XML will suit our needs. Load up that file and then save the file as our new soldier. You may want to use the same naming convention as the game for convenience, so we will save the file as Unit_INF_Legion_Elite_00.XML in your mod's Data\XML directory.

At the top of the data is the object name. It is suggested that the object name match your file name (without the .XML ending). So we will name this object Unit_INF_Legion_Elite_00. Note that the 00 suffix is intended to allow us to create minor variants of the same unit. For example, the FT tanks have a 00 for the machine gun version and a 01 for the cannon version.

Since we are not changing the base functionality of the unit, we don’t have to change much of the remaining data. We do, however, have to REMOVE duplicated data; having multiple objects with the same name will crash the game. Scrolling down to the end of the infantry data block, we see Unit_INF_French_Elite_Attack_Ability. This ability already exists on the French Elite soldier, and since the weapon would be identical, we have no need for this. If you want to adjust the weapon ability for our new Foreign Legion soldier you can do so, but you would need to rename this ability to something unique (such as Unit_INF_Legion_Elite_Attack_Ability). If you do so, you also need to change the ability reference in the AbilityManagerComponent in the unit’s data.

We can also completely remove the Unit_INF_French_Elite_MARKER_00 from the file – this is used for the “game piece” marker on the world map, but we can use the French one for now, and we don’t want the duplicate object here.

Check everything over and save your file. This completes step 1.

Step 2: Add the file to the game

In order for the game to see your new unit, it must know to load your new XML file. This is achieved by adding the file name into the section of your ModConfig.xml file. This contains a list of all additional object XML files for the mod. If your XML files doesn’t appear here, the game doesn’t know it exists, and worse, if you reference an object elsewhere and the game can’t see it, the game will crash.

Add your file to the AdditionalGameObjectXMLFiles section in ModConfig.xml by inserting Unit_INF_Legion_Elite_00.XML and then move on to step 3.

Step 3: Create the Company

All existing companies in the game are located in CompanyObjects.XML, however we want to add a new XML file to contain the company. Create a new XML file in your Data\XML directory called COMPANY_Infantry_Legion_Elite.XML. As with the unit, we can use the COMPANY_Infantry_French_Elite object as a template. Copy this, then past it in your new file. Rename the company to COMPANY_Infantry_Legion_Elite so we match our new unit.

As with the unit, we shouldn’t have to change much here since we aren’t changing the unit type. In the CompanyComponent, you will need to link your new unit into the company by replacing Unit_INF_French_Elite_00 with Unit_INF_Legion_Elite_00.

Add your new company file to the AdditionalGameObjectXMLFiles section in ModConfig.xml by inserting COMPANY_Infantry_Legion_Elite.XML

Step 4: Modify the Count Attribute

One very important change is the count attribute. Look in the CompanyComponent for the tag PopulationCountAttribute. This attribute acts as the limit for deploying your new company in battle; it tells the game how many are available when playing in the campaign, and locks out the button in battle if you run out of available companies. Changing this attribute requires three steps.

  • Enter a new attribute name for your count variable into PopulationCountAttribute. You can name it anything you want, but it is suggested that you follow the same naming convention. For example: InfantryCompanyLegionCount
  • Using Attributes.XML as reference, create a new attribute XML file (named something other than Attributes.XML) in your mod's Data\XML directory. Find one of the other count attributes in Attributes.XML, copy it to your new XML file and replace that object with your new attribute name. Add your new attribute XML file to the section of your ModConfig.xml
  • The build limits for your new unit need to be specified, even if they are zero. Specific build limits are only used in Historic missions, otherwise the build limits are determined by the corps. Nevertheless they must exist. You can add a default build limit for your new unit in ModConfig.xml under AdditionalSkirmishBuildLimits:

<AdditionalSkirmishBuildLimits>
    <Entry>
        <Key>Faction1</Key>
        <Value>
            <Entry>
                <Key>InfantryCompanyLegionCount</Key>
                <Value>0.0</Value>
            </Entry>
        </Value>
    </Entry>
</AdditionalSkirmishBuildLimits>

Optional: To set a non-zero build limit in a specific historic mission, you need to update that mission's instance definition. To do this you would copy the DefaultSkirmishBuildLimits from an existing historic instance in Instances.XML (a list of every map in the game) and paste them into a new XML file in your mod. Make sure your new XML file follows the same format as Instances.xml (but is named differently) and use the "Modify=" attribute to allow the same instance name in your mod and just change the DefaultSkirmishBuildLimits. Add the build limit for your new unit in your new XML file, and then reference that file in ModConfig.xml in the AdditionalInstancesXMLFiles section. Once you have the count attribute set up, you can move on to the next step.

Step 5: Modify Misc Data (if desired)

Moving down through the data, go to the EncyclopediaComponent. This contains all of the text, flag and portrait data for the company. The image data is generally in TGA format, though JPG can be used as well. The text sections will take text tags (see the Changing Text section above for how to add and edit text).

The AttributeDirectoryComponent contains all of the numeric variable values for the unit; this includes purchase prices, pop-cap values, score values etc. You don’t need to change these, but you can if you are planning for a more comprehensive mod.

The AudioComponent contains all of the audio response lines for the company. Note that changing audio is NOT covered in this document, but to sum it up briefly, vocal response lines are contained in AudioText.CSV. That file contains a text tag for the unit response line and a file name which corresponds to the actual audio file. Note that each company has a unique set of text tags, even if the lines are identical – they are distinguished by a three letter actor code in the text tag. For example, TEXT_SFX_FRI_SELECT is the select line for the company. The letters FRI is the actor code for French Infantry. There are five lines for each response type (so five SELECT lines) which are randomized each time they activate.

After modifying everything in the company you want to change, save the file, and go on to the next step.

Step 6: Create the new Corps

In modding terms, a “corps” is any object that contains a selection of companies that is moved at the world map level. For example, tank corps are called Battalions when playing the game, but in the data everything is referred to as corps.

Corps have types: Infantry, Tank, Artillery or Aircraft. You must make sure you are referencing the correct corps type for the companies you are adding when making a new one. To make things simple, we will copy a similar existing corps as we did with the soldier and company. Copy CORPS_French_Elite_Base and rename it CORPS_African_Base. We only have one new company to add here, but we can always add different new companies to this corps later if we want. For now, Let’s replace all of the French elite infantry companies with our new COMPANY_Infantry_Legion_Elite. In general, infantry companies contain 20 infantry companies total, with one light and one heavy artillery battery. Some companies also contain one each of a raider and flamethrower company. Remember that while companies must be comprised of the same unit types, corps can contain any combination of company that you want.

As with the company, the corps as an EncyclopediaComponent that contains all of the text and GUI visuals for the corps itself. Edit or change this as desired in the same method used before.

Note: Two values that may be of interest in the corps data are TacticalSkirmishLobbyLoadoutPrice and RegionSupplyCapModifier.

TacticalSkirmishLobbyLoadoutPrice is the supply cost of the corps when playing a skirmish mode game (as part of the loadout).

RegionSupplyCapModifier is the amount of supply that the corps adds to a region in the campaign mode.

You do not need to edit either of these, but they may be of use if you are working on a more comprehensive mod.

Your new unit is completed data-wise and would work in the game if you just dropped it in. However, in order for your new unit to be fully integrated into the game, you will need to hook it into other systems. At the highest level, the faction your new unit belongs to must know about the unit.

As our example is an Allied unit, we will want to modify Faction1. Create a new XML file in your mod's Data\XML directory called Faction1_New_Unit.xml. See Faction1.XML for a reference for the format of the new file. We want to add the company to UnitHierarchyObjects, BuildableUnitObjectsPreBattle & BuildableUnitObjects, and the corps needs to be added to SkirmishLobbyLoadoutObjects, so your XML should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<ObjectTypeList>
    <ObjectTypeClass Name="Faction1" Modify="">
        <FactionComponent>
            <UnitHierarchyObjects append="">
                <entry>COMPANY_Infantry_Legion_Elite</entry>
            </UnitHierarchyObjects>
            <BuildableUnitObjectsPreBattle append="">
                <entry>COMPANY_Infantry_Legion_Elite</entry>
            </BuildableUnitObjectsPreBattle>
            <BuildableUnitObjects append="">
                <entry>COMPANY_Infantry_Legion_Elite</entry>
            </BuildableUnitObjects>
            <SkirmishLobbyLoadoutObjects append="">
                <entry>CORPS_African_Base</entry>
            </SkirmishLobbyLoadoutObjects>
        </FactionComponent>
    </ObjectTypeClass>
</ObjectTypeList>

Step 7a: World Map Construction

Infantry companies are not built from the world map by default like tanks or aircraft. However, if you eventually decide to make a new vehicle corps, you must add it to the Faction1_Strategic.XML file in a similar fashion to step 7 above. Add your corps to BuildableStrategicUnitObjects.

Step 8: Production Restrictions

All units have a set of rules that determine whether you can build them or not. Infantry are not locked out by tech, so the only real limit to their production is that you have companies in reserve. This is what that count attribute in Step 4 was all about. We added the count, now we have to add the rule that uses it. Using Faction1_Unit_Voters.XML as a reference, create a new XML file in the Data\XML directory called InfantryLegionEliteVoters.XML. Add InfantryLegionEliteVoters.XML to the section in your ModConfig.XML. Voters is a list of rules per buildable object that tells the system whether they can be built or not. It is assumed on a global level that you must have enough resources (supply in this case) to buy the unit, so that isn’t listed in the rules.

In our new InfantryLegionEliteVoters.XML, we can copy any of the blocks for an infantry unit from Faction1_Unit_Voters.XML since they are relatively the same. Let’s copy the French elite infantry unit block. We replace the count attribute with the new one re creased, and change the block name to the name of our Foreign Legion company like so:

<StructureVoterInfoTypeClass Name="COMPANY_Infantry_Legion_Elite">
    <StructureVoters>
        <entry>
            <entry type="AttributeRequiredStructureVoterClass">
                <Attribute>InfantryCompanyLegionCount</Attribute>
                <AttributeContext>OwnerPlayer</AttributeContext>
                <RequiredValue>1</RequiredValue>
                <CompareOperator>GreaterThanOrEqualTo</CompareOperator>
            </entry>
        </entry>
    </StructureVoters>
</StructureVoterInfoTypeClass>

This block tells the game that you can only build the legion company if the count of that company is one or more. In the campaign or skirmish loadout each time you build a corps in a region (or your loadout) it adds +1 to your count attribute for every company you have of that type. So if you built your corps with 20 companies of Legionaires and you put that corps in the region, the InfantryCompanyLegionCount value is set to 20. Each time you build one the attribute is diminished by 1.

In some cases you may want to have your new unit locked behind a tech node. You can add this restriction in the same block with your unit count lock. The first step is to determine which tech node you want to use as your lock. All of the tech nodes are listed in STRATEGIC_TECH_TREE_OBJECTS.XML. Find the node you wish to use as your lock and then in that block look for this XML tag:

<AppliedPlayerStates>
    <entry>TECH_INFCOM_Rifleman_1</entry>
</AppliedPlayerStates>

This is the object state you will use for your lockout. Next, create a new object state required check entry right below your count check entry:

<StructureVoterInfoTypeClass Name="COMPANY_Infantry_Legion_Elite">
    <StructureVoters>
        <entry>
            <entry type="AttributeRequiredStructureVoterClass">
                <Attribute>InfantryCompanyLegionCount</Attribute>
                <AttributeContext>OwnerPlayer</AttributeContext>
                <RequiredValue>1</RequiredValue>
                <CompareOperator>GreaterThanOrEqualTo</CompareOperator>
            </entry>
<entry type="ObjectStateRequiredStructureVoterClass">
<ObjectStateContext>OwnerPlayer</ObjectStateContext>
<RequiredIncludedObjectStates>
<entry> TECH_INFCOM_Rifleman_1</entry>
</RequiredIncludedObjectStates>
</entry>
        </entry>
    </StructureVoters>
</StructureVoterInfoTypeClass>

Other check types can be added in the same way. All checks are cumulative, such that all of the conditions must be met before the unit can be built.

Step 9: Add your Unit to the AI’s Awareness

While your game is now ready to use in Skirmish and Campaign modes, the AI will have no concept of your new unit or what to do with it. In order for the AI to react to your unit, it must be added to the LUA data. This can be accomplished by creating a new Lua script that adds the unit to the AI's existing list of units. In your mod, create a new file called Add_Legion_Elite_Unit.lua in the Data\luaversions\current\lua\ai directory. We need to add the new lua file to the ModConfig.xml so it will be loaded into the AI when it initializes. Edit the section in your ModConfig.XML to include the new .lua file like this:

require("Lua.AI.Data.ModCompanyData")

function LegionEliteUnitInitAI(player_id, faction_type)
    print("LegionEliteUnitInitAI")
    local new_unit_data = {
        Faction = "Faction1",
        CompanyName = "COMPANY_INFANTRY_LEGION_ELITE",
        Type = "INFANTRY", -- INFANTRY_STORMTROOPER, TANK, TANK_LIGHT
        Allocation = 10, -- Used for selection chance when purchasing in tactical.
        TargetPriority = 4, -- Used when attacking this target type.
        CountAttribute = "InfantryCompanyLegionCount", -- Set in XML, determines how many companies the player has in tactical.
    }

    table.insert(ModCompanyData, new_unit_data)
end

function LegionEliteUnitUpdateAI()
end

Step 10 (Optional): Add Your New Corps to a Campaign

At this point your new corps can be played in Skirmish and multiplayer mode. It will appear in the loadout list (in the French army section) and you can play a battle with that unit. However, playing with that unit in the campaign requires one more step. If you don’t care about the campaign then you can skip this.

Campaign starting unit data is located in an individual campaign file per campaign, but not per faction. For example, the starting campaign data for the 1916 campaign for both Allies and Central Powers is located in Regions_1916.XML. If we open up this file, we will see a block for Paris (Region 1) at the top of the file. In this block you will see StartingCorpsCounts. This is a list of every corps that begins in that region at the start of the game. To add your new unit, copy an entry block in that section, then add the corps name and starting number to the block. Do this for each region where you want your new unit to start.

You can do this for any of the existing campaigns, or create a new campaign file and add them there. Note that changing the contents of the tutorial campaign files may break the campaign scripts; it is suggested that you don’t modify those files.