• 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:
i wish i was right. I reviewed the fl and all are saved as .xml. and still not working. I can see where boot says it is reading them. but when you log into the game it still gives the vanilla starting loot. I have even tried deleting the blocks and loot files and replacing the item with a vanilla one, and it still ignores the swapped loot.

I am having the same problem with several other peoples mods, where the vanilla files are simply not being overwritten at bootup, even though the boot files says that it read the modlet.
Do you have a zip file of one of these mods along with a log file?

 
Do you have a zip file of one of these mods along with a log file?
no, because i wiped my 7d2d files in hopes it was a caching error. But I am going to try it again today and can try to zip you one.

 
so i figured out the real issue. even if i open up a .xml file. whenever i hit save, notepadd++ converts it to a .txt

if i try to resave as extensivemarkup (.xml, etc) it ells me it cant as the file is already open. If create new file and try to save it, same issue.if i delete the hardcopy and try to save either of the two previous ways, it ways it is still open. ifi create brand new file and select save as extensive markup (as pure .xml is nto available) it still sets it as .txt.

I have tried to update notepadd++, wipe cookies and cache, reboot my computer, start with bran new files, and still have it only saving everything as .txt.

I thank you for your help. I must find anotherfree program for writing code as clearly my version of notepad++ is broken.

 
I had bookmarked this forum post. I use it all the time.

However, right now, it seems the CODE blocks are broken, so I can't really read the original posts.

 
Hello...returning player here (so please excuse the ignorance :) )

I'm trying to add some more functions to "Action1" for the drinkJarEmpty using <append> (eg. drawing water from showerheads.)

i've read all of the examples on page 1 and had a couple of tries but i haven't had any luck yet...is it something straightforward or am i asking too much at the current point in time?

Thanks in advance :)

 

 
Last edited by a moderator:
Hello...returning player here (so please excuse the ignorance :) )

I'm trying to add some more functions to "Action1" for the drinkJarEmpty using <append> (eg. drawing water from showerheads.)

i've read all of the examples on page 1 and had a couple of tries but i haven't had any luck yet...is it something straightforward or am i asking too much at the current point in time?

Thanks in advance :)

 
Say you wanted to add something inside the Action1 of an item called ThisItem, you would do it like this:

In items.xml of your mod:

Code:
<configs>
  <append xpath="/items/item[@name='ThisItem']/property[@class='Action1']">
  	<!-- Your additional code goes here -->
  </append>
</configs>
 
Last edited by a moderator:
Say you wanted to add something inside the Action1 of an item called ThisItem, you would do it like this:

In items.xml of your mod:

<configs>
<append xpath="/items/item[@name='ThisItem']/property[@class='Action1']">
<!-- Your additional code goes here -->
</append>
</configs>

Thnx for the reply.

i was trying syntax similar to:

Code:
<append xpath="/items/item/property[@class='Action1']/property[@name='drinkJarEmpty' or @name='bucketEmpty']/@name='Focused_blockname_6' value="faucet02"></append>
with no success....guess I'm going to simplify how i try to express what i want done...

PS. Would i be right to assume that if i wanted to add an alternative action 1 i would have to write it down as

Code:
<configs>
  <append xpath="/items/item[@name='ThisItem']">
      <!-- Code similar to this goes here -->
      <property class="Action1"> <!-- UseAction -->
        <property name="Class" value="ExchangeItem"/>
        <property name="Delay" value="1.0"/>
        <property name="Change_item_to" value="NAME-ResultingItem"/>
        <property name="Do_block_action" value="deplete1"/>     <---------------------------this line is for natural water blocks only ?
        <property name="Focused_blockname_1" value="NAME-TargetBlock"/>
        <property name="Sound_start" value="bucketfill_water"/>
    </property>    
  </append>
</configs>
 
--The optimal result for what i'm looking to achieve (atm) is having the ability to scavenge different items from different sources whilst introducing as few custom items as possible...eg being able to collect with EmptyJar dirty water from shower heads, petrol from cars/gas pumps, wine from wine barrels..

I figured that attempting a forge-like bottling plant...would be good practice and (perhaps ?) the end product can fill a gap in terms of user modded content for 18.4
 
Your code for adding Action1 on item with name ThisItem is correct, but please note that doing it exactly as you wrote it really assumes that the item called ThisItem does not have Action1 in its code yet.

If it already has Action1 in its code and you want to modify it somehow, you have the following options:

1) change individual parts of the existing code

2) remove the whole Action1 property and then write a new one that would take place of the original

3) add to the existing code

