A quick tutorial of xpathing and patching

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

Previous topic - Next topic

DarkSnowi

Hey its me again.

It seems like I figured out what has changed.
Weapons are no longer in ThingDefs , the Tag is now called simply Defs . (Also there is a new Gun and naturally they renamed the Pistol in the tag logic)

So,
<xpath>/ThingDefs/ThingDef[defName = "Gun_PumpShotgun"]/label</xpath>

is now

<xpath>/Defs/ThingDef[defName = "Gun_PumpShotgun"]/label</xpath>

CannibarRechter

> Weapons are no longer in ThingDefs , the Tag is now called simply Defs

I see why I didn't notice. I use xpath notations that look like this:

<xpath>*/ThingDef[defName = "Beer"]/graphicData/texPath</xpath>


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

Manhunting Muffalo

#47
So something has changed in 0.18 that I can't suss out, and the error I'm getting is unhelpful ("patching operation failed"). My code is very simple, just trying (for the sake of practice) to change the power consumption for a standing lamp to 15. This is what I have:


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

<Patch>
<Operation Class="PatchOperationReplace">
<xpath>/Defs/ThingDef[defName="StandingLampBase"]/comps/li[@Class="CompProperties_Power"]/basePowerConsumption</xpath>
<value>
<basePowerConsumption>15</basePowerConsumption>
</value>
</Operation>

</Patch>


I can't seem to figure out what it can't find. Could someone point it out since I seem to be extra dumb today?

kaptain_kavern

I too notice something like this lately as well.

Can't seems to be able to target an Abstract with the use of "@". I worked around this by targeting each child ThingDef by defName each time. In your case all the standing lamps: normal and each color version. But it's far than optimum IMHO.

By then I was just thinking I derped and moved on something else, but it was this exact same case as you described.

Manhunting Muffalo

But standing lamp sub-versions don't have a basePowerConsumption entry..?

kaptain_kavern

#50
When the game uses abstract it "constructs" "normal" thingDef from the abstracted ones and then "discards" the abstract defs. That's what I've been told I really don't know how it works precisely but it works if you use PatchOperationAdd on a Def without it originally, because you then "just" overwrites tags in the "recreated" def, which were inherited from the Abstract

In this patch, I added tags to Spacer faction def (4th patch operation), for instance.
https://github.com/kaptain-kavern/Gun-Tech-Removal/blob/master/Patches/patches.xml


I'm lacking precise words (I'm not a native English speaker) and knowledge to explain better. Hope someone else will do ;-)

Manhunting Muffalo

Nope, still missing something, I guess I'm not smart enough to suss out what you're saying. God damnit, I wish the error message was a bit more informative. Very frustrating that I can't even do something this simple.

frenchiveruti

Oh my... Well this really needs to be updated because I kept patching ThingDefs and not Defs and that kept breaking my game.
I almost gave up on modding but decided to check out this page and found that it changed the name.
I have a new question, how do I check out if a patch operation went right?
I have HugsLibs in my modlist, is there a way to tell?

Nightinggale

Quote from: frenchiveruti on December 17, 2017, 08:32:25 PM
I have a new question, how do I check out if a patch operation went right?
Make a sequence like in this guide. As the last item, put something in the list like isModLoaded and add both customMessageSuccess and customMessageFail. One of them will trigger and write the contents of the tag to the log.

I'm not done writing the guide, but it should be of interest to everybody writing patches.

Quote from: frenchiveruti on December 17, 2017, 08:32:25 PMI have HugsLibs in my modlist, is there a way to tell?
ModCheck.isModLoaded
ModCheck - boost your patch loading times and include patchmods in your main mod.

frenchiveruti

Quote from: Nightinggale on December 17, 2017, 09:07:16 PM
Quote from: frenchiveruti on December 17, 2017, 08:32:25 PM
I have a new question, how do I check out if a patch operation went right?
Make a sequence like in this guide. As the last item, put something in the list like isModLoaded and add both customMessageSuccess and customMessageFail. One of them will trigger and write the contents of the tag to the log.

