• If you have a mod, tool or prefab, please use the Resources section. Click Mods at the top of the forums.

XPath Modding Explanation Thread

This is a large amount of information in these posts. I'll be working on a full, properly formed tutorial as we get access to A17 and we can really make the xpath system shine. I've listed some examples here, and we'll be posting a ton more xpath samples over the coming weeks, as we port the SDX modlets over to use the native hooks.

By all means, begin posting your comments, questions, or requests for clarity.

Since we now know that xpath support will be built-into the vanilla base game, and discussions earlier were getting a bit confusing, I've decided to make a new thread to try to demystify xpath and what it'll mean for mods and modders going forward in A17. The information in this thread has been pieced together from forum and discord discussions. They may not be 100% accurate, but I will update this thread when we know the full implementation.

XPath is a way of adding, changing, or removing XML lines and nodes, without directly editing the XML files. It allows you to apply patches to the XML files without manually editing the vanilla XML files.

SDX has had partial support for this since its initial release, and a lot of the SDX Modlets are already written this way. We will be using some of the SDX's xpath as examples in this thread, but SDX is not required to do this in A17 and onwards.

I believe in using examples to explain concept, so in the next few posts, you'll see a mixture of explanation, along with sample xpath code.

The following Mod structure is expected for A17 and beyond:

Code:
Mods/
   <ModName>/
       Config/
       UIAtlases/ItemIconAtlas/
       ModInfo.xml

   <ModName2>/
       Config/
       ModInfo.xml
You will be able to have multiple mods loaded, and loading will occur as long as the ModInfo.xml exists. This is unchanged from what we've been doing doing with other alphas, with the exception of the Config folder.

This Config folder will support loading XML files, written using xpath, in the following folder structure:

Code:
Config/entityclasses.xml
Config/gamestages.xml
Config/items.xml
The files in the Config folder will not be a full copy of the vanilla file with your changes. Rather, it'll contain the changes you want done to the vanilla files. The files under the Config must match the vanilla file name. You cannot create an entityclasses2.xml file, and expect it to work. Any changes in the entityclasses.xml will have to be done in the same file. However, each mod can have its own entityclasses.xml.

During the game's initialization, it will perform the xpath merge in-memory only; no files will be actually be modified. This would allow us to remove mods we no longer want, without re-validating against steam, or previous copies of the xml. That's a big one. No more half merging of a mod, and not having it work, then trying to pull it back out.

What this means for us is that we'll be able to make a variety of smaller mods, which I've been calling modlets, which can add, remove and change smaller pieces of the game. They can be used together, or they could be added to an overhaul mod, in order to style your game play easier.

These modlets would also exists outside of the Data/Config folder, so if you have made direct XML changes in your Alpha 17.1 Data/Config files, and Steam updated the game to 17.2, you would have lost your changes, or would have to re-merge them in. We've all been there before. But if they existed as modlets, under the Mods folder, they would be safe. And as long as your xpath is still valid to the new XML, it should load up with no additional work on your part.

If we could use xyth's JunkItems modlet, which adds random, scrappable junk items to loot containers, and add them to Valmod Overhaul. Likewise, if Valmod Overhaul did not have the No Ammo modlet (which gives you the ability to unload a gun and get its bullets back without disassembling it), you could drop the NoAmmo modlet into your Mods folder. Headshots only? Want to increase stack sizes? Same deal.

With a properly constructed modlet, we'll be able to piece together new play styles for people to enjoy and share. A modder working on a large overhaul won't have to duplicate work. If they wanted to include the No Ammo mod, they wouldn't have to code it themselves, letting them focus on the bits that make their mod really unique.

Let's get started on your journey...

 
Last edited by a moderator:
This A18 localization support works similar to SDX Tool localization support.

Example:

You makes a localization file like this:

Code:
Key,English
myKeyHere,My Text Here
And SDX Tool pushes to localization file like this:

Code:
myKeyHere,,,,My Text Here,,,,,
 
Last edited by a moderator:
Having some weird problems , trying to alter the icons on some of the vanilla items, for example scrapiron, using this line in a modlet items.xml

<append xpath="/items/item[@name=resourceScrapIron]/property[@name=HoldType]">

