Ludeon Forums

Ludeon Forums

  • September 24, 2020, 01:56:09 AM
  • Welcome, Guest
Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 [2] 3 4 ... 6

Author Topic: A quick tutorial of xpathing and patching  (Read 52845 times)

Shinzy

  • Battering ram
  • Global Moderator
  • Transcendent
  • ****
  • Posts: 3071
  • Ramming speeed!
    • View Profile
    • My mods, all of them!
Re: A quick tutorial of xpathing and patching
« Reply #15 on: May 27, 2017, 01:00:23 PM »

Hi,

Is it possible to use the patching-method to change things added from other mods? I did read somewhere that this process is used before adding the mods.

Just for clarification

It is possible yes, all the defs are loaded first (including mods), then the xpath patching happens after all that

so yes you can modify modded defs too. Works really well for things like compatibility patches etc
Logged

benniii

  • Muffalo
  • *
  • Posts: 4
  • Refugee
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #16 on: May 27, 2017, 01:17:31 PM »

Hm, so it is. Is there an example out there? It might be possible that i do something wrong. I tried like several hours yesterday and just came to the conclusion that this might not work, lol.

If i change the defName here to "HorseshoesPin" the description would change, but with added items from mods it does not. And i'm loading my mod at the very end after them. So where would be the secret behind that? Thanks for answering and sorry if it doesn't fit in this topic.

Code: [Select]
<Patch>
  <Operation Class="PatchOperationReplace">
    <xpath>*/ThingDef[defName = "PowerConduitInvisible"]/description</xpath>
    <value>
      <description>This is just a test.</description>
    </value>
  </Operation>
</Patch>
Logged

minimurgle

  • Colonist
  • ***
  • Posts: 124
  • Horribly confused
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #17 on: May 27, 2017, 01:59:02 PM »

Hi Benni. While it is possible to use this process to change other mods you should have permission from the mod author first unless it's for your own personal use. If it is uploaded and you got permission from the author of the mod that your changing you should make it very clear that you've changed stuff from the other mod.

The only other things I can tell you from my experience is that your mod needs to be loaded after the other mod. You can also put <success>Always</success> to suppress errors if the other mod isn't present. (that could be wrong but it's something like that)

Just a warning it would appear that people are having trouble getting this to work all the time.
Logged
Don't mind the questions. I'm probably just confused.

benniii

  • Muffalo
  • *
  • Posts: 4
  • Refugee
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #18 on: May 27, 2017, 04:05:23 PM »

Hey.

Thanks for your concern but don't worry that's for personal use only. I'm more the introvert lurking guy here, i don't plan to publish anything. ^^

I just did some other testings and it does indeed work with other values. Replacing description or label doesn't work so far. I did start testing with these thats why i was questioning it. Kinda wondering why though. But im set now, so thanks for the tip and answering. :)

Edit: I figured out why i couldn't replace description or label. It is because of the provided languages files.
« Last Edit: May 28, 2017, 05:01:14 PM by benniii »
Logged

Vindar

  • Colonist
  • ***
  • Posts: 102
  • Happy Days!~
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #19 on: May 27, 2017, 06:31:19 PM »

Lmao, I gotta be honest, I started learning it yesterday and I'm already falling in love w/ xpathing.

some of the things ive learned that might be helpful for people just starting it here w/ the intent to use in rimworld.

1) not all things start w/ ThingDefs, some items start w/ Buildings, ect

2) be very specific and check both the spelling and the capitalization, if its capitalized differently in the core xml, xpath wont read it and will spit out a fail.

3) start the document with the XML header:

<?xml version="1.0" encoding="utf-8" ?>

Save as an XML

Use:

<Patch>   and </Patch> to open and close the document (placed after the header)

3 might seem simple but it was the first question i asked myself anyways

====================================================
 
to help people along ill post some examples of operations that i have working in my mod(still being worked on):

================Simple replace operation=============================