I'm not done writing the guide, but it should be of interest to everybody writing patches.

Quote from: frenchiveruti on December 17, 2017, 08:32:25 PMI have HugsLibs in my modlist, is there a way to tell?
ModCheck.isModLoaded

Ok, so that involves adding something extra. Cool.
I think, for the scope of my mod, that's really not necessary, right?

Jaxxa

Is it possible to write logic in C# to decide if an XML patch will be applied or not?
I want to conditionally execute an XML patch based on a value in mod settings.

Nightinggale

Quote from: Jaxxa on December 17, 2017, 10:10:14 PM
Is it possible to write logic in C# to decide if an XML patch will be applied or not?
That's what ModCheck is all about. Adding C# code to add features to handle conditional xml patching. Well that, performance boosting and allowing patches to write to the log.

If you have more questions on how ModCheck works and if you want some specific feature, I would recommend using the ModCheck thread to do so.

Quote from: Jaxxa on December 17, 2017, 10:10:14 PMI want to conditionally execute an XML patch based on a value in mod settings.
It depends. If the setting in question is loaded prior to xml loading, then it's easy to do. If not, then it could get complicated. I would encourage you to post about it in more detail in the ModCheck thread and I will see if I can make a PatchOperation to check the setting in question.
ModCheck - boost your patch loading times and include patchmods in your main mod.

Nightinggale

Quote from: frenchiveruti on December 17, 2017, 09:38:45 PMOk, so that involves adding something extra. Cool.
I think, for the scope of my mod, that's really not necessary, right?
No. It's a minor addition. It's just adding two small DLL files (one is harmony) and you will be able to use everything it provides the added features. The most important one is ModCheck.FindFile where you tell which file to patch, which will ALWAYS be a massive performance boost compared to vanilla. Read the ModCheck thread. I used a modified ADS patch and applied it in 1.5 ms when the template use 115 ms. Even better if you double the number of xml files, FindFile will still use 1.5 ms (same due to rounding) while the template using vanilla would use around 230 ms. Now double again and multiply with the number of mods, which use patches and it's no longer talk of some ms while starting.

We can start RimWorld a lot faster when loading lots of mods, but only if the usage of ModCheck becomes widespread. Granted you only has one PatchOperationAdd, but it's still big enough to get a massive performance boost.
ModCheck - boost your patch loading times and include patchmods in your main mod.

frenchiveruti

Quote from: Nightinggale on December 18, 2017, 12:36:19 AM
Quote from: frenchiveruti on December 17, 2017, 09:38:45 PMOk, so that involves adding something extra. Cool.
I think, for the scope of my mod, that's really not necessary, right?
No. It's a minor addition. It's just adding two small DLL files (one is harmony) and you will be able to use everything it provides the added features. The most important one is ModCheck.FindFile where you tell which file to patch, which will ALWAYS be a massive performance boost compared to vanilla. Read the ModCheck thread. I used a modified ADS patch and applied it in 1.5 ms when the template use 115 ms. Even better if you double the number of xml files, FindFile will still use 1.5 ms (same due to rounding) while the template using vanilla would use around 230 ms. Now double again and multiply with the number of mods, which use patches and it's no longer talk of some ms while starting.

We can start RimWorld a lot faster when loading lots of mods, but only if the usage of ModCheck becomes widespread. Granted you only has one PatchOperationAdd, but it's still big enough to get a massive performance boost.
Ok I'll see if I can add it without blowing everything up haha.

frenchiveruti

Hello Nightinggale, I've made what you suggested on "speed_patching", there were a few issues on it as you placed the wrong tags on the wiki, but solved and reported it on the GitHub.
One thing though. "ModCheck.FindFile" doesn't allow custom messages, am I right?
I mean, I made it so it goes for the wildplants and well, it always succeeds, but I can't tell in the log if that was the case because is not supported by the Operation Class. Also "yourMod" tag isn't supported by that operation.
Is that correct? That's what I understood from the red warning yelling. :)