Skip to content

Groups and Conditions

Group

117 & 1800

You can group multiple ModOps into one group with Group.

<ModOps>
  <Group>
    <ModOp />
    <ModOp />
  </Group>
</ModOps>

Available attributes: Condition, Skip, MaxRepeat

Include

117 & 1800

Include behaves the same as Group except its content is loaded from another XML file.

<ModOps>
  <Include File="feature.include.xml" />
</ModOps>

Use the extension .include.xml to ensure the file is treated as an include file in tools and the game.

Available attributes: Condition, Skip

Includes from other folders

The file path is relative to the file your including from. Use ../ to move up one folder.

Start the path with / to specify a path relative to the mod root folder.

Condition

117 & 1800

ModOps are only applied when their Condition attribute matches to a non-empty list or to true(). Conditions can be used with all ModOps: ModOp, Group, Include and Asset.

<Group Condition="//Values[Standard/GUID='1500010714']">
  <!-- Apply ModOps if asset 1500010714 exists. -->
</Group>
<Group Condition="!//Values[Standard/GUID='1500010714']">
  <!-- Apply ModOps if 1500010714 does NOT exist. -->
</Group>
Any valid XPath is allowed.

<Group Condition="@1500010714">
  <!-- Apply ModOps if asset 1500010714 exists. -->
</Group>
<Group Condition="!@1500010714">
  <!-- Apply ModOps if 1500010714 does NOT exist. -->
</Group>
@GUID short for //Values[Standard/GUID='<GUID>'] only works at the start of an XPath.

Relative condition

Conditions can be relative to the GUID your ModOp is operating on.

<ModOp GUID="800111" Add="Property/List"
       Condition="!Property/List[Item/Product='1500010120']">
  <Item>
    <Product>1500010120</Product>
  </Item>
</ModOp>
<ModOp GUID="800111" Type="add" Path="/Values/Property/List"
       Condition="!/Values/Property/List[Item/Product='1500010120']">
  <Item>
    <Product>1500010120</Product>
  </Item>
</ModOp>

Be aware of condition path difference

When using short ModOp style also the Condition path skips /Values/.

Prefer negative conditions.

The following two ModOps will lead to the same result, but with a difference.

<!-- negative condition -->
<ModOp Type="add" GUID="800111"
       Condition="!/Values/Feature/Options[Item/Product='1500010120']"
  Path="/Values/Feature/Options/FeedOptions" />

<!-- positive condition -->
<ModOp Type="add" GUID="800111"
       Condition="/Values/Feature/Options[not(Item/Product='1500010120')]"
  Path="/Values/Feature/Options" />

The negative condition is true and results in log warnings, if GUID 800111 is missing or Feature has been removed from it.

On the other hand, the positive condition skips the ModOp without any warning in the same situation.

Loop

117 (not in demo)

You can repeat ModOps until a Condition doesn't match anymore with setting MaxRepeat. The default MaxRepeat=1 behaves like a normal Group.

<Group Condition="@123/List/Item" MaxRepeat="10">
  <!-- ..  -->
</Group>

ModID Condition

117 & 1800

Conditions can check if a mod is active. The condition does not consider mod loadering order. Use LoadAfterIds to ensure it's loaded before your mod.

<Group Condition="#mod-id">
  <!-- Apply ModOps if `mod-id` is active. -->
</Group>
<Group Condition="!#mod-id">
  <!-- Apply ModOps if `mod-id` is NOT active. -->
</Group>

Check multiple ModIDs 117

Since Anno 117, #mod-id expressions are expanded to true() and false() to be used within XPath. That means you can combine them like XPath expressions with and and or.

<Group Condition="#mod-a and not(#mod-b)">
  <!-- ... -->
</Group>
<Group Condition="#mod-a">
  <Group Condition="!#mod-b">
    <!-- ... -->
  </Group>
</Group>

Disable Match Warning

117 & 1800

The attribute AllowNoMatch disables match not found warnings. That is useful if you have a complex or expensive path and don't want to repeat it as a condition.

<ModOp Type="replace" AllowNoMatch="1"
       Path="//EffectTargets/Item[GUID='1010346' and (../../../../Template='TownhallBuff')]">
  <Item>
    <GUID>193861</GUID>
  </Item>
</ModOp>

Use AllowNoMatch sparingly as it hides all warnings.

AllowNoMatch can be slow when there's no match. 1800

This only applies to Anno 1800. In Anno 117, AllowNoMatch is as fast as Condition.

Skip

117 & 1800

You only need this feature for iModYourAnno tweaks.

The attribute Skip can be used with Group and Include to ignore that operation.

<ModOps>
  <Include File="/feature.include.xml" Skip="1" />
</ModOps>

Note: the skip happens when the attribute Skip is present. It doesn't matter if you write Skip="1", Skip="True" or even Skip="0" - all of them lead to skipping the include.