Remove trait by patch

Started by m1st4x, March 05, 2021, 05:09:07 PM

Previous topic - Next topic


I want to get rid of a trait added by another mod, so I've applied a xml PatchOperationRemove to remove its definition.
This works, but now I'm getting errors by classes which use that definition:
"Failed to find RimWorld.TraitDef named <traitToRemove>. There are <num> defs of this type loaded."
Do I have to patch each class/method which is involved? What's best practice here?


LWM through all the XML for everything that explicitly references this trait?

That's the most likely source of this error.


I dont know how to mod, but what I do with some mods is just go to their files and change/remove what i dont like. In this case it would be to remove that trait. Just be careful when the mod gets updated again, since you would have to do this again


alternative method rely on code injection that will prevent blacklisted stuff selection (that can be anything) from database without actually removing anything from database.

this won't need updates as long as defname is same, but require some effort for initial setup.


Hi guys, thanks for your thoughts.

There's no other xml-reference to the defname I removed.

So guess I've to 'blacklist' the corresponding code...
Is it worth the effort?
Can I do this with Harmony?


Hmm.  What's the XML you are using to remove it, what's the trait, and what's the full stack trace from the "Failed to find" error you got?

If you don't see any other references to its defName in any XML files, then something unusual is happening to the def.


I want to remove VTE_Neat and VTE_Slob from VanillaTraitsExpanded.

patch operation:
  <Operation Class="PatchOperationRemove">

stack trace:

Failed to find RimWorld.TraitDef named VTE_Neat. There are 96 defs of this type loaded.
Verse.Log:Error(String, Boolean)
Verse.DefDatabase`1:GetNamed(String, Boolean)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.GenGeneric:InvokeStaticMethodOnGenericType(Type, Type, String, Object[])
Verse.GenDefDatabase:GetDef(Type, String, Boolean)
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Threading.ExecutionContext:Run(ExecutionContext, ContextCallback, Object, Boolean)
System.Threading.ExecutionContext:Run(ExecutionContext, ContextCallback, Object)


The Defname is ok.
I don't think you made the mistake and your mod is before VanillaTraitsExpanded ? :-)
I have no clue about the syntax, but does the xpath maybe need a / between TraitDef and [defName ?


this can be done with any code injection, just patch method that assign traits to pawn or pawn generation itself, most "effective" will be rerolling pawn completely if he happened to get blacklisted trait or any other blacklisted features.

*not effective, pawn generation is costly operation, but it's very simple to just reroll pawn instead of fixing it's attributes one by one.



public static class VTEDefOf
public static TraitDef VTE_Neat;
public static TraitDef VTE_Slob;

these objects are used by VTE for harmony patching in order to implement the behavior of the trait.

My mod gets loaded afterwards and removes the xml-definition of VTE_Neat and VTE_Slob.

It feels clear to me that I cannot remove XML when there is still code which refers to it.

That means I'd have to 're-patch' all VTE methods which use the deleted definitions.

-To avoid these traits being assigned to new generated pawns is a much better solution

Thanks RawCode


Oh, good, you figured out what was going on :)


Yes, and it's always the same :D
Thanks@all for helping!


VTE has a option in the mod settings to disable traits.
Just in case you do not know and this would fix your problem.


Yes indeed I didn't know and it fixes the problem, thanks :)