• 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:
Hello, i'm new with modlet and xpath, i am trying to do soem changes for my own use and i keep getting erros when load the mod, i am getting "yyExeption irrecoverable syntax error" when i load my world editor with those changes

Code:
<rwgmixer>
         <!-- Biome Range -->
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap0.Range']/@value">,0,5</set>
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap1.Range']/@value">,5,7</set>
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap2.Range']/@value">,7,7.3</set>
	 <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap3.Range']/@value">,7.3,8</set>
	 <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap4.Range']/@value">,8,9</set>

        <!-- Prefab Spawn Chance -->
        <set xpath="/rwgmixer/prefab_rules/prefab_rule/[@name='industrial_JunkyardsLots']/prefab[@name='junkyard_med_01']/@value">0.5</set>
	 <set xpath="/rwgmixer/prefab_rules/prefab_rule/[@name='industrial_JunkyardsLots']/prefab[@name='utility_celltower_02']/@value">0.3</set>
        <set xpath="/rwgmixer/prefab_rules/prefab_rule/[@name='industrial_JunkyardsLots']/prefab[@name='junkyard_lg_01]/@value=">0.10</set>

</rwgmixer>
What im doing wrong?
In your Prefab spawn chance, you have /prefab_rule/[@name='... you probably don't want the / in the middle. /prefab_rule[@name='.

Also, your last three lines try to change the @value. But that's not a valid attribute for that line. Do you mean @count?

 
Hello, i'm new with modlet and xpath, i am trying to do soem changes for my own use and i keep getting erros when load the mod, i am getting "yyExeption irrecoverable syntax error" when i load my world editor with those changes

Code:
<rwgmixer>
         <!-- Biome Range -->
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap0.Range']/@value">,0,5</set>
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap1.Range']/@value">,5,7</set>
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap2.Range']/@value">,7,7.3</set>
	 <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap3.Range']/@value">,7.3,8</set>
	 <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap4.Range']/@value">,8,9</set>

        <!-- Prefab Spawn Chance -->
        <set xpath="/rwgmixer/prefab_rules/prefab_rule/[@name='industrial_JunkyardsLots']/prefab[@name='junkyard_med_01']/@value">0.5</set>
	 <set xpath="/rwgmixer/prefab_rules/prefab_rule/[@name='industrial_JunkyardsLots']/prefab[@name='utility_celltower_02']/@value">0.3</set>
        <set xpath="/rwgmixer/prefab_rules/prefab_rule/[@name='industrial_JunkyardsLots']/prefab[@name='junkyard_lg_01]/@value=">0.10</set>

</rwgmixer>
What im doing wrong?
There are a couple of odd set commands there that I imagine are causing the issue.

Here is one of the properties you are trying to set.

Code:
				<property name="biomemap0.Range" value="0.2,0.5"/>
After the set command above it will look like this:

Code:
				<property name="biomemap0.Range" value=",0,5"/>
 
In your Prefab spawn chance, you have /prefab_rule/[@name='... you probably don't want the / in the middle. /prefab_rule[@name='.
Also, your last three lines try to change the @value. But that's not a valid attribute for that line. Do you mean @count?
Thanks for the fast reply, and i thought all the last attributes needed to be value to be changed, but its equal written in the xml? i didnot noticed the junkyard_med_01 had only 1 count, thank you so much again. i need to keep learning from this post tultorial.

 
There are a couple of odd set commands there that I imagine are causing the issue.Here is one of the properties you are trying to set.

Code:
				<property name="biomemap0.Range" value="0.2,0.5"/>
After the set command above it will look like this:

Code:
				<property name="biomemap0.Range" value=",0,5"/>
You are right, all the numbers are wrong and the game can't load with those changes, thanks for show me what's wrong, i was breaking my head with this LOL, after the prob and value or count i need to put @value=">0< or @value">0<

 
Thanks for the fast reply, and i thought all the last attributes needed to be value to be changed, but its equal written in the xml? i didnot noticed the junkyard_med_01 had only 1 count, thank you so much again. i need to keep learning from this post tultorial.
It's a common misconception that everything is @value, but that's just because a lot of the things we are changing is actually value. In reality, the @value is the attribute called 'value' on the line.

Code:
<drop event="Harvest" name="resourceRockSmall" count="50" tag="oreWoodHarvest"/>
@event, @name, @count, and @tag are all changeable

Code:
<set xpath="/blocks/block[@name='terrStone']/drop/@event">NewEvent</set>
<set xpath="/blocks/block[@name='terrStone']/drop/@name">newName</set>
<set xpath="/blocks/block[@name='terrStone']/drop/@count">33</set>
<set xpath="/blocks/block[@name=terrStone]/drop/@tag">all, my,new,tags</set>

 
It's a common misconception that everything is @value, but that's just because a lot of the things we are changing is actually value. In reality, the @value is the attribute called 'value' on the line.

Code:
<drop event="Harvest" name="resourceRockSmall" count="50" tag="oreWoodHarvest"/>
@event, @name, @count, and @tag are all changeable

Code:
<set xpath="/blocks/block[@name='terrStone']/drop/@event">NewEvent</set>
<set xpath="/blocks/block[@name='terrStone']/drop/@name">newName</set>
<set xpath="/blocks/block[@name='terrStone']/drop/@count">33</set>
<set xpath="/blocks/block[@name=terrStone]/drop/@tag">all, my,new,tags</set>
Now i understand what "value" really means, instead of this i was writing all in value instead of the real tag, Thanks, My changes are working now, i was doing everything wrong :smile-new:

Now the code is like

Code:
<rwgmixer>
         <!-- Biome Range -->
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap0.Range']/@value">0,0.5</set>
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap1.Range']/@value">0.5,0.7</set>
        <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap2.Range']/@value">0,7.3</set>
	 <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap3.Range']/@value">7.3,0.8</set>
	 <set xpath="/rwgmixer/biome_generators/biome_generator/module[@name='biomeOutput']/property[@name='biomemap4.Range']/@value">0.8,1.1</set>

        <!-- Prefab Spawn Chance -->
	 <set xpath="/rwgmixer/prefab_rules/prefab_rule[@name='industrial_JunkyardsLots']/prefab[@name='utility_celltower_02']/@prob">0.3</set>
        <set xpath="/rwgmixer/prefab_rules/prefab_rule[@name='industrial_JunkyardsLots']/prefab[@name='junkyard_lg_01']/@prob">0.10</set>
</rwgmixer>
 
I've used the following xpath to move the buffs popup text away from the main screen:

<set xpath="/windows/window[@name=popupMenu]/@pos">200,-400</set>

This seems to work, as I can drink a beer and no text comes up to say I have a buzz. However when I open my backpack the text pops up in the normal position on the screen, and seems to refresh when I leave my backpack so the text lingers a few seconds on the main screen... anyone know why?

 
Hmm. I think I have another probably stupid question, is it possible to remove the eh... tag "tag"

For example, remove the entire "tags="learnable"" part of a recipie like <recipe name="gunRocketLauncher" craft_area="workbench" count="1" tags="learnable">

 
Hmm. I think I have another probably stupid question, is it possible to remove the eh... tag "tag"For example, remove the entire "tags="learnable"" part of a recipie like <recipe name="gunRocketLauncher" craft_area="workbench" count="1" tags="learnable">
It's not a stupid question, and sadly, no. There's no <remoteattribute>. We can however, set it to blank, and see if that helps.

 
Hi everyone! I want to change the stone shovel, so that it can till soil like the hoe. I tested it by changing the items.xml manually and it works, but if i try it via mod it generates an error message, so obviously my mistake is in the modlet / syntax. Hope you can help me.
I simply want to replace the secondary action of the shovel (power attack by default) with the secondary action of the hoe. Here is my mod-code.

Code:
<!-- Deleting the secondary action and the power attack -->
<remove xpath="items/item[@item name='meleeToolShovelStone']/property[@class='Action1']">
<remove xpath="items/item[@item name='meleeToolShovelStone']/effect_group[@name='Power Attack']">

<!-- Adding the new secondary action -->
<append xpath="items/item[@item name='meleeToolShovelStone']/property[@class='Action1']">
	<property name="class" value="Repair"/>
	<property name="Repair_amount" value="30"/>
	<property name="Upgrade_hit_offset" value="-4"/>
	<property name="Delay" value="1.3"/>
	<property name="Upgrade_action_sound" value="ImpactSurface/metalhitearth"/>
	<property name="Allowed_upgrade_items" value="meleeToolHoeIron,resourceClayLump"/>
</append>
you could try InsertAfter which will drop it right after action0 instead of at the end of the node, and I also noticed your remove lines don't have a closing slash (..."/>) which would have left them in and functioning even if your append did the trick. ALSO, the remove removes the entire node, you have to construct a new action1 node to wrap your new properties in, you missed that in your append. I missed it too on first go :p

The code below should do the trick, otherwise, your work looks like it was spot on...

Code:
<!-- Deleting the secondary action and the power attack -->
<remove xpath="items/item[@item name='meleeToolShovelStone']/property[@class='Action1']"/>
<remove xpath="items/item[@item name='meleeToolShovelStone']/effect_group[@name='Power Attack']"/>

<!-- Adding the new secondary action -->
<insertAfter xpath="items/item[@item name='meleeToolShovelStone']/property[@class='Action0']">
<property class="Action1">
	<property name="class" value="Repair"/>
	<property name="Repair_amount" value="30"/>
	<property name="Upgrade_hit_offset" value="-4"/>
	<property name="Delay" value="1.3"/>
	<property name="Upgrade_action_sound" value="ImpactSurface/metalhitearth"/>
	<property name="Allowed_upgrade_items" value="meleeToolHoeIron,resourceClayLump"/>
</property>
</insertAfter>
 
Last edited by a moderator:
Hmm. I think I have another probably stupid question, is it possible to remove the eh... tag "tag"For example, remove the entire "tags="learnable"" part of a recipie like <recipe name="gunRocketLauncher" craft_area="workbench" count="1" tags="learnable">
If you're trying to remove the rocket launcher and ammo from being craftable, but still found in game, this is what I did in recipies.xml.

Code:
<!-- Remove recipes (can still find em in game, just not make em) -->
	<remove xpath="/recipes/recipe[@name='gunRocketLauncher']" />
	<remove xpath="/recipes/recipe[@name='ammoRocketFrag']" />
	<remove xpath="/recipes/recipe[@name='ammoRocketHE']" />
	<remove xpath="/recipes/recipe[@name='resourceRocketCasing']" />
	<remove xpath="/recipes/recipe[@name='resourceRocketTip']" />
You can re-add the entire recipe without the learnable tag with an Append.

 
Last edited by a moderator:
Hi everyone :)

I would like to change the output for Lead in the Forge but everything i tried, is not working. I am new to XPath modding (have only changed simple things in A15 and A16) This is what i have tried so far...

Code:
<changedrecipes>

<!-- <append xpath="/recipes/recipe[@name='resourceScrapLead']/@count">3</append> -->


<!-- <set xpath="/recipes/recipe[@name='resourceScrapLead']/@count">3</set> -->


<!-- <set xpath="/recipes/recipe[@name='resourceScrapLead']/ingredient [@name='unit_lead']/@count">3</set> -->

<!-- <set xpath="/recipes/recipe[@name='resourceScrapLead']/ingredient [@name='unitlead']/@count">3</set> -->


<append xpath="/recipes">
<recipe name="resourceScrapLead" count="1" craft_area="forge" material_based="true" craft_time = "1" craft_exp_gain="0" always_unlocked="true">
<ingredient name="unit_lead" count="3"/>
</recipe>

</append>


</changedrecipes>
Somehow noone is asking for this to be changed (or i can't find it, been searching on Google, and went thru Nexus, Youtube and this Forum so far) and i am starting to wonder if we can change it at all ? I have tried the codes all seperatly but the output stays at 1.

I have the 'ModInfo.xml' so that's not the problem.

Any help is greatly appreciated

greets cheeky2

 
Hi everyone :)
I would like to change the output for Lead in the Forge but everything i tried, is not working. I am new to XPath modding (have only changed simple things in A15 and A16) This is what i have tried so far...

Code:
<changedrecipes>

<!-- <append xpath="/recipes/recipe[@name='resourceScrapLead']/@count">3</append> -->


<!-- <set xpath="/recipes/recipe[@name='resourceScrapLead']/@count">3</set> -->


<!-- <set xpath="/recipes/recipe[@name='resourceScrapLead']/ingredient [@name='unit_lead']/@count">3</set> -->

<!-- <set xpath="/recipes/recipe[@name='resourceScrapLead']/ingredient [@name='unitlead']/@count">3</set> -->


<append xpath="/recipes">
<recipe name="resourceScrapLead" count="1" craft_area="forge" material_based="true" craft_time = "1" craft_exp_gain="0" always_unlocked="true">
<ingredient name="unit_lead" count="3"/>
</recipe>

</append>


</changedrecipes>
Somehow noone is asking for this to be changed (or i can't find it, been searching on Google, and went thru Nexus, Youtube and this Forum so far) and i am starting to wonder if we can change it at all ? I have tried the codes all seperatly but the output stays at 1.

I have the 'ModInfo.xml' so that's not the problem.

Any help is greatly appreciated

greets cheeky2
Let's try something like this. This will remove the existing wildcard_forge_category, and add a new one.

Code:
<changedrecipes>
   <remove xpath="/recipes/recipe[@name='resourceScrapLead']/wildcard_forge_category" />
   <append xpath="/recipes/recipe[@name='resourceScrapLead']">
         <ingredient name="unit_lead" count="3" />
   </append>
</changerecipes>
 
Hi guys i got a new Error for unknown reasons.

i added new Lootcontainer like the screenshot below shows:

http://prntscr.com/m4v61y

http://prntscr.com/m4v6bj

the new Container are named "metalJunk" and "otherJunk"

after the New Container, i added the Group "otherJunk" to the LootGroup "Garbage"

but when i start the Game the following Error is shown:

http://prntscr.com/m4v4yv

Can anyone explain me why this happend ? the new Container are above the edit once in loading order.

 
Hi guys i got a new Error for unknown reasons.
i added new Lootcontainer like the screenshot below shows:

http://prntscr.com/m4v61y

http://prntscr.com/m4v6bj

the new Container are named "metalJunk" and "otherJunk"

after the New Container, i added the Group "otherJunk" to the LootGroup "Garbage"

but when i start the Game the following Error is shown:

http://prntscr.com/m4v4yv

Can anyone explain me why this happend ? the new Container are above the edit once in loading order.
Sounds like its being added out-of-order.

Change your appends to be:

Code:
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
  <!--  your xml -->
</insertAfter>
This should explicity place it after the garbage loot container, allowing it to load in order.

 
so should i write:

Code:
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
<item group="otherJunk" count="1,3" prob="0.60"/>
</insertAfter>
or

Code:
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
<!-- The whole script from loot.xml file ??? -->
</insertAfter>
never used "insertAfter" before :D

 
so should i write:
Code:
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
<item group="otherJunk" count="1,3" prob="0.60"/>
</insertAfter>
or

Code:
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
<!-- The whole script from loot.xml file ??? -->
</insertAfter>
never used "insertAfter" before :D
insertAfter is exactly like an append, but it'll insert your snippet in a position.

Code:
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
   <lootgroup name="metalJunk" >
          <!-- your other stuff -->
   </lootgroup>

   <lootgroup name="otherJunk" >
          <!-- your other stuff -->
   </lootgroup>

</insertAfter>
 
so do i need the write the <append xyz> command to start with insert after?

Code:
<configs>
<append xpath="/lootcontainers">  ----- IS THIS STILL NEEDED ?????? cuz of setting the path !?
<insertAfter xpath="/lootcontainers/lootcontainer[@name='Garbage']" >
<lootgroup name="metalJunk">
      ---ALL THE STUFF
       </lootgroup>
</insertAfter>
</append>
anyway

<insertAfter xpath="/lootcontainers/lootcontainer[@name=Garbage]" >

... i mean garbage was a LootGroup instead a Lootcontainer

<insertAfter xpath="/lootcontainers/lootgroup[@name=Garbage]" >

 
Last edited by a moderator:
Back
Top