• 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:
for a shareable modlet, yes. You won't know what changes were done previously.
If you were just doing an Overhaul, it'd be fine.
Just to be clear, when I said overwrite the XML, I meant using <remove> and then <append>

 
Just to be clear, when I said overwrite the XML, I meant using <remove> and then <append>
That's different, and totally fine :)

I thought you were asking if you could remove and replace the entire file.

 
I just tried using the method with spawning.XML and I got the notification that it failed parsing the XML because "multiple document element was detected". I could successfully start a world, but zombies wouldn't spawn. I used Guppy's technique of exporting the resultant XML, and that looked okay. I presume I have some syntax error or my filenames aren't correct. Can you give advice on what's wrong with this this modlet?View attachment 27012

DimpySpawn.zip

 

Attachments

You are missing your top level node. It can be anything

Code:
<configs>
<remove xpath="/spawning"/>
<append xpath="/">
	<spawning>
                     <!-- blah blah -->
               </spawning>
        </append>
</configs>
 
<append xpath=""> - it also may allow us to append a value to an existing value. ( this needs testing )

example:

This line could potentially add noammo to the existing value of 9mmbullet.

Code:
<append xpath="/items/item/property[@class='action0']/property[@name='magazine_items' and @value='9mmbullet']/@value">,noammo</append>
Forgive me for not reading the whole thread, but I just tested this and I can report it does appear to work. My mod added this code...

Code:
	<append xpath="/items/item[starts-with(@name,'hazmat')]/effect_group[@tiered='false']/passive_effect[@name='ElementalDamageResist']/@tags">,heat</append>
...and, using exportcurrentconfigs, I got this result...

Code:
<item name="hazmatBoots">
<property name="Extends" value="hazmatClothingMaster" param1="CustomIcon" />
<property name="Tags" value="lowerbody,feet,clothing" />
<property name="EquipSlot" value="Feet" />
<property class="UMA">
	<property name="Mesh" value="armor_hazmat_feet" />
	<property name="Overlay0" value="armor_hazmat_boots" />
	<property name="Layer" value="0" />
	<property name="UISlot" value="Footwear" />
</property>
<effect_group tiered="false">
	<passive_effect name="ModSlots" operation="base_set" value="1" />
	<passive_effect name="HypothermalResist" operation="base_add" value="6"><!--Attribute "value" replaced by: "ComSenMod"--></passive_effect>
	<passive_effect name="HyperthermalResist" operation="base_add" value="1" />
[color="#FF8C00"]		<passive_effect name="ElementalDamageResist" operation="base_add" value="5" tags="lowerbody,feet,radiation,toxic,[b]heat[/b]" match_all_tags="true"><!--Attribute "tags" appended by: "ComSenMod"--></passive_effect>
[/color]	</effect_group>
</item>
Now it doesn't have the desired effect, mind you - I'm still figuring that out. But at least I can confirm that append can modify the script in this way. :)

 
Tried to add a new Item to GameStart. can anyone explain my mistake ?

Code:
<set xpath="/entity_classes/entity_class[@name='playerMale']/proberty[@name='ItemsOnEnterGame.GameModeSurvival']/@value">keystoneBlock,qc_welcomeMod</set>
 
Tried to add a new Item to GameStart. can anyone explain my mistake ?
Code:
<set xpath="/entity_classes/entity_class[@name='playerMale']/proberty[@name='ItemsOnEnterGame.GameModeSurvival']/@value">keystoneBlock,qc_welcomeMod</set>
It's /property, not /proberty :)

 
so simple xD

but it dosen't fix the problem :D

Code:
<set xpath="/entity_classes/entity_class[@name='playerMale']/property[@name='ItemsOnEnterGame.GameModeSurvival']/@value">keystoneBlock,qc_welcomeMod</set>
 
Last edited by a moderator:
That didn't work. The error message did change though. Now it says "object reference not set to an instance of object"
I'm not familiar with the syntax required to remove all of a file. You could try something like

Code:
<remove xpath="/spawning/*" />
...
 
Code:
	<remove xpath="/spawning"/>
does not delete the whole file (fine by me); Just the part that is contained in

Code:
<spawning></spawning>
I looked at the resultant XML from exportcurrentconfigs and on one iteration of the Append syntax, everything except the header comment was gone, so I think the issue is with the append syntax. I changed the append syntax and the code reappeared, but it wasn't the code I told it to put back in; it was the original. I presume the game will reset the XML if it finds errors.

Code:
<append xpath="/spawning"/>
resets it and

Code:
<append xpath=""/>
has everything deleted.

Here is the file.

View attachment 27029

Who should I ask for help on this?

DimpySpawn.zip

 

Attachments

The following does not appear to work, can you not remove passive_effect?

<remove xpath="items/item[@name=gunPistolAdmin]/passive_effect[@name=EntityDamage]"/>

 
The following does not appear to work, can you not remove passive_effect?
<remove xpath="items/item[@name=gunPistolAdmin]/passive_effect[@name=EntityDamage]"/>
missing your leading / on xpath="/items/item ?

 
Thank you for the reply, but it seems the leading '/' is not mandatory, although I've now added it for completeness, it's made no difference.

Just had a deeper look and it seems to be fixed, I had to reference the Effect Group also...

<remove xpath="/items/item[@name=gunPistolAdmin]/effect_group[@name=Base Effects]/passive_effect[@name=EntityDamage]"/>

 
Last edited by a moderator:
Thank you for the reply, but it seems the leading '/' is not mandatory, although I've now added it for completeness, it's made no difference.
Just had a deeper look and it seems to be fixed, I had to reference the Effect Group also...

<remove xpath="/items/item[@name=gunPistolAdmin]/effect_group[@name=Base Effects]/passive_effect[@name=EntityDamage]"/>
I am glad you got it working.

XPath can be tricky with its syntax. I'll always recommend fixing the inconsistencies I find first, as it may make some corner cases start working.

 
I am glad you got it working.
XPath can be tricky with its syntax. I'll always recommend fixing the inconsistencies I find first, as it may make some corner cases start working.
Hey Sphereii, thanks for adding in detail to the xpath modding, this is really helpful work, thank you

 
Back
Top