<property name="CustomIcon" value="iron"/>

</append>

but ending up with this looks in the items.xml under configdumps,

<item name="resourceScrapIron">

<property name="HoldType" value="45">

<property name="CustomIcon" value="iron"><!--Element appended by: "Holo's fixes"--></property>

</property>

what am i doing wrong? tried with append and insertafter but always ending up with the </property> that's not supposed to be there and making the lines unread by the server.

 
Having some weird problems , trying to alter the icons on some of the vanilla items, for example scrapiron, using this line in a modlet items.xml
<append xpath="/items/item[@name=resourceScrapIron]/property[@name=HoldType]">

<property name="CustomIcon" value="iron"/>

</append>

but ending up with this looks in the items.xml under configdumps,

<item name="resourceScrapIron">

<property name="HoldType" value="45">

<property name="CustomIcon" value="iron"><!--Element appended by: "Holo's fixes"--></property>

</property>

what am i doing wrong? tried with append and insertafter but always ending up with the </property> that's not supposed to be there and making the lines unread by the server.
Your append is too deep. You are telling it to append the CustomIcon lin to HoldType, so it looks like this:

Code:
<property name="HoldType" value="45" >
  <property name="CustomIcon" value="iron" />
</property>
You want this:

Code:
<append xpath="/items/item[@name='resourceScrapIron']">
<property name="CustomIcon" value="iron"/>
</append>
 
Agh. I'll never get the hang of xpath it seems :/ I'm trying to remove items from the progression, so we -must- find the schematic,

trying to remove the whole line with

<remove xpath="/progression/perks/perk[@name=perkYeahScience]/effect_group[@tags=chemistryStation]" />

but the game won't allow that and I'm not sure how to remove things from progression and can't find any examples from other mods :(

 
Last edited by a moderator:
Agh. I'll never get the hang of xpath it seems :/ I'm trying to remove items from the progression, so we -must- find the schematic, trying to remove the whole line with

<remove xpath="/progression/perks/perk[@name=perkYeahScience]/effect_group[@tags=chemistryStation]" />

but the game won't allow that and I'm not sure how to remove things from progression and can't find any examples from other mods :(
You are close. The chemistryline is part of the passive_effect line, not the effectgroup itself. Once you target the passive_effect line, you can add the name attribute as an additional condition, or continue just to target the @tags='chemistryStation'.

Code:
<remove xpath="/progression/perks/perk[@name='perkYeahScience']/effect_group/passive_effect[@name='RecipeTagUnlocked' and @tags='chemistryStation']" />

<remove xpath="/progression/perks/perk[@name='perkYeahScience']/effect_group/passive_effect[@tags='chemistryStation']" />
 
Hello,

I'm having trouble with a "simple-ish" modlet I'm trying to make. I'm basically trying to change the % value of all zombies in game from 1 to .5 or 0.1 or whatever (aka, so they have less life). I want to do it through the % values so the game balance stays intact (somewhat).

The game loads the mod properly at the start of the game, displays the version, but it doesn't do anything. The zombies have the same health value as they had before.

This is my modlet code for the entityclasses.xml:

Code:
<?xml version="1.0" encoding="UTF-8"?>

<entityclasses>

<set xpath="/entity_classes/entity_class[starts-with(@name,'zombie')]/effect_group[@name='Base Effects']/passive_effect[@name='HealthMax'][@operation='perc_set'][@value='1']/@value">.1</set>

</entityclasses>
What did I mess up?

p.s. sphereii, bless your soul for helping us

 
Hello,
I'm having trouble with a "simple-ish" modlet I'm trying to make. I'm basically trying to change the % value of all zombies in game from 1 to .5 or 0.1 or whatever (aka, so they have less life). I want to do it through the % values so the game balance stays intact (somewhat).

The game loads the mod properly at the start of the game, displays the version, but it doesn't do anything. The zombies have the same health value as they had before.

This is my modlet code for the entityclasses.xml:

Code:
<?xml version="1.0" encoding="UTF-8"?>

<entityclasses>

<set xpath="/entity_classes/entity_class[starts-with(@name,'zombie')]/effect_group[@name='Base Effects']/passive_effect[@name='HealthMax'][@operation='perc_set'][@value='1']/@value">.1</set>

