• 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:
Now the true challenge begins, now that I know i can target the node, I need to add a new item to drop. So not sure whats better for this, append or insert? I'll try append first..

 
your orginal suggestion WORKED!!
Code:
<set xpath="/blocks/block[@name='treeCactus01']/drop[@name='resourceYuccaFibers']/@count">20</set>
I was never checking the fibers as i was checking fruit. Also a huge red flag that kept me from troublshooting, was the simple rotation, that even editing the orginal XML file for the game, never worked, so it was a bad red hearing to use for testing.

I cant believe this.. thank you so much for your time with this issue, but wanted you to know, the your first code was the correct one that worked all this time. Ugh..
I'm glad you got it sorted out :)

- - - Updated - - -

Now the true challenge begins, now that I know i can target the node, I need to add a new item to drop. So not sure whats better for this, append or insert? I'll try append first..
I always recommend going with an append, it's less precise and less prone to breaking if your insertBefore or insertAfter conditions change.

 
I'm glad you got it sorted out :)
- - - Updated - - -

I always recommend going with an append, it's less precise and less prone to breaking if your insertBefore or insertAfter conditions change.
Yea i did.. when I finish and release my mod, i'll be giving you credit.. thanks again for your time.

 
I'm glad you got it sorted out :)
- - - Updated - - -

I always recommend going with an append, it's less precise and less prone to breaking if your insertBefore or insertAfter conditions change.
Yea i did.. when I finish and release my mod, i'll be giving you credit.. thanks again for your time.

 
Halp! :)

I'm trying to add the hazmat suit in the yeah science 2 perk requirement, already added the recipes. I want to add it here:

Code:
	<perk name="perkYeahScience" parent="skillCraftsmanship" name_key="perkYeahScienceName" desc_key="perkYeahScienceDesc" icon="ui_game_symbol_chemistry">
	<SNIP>
	<effect_group>
	<SNIP>
	<passive_effect name="RecipeTagUnlocked" operation="base_set" value="1" level="2,5"
			tags="thrownDynamite,ammo9mmBulletSteel,ammo44MagnumBulletSteel,ammo762mmBulletFMJSteel,ammoShotgunSlug,ammoArrowSteelAP,ammoCrossbowBoltSteelAP,ammoArrowFlaming,mineAirFilter,rScrapIronPlateMine,resourceMilitaryFiber,modMeleeBunkerBuster"/>
	<SNIP>
	</effect_group>
</perk>
So I thought I'd just append a new passive effect line that resembles the one above, like this:

Code:
<append xpath="/progression/perk[@name='perkYeahScience']/effect_group">
		<passive_effect name="RecipeTagUnlocked" operation="base_set" value="1" level="2,5"
			tags="hazmatBoots,hazmatPants,hazmatShirt,hazmatGloves,hazmatMask"/>
</append>
However I'm getting an error that this couldn't be applied, I'm guessing I've done an error in the xpath, but I can't figure out what exactly.

Edit: nvm, think hard enough and the answer will come on it's own

/perks is missing between progression and perk.....

doh!

 
Last edited by a moderator:
Is there a fast way to remove a whole section of code with one line? For example I want to remove an entire quest from the game, how can i do that with one line of code and not have to write a whole bunch of <remove xpath=".... blah blah etc...

 
Another question, does anyone know how to add a level requirement to a quest? I have tried a few different ways and have yet to get it working.

 
Is there a fast way to remove a whole section of code with one line? For example I want to remove an entire quest from the game, how can i do that with one line of code and not have to write a whole bunch of <remove xpath=".... blah blah etc...
You should be able to use <remove xpath="/quests/quest[@name=whatever]" /> to remove the quest

 
Thank you Sphereii, I did not think it would work that way, but it works perfectly. I seriously thought i would have to remove each line of code. Thank you again.

 
Quick question...has something changed with <set> and/or <append>? I've been using the following:

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

<set xpath="recipes/recipe[@name='foodBoiledMeat']">
	<ingredient name="foodRawMeat" count="2"/>
</set>
to add Fat to Bacon and Eggs and lower the Meat content in Boiled Meat to 2 instead of 5.

However...I went to craft some Boiled Meat and noticed that the recipe in game is now ONLY:

2 Raw Meat and NO Jar of Water

Also...the Fat ADDED to what was already in the original recipe (was 1 and then 2 with my edits)...that I can understand.

I did an experiment and changed the APPEND in Bacon and Eggs to SET (no other change) and in game I get that Bacon and Eggs only requires Fat AND NOTHING ELSE...here's what I did:

Code:
       <set xpath="recipes/recipe[@name='foodBaconAndEggs']">
	<ingredient name="resourceAnimalFat" count="1"/>
</set>
The top code I've been using for quite a while with no issues. As I understand...SET is used when you want to CHANGE a value and APPEND is used when you want to ADD something. But it seems that SET is ONLY using what it's given and removing everything else. Again...I can understand APPEND adding (from 1 to 2 if the original recipe had 1) so that's not really too much of an issue but this is the first time I've had this happen and I'm confused.

 
I'm having trouble trying to append some recipes. I keep getting and error that says;