<!-- Change Basic Shirt Worn Graphic -->
   <Operation Class="PatchOperationReplace">
      <xpath>/ThingDefs/ThingDef[defName = "Apparel_BasicShirt"]/apparel/worngraphicPath</xpath>
      <value>
         <worngraphicPath>Things/Pawn/Humanlike/Apparel/Bodywear_Clothing/TeeShirt/TeeShirt</worngraphicPath>
      </value>
   </Operation>

=======================Simple Add Operation====================================

<!-- Change Basic Pants Worn Graphic -->
   <Operation Class="PatchOperationAdd">
      <xpath>/ThingDefs/ThingDef[defName = "Apparel_Pants"]/apparel</xpath>
      <value>
         <worngraphicPath>Things/Pawn/Humanlike/Apparel/Bodywear_Clothing/Pants/Pants</worngraphicPath>   
      </value>
   </Operation>

==================A replace Operation which starts at Buildings as opposed to ThingDefs=========

<!-- Coal to Fueled Generator -->
   <Operation Class="PatchOperationReplace">
      <xpath>/Buildings/ThingDef[defName = "FueledGenerator"]/description</xpath>
      <value>
         <description>Produces power by consuming wood fuel or coal. Must be fueled by hand.</description>   
      </value>
   </Operation>

==========An operation that had me confused for a while. (needs DefName as oppsed to defName)======
==============Note i also used: li[@Class = "CompProperties_Refuelable"] =========

<!-- Coal to Fueled Smithy -->   
   <Operation Class="PatchOperationAdd">
       <xpath>/ThingDefs/ThingDef[DefName = "FueledSmithy"]/comps/li[@Class = "CompProperties_Refuelable"]/fuelFilter/thingDefs</xpath>
       <value>
             <li>MedTimes_Resource_Coal</li>
       </value>
   </Operation>   

=================and finally one that adds alot of values to a trader:======================

<!-- Adding Goods to Neolithic Base -->
   <Operation Class="PatchOperationAdd">
       <xpath>/DefPackage-TraderKindDef/TraderKindDef[defName = "Base_Neolithic_Standard"]/stockGenerators</xpath>
       <value>
         <li Class="StockGenerator_SingleDef">
            <thingDef>MedTimes_Resource_IceBlocks</thingDef>
            <price>Expensive</price>
         </li>      
         <li Class="StockGenerator_Category">
            <categoryDef>TradeGoods</categoryDef>
            <price>Expensive</price>            
            <thingDefCountRange>
               <min>2</min>
               <max>5</max>
            </thingDefCountRange>
         </li>
         <li Class="StockGenerator_Tag">
            <tradeTag>MedTimes_Weapons</tradeTag>
            <price>Expensive</price>
            <thingDefCountRange>
               <min>2</min>
               <max>5</max>
            </thingDefCountRange>         
         </li>            
         <li Class="StockGenerator_Tag">
            <tradeTag>MedTimes_Armour</tradeTag>
            <price>Expensive</price>
            <thingDefCountRange>
               <min>2</min>
               <max>5</max>
            </thingDefCountRange>            
         </li>            
         <li Class="StockGenerator_Tag">
            <tradeTag>MedTimes_Artifact</tradeTag>
               <thingDefCountRange>
                  <min>1</min>
                  <max>3</max>
               </thingDefCountRange>               
         </li>   
         <li Class="StockGenerator_Tag">
            <tradeTag>MedTimes_Legendary</tradeTag>
         </li>         
       </value>
   </Operation>



 
« Last Edit: May 27, 2017, 06:33:06 PM by Vindar »
Logged

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #20 on: June 01, 2017, 08:58:50 AM »

Ive just seen someone (i think) telling people that patching things like the min/max valules in the biomedefs for soil types isnt possible without patching the whole set, just wanted to state that sibling values are xpathable very simply using something like:

/thingdef/whatever[text()="thename"]/following-sibling::value[1]/text()