</entityclasses>
What did I mess up?

p.s. sphereii, bless your soul for helping us
It seems to be a valid xpath. Have you checked your exported configs, under your SaveGame folder to see if it applied the changes you expect? It could be that what you are changing isn't the final determination on what the health of a zombie has.

 
It seems to be a valid xpath. Have you checked your exported configs, under your SaveGame folder to see if it applied the changes you expect? It could be that what you are changing isn't the final determination on what the health of a zombie has.
I presume it's the thing under %appdata% so I went there, specifically under "C:\Users\PCuser\AppData\Roaming\7DaysToDie\Saves\Navezgane\myworld\ConfigsDump\entityclasses.xml"

And yes, as you said, it didn't apply the changes there.

Another thing that I forgot to mention is that I tried changing these values manually and when I changed them manually with notepad++ (all 84 lines that matched that line and the value "1") it applied the HP change as intended. Since that worked I went and tried to make a modlet that would do the same but unfortunately it didn't work :/

The only other mod I'm using is the SMX hud overhaul but I doubt that would be causing any conflicts.

Wat do? Am I perhaps missing something with my mod structure? I attached an image below showing my whole folder structure for the mod.

ModStructure.jpg


 
Nvm! I fixed it!

I deleted the Item Icons folder since I wasn't using it ( I checked it was for A17 and before) and I added the mod.xml and filled out the required data. Works like a charm. Thanks for the help! <3

 
You are close. The chemistryline is part of the passive_effect line, not the effectgroup itself. Once you target the passive_effect line, you can add the name attribute as an additional condition, or continue just to target the @tags='chemistryStation'.
Code:
<remove xpath="/progression/perks/perk[@name='perkYeahScience']/effect_group/passive_effect[@name='RecipeTagUnlocked' and @tags='chemistryStation']" />

<remove xpath="/progression/perks/perk[@name='perkYeahScience']/effect_group/passive_effect[@tags='chemistryStation']" />
Ahh Thanks! I was not aware one could have longer then a single 'item' here "effect_group/passive_effect"

But I'm running into brickwall again with other ideas :/

trying to revert there weird choice to increase material amount as one get better at making things, and been trying everything I can think of.

