RomenH Posted March 16 Share Posted March 16 The next version of ONI in public_testing is moving to Unity 6. This seems to have some impact on the way modders compile their mods, and we're not entirely sure why the switch to Unity 6 has forced certain requirements on our build configurations suddenly. I have questions here for the Klei devs and I wasn't sure who I should ping to be sure a dev actually notices this post; Sorry to @EricKlei if this is was any inconvenience. I have put the important details or questions from this post in bold. The major problem we are seeing with the switch to Unity 6 is that our projects suddenly must be changed to .NET Standard 2.1 instead of .NET Framework 4.8 to compile. Keeping "net48" as our target framework leads to types such as System.Memory.Span being missing when you reference ImageConversionModule in Unity. Fixing this leads you down a deep rabbit hole of broken references and types not being found with the default Microsoft framework DLLs. The "solution" I found here is to explicitly remove all default framework references for a .NET Framework library, and add manual references pointing to the "correct" ones in the game installtion folder (for libs like mscorlib, System.dll, etc.). This "solution" is not something a typical C# app or library project should ever need, so I'm proposing that something is wrong upstream and we need to understand better why targeting "net48" doesn't work anymore. We never had to do this with the Unity 2022 engine, which has the same mono runtime as Unity 6 so it is mysterious what even changed. I would also like to know the answer to these three questions: Does Klei intend for mods to target .NET Framework 4.8, or .NET Standard 2.1? What is the "API Compatibility Level" set to in ONI's unity project? What is the "Managed Stripping Level" set to in ONI's Unity project? The answers to these questions will be great guidance on how to correctly proceed with fixing our mod build configurations. Because right now we're just guessing. The alleged dilemma in my post title comes from a second problem we get from targeting .NET Standard 2.1 to work around the broken .NET Framework targeting. Harmony's tutorial website very clearly states: Quote It supports Mono and .NET environments on Windows, Unix and macOS except when Unity uses the stripped down NetStandard profile (.NET 4.x profile works fine). HarmonyLib was never designed for the newer Unity engine that allows targeting .NET Standard. And the reason why goes pretty deep. HarmonyLib has a closed the issue around supporting .NET Standard in general, and it is clear the devs do not intend to fix it. netstandard2.0 target · Issue #483 · pardeike/Harmony The problem goes even further upstream to Microsoft themselves: .NET Standard 2.1 mscorlib misses type forwarder for System.Reflection.Emit.ILGenerator · Issue #1662 · dotnet/standard The consequence of Microsoft not fixing this issue is that the official API surface of .NET Standard 2.1 is missing the "System.Reflection.Emit.*" types. This then means that HarmonyLib can't even be compiled targeting .NET Standard 2.1 because it depends on those types. Which ultimately means there is no correct version of HarmonyLib to use with a Unity game targeting .NET Standard 2.1. When we make our mods target .NET Standard 2.1 we must avoid using specific HarmonyLib features or else it will fail to build, or also crash at runtime if stripping was used. This limits what modders can do to the game because these unusable types are crucial to writing certain kinds of transpilers. A good example would be needing to use the System.Reflection.Emit.Label class to scan for a label to be inserting instructions around, or adding a label as part of your injected instructions. In summary, the dilemma is that the switch to Unity 6 has mysteriously broken mods targeting .NET Framework, and then switching to .NET Standard forces us to face an unsolvable problem with HarmonyLib. There are two things I think Klei could do to get us away from this dilemma, but both have a pretty significant business cost: Switch to .NET Framework profile, so that the existing HarmonyLib DLL for .NET Framework 4.8 is once again valid to use. I suspect that a lot of code already in ONI relies on .NET Standard 2.1 profile and it could lead to a big development cost to toggle this. In addition to that, upgrading the engine again someday may require moving to .NET Standard 2.1 because Unity intends to drop mono someday. Change HarmonyLib for HarmonyX. This fork exists to solve the .NET Standard support problem. It is built to work with the branch of mono that Unity developed and specifically meant for modding Unity games, not just .NET games. Switching the Harmony library would break all existing mods on the workshop though. If any .NET experts want to chime in at this point and suggest other paths forward then I'm all ears! Thank you for your time. Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/ Share on other sites More sharing options...
Developer EricKlei Posted March 17 Developer Share Posted March 17 Thanks for the detailed write-up! The Api Compatibility Level is set to .NET Framework and Managed Stripping Level is disabled, this has not changed. It appears that Unity is using more .NET Standard 2.1 features in their own assemblies, notably an overload of ImageConversion.LoadImage was added using ReadOnlySpan<byte>. The UnityEngine.*.dll assemblies require .NET Standard 2.1, this was also true for Unity 2022.3. Is the issue with just mods using ImageConversionModule.dll, or more widespread than that? Could you link to an example mod that uses ImageConversion? Quote The "solution" I found here is to explicitly remove all default framework references for a .NET Framework library, and add manual references pointing to the "correct" ones in the game installation folder (for libs like mscorlib, System.dll, etc.). This "solution" is not something a typical C# app or library project should ever need, so I'm proposing that something is wrong upstream and we need to understand better why targeting "net48" doesn't work anymore. We never had to do this with the Unity 2022 engine, which has the same mono runtime as Unity 6 so it is mysterious what even changed. Unity's documentation mentions that .NET Framework also includes additional APIs from .NET Standard 2.1, so the solution you found for referencing the shipped assemblies does make some sense. Are there other concerns you have in referencing the Unity specific assemblies over the standard ones other than how cumbersome it is? We're still investigating, but wanted to share what we discovered so far. Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854112 Share on other sites More sharing options...
RomenH Posted March 17 Author Share Posted March 17 (edited) Quote Are there other concerns you have in referencing the Unity specific assemblies over the standard ones other than how cumbersome it is? The concern isn't just that it's combersome for us, but that it's too complicated of a solution that requires deep understanding of msbuild and the XML project properties. A less experienced C# developer probably wouldn't figure this out and just get frustrated by the "bottomless pit" of errors. My biggest concern is that it is a "skill check" for modding that wasn't there before switching to Unity 6. Currently we have to use "<DisableImplicitFrameworkReferences>" in our csproj to prevent Visual Studio from automatically referencing the default framework DLLs; It requires a fair bit of experience with MSBuild to even stumble into this solution. (You don't know what to search for if you don't know how MSBuild works) Then we also have to add references for mscorlib, System.dll, System.Core.dll, etc. from the game folder to bring back basic c# types that are normally taken for granted. Most entry level C# devs would never have to manually reference mscorlib, so again it requires a level of experience that allows them to know which DLLs those missing types even come from. I think that most modders will be unable to figure this stuff out and get scared away from modding. (Assuming they targeted .NET Framework to start.) From my experiments, referencing .NET Standard 2.1 now provides the good beginnner environment for modding that we lost from .NET Framework, so I'm not opposed to suggesting that as the first place to start. We could go chasing this HarmonyLib issue rather than the .NET Framework issue. Quote Is the issue with just mods using ImageConversionModule.dll, or more widespread than that? Could you link to an example mod that uses ImageConversion? It seems ImageConversionModule was just the most commonly hit problem from the other modders I spoke with. Because many of us have at least one mod that needs to load a Texture2D from file so this library has to be directly referenced. @SGT_Imalas also encounted an issue where the Stack<T> type was defined in two places and ambiguous due to a System.dll reference coming from Unity causing two System.dlls to be transitively referenced. I think we could probably uncover several other conflicts like this if we found creative reasons to use the other DLLs in UnityEngine (VR? Multiplayer? UI Toolkit?) Edited March 17 by RomenH Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854118 Share on other sites More sharing options...
Sanchozz Posted March 18 Share Posted March 18 I suggest updating the 0Harmony.dll distributed with the game to the latest version 2.4.2. Then modders can referencing to the "Lib.Harmony.Ref" nuget package instead of just 0Harmony.dll. This will solve the problem of missing "System.Reflection.Emit.*" types when targeting .NET Standard 2.1 3 Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854227 Share on other sites More sharing options...
RomenH Posted March 18 Author Share Posted March 18 9 hours ago, Sanchozz said: I suggest updating the 0Harmony.dll distributed with the game to the latest version 2.4.2. Then modders can referencing to the "Lib.Harmony.Ref" nuget package instead of just 0Harmony.dll. This will solve the problem of missing "System.Reflection.Emit.*" types when targeting .NET Standard 2.1 I didn't know about this other package, thanks for pointing it out. Looks like there's no way around needing to use this nuget package, Klei can't include the "ref" lib with the game because they need the actual harmony0.dll? Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854270 Share on other sites More sharing options...
Sanchozz Posted March 20 Share Posted March 20 I looked at it again. it turned out to be even simpler. We can just referencing to the "Lib.Harmony" nuget package. if we targeting .NET Framework 4.8, it's just used as it is. if we targeting .NET Standard 2.1, it pulls the "Lib.Harmony.Ref" and other necessary dependencies. we can do this even at rigth now, and it will even work, provided that we don't use the new Harmony features added after 2.2.2 version. Of course, it won't work if we try to referencing "Lib.Harmony" nuget package version 2.2.2 because it doesn't support.NET Standard targeting. That's why I'm asking the developers to update the version. There were other reasons for the update that I mentioned here, but they were ignored. On 3/19/2026 at 4:30 AM, RomenH said: Klei can't include the "ref" lib with the game because they need the actual harmony0.dll? Of course, developers should include the full 0Harmony.dll , not the "ref". On 3/19/2026 at 4:30 AM, RomenH said: Looks like there's no way around needing to use this nuget package Are there any good reasons to avoid nuget packages ? I suppose you can download the "ref" from github and referencing to it. Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854831 Share on other sites More sharing options...
RomenH Posted March 20 Author Share Posted March 20 (edited) I think the path of least resistance is definitely what Sanchozz is suggesting. Update HarmonyLib to 2.4.2 Provide an official forum pinned post with the currently required msbuild properties: <PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Lib.Harmony.Ref" Version="2.4.2"/> </ItemGroup> Quote Are there any good reasons to avoid nuget packages ? I suppose you can download the "ref" from github and referencing to it. My only concern was that it is difficult for a new modder to figure this out on their own. If the Harmony0.dll included with the game isn't everything you need then they need somewhere to look and find the rest of the puzzle already figured out. We can't take for granted that this modder has joined a discord, or found an up-to-date modding guide or example project. Edited March 20 by RomenH 1 Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854837 Share on other sites More sharing options...
Developer EricKlei Posted March 20 Developer Share Posted March 20 We upgraded to Harmony 2.4.2. Please give this a read and let us know what you think. 4 Link to comment https://forums.kleientertainment.com/forums/topic/170067-modders-now-face-a-dilemma-with-unity-6/#findComment-1854895 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now