Patch element does not have an xpath attribute. Here is the code I used.

Code:
<New_Recipies>
   <append xpath="/recipes">
	<recipe name="solarCell" count="1">
		<ingredient name="resourceScrapIron" count="1"/>
		<ingredient name="resourceScrapPolymers" count="1"/>
	</recipe>
	<recipe name="solarbank" count="1">
		<ingredient name="resourceScrapIron" count="1"/>			
		<ingredient name="resourceScrapPolymers" count="5"/>
	</recipe>
	<recipe name="carBattery" count="1">
		<ingredient name="resourceScrapIron" count="1"/>			
		<ingredient name="resourceScrapPolymers" count="5"/>
	</recipe>
	<recipe name="resourceElectricParts" count="1">
		<ingredient name="resourceScrapIron" count="1"/>			
	</recipe>
</append>
<New_Recipies/>
Not sure where I went wrong, i followed Buggi's video but it's not working. Any help would be appreciated.

 
I'm having trouble trying to append some recipes. I keep getting and error that says;
Patch element does not have an xpath attribute. Here is the code I used.

Code:
<New_Recipies>
   <append xpath="/recipes">
	<recipe name="solarCell" count="1">
		<ingredient name="resourceScrapIron" count="1"/>
		<ingredient name="resourceScrapPolymers" count="1"/>
	</recipe>
	<recipe name="solarbank" count="1">
		<ingredient name="resourceScrapIron" count="1"/>			
		<ingredient name="resourceScrapPolymers" count="5"/>
	</recipe>
	<recipe name="carBattery" count="1">
		<ingredient name="resourceScrapIron" count="1"/>			
		<ingredient name="resourceScrapPolymers" count="5"/>
	</recipe>
	<recipe name="resourceElectricParts" count="1">
		<ingredient name="resourceScrapIron" count="1"/>			
	</recipe>
</append>
<New_Recipies/>
Not sure where I went wrong, i followed Buggi's video but it's not working. Any help would be appreciated.
Take a look at your last entry: <New_Recipes/> should be </New_Recipes>, as it's closing the top node.

 
Alright, quick question for you... I'm trying to adjust a particular block in the blocks.xml. The line I have is

Code:
<drop event="Harvest" name="resourceWood" count="500" tag="oreWoodHarvest"/>
I'm attempting to change the "500" part of the above code. What I attempted was:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/property[@name='drop']@count">600</set>
I know the code is wrong but I can't find any information on how to point to the "count" field inside the (drop event="Harvest") line?

I want to change an existing harvest amount to be different in case the above jumble made no sense. For my future reference I would like to change the (name) field as well? Maybe it is simpler than I think. Any ideas?

 
Last edited by a moderator:
Alright, quick question for you... I'm trying to adjust a particular block in the blocks.xml. The line I have is

Code:
<drop event="Harvest" name="resourceWood" count="500" tag="oreWoodHarvest"/>
I'm attempting to change the "54000" part of the above code. What I attempted was:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/property[@name='drop']@count">600</set>
I know the code is wrong but I can't find any information on how to point to the "count" field inside the (drop event="Harvest") line?

I want to change an existing harvest amount to be different in case the above jumble made no sense. For my future reference I would like to change the (name) field as well? Maybe it is simpler than I think. Any ideas?
Try this:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop[@name='resourceWood']/@count">600</set>
You wouldn't use property here, since <property does not exist on the line.

 
Try this:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop[@name='resourceWood']/@count">600</set>
You wouldn't use property here, since <property does not exist on the line.
Okay after you pointed out my very obvious retardation I tried this:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop_event[@name='Harvest']@count">60000</set>
I also tried

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop[@event='Harvest']@count">60000</set>
Still no dice. I've tried variations of dropEvent, drop, drop_Event, and drop event but it still errors out. I would like to make sure that my change ONLY affects the <drop event="Harvest" name="resourceWood" count="???"> area...

 
Try this:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop[@name='resourceWood']/@count">600</set>
You wouldn't use property here, since <property does not exist on the line.
Okay after you pointed out my very obvious retardation I tried this:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop_event[@name='Harvest']@count">60000</set>
I also tried

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop[@event='Harvest']@count">60000</set>
Still no dice. I've tried variations of dropEvent, drop, drop_Event, and drop event but it still errors out. I would like to make sure that my change ONLY affects the <drop event="Harvest" name="resourceWood" count="???"> area...

The code you provided gives me a syntax error.

 
Okay after you pointed out my very obvious retardation I tried this:

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop_event[@name='Harvest']@count">60000</set>
I also tried

Code:
<set xpath="/blocks/block[@name='woodLogPillar100']/drop[@event='Harvest']@count">60000</set>
Still no dice. I've tried variations of dropEvent, drop, drop_Event, and drop event but it still errors out. I would like to make sure that my change ONLY affects the <drop event="Harvest" name="resourceWood" count="???"> area...

The code you provided gives me a syntax error.
I think my example still works. In both of your other iterations, you forgot to put in a forward slash in front of the @ /@count

 
Back
Top