web stats

KATA 2 OF 8 · XML LAYER

The XPath Toolkit: All Eleven Commands

In Kata 1 you used <set> to change one value. That is one of eleven XML modification commands the game exposes (the same eleven on every build from V1.4 to V3.3, read from the game's own patcher). Learn them and the XPath that aims them, and you can change, add, or remove anything in the game's XML - which is the entire job for the next two katas. This is the reference you will come back to most.

7 Days to Die XPath cheat sheet

You want toCommandShape
Change a value that already exists<set><set xpath="/items/item[@name='resourceWood']/property[@name='Stacknumber']/@value">6000</set>
Add or change an attribute on a node<setattribute><setattribute xpath="/items/item[@name='resourceWood']" name="tag">wood</setattribute>
Add a new child node inside a node<append><append xpath="/items"> ...new <item>... </append>
Insert a node next to an existing one<insertBefore> / <insertAfter><insertAfter xpath="/items/item[@name='resourceWood']"> ...new <item>... </insertAfter>
Delete a node<remove><remove xpath="/items/item[@name='resourceWood']/property[@name='Stacknumber']"/>
Delete an attribute<removeattribute><removeattribute xpath="/items/item[@name='resourceWood']/@tag"/>
Add a new child node at the start of a node<prepend><prepend xpath="/items"> ...new <item>... </prepend>
Add to or remove from a comma-separated value<csv><csv xpath="/items/item[@name='resourceWood']/property[@name='Tags']/@value" delim="," op="add">myTag</csv>
Apply a block only on some game or mod versions<conditional><conditional><if cond="game_version() &gt;= version(3,0)"> ... </if><else> ... </else></conditional>
Pull in another patch file<include><include filename="items_part2.xml" />

Every command lives inside <configs> ... </configs> in a file under your modlet's Config/ folder named after the vanilla file it patches. The rest of this page walks each command with a working example and the XPath selectors that aim them; the same commands drive XUi interface mods. Not sure what to write? The Server Tweak Mod Generator writes a complete server-settings modlet for you; open its Config/ files and you will find exactly these commands.

What you'll build

No single mod this time - this kata is the toolkit itself, with a verified example of each command, then a small combined modlet at the end that uses three of them together.

The eleven commands

Nine take an xpath attribute that points at a node or attribute; conditional and include wrap other commands and take none. The seven below were introduced in Alpha 17; prepend, csv, conditional and include are in the game too, on every build from V1.4 to V3.3. A command the game does not know is logged as Patch type (name) unknown and skipped; a command whose xpath matches nothing is logged as XML patch for "file" from mod "Name" did not apply and skipped, and the mod still loads.

set - change an existing attribute

Changes a value that already exists. If the target attribute does not exist, it does not create it - it logs a warning. This is the Kata 1 command.

<set xpath="/items/item[@name='meleeToolStoneAxe']/property[@name='DegradationMax']/@value">500</set>

setattribute - add or change a named attribute

Unlike set, this can create an attribute on a node that did not have it. You give the node in xpath and the attribute in name.

<setattribute xpath="/items/item[@name='meleeToolStoneAxe']/property[@name='Weight']" name="measure">kilograms</setattribute>

append - add new nodes (or extend an attribute)

The workhorse for adding content. Point at a parent node and the content inside the tag becomes a new child. (Point at an attribute instead and the text is appended to that attribute's value - handy for adding a tag.)

<!-- add a whole new property to an item -->
<append xpath="/items/item[@name='gunHandgunT1Pistol']">
    <property name="MyCustomProp" value="1" />
</append>

<!-- or append to an attribute value (note the leading comma) -->
<append xpath="/items/item[@name='gunHandgunT1Pistol']/property[@name='Tags']/@value">,myNewTag</append>

insertAfter / insertBefore - place a sibling node

Where append adds a child inside a node, these add a sibling directly after or before the targeted node - useful when order matters (recipes, progression, UI elements).

<insertAfter xpath="/items/item[@name='gunHandgunT1Pistol']/property[@name='Tags']">
    <property name="AddedAfterTags" value="a,b,c" />
</insertAfter>

remove - delete a node

Deletes the node(s) the xpath selects. Self-closing - there is no content.

<remove xpath="/items/item[@name='gunHandgunT1Pistol']/property[@name='UnlockedBy']" />

removeattribute - delete one attribute

Deletes a single attribute, leaving the node in place.

<removeattribute xpath="/items/item[@name='meleeToolStoneAxe']/@category" />

prepend - add new nodes at the start

Like append, but the new content goes in first inside the targeted node (or at the start of an attribute value), which matters when the game reads a list in order.

<prepend xpath="/items/item[@name='gunHandgunT1Pistol']">
    <property name="MyFirstProp" value="1" />
</prepend>

csv - add to or remove from a comma-separated value

Many attributes are lists (Tags, Groups, loot and spawn lists). csv edits one entry of such a list without rewriting the whole value, so two mods can touch the same list. op is add or remove; delim changes the separator (one character, or \n), and remove accepts * at the start or end of an entry as a wildcard. The target must be an attribute or a text node.

<csv xpath="/items/item[@name='gunHandgunT1Pistol']/property[@name='Tags']/@value" delim="," op="add">myNewTag</csv>
<csv xpath="/items/item[@name='gunHandgunT1Pistol']/property[@name='Tags']/@value" op="remove">weapon,ranged*</csv>

conditional - apply a block only when a test passes

Wraps if branches and an optional else. The cond expression can test the game version, whether another mod is loaded, and that mod's version, so one modlet can carry a 2.6 branch and a 3.x branch. conditional and include are the two commands that take no xpath of their own.

<conditional>
    <if cond="game_version() &gt;= version(3,0)">
        <set xpath="/items/item[@name='resourceWood']/property[@name='Stacknumber']/@value">6000</set>
    </if>
    <else>
        <set xpath="/items/item[@name='resourceWood']/property[@name='Stacknumber']/@value">3000</set>
    </else>
</conditional>

The functions the evaluator knows, from the game's own code: game_version(), version(major, minor, ...) to build a value to compare against, mod_loaded("ModName"), mod_version("ModName") (the Version from that mod's ModInfo.xml), gamepref("Name"), game_loaded(), serverinfo(...) (only once a game is loaded), time_minutes(), has_entitlement(...), xpath(...) and event(...). An expression the game cannot evaluate stops the rest of that patch file (the log says XML loader: Patching 'file' from mod 'Name' failed), so test a conditional on a throwaway server first.

include - split a patch file

Pulls in another patch file, named relative to the file that contains the include, and applies its commands in place. Useful to keep a large items.xml patch in readable pieces.

<include filename="items_weapons.xml" />

Aiming them: the XPath you need

The command is the verb; the XPath is the address. Ninety percent of modding is writing an XPath that selects exactly the node you mean and nothing else. The pieces:

PatternSelects
/items/itemevery <item> directly under <items>
/items/item//property<property> at any depth under an item (note the double slash)
/items/item/@namethe name attribute of those items
[@name='resourceWood']only the node whose name equals that (a predicate)
[@value > 2] / [@value < 4]numeric comparison - write &gt; / &lt; inside the XML
[@name='x' or @name='y']logical OR; and and not(...) work too
[starts-with(@name,'gun')]string match - also ends-with and contains
[1] / [last()]the first / last matching sibling by position
[@category]nodes that simply have a category attribute
/..step up to the parent node

Combine them freely: /items/item[contains(@name,'gun') and not(@name='gunHandgunT1Pistol')]/property[@name='Magazine_size']/@value selects the magazine size of every gun except that one pistol.

A combined example

Here is a single Config/items.xml that uses three commands together - the kind of small, real modlet you will write constantly:

<configs>
    <!-- bump every stone tool's durability -->
    <set xpath="/items/item[starts-with(@name,'meleeToolStone')]/property[@name='DegradationMax']/@value">1000</set>

    <!-- give the stone axe a new tag -->
    <append xpath="/items/item[@name='meleeToolStoneAxe']/property[@name='Tags']/@value">,reinforced</append>

    <!-- strip the perk requirement off the wrench -->
    <remove xpath="/items/item[@name='meleeToolRepairT1Wrench']/property[@name='UnlockedBy']" />
</configs>

Test it the smart way

You do not have to relaunch and play to verify XPath. Two faster loops:

  • Read the log on load. A bad xpath that matches nothing usually logs a warning (for set) or a clear error; a malformed file logs a red XML error with the line number. Watch the startup log first, every time.
  • Confirm the node names against vanilla. Open the game's own Data/Config/items.xml (and blocks.xml, recipes.xml...) and search for the exact name before you write the xpath. Most "my mod did nothing" cases are a misremembered name, and these files are the only source of truth.

Common pitfalls

  • set vs setattribute. set only edits attributes that already exist; to create a new attribute use setattribute, to add a whole node use append.
  • Unescaped comparison operators. A literal < or > inside an xpath breaks the XML. Always write &lt; and &gt;.
  • Too-greedy selectors. /items/item hits every item in the game. Add a predicate, or you will edit thousands of things and wonder why balance feels off. Test broad selectors against vanilla first.
  • A typo in a command name is not an error that stops the mod. The game logs Patch type (naem) unknown, skips that command and loads the rest, so read the log after every restart rather than trusting the mod list.
  • Load order matters for conflicts. If two modlets set the same attribute, the one that loads later wins. Kata 8 covers controlling that.

Next: Kata 3 - Add an Item, Recipe & Localization. You can now edit, add, and remove. Next you combine append across items.xml and recipes.xml with a Localization entry to ship a genuinely new, craftable, properly-named item.