top of page

Beginner Course – Phase 1: Editing Troop Trees
 

Lesson 4: Best Practices and Troubleshooting

Objective:
By the end of this lesson, you will be able to:

​

  • Identify and avoid the most common XML modding mistakes.

  • Validate and debug your mod files effectively.

  • Understand how load order and file structure affect mod stability.

  • Apply techniques that improve compatibility and future-proof your mod.

Common XML Modding Issues & Solutions
 

a) Syntax Errors

Problem:
Typos like missing angle brackets (<, >), mismatched quotes ("), missing closing tags (</tag>), or using invalid characters.

Symptoms:

  • The game crashes on startup.

  • The file fails to load.

  • The unit does not appear or behaves strangely.

Solution:

  • Use a code editor with XML syntax highlighting (e.g., VS Code, Notepad++).

  • Use an online XML validator or your custom validation tool.

  • Format your XML clearly and consistently.

b) Duplicate IDs

Problem:
You reuse an existing id from the base game or another mod.

Symptoms:

  • Your custom troop doesn’t appear.

  • The original troop disappears or behaves incorrectly.

  • Data may be overwritten or merged improperly.

Solution:

  • Always use unique IDs with a prefix.

  • Good example: mymod_rebel_archer_01.

  • Before creating a new id, search all your mod files (and optionally other mods) for possible conflicts.

c) Missing Tags / Incorrect Nesting

Problem:

  • Forgetting required tags like <skills>, <Equipments>, or <upgrade_targets>.

  • Putting tags in the wrong place (e.g., placing <upgrade_targets> outside of <NPCCharacter>).

Symptoms:

  • The troop might load with missing stats or equipment.

  • The game might ignore the unit or fail to compile the file.

  • Crashes or silent errors.

Solution:

  • Follow the format of base game entries.

  • Use code folding in your editor to visualize the tag hierarchy.

  • Keep all nested tags indented correctly.

d) Logical Errors

Problem:
The XML is valid but refers to things that don’t exist or don’t make sense:

  • Invalid item IDs

  • Incorrect troop upgrade links

  • Skill values that don’t fit the troop tier

  • Wrong culture assignment

Symptoms:

  • Troop appears without weapons or clothes.

  • Upgrade path is broken.

  • Game loads, but things behave incorrectly.

Solution:

  • Double-check referenced IDs (NPCCharacter, Item, Culture, etc.).

  • Make incremental changes and test regularly.

  • Use the cheat console to spawn and inspect troops in-game.

d) Logical Errors

Problem:
The XML is valid but refers to things that don’t exist or don’t make sense:

  • Invalid item IDs

  • Incorrect troop upgrade links

  • Skill values that don’t fit the troop tier

  • Wrong culture assignment

Symptoms:

  • Troop appears without weapons or clothes.

  • Upgrade path is broken.

  • Game loads, but things behave incorrectly.

Solution:

  • Double-check referenced IDs (NPCCharacter, Item, Culture, etc.).

  • Make incremental changes and test regularly.

  • Use the cheat console to spawn and inspect troops in-game.

Example Error:

​

<NPCCharacter id="custom_troop" name="Test Troop>

→ Missing quote after Test Troop. This would break the file.

Example: Invalid XML (Missing Tag + Incorrect Nesting)

<NPCCharacter 
    id="mymod_broken_troop"
    name="Broken Troop"
    level="8"
    occupation="Soldier"
    culture="Culture.empire">

  <!-- Missing <skills> wrapper -->
  <skill id="OneHanded" value="30" />
  <skill id="Athletics" value="25" />

  <!-- Incorrect nesting: upgrade_targets placed outside NPCCharacter -->
</NPCCharacter>

<upgrade_targets>
  <upgrade_target id="NPCCharacter.imperial_infantryman" />
</upgrade_targets>