Hope that makes sense, the examples bad but it should give you the bits you need.
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #21 on: June 02, 2017, 04:11:09 AM »

Also heres a good list of the functions available to us in xpath 1.0 (we arent using 2.0 in .net 3.5)

http://www.edankert.com/xpathfunctions.html


Shinzyedit:
And if all else fails here's Skully's Xpath hotline for help

Skullyedit:
Did you just.....well....thats just rude....but thanks. :)

Shinzyedit:
Oh don't mention it, My pleasure!
« Last Edit: June 02, 2017, 03:04:20 PM by Shinzy »
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

kaptain_kavern

  • Planetologist
  • ****
  • Posts: 2074
  • started 10 mods in one tick.
    • View Profile
    • RimWorldMod Slack - A place for live chatting about RimWorld modding
Re: A quick tutorial of xpathing and patching
« Reply #22 on: June 02, 2017, 09:21:13 AM »

If it can help, here my biggest patches files. It works and maybe can be used as helping material.

I use all basic syntax in it

https://github.com/kaptain-kavern/CK_AnimalPlant_Pack/blob/master/Patches/patches.xml

minimurgle

  • Colonist
  • ***
  • Posts: 124
  • Horribly confused
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #23 on: June 02, 2017, 01:00:06 PM »

Thank you so much for adding in some examples Skully and Kaptain. Thanks for the hotline Shinzy?
Logged
Don't mind the questions. I'm probably just confused.

sulusdacor

  • Colonist
  • ***
  • Posts: 242
  • Refugee
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #24 on: June 11, 2017, 03:05:15 AM »

you should mention you can patch abstracts ;)
with
Code: [Select]
[@Name = "AbstractName"]

kaptain_kavern

  • Planetologist
  • ****
  • Posts: 2074
  • started 10 mods in one tick.
    • View Profile
    • RimWorldMod Slack - A place for live chatting about RimWorld modding
Re: A quick tutorial of xpathing and patching
« Reply #25 on: June 12, 2017, 06:00:17 PM »

Hey it's me again with a little more info I found while playing with the new method.

Believe it or not, but most of the time when patch aren't working it's because of a wrong xpath of course. Asking for a fresh pair of eyes can help. But here is a bit more help ...
Following are 2 things that made me lost some hours, so if it can help anyone ... ;)

- Pay attention to Parent nodes! There is no full consistency in uses. Sometimes you'll find Defs, sometimes ThingDefs for instance  8)  - Funpost with actual reply by Tynan


- Another one for the fun : I spotted that in 5 xml files <Defname> is used instead of <defname> (upcase D)

Concerned files :
  • \Core\Defs\Misc\Designations\DesignationCategories.xml
  • \Core\Defs\NeedDefs\Needs.xml
  • \Core\Defs\TerrainDefs\Terrain_Floors.xml
  • \Core\Defs\TerrainDefs\Terrain_Floors_StoneTile.xml
  • \Core\Defs\ThingDefs_Buildings\Buildings_Production.xml

EDIT
Bonus gift : if you are using SublimeText as a text editor, here's a link to a very useful plugin regarding xpath : https://github.com/rosshadden/sublime-xpath


copy xpath of selected node to clipboard
« Last Edit: June 14, 2017, 09:25:11 AM by kaptain_kavern »
Logged

minimurgle

  • Colonist
  • ***
  • Posts: 124
  • Horribly confused
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #26 on: June 16, 2017, 09:21:56 AM »

Thanks for pointing those things out Kaptain! I may be taking a looksy at that plugin too.
Logged
Don't mind the questions. I'm probably just confused.

Kilroy232

  • Colonist
  • ***
  • Posts: 230
  • Process Automation Engineering Student
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #27 on: June 17, 2017, 01:38:18 PM »

I have a question now that I have read through the original post and some of the comments. In my turrets mod I used this method to change specific values:
Code: [Select]
<researchMods>
      <li>
        <specialAction>TP.TPResearchMods.EnergyTurretOvercharge</specialAction>
      </li>
    </researchMods>

They have now removed the <researchMods> function but I would like to know if I can use patching in its place. I want to be able to have a research that will say increase a weapons range or damage. If anyone can help me out with that I would greatly appreciate it

Antaios

  • Drifter
  • **
  • Posts: 79
  • Refugee
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #28 on: June 17, 2017, 11:14:15 PM »

Reposting a discussion me and AngelWyrm are having over in mods, should be useful here.
This post explains how to make an xpath statement that isn't going to generate duplicate field errors. Quick recap:

<Operation Class="PatchOperationSequence">
  <success>Always</success>
  <operations>
    <li Class="PatchOperationTest">
      <xpath>*/ThingDef[defName = "ChosenThingy"]/elementThatIWannaAdd</xpath>
      <success>Invert</success>
    </li>
    <li Class="PatchOperationAdd">
      <xpath>*/ThingDef[defName = "ChosenThingy"]</xpath>
      <value>
        <elementThatIWannaAdd> someValue </elementThatIWannaAdd>
      </value>
    </li>
  </operations>
</Operation>

I've used this test to do the same thing: Add a sub-element if it doesn't exist.

The error messages are saying that two separate attempts (by two different mods) were made to add a specific element, and so it failed the second time because that element already exists.

This test checks to see if the element already exists (maybe because some other mod created it), and if it doesn't then there's a spot in there to add the element. And if it does already exist, then the check quietly bails out of it's sequence without spilling big red oops onto the user's screen.
Do take note that PatchSequenceTest operates per file, not global and not per def.

So if for example you're editing ThingDefs and looking to add RandomProperty1 if it doesn't exist in any of them, you need to be sure that no single file contains both ThingDefs which are missing RandomProperty1 and ThingDefs which include RandomProperty1 already.

It's why when I did that, I use a placeholder tag and some gymnastics with '../' in xpath, rather than PatchOperationTest.
There should be no connection between xpath data searches and the underlying physical storage of that data.

The assertion that there is implies a defect in the implementation of the PatchSequenceTest function. Can you construct a test case that fails if the test draws values from different files, but succeeds if those values are drawn from the same file?
It is evident in the code, if you take a look at ModContentPack.LoadDefs(IEnumerable<PatchOperation> patches), PatchOperation, PatchOperationSequence and PatchOperationTest.
But a simple test is to take tuning fork, and in the core defs of Rimworld, add a blank abstract in Core\Defs\ThingDefs_Items.xml which has an ingestible/chairSearchRadius. You'll notice the patch no longer works on core meals.
Logged

AngleWyrm

  • Planetologist
  • ****
  • Posts: 1154
  • Refugee
    • View Profile
Re: A quick tutorial of xpathing and patching
« Reply #29 on: June 18, 2017, 12:50:23 AM »

Quote
So if for example you're editing ThingDefs and looking to add RandomProperty1 if it doesn't exist in any of them, you need to be sure that no single file contains both ThingDefs which are missing RandomProperty1 and ThingDefs which include RandomProperty1 already.

I've attached a testing scaffold mod that contains three files: A patch file, and two defs files.

The first defs file contains two entries with <label> tags, and the second defs xml contains three entries, with one of them that does not contain a <label> tag. The two defs files look about like so:

<Defs>
    <ThingDef>
        <defName>thingy-1</defName>
        <label>one</label>
   </ThingDef>
    <ThingDef>
        <defName>thingy-2</defName>
        <lable>two</lable>
   </ThingDef>
</Defs>


For feedback on a success/failure test, I suggest changing some visible GUI text within the game if the test succeeds.
So: What patch test operation will best demonstrate a reliance on file structure?

[attachment deleted by admin due to age]
« Last Edit: June 18, 2017, 12:54:43 AM by AngleWyrm »
Logged
My 5-point rating system: Yay, Kay, Meh, Erm, Bleh
Pages: 1 [2] 3 4 ... 6