Difference between revisions of "Modding Tutorials/PatchOperations"
m |
(Started in on expanding this tutorial) |
||
Line 1: | Line 1: | ||
{{BackToTutorials}} | {{BackToTutorials}} | ||
{{stub}} | {{stub}} | ||
− | + | ||
+ | RimWorld Alpha 17 added a new modding feature: '''XML PatchOperations'''. Using these allows mods to edit specific elements of XML defs, rather than simply overwriting the old def with a new one, which was the required approach until A17. This greatly reduces mod conflicts, because mods that make separate changes to the same def won't necessarily overwrite one another's changes. Mods using PatchOperations can avoid requiring special compatibility mods, and can even add special features conditional on other mods being loaded. | ||
Here's a simple example of replacing the texture path for deep water: | Here's a simple example of replacing the texture path for deep water: | ||
− | < | + | <source lang="xml"> |
<Operation Class="PatchOperationReplace"> | <Operation Class="PatchOperationReplace"> | ||
− | <xpath> | + | <xpath>*/TerrainDef[defName="WaterDeep"]/texturePath</xpath> |
<value><texturePath>Your/Texture/Path/Here</texturePath></value> | <value><texturePath>Your/Texture/Path/Here</texturePath></value> | ||
</Operation> | </Operation> | ||
− | </ | + | </source> |
+ | |||
+ | == Overview of available PatchOperations == | ||
+ | There are 11 available PatchOperation types: | ||
+ | |||
+ | * Four do basic operations on XML nodes: | ||
+ | ** '''[[#PatchOperationAdd|PatchOperationAdd]]''' adds a provided child node to the selected node | ||
+ | ** '''[[#PatchOperationInsert|PatchOperationInsert]]''' adds a provided sibling node to the selected node | ||
+ | ** '''[[#PatchOperationRemove|PatchOperationRemove]]''' deletes the selected node | ||
+ | ** '''[[#PatchOperationReplace|PatchOperationReplace]]''' replaces the selected node with the provided node | ||
+ | * Three do basic operations on XML attributes: | ||
+ | ** '''[[#PatchOperationAttributeAdd|PatchOperationAttributeAdd]]''' adds a provided attribute to the selected node if and only if the attribute name is not already present | ||
+ | ** '''[[#PatchOperationAttributeSet|PatchOperationAttributeSet]]''' sets a provided attribute for the selected node, overwriting the attribute value if the attribute name is already present | ||
+ | ** '''[[#PatchOperationAttributeRemove|PatchOperationAttributeSet]]''' removes an attribute for the selected node | ||
+ | * Four allow for more complex operations: | ||
+ | ** '''[[#PatchOperationAddModExtension|PatchOperationAddModExtension]]''' adds a ModExtension. | ||
+ | ** '''[[#PatchOperationSetName|PatchOperationSetName]]''' changes the name of a node. It is generally useless. | ||
+ | ** '''[[#PatchOperationSequence|PatchOperationSequence]]''' contains a set of other PatchOperations, and aborts upon any operation failing | ||
+ | ** '''[[#PatchOperationTest|PatchOperationTest]]''' tests nodes, which is useful inside a PatchOperationSequence | ||
+ | |||
+ | ==XPath syntax== | ||
+ | Each PatchOperation must specify an XML node to modify. It uses XPaths to specify them. An XPath is a "path" for the patch to follow when trying to find XML nodes matching the description. It will follow each part of the path from left to right. | ||
+ | Most XPaths should start with <code>*/</code>. The <code>*</code> matches any element, so it'll match the root (the top level) of the XML tree. The following slash selects Using <code>//</code> is technically also valid, but because that construct selects ''all'' the elements in the XML tree, it's an expensive operation that makes a mod needlessly slow to load. | ||
− | = Resources = | + | Once the root is selected, the XPath lets the system walk down specific branches of the tree. If we use the example from the lead, we get a specific path: |
+ | |||
+ | <code>*/TerrainDef[defName="WaterDeep"]/texturePath</code> | ||
+ | |||
+ | # The root node is selected | ||
+ | # All child nodes of the root node called "TerrainDef" are selected | ||
+ | # We narrow down from "all TerrainDefs" to only those with the child "defName" node whose value is "WaterDeep", which should give us exactly one node because defNames must be unique | ||
+ | # We select the child node "texturePath" from this node | ||
+ | |||
+ | ==Overview of individual PatchOperations== | ||
+ | (to do) | ||
+ | ===PatchOperationAdd=== | ||
+ | ===PatchOperationInsert=== | ||
+ | ===PatchOperationRemove=== | ||
+ | ===PatchOperationReplace=== | ||
+ | ===PatchOperationAttributeAdd=== | ||
+ | ===PatchOperationAttributeSet=== | ||
+ | ===PatchOperationAttributeRemove=== | ||
+ | ===PatchOperationAddModExtension=== | ||
+ | ===PatchOperationSetName=== | ||
+ | ===PatchOperationSequence=== | ||
+ | ===PatchOperationTest=== | ||
+ | |||
+ | == Resources == | ||
The best tutorial on PatchOperations created by Zhentar: [https://gist.github.com/Zhentar/4a1b71cea45b9337f70b30a21d868782 Introduction to PatchOperation] | The best tutorial on PatchOperations created by Zhentar: [https://gist.github.com/Zhentar/4a1b71cea45b9337f70b30a21d868782 Introduction to PatchOperation] | ||
Line 20: | Line 66: | ||
There is also an [https://github.com/roxxploxx/RimWorldModGuide/wiki/SHORTTUTORIAL:-DefPatches Overview of PatchOperations] on the [https://github.com/roxxploxx/RimWorldModGuide/wiki RimWorldModGuide]. | There is also an [https://github.com/roxxploxx/RimWorldModGuide/wiki/SHORTTUTORIAL:-DefPatches Overview of PatchOperations] on the [https://github.com/roxxploxx/RimWorldModGuide/wiki RimWorldModGuide]. | ||
− | |||
− | |||
− | |||
− | |||
− |
Revision as of 16:00, 31 October 2017
This article is a stub. You can help RimWorld Wiki by expanding it. Reason: Please add a reason . |
RimWorld Alpha 17 added a new modding feature: XML PatchOperations. Using these allows mods to edit specific elements of XML defs, rather than simply overwriting the old def with a new one, which was the required approach until A17. This greatly reduces mod conflicts, because mods that make separate changes to the same def won't necessarily overwrite one another's changes. Mods using PatchOperations can avoid requiring special compatibility mods, and can even add special features conditional on other mods being loaded.
Here's a simple example of replacing the texture path for deep water:
<Operation Class="PatchOperationReplace"> <xpath>*/TerrainDef[defName="WaterDeep"]/texturePath</xpath> <value><texturePath>Your/Texture/Path/Here</texturePath></value> </Operation>
Overview of available PatchOperations
There are 11 available PatchOperation types:
- Four do basic operations on XML nodes:
- PatchOperationAdd adds a provided child node to the selected node
- PatchOperationInsert adds a provided sibling node to the selected node
- PatchOperationRemove deletes the selected node
- PatchOperationReplace replaces the selected node with the provided node
- Three do basic operations on XML attributes:
- PatchOperationAttributeAdd adds a provided attribute to the selected node if and only if the attribute name is not already present
- PatchOperationAttributeSet sets a provided attribute for the selected node, overwriting the attribute value if the attribute name is already present
- PatchOperationAttributeSet removes an attribute for the selected node
- Four allow for more complex operations:
- PatchOperationAddModExtension adds a ModExtension.
- PatchOperationSetName changes the name of a node. It is generally useless.
- PatchOperationSequence contains a set of other PatchOperations, and aborts upon any operation failing
- PatchOperationTest tests nodes, which is useful inside a PatchOperationSequence
XPath syntax
Each PatchOperation must specify an XML node to modify. It uses XPaths to specify them. An XPath is a "path" for the patch to follow when trying to find XML nodes matching the description. It will follow each part of the path from left to right.
Most XPaths should start with */
. The *
matches any element, so it'll match the root (the top level) of the XML tree. The following slash selects Using //
is technically also valid, but because that construct selects all the elements in the XML tree, it's an expensive operation that makes a mod needlessly slow to load.
Once the root is selected, the XPath lets the system walk down specific branches of the tree. If we use the example from the lead, we get a specific path:
*/TerrainDef[defName="WaterDeep"]/texturePath
- The root node is selected
- All child nodes of the root node called "TerrainDef" are selected
- We narrow down from "all TerrainDefs" to only those with the child "defName" node whose value is "WaterDeep", which should give us exactly one node because defNames must be unique
- We select the child node "texturePath" from this node
Overview of individual PatchOperations
(to do)
PatchOperationAdd
PatchOperationInsert
PatchOperationRemove
PatchOperationReplace
PatchOperationAttributeAdd
PatchOperationAttributeSet
PatchOperationAttributeRemove
PatchOperationAddModExtension
PatchOperationSetName
PatchOperationSequence
PatchOperationTest
Resources
The best tutorial on PatchOperations created by Zhentar: Introduction to PatchOperation
You can also learn about XPaths here: XPath tutorial
There is also an Overview of PatchOperations on the RimWorldModGuide.