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].