Currently ended up with this code, with the thrownspeariron as a test to see if even the syntax was correct, but it was not applied :(

<set xpath="/recipies/recipe[@name=meleeThrownSpearIron]/effect_group/passive_effect[@name=CraftingIngredientCount' and @value='.5,2.5]/@value">2.5,.5</set>

hoping to replace the meleeThrownSpearIron with a wildcard (if that's doable?) to fix all those recipies, but can't get the syntax right.

 
Hello everyone, help me deal with the icons for items. I’m doing a mod on 18.2, I add an arrow object, in the ItemIcons folder there is a picture 160 * 160 in .png format

The game has an item, there is a recipe, but there is no icon that I made for this item. What's wrong, with the code that I wrote, here it is.

<item name="ammoArrowStonePaper">

<property name="CustomIcon" value="#@modfolder:ItemIcons/ammoArrowStonePaper.png" />

<!--<property name="CustomIcon" value="#@modfolder:Textures/iconsItem/ammoArrowStonePaper.png" />-->

I tried to put it in another folder, but still there is no icon in the game

tell me what is wrong or what needs to be done!

 
How do i add a Battery to the Junk Turret recipe? I tried but ended up with double recipes lol
what does your XML look like?

- - - Updated - - -

Hello everyone, help me deal with the icons for items. I’m doing a mod on 18.2, I add an arrow object, in the ItemIcons folder there is a picture 160 * 160 in .png formatThe game has an item, there is a recipe, but there is no icon that I made for this item. What's wrong, with the code that I wrote, here it is.

<item name="ammoArrowStonePaper">

<property name="CustomIcon" value="#@modfolder:ItemIcons/ammoArrowStonePaper.png" />

<!--<property name="CustomIcon" value="#@modfolder:Textures/iconsItem/ammoArrowStonePaper.png" />-->

I tried to put it in another folder, but still there is no icon in the game

tell me what is wrong or what needs to be done!
I think it builds an atlas, so your custom icon would probably be something like

Code:
<property name="CustomIcon" value="ammoArrowStonePaper" />
if you name you item as ammoArrowStonePaper, it should also work without custom icon.

 
<configs><append xpath="/recipes">

<recipe name="gunJunkTurret" count="1" craft_area="workbench" tags="learnable,perkTurrets">

<ingredient name="gunJunkTurretParts" count="4"/>

<ingredient name="resourceForgedIron" count="40"/>

<ingredient name="carBattery" count="1"/>

<ingredient name="resourceDuctTape" count="1"/>

<ingredient name="resourceScrapPolymers" count="10"/>

<ingredient name="resourceSpring" count="10"/>

<effect_group>

<passive_effect name="CraftingIngredientCount" level="2,6" operation="perc_add" value=".5,2.5" tags="gunJunkTurretParts,resourceForgedIron,resourceDuctTape,resourceScrapPolymers,resourceSpring"/>

</effect_group>

</recipe>

</append>

</configs>

It works, but the vanilla recipe is there too. I just want to "insert" a battery into the existing vanilla recipe

 
Last edited by a moderator:
It works, but the vanilla recipe is there too. I just want to "insert" a battery into the existing vanilla recipe
ahh you want to do this:

Code:
<append xpath="/recipes/recipe[@name='gunJunkTurret']">
  <ingredient name="carBattery" count="1"/>
</append>
 
ahh you want to do this:

Code:
<append xpath="/recipes/recipe[@name='gunJunkTurret']">
  <ingredient name="carBattery" count="1"/>
</append>


Code:
<configs>
<append xpath="/recipes/recipe[@name='gunJunkTurret']">
  <ingredient name="carBattery" count="1"/>
</append>
</configs>
Full code correct?

 
Howdy!

I've been working on a "no crafting" mod, and this thread has been gold! for information. I've learned a lot about xpath, etc.

I have unfortunately run into something.. Ive been able to get everything working the way i want it, but one part is giving me some issue.

The short story is this:

Code:
<config>

<remove xpath="/items/item[@name='modArmorPlatingBasicSchematic']" />

<append xpath="/items">
<item name="modArmorPlatingBasicSchematic">
<property name="Extends" value="schematicNoQualityMaster"/>
<property name="CreativeMode" value="Player"/>
<property name="CustomIcon" value="modArmorPlatingBasic"/>
<property name="Unlocks" value="modArmorPlatingBasic"/>
<effect_group tiered="false">
	<triggered_effect trigger="onSelfPrimaryActionEnd" action="ModifyCVar" 
cvar="modArmorPlatingBasic" operation="set" value="0"/>
	<triggered_effect trigger="onSelfPrimaryActionEnd" action="GiveExp" exp="50"/>
</effect_group>
</item>
</append>

</config>
this works, but everything i have tried to try to write it shorter.. to take up less space, and not have to

include everything... how am i trying to say this...

For some reason, just the way the game is, and does what it does right now, i can remove

all recipes from "recipes.xml", BUT, when i do, the trader sells all the item mods at 0 cost..

while all other items they sell DO have cost..

my workaround was to leave the recipes in there (that works fine), then to change

this line from value=1 --> value=0

Code:
<triggered_effect trigger="onSelfPrimaryActionEnd" action="ModifyCVar" 
cvar="modArmorPlatingBasic" operation="set" value="0"/>
that allows the trader to sell the item mods for #cost, but when you read the schematic,

you get the xp, but not the ability to craft it.

This is the intended goal, but i am looking for a shorter way to write this, rather than

write it the way i did above for every mod*schematic...

btw.. if i have to, i will. but i am sure there is a better way..

also, before i try with xpath, i DO try the changes in the actual xml file,

to make sure what i am trying is even valid..

i have tried starts-with, ends-with, set, etc...

each time it looks me right in the eye, and says F you,

for example:

Code:
<set xpath="/items/item[starts-with(@name, 'mod')]/triggered_effect[@operation='set']/@value">0</set>
this fails, for some reason..

Thanks!

 
can xpath add in new entityclasses like a new zombie or animal? or do I need sdx still?
You can add new models for zombies and animals using just XML and Unity Bundles.

You would need SDX/DMT if you wanted to add a custom entity with its own animations, etc

 
Back
Top