Code for all of these options would be different and generally the less amount of changes means better compatibility with other mods that may depend on the vanilla code.

Action0 and Action1 actually represent left and right mouse button actions, so the game would most likely throw you an error if you tried to add a "an alternative action 1" leaving the code with two Action1 properties.

Assuming that all you really want is just to add some new code inside an existing Action1 property of drinkJarEmpty item, your code in items.xml of your mod would look like this:

<append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
<!-- Any code written here will go inside Action1 property of drinkJarEmpty item -->
</append>


Again, this is for injecting a new code inside the existing Action1 property of drinkJarEmpty. If you wanted to edit the existing code there, not to add new one, you would have to do it differently. What would the code look like in that case highly depends on what exactly you would want to change there.

 
Last edited by a moderator:
Say you wanted to add something inside the Action1 of an item called ThisItem, you would do it like this:

In items.xml of your mod:

<configs>
<append xpath="/items/item[@name='ThisItem']/property[@class='Action1']">
<!-- Your additional code goes here -->
</append>
</configs>

Thanks for the reply :)  Please allow me to be a bit more specific  in order to (hopefully) assist you in helping me.

I would like to add different results depending on the source where the liquid was sourced from...but i cant find any vanilla item that actually does something similar...so i'm throwing rocks in the dark, hoping to hear the right kind of thunk sort of speak...

So far...The following code adds dirty water collection from sinks etc..i'll call it codeA from now on for short.

Code:
    <append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
        <property name="Focused_blockname_6" value="faucet02"/>
        <property name="Focused_blockname_7" value="faucet04"/>
        <property name="Focused_blockname_8" value="faucetBrass02"/>
        <property name="Focused_blockname_9" value="faucetBrass04"/>
        <property name="Focused_blockname_10" value="cntToilet01"/>
        <property name="Focused_blockname_11" value="cntToilet02"/>
        <property name="Focused_blockname_12" value="cntToilet03"/>
        <property name="Focused_blockname_13" value="cntCabinetOldSink"/> 
        <property name="Focused_blockname_14" value="cntGraniteSink"/>
        <property name="Focused_blockname_15" value="utilitySink"/>
        <property name="Focused_blockname_16" value="wallHungSink"/>
        <property name="Focused_blockname_17" value="showerHead"/>
        <property name="Focused_blockname_18" value="fountain"/>
    </append>
The issues arise once i try to add another result/source:

- Appending an extra 'Action1' block of code as a new entry further down the config throws an error. (just like you said) 

- Appending the following block of code (codeB) as a new entry further down the config forces all sources appended from codeA to now provide clean water.

Code:
    <append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
        <property name="Class" value="ExchangeItem"/>
        <property name="Delay" value="1.0"/>
        <property name="Change_item_to" value="drinkJarBoiledWater"/>
<---blockname_1 or blockname_19 makes no difference to the result-->
        <property name="Focused_blockname_1" value="cntWaterCoolerFull"/>
        <property name="Sound_start" value="bucketfill_water"/>
    </append>


- Appending both CodeA and Codeb as a single entry also forces all sources appended to provide clean water.

Code:
    <append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
        codeA
        codeB
    </append>
This was also the case 4 years ago...you couldn't have more than 1 type of liquid collected via glass jar.

Is that possible atm?
If not , would a tool that uses glass jars as fuel/ammo be (theoretically) able to do this...given what one can or can't do at this point of time?
Thanks in advance :)
 

 
Last edited by a moderator:
Thanks for the reply :)  Please allow me to be a bit more specific  in order to (hopefully) assist you in helping me.

I would like to add different results depending on the source where the liquid was sourced from...but i cant find any vanilla item that actually does something similar...so i'm throwing rocks in the dark, hoping to hear the right kind of thunk sort of speak...

So far...The following code adds dirty water collection from sinks etc..i'll call it codeA from now on for short.

Code:
    <append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
        <property name="Focused_blockname_6" value="faucet02"/>
        <property name="Focused_blockname_7" value="faucet04"/>
        <property name="Focused_blockname_8" value="faucetBrass02"/>
        <property name="Focused_blockname_9" value="faucetBrass04"/>
        <property name="Focused_blockname_10" value="cntToilet01"/>
        <property name="Focused_blockname_11" value="cntToilet02"/>
        <property name="Focused_blockname_12" value="cntToilet03"/>
        <property name="Focused_blockname_13" value="cntCabinetOldSink"/> 
        <property name="Focused_blockname_14" value="cntGraniteSink"/>
        <property name="Focused_blockname_15" value="utilitySink"/>
        <property name="Focused_blockname_16" value="wallHungSink"/>
        <property name="Focused_blockname_17" value="showerHead"/>
        <property name="Focused_blockname_18" value="fountain"/>
    </append>