What's wrong here?

  1. Missing Tag:

    • The <skills> wrapper is missing.

    • Skills must always be wrapped like this:

      xml

      KopierenBearbeiten

      <skills> <skill id="..." value="..." /> </skills>

  2. Incorrect Nesting:

    • The <upgrade_targets> block is outside of the <NPCCharacter> block.

    • It must be placed inside the troop's definition to be recognized.

Corrected example:

<NPCCharacter 
    id="mymod_broken_troop"
    name="Broken Troop"
    level="8"
    occupation="Soldier"
    culture="Culture.empire">

  <skills>
    <skill id="OneHanded" value="30" />
    <skill id="Athletics" value="25" />
  </skills>

  <upgrade_targets>
    <upgrade_target id="NPCCharacter.imperial_infantryman" />
  </upgrade_targets>

</NPCCharacter>
 

Items examples

    <Item

        id="long_desert_robe"

        name="{=bKBa7ahF}Long Simple Robe"

        mesh="aserai_tunic_long"

        culture="Culture.aserai"

        weight="1.6"

        appearance="1"

        Type="BodyArmor">

        <ItemComponent>

            <Armor

                body_armor="2"

                leg_armor="2"

                arm_armor="1"

                has_gender_variations="true"

                covers_body="true"

                modifier_group="cloth_unarmoured"

                material_type="Cloth" />

        </ItemComponent>

        <Flags

            UseTeamColor="true"

            Civilian="true" />

    </Item>

Weapon

<CraftedItem

        id="the_scalpel_sword_t3"

        name="{=LzqugHen}Scalpel"

        crafting_template="OneHandedSword"

        is_merchandise="false">

        <Pieces>

            <Piece

                id="aserai_blade_2"

                Type="Blade"

                scale_factor="100" />

            <Piece

                id="aserai_guard_7"

                Type="Guard"

                scale_factor="100" />

            <Piece

                id="khuzait_grip_14"

                Type="Handle"

                scale_factor="100" />

            <Piece

                id="khuzait_pommel_1"

                Type="Pommel"

                scale_factor="100" />

        </Pieces>

    </CraftedItem>

Summary – Key Takeaways
 

  • Always use unique IDs to avoid conflicts.

  • Work in small steps and test regularly.

  • Use comments and organize your changes.

  • Validate your XML for syntax and structure.

  • Back up your files before making changes.

  • Prefer additive modding over overwriting native content.

  • Learn about mod load order to prevent incompatibility.

  • Prepare for game updates by isolating and tracking your changes.

Best Practices for Stability
 

a) Unique IDs Are Non-Negotiable

Never reuse or overwrite existing game IDs unless you intentionally want to override something (and even then, be careful). Using a clear, consistent prefix system helps avoid conflicts.

​

id="mymod_mercenary_lancer"

​

b) Work Incrementally

Make small changes. Test. Then continue.

Avoid changing multiple complex files at once unless you have experience tracking dependencies.

If you change 30 troops and something breaks, it’s much harder to isolate the cause.

​

c) Always Make Backups

Before editing a file, create a backup copy in the same folder:

​

spnpccharacters.xml → spnpccharacters_backup.xml

​

For larger projects, consider using Git or other version control to manage versions and track changes over time.

​

d) Use Comments

Comments help you track what you changed and why.
They’re ignored by the game but essential for personal or team clarity.

​

<!-- My Custom Troop Section START -->
<NPCCharacter id="mymod_super_soldier" ... >
<!-- Increased OneHanded skill -->
<skill id="OneHanded" value="150" /> ...
</NPCCharacter>
<!-- My Custom Troop Section END -->

​

e) Structure Your Work Clearly

Keep your custom entries grouped or at the bottom of XML files with clear visual separation. If needed, leave a comment marker like:

​

<!-- ========================= MY CUSTOM TROOPS ========================= -->

Exercises
 

  • Duplicate the imperial_recruit to have 50 Polearm skill and different starting boots. (copy the boots from any other troop. Save, validate your xml and test in game.

  • Create a new Tier 2 troop named 'My custom Footman' that upgrades from the 'imperial_recruit', giving it specific stats and equipment. Save, validate your xml and test in game.

bottom of page