Patch does not run if specific other patch exists
See original GitHub issueApologies in advance for the vague description. This is a mind boggling issue for me (I’m new to this) and I’m not even sure if Harmony is at fault. I’m hoping someone can point me in the right direction with this.
Consider this pseudo code:
void DoThings()
{
OneThing();
AnotherThing();
}
If I patch OneThing
, that works as expected. Prefix, postfix, finalizer, all work fine.
Now, if I also patch DoThings
, that works, but any patch for OneThing
will now be skipped. That is to say, the debug logs say that the method did get patched, but the code does not run. It does not matter if it is a prefix, postfix, or finalizer. None of them run.
In fact, if the patch on DoThings
is empty, like so:
void Prefix() { }
Obviously it will now not do anything, and yet it still breaks the other patch.
Is this expected behaviour?
The context in which I discovered this is the Unity game Valheim, and the bug (if it is one) happens in a mod I wrote, but was initially caused by another mod. Meaning, my mod had patched OneThing
and that no longer worked because another mod had patched DoThings
.
How can I debug this and figure out what’s actually going on “behind the scenes”?
Issue Analytics
- State:
- Created 6 months ago
- Comments:11 (5 by maintainers)
Top GitHub Comments
Thanks, @ghorsington will have to take a look at it.
The more I think about this, the less sense it makes in my head. Why does the inner method get inlined when a harmony patch exists on the outer method, but not if it doesn’t?
Getting other mods to add a soft dependency on my mod would be an impossible task. There are a plethora of mods that patch the outer method. It seems that in a game where you can build stuff, lots of mods are interested in the build event for some reason! 😛 Renaming my mod isn’t great either as I would have to abandon the current mod and make a new one, risking my sanity as well as a loss in endorsements and users. Writing a preloader just because I want to know when a specific item is being built in a game seems like insane overkill, I’d like to avoid that approach at all costs.
I did write a silly work-around which checks the result of the inner method after a small delay, and in that way I am able to “emulate” the circumstances under which the inner patch “would have” run. It’s very ugly but I guess it’ll have to do.
Is there a way for me to detect that the outer method was patched? Because if it wasn’t, I can patch the inner method and everything will be fine, and I won’t need my work-around. I can then opt to only run my work-around if strictly necessary.(edit: I foundHarmony.GetAllPatchedMethods()
, yay!)The only other thing for it, I suppose, would be to write “known issue” in the comment above my patch and move on with life.
Edit: Working around this issue like so:
Seems to get the job done when I patch the outer method myself.
(
Piece.SetCreator
is another inner method that is being called by the same outer method - it’s not the event I’m looking for, but in its postfix I can, after a small delay, check the results of the inlined method)Now it doesn’t matter if my mod was loaded first or not - so long as the outer method was not patched yet, patching the inner one will work. And once the inner method is patched, patching the outer method does not cause problems.