v5: Upgrade HarmonyX to version 2.13.0 #902
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This upgrades the version of HarmonyX to be 2.13.0 alongside matching MonoMod upgrades. This is a MAJOR breaking change, particularly for plugins that uses MonoMod's API's directly as it underwent a full rewrite that, while offering equivalent APIs, majorly breaks compatibility. This also includes some breaking changes on the HarmonyX side, but it seems they are much more minimal.
Due to BepInEx being affected by some breaking changes, some adaptations were needed, but they are relatively minor and non breaking:
Additionally, BepinEx.Harmony's submodule was changed to point to my fork which received similar upgrades. THIS MEANS THIS PR CANNOT BE MERGED AS IS! There will be a PR opened on the BepinEx.Harmony's side (BepInEx/BepInEx.Harmony#3) which should we decide to go forward with this pr, BepinEx.Harmony's pr needs to be merged first, then I change the submodule to point to it and only then it can be merged. This is however enough at the moment to perform testing and it does build.
Motivation and Context
BepinEx v6's maintenance has become uncertain since years which creates a problem for unity mono games. In these environments, v5 is more tested, more stable and is known to work which isn't the case for v6. The problem is BepinEx v5 has been stuck on HarmonyX 2.9.0 meaning it doesn't get interesting features that new HarmonyX versions provides.
Normally, it would have been fine to not upgrade it further (2.10.0 is where breaking changes starts to occur), but v6's maintenance situation changes this where it is being considered if a v5 upgrade should happen even if it is breaking. In other words, v5 seems to be stuck in a maintenance limbo where it is the best for Mono games, but also years behind in terms of patching libraries.
Recently, I helped MonoMod uncover and address a couple of old mono's runtime issues which allowed games to boot from this upgrade (see the testing section for more details).
The main breaking cases seems to be using MonoMod directly. HarmonyX's API does have breaking changes, but I checked with an API diff tool and found the changes are much less problematic than with MonoMod. Effectively, this breaks all MonoMod plugins: those plugins will need to be adapted to the new APIs. For HarmonyX, it depends, but as an example, Unity Explorer didn't need any changes and works ootb. From checking the HarmonyX changelogs, it seems the breaking changes aren't too bad, but they are still present.
How Has This Been Tested?
I validated that BepinEx installs, boots and loads my fork of UnityExplorer in the following Unity games (tested on both Windows and Linux):
*: These games REQUIRED to redirect the corlibs set or a preloader crash occured. It seems to affect unity games affecting netstandard because I experienced a similar issue with UnityExplorer before and I found that it had to do with the compatibility profile selected in the Unity project. This seems worrying: netstandard can often be the default target so there's a good chance a significant amount of games now requires corlibs redirections when they didn't before and the range of affected Unity versions seems broad (at least 2018.x and most of 2019.x, but I don't know for further). Interestingly, Marble it up did NOT required this, but that's because they targeted the .net profile instead of the netstandard one. If this issue occurs, you will get this exception in the preloader log:
Overall, it seems that with the exception of the corlibs problem (which I wonder if MonoMod should look into because it might affect more games than I expected), Bepinex still works. This is obviously not exhaustive and testing is encouraged, but it seems more promising than before where old mono would cause very bad native crashes.
Types of changes
Checklist: