A quick tutorial of xpathing and patching

Started by minimurgle, May 24, 2017, 08:27:11 PM

Previous topic - Next topic

Antaios

#30
Quote from: AngleWyrm on June 18, 2017, 12:50:23 AM
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?

attatched an example, uses this patch:
<Operation Class="PatchOperationSequence">
   <operations>
      <li Class="PatchOperationTest">
         <xpath>*/ThingDef/changeMyLabel</xpath>
      </li>
      <li Class="PatchOperationReplace">
         <xpath>*/ThingDef/label</xpath>
         <value>
            <label>Label Replaced</label>
         </value>
      </li>
   </operations>
</Operation>


You might assume that this patch would either:
if a ThingDef with a <changeMyLabel> tag exists at all, change all ThingDef/labels to "Label Replaced"
Or
If a ThingDef has a <changeMyLabel> tag, change that thingDef's label to "Label Replaced"

What It'll actually do is change the label of any thingDefs whose file includes a thingDef which has the <changeMyLabel> tag

you can test it by adding:

<ThingDef>
   <defName>thingy-1</defName>
   <changeMyLabel>IrrelevantValue</changeMyLabel>
</ThingDef>


to any core or mod xml file which defines thingDefs, then checking their label ingame.

It will error when loaded by the way, since the xml loader (which happens after patching) doesn't know what to do with <changeMyLabel> tags.
You can add a seperate PatchOperationRemove to get rid of <changeMyLabel> tags after the sequence to get rid of the error if you want.

[attachment deleted by admin due to age]

skullywag

The patcher runs against each individual def, one by one, so no i wouldnt have expected your xpath to do what you state.

however others might, so yeah, patcher runs 1 by 1 through defs, not the whole def db in one go. Its a start stop process.
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

Antaios

Quote from: skullywag on June 19, 2017, 08:17:45 AM
The patcher runs against each individual def, one by one, so no i wouldnt have expected your xpath to do what you state.

however others might, so yeah, patcher runs 1 by 1 through defs, not the whole def db in one go. Its a start stop process.
*did you mean 1 by one through files? tests and looking at the code show it's files not individual defs.

The posts were more specifically with regard to cautioning people when they use PatchOperationTest to avoid duplicating defs, they might not get the response they expect.

Searching/Testing/Replacing based on specific defNames is fine, since they're unique per def. but since the patcher operates per file patching files one by one, broader search/test/replace terms can lead to unexpected results.

faltonico

Can i use a test operation to find a def and then modify a def in another document?

e.g. i want to look for a specific def that would tell me that a particular mod is installed, and then i would modify another def from another mod knowing that the first one is present.

Thanks in advance for the help!

FauxGrim


gipothegip

#35
Curious question on how this thing works; Why do we not have to specify a file path? Why do we just start with ThingDefs (or any other equivalent top level node)?

I know, not the most important information, but it had me confused at the start :P There isn't a file or folder named ThingDefs, after all (and I had thought the file path would be important).
Should I feel bad that nearly half my posts are in the off topic section?

SpaceDorf

Just for clarification :

XPathes are only able to edit existing definitions not adding new ones or replacing funtions ( methods .. whatever the hip name is today )
Maxim 1   : Pillage, then burn
Maxim 37 : There is no overkill. There is only open fire and reload.
Rule 34 of Rimworld :There is a mod for that.
Avatar Made by Chickenplucker

Varisha

#37
Hello,

i am sure this question popped up somewhere already.

What if 2 different mods replace the same "class" with an XML-Patch-Operation.
Example:

<Operation Class="PatchOperationReplace">
  <xpath>//MainButtonDef[defName = "Inspect"]/tabWindowClass</xpath>
  <value>
    <tabWindowClass>ModA.NewClassA</tabWindowClass>
  </value>
</Operation>


<Operation Class="PatchOperationReplace">
  <xpath>//MainButtonDef[defName = "Inspect"]/tabWindowClass</xpath>
  <value>
    <tabWindowClass>ModB.NewClassB</tabWindowClass>
  </value>
</Operation>

Which class will be the winner or are both instantiated and executed according to mod order?

kaptain_kavern

I'm pretty sure the last one in mod order will "win"

LOLKAT_KOMRAD_94

Hi !

I just started modding on RimWorld yesterday and this was exactly one of the things I was wondering - how to modify Core defs without overwritting them completely. So thanks for the post! :D

I do have a question though. The addition I wanted to have new bills on the Body_Humanoid (or something like). From what I'm reading here, it's possible to replace / change an existing value, but is it possible to add to a list?

Cheers!

CannibarRechter

>  From what I'm reading here, it's possible to replace / change an existing value, but is it possible to add to a list?

Yes. PatchOperationAdd is what you are looking for.
CR All Mods and Tools Download Link
CR Total Texture Overhaul : Gives RimWorld a Natural Feel
CR Moddable: make RimWorld more moddable.
CR CompFX: display dynamic effects over RimWorld objects

LOLKAT_KOMRAD_94

Quote from: CannibarRechter on November 13, 2017, 08:32:37 AM
>  From what I'm reading here, it's possible to replace / change an existing value, but is it possible to add to a list?

Yes. PatchOperationAdd is what you are looking for.

Hum, yeah, that makes total sense. I feel stupid now ahah.

Anywhere with documentation on all PatchOperations available?

CannibarRechter

Zhentar's Patch Guide

I'd advise against using the sequence operation until A18. The A17 release of it is missing a critical usability feature (if it fails, it doesn't explain which of your sequences is broken: not worth it). That's fixed for A18.
CR All Mods and Tools Download Link
CR Total Texture Overhaul : Gives RimWorld a Natural Feel
CR Moddable: make RimWorld more moddable.
CR CompFX: display dynamic effects over RimWorld objects

LOLKAT_KOMRAD_94


DarkSnowi

Okay guys, I think I need some advice here.

I published the Vanilla Gun Name mod in A17 a while ago, now with patch A18 hitting today I wanted to update said mod.
Unfortunately simply changing the target version gives me a long list of debug errors saying that he couldn´t complete the xpathing replace action in every line.


Every error looks like this:
RimWorld 0.18.1722 rev1198
Verse.Log:Message(String)
RimWorld.VersionControl:LogVersionNumber()
Verse.Root:CheckGlobalInit()
Verse.Root:Start()
Verse.Root_Entry:Start()

[+DEV+ Real Vanilla Gun Names] Patch operation Verse.PatchOperationReplace(/ThingDefs/ThingDef[defName = "Gun_Pistol"]/label) failed
file: D:\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\DEV Real Vanilla Gun Names\Patches\patchedChanged_Weapons_Guns.xml
Verse.Log:Error(String)
Verse.PatchOperation:Complete(String)
Verse.LoadedModManager:LoadAllActiveMods()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__1()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__1()


Did something change?

(Original file is attached)



[attachment deleted by admin: too old]