The issues arise once i try to add another result/source:

- Appending an extra 'Action1' block of code as a new entry further down the config throws an error. (just like you said) 

- Appending the following block of code (codeB) as a new entry further down the config forces all sources appended from codeA to now provide clean water.

Code:
    <append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
        <property name="Class" value="ExchangeItem"/>
        <property name="Delay" value="1.0"/>
        <property name="Change_item_to" value="drinkJarBoiledWater"/>
<---blockname_1 or blockname_19 makes no difference to the result-->
        <property name="Focused_blockname_1" value="cntWaterCoolerFull"/>
        <property name="Sound_start" value="bucketfill_water"/>
    </append>


- Appending both CodeA and Codeb as a single entry also forces all sources appended to provide clean water.

Code:
    <append xpath="/items/item[@name='drinkJarEmpty']/property[@class='Action1']">
        codeA
        codeB
    </append>
This was also the case 4 years ago...you couldn't have more than 1 type of liquid collected via glass jar.

Is that possible atm?
If not , would a tool that uses glass jars as fuel/ammo be (theoretically) able to do this...given what one can or can't do at this point of time?
Thanks in advance :)
 
Please note that <append> command is really for adding new things within the scope of the last node inside the xpath. If you would rather want to change the existing parts of the code inside that node, you could construct a <set> command to target specific lines of code to change their values, or <insertAfter> / <insertBefore> to add lines after or before the specified xpath. I believe your codeB is a good example where you should be using something different than append as drinkJarEmpty already contains some of those lines you're adding and just like in case of Action1 duplicate, duplication of other lines of code may be undesirable as well.

As for the solution for your actual problem, right now I can't think of anything that I know would surely work, but that doesn't mean there's no solution for it. Some modders are quite resourceful and could probably give you a solution for this with no problem. You could try cvars, buffs, custom effect groups with predefined requirements or combinations of them. I may be wrong, but perhaps it could be done by setting up custom effect group that would give different results based on various different requirements. If everything else fails, you could get this done through DMT (Successor of SDX), but of course that's a whole new level of modding.

 
Hmm....perhaps i should go the roundabout way for now...and look to create forge-like versions of the blocks i want to use as sources then use jars as the ingredient and polymer as the fuel (think of it as the cost for making sealed bottle caps)...then get them in the game as "extra options" so that they spawn alongside the vanilla blocks for POIs.

(that has its issues/limitations as well, as you wont be able to loot them...but the player's inventory wont be cluttered with so many different jars .)

I wouldn't know where to start with DMT etc   :)  hopefully someone who knows what they are doing will sort it out eventually :)  

 
I don’t know if anyone will see this but I’ve been trying so so hard to write up a modlet that will make it so hostile animals will still spawn with enemy spawning turned off, I know I’m looking at entity classes and the hostileanimalstemplate but when I load in to game I get the error ‘element does not contain attribute’ 

 
I don’t know if anyone will see this but I’ve been trying so so hard to write up a modlet that will make it so hostile animals will still spawn with enemy spawning turned off, I know I’m looking at entity classes and the hostileanimalstemplate but when I load in to game I get the error ‘element does not contain attribute’ 
Instead of turning enemy spawning off completely, make a mod that will remove zombie groups from spawning and only leave animals, assuming that is what you're after.

 
Guys, I need help! Why do I get an error (screenshot under the spoiler) when connecting friends to me without the modlet installed (and with it, too), which is why they can't connect, freezing on getting server configurations? Although I can easily connect to them with the modlet installed.

100164930.83500001_image.png

View attachment output_log__2020-07-05__02-35-06.txt

 
Last edited by a moderator:
Guys, I need help! Why do I get an error (screenshot under the spoiler) when connecting friends to me without the modlet installed (and with it, too), which is why they can't connect, freezing on getting server configurations? Although I can easily connect to them with the modlet installed.



View attachment 11438
What does your localization file look like on the server? The server log might give a hint on which localization is causing the issue.

 
What does your localization file look like on the server? The server log might give a hint on which localization is causing the issue.
This topic contains a modlet with my alternative localization. The server is local - I create a game, and my friends just join me. I attached the log. Or do you need another one? If so where can I get it?

 
Hi to all!

Help me please, if your can.
Tell me how can I add a new custom icon for the new buff in my modlet.
What type of image needed, where it place and how to specify the path to it in modlet "buffs. xml"
Thank.

More info: 






 
Last edited by a moderator:
Back
Top