Skip to content

Get Started with ModOps

ModOps

A ModOp is a single patch operation that is done when the game loads its game data. It can modify, remove or add to a file.

<ModOp Type="Replace"
       Path="/Path/To/Node">
  <!-- content -->
</ModOp>

The Type defines the kind of operation like replace, remove or add.

The Path defines the target node or nodes of the operation.

Choose Type

The modification type can be specified in two ways:

  • Short: type as path attribute <type>="<path>" 117
  • Legacy: extra type attribute Type="<type>" Path="<path>" 117 & 1800
<!-- remove Standard/Name of asset 1337 -->
<ModOp GUID="1337" Remove="Standard/Name" />
<!-- remove Standard/Name of asset 1337 -->
<ModOp GUID="1337" Type="Remove" Path="/Values/Standard/Name" />
Short ModOps skip the /Values/ part of the path. 117

If you want to select the Asset node you need to use ../ as the path.

<!-- removes Values/ child of asset 1337 -->
<ModOp GUID="1337" Remove="" />
<!-- removes asset 1337 -->
<ModOp GUID="1337" Remove="../" />
<!-- removes Values/ child of asset 1337 -->
<ModOp GUID="1337" Type="Remove" Path="/Values/" />
<!-- removes asset 1337 -->
<ModOp GUID="1337" Type="Remove" Path="" />
Short ModOps and @GUID have same path behavior.
<ModOp GUID="1010372" Merge="Building">
  <AllowChangeVariation>1</AllowChangeVariation>
</ModOp>

<ModOp Merge="@1010372/Building">
  <AllowChangeVariation>1</AllowChangeVariation>
</ModOp>

<ModOp GUID="123" Replace="../Template">
  <Template>Icon</Template>
</ModOp>
<ModOp Type="merge" GUID="1010372" Path="/Values/Building">
  <AllowChangeVariation>1</AllowChangeVariation>
</ModOp>

<ModOp Type="merge" Path="@1010372/Building">
  <AllowChangeVariation>1</AllowChangeVariation>
</ModOp>

<ModOp Type="replace" GUID="123">
  <Template>Icon</Template>
</ModOp>

Select a Target

Look up and select the XML node you want to edit with XPath using the Path attribute.

<ModOp Path="/Templates/Group[Name='Objects']/Template">

XPath can be quite powerful. Checkout the XPath Cheatsheet to learn more.

Lookup Helper

Lookup helper simplify the selection path with common patterns. They make the code more readable, and also improve loading speed.

For the assets file, you can also use the GUID attribute for example.

<!-- standard XPath way -->
<ModOp Path="//Asset[Values/Standard/GUID='1137']/Values/Standard/Name">

<!-- same with GUID helper -->
<ModOp GUID="1337" Path="/Values/Standard/Name">
Lookup Files XPath Equivalent
GUID Assets (assets.xml) //Asset[Values/Standard/GUID='<guid>']
Property Assets (assets.xml) //Values/<property> 117
GUID InfoTips (export.bin) //InfoTipData[Guid='<guid>'] 117
Template Templates (templates.xml) //Template[Name='template']

Property Lookup

<ModOp Property="ModuleOwner" Merge=".[FarmType='PlantFarm']">
  <ModuleOwner>
    <ModuleBuildRadius>20</ModuleBuildRadius>
  </ModuleOwner>
</ModOp>
<ModOp Type="merge" Path="//ModuleOwner/[FarmType='PlantFarm']">
  <ModuleOwner>
    <ModuleBuildRadius>20</ModuleBuildRadius>
  </ModuleOwner>
</ModOp>
Only selects assets with the property in assets.xml

The lookup does not select assets without that property in assets.xml, even if it is part of their template or base asset."

. shortcut for self::node()

The use of .[Condition] is supported at the beginning of a Path, e.g. Property="ModuleOwner" Merge=".[FarmType='PlantFarm']".

The usage of . before brackets is not allowed in XPath 1.0 but in XPath 2.0. The modloader supports it by replacing it with self::node()[Condition].