Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
NoArbitraryIncompatibilityFlag
Removes incompatibility restrictions from RtD mods, allowing them to work with other popular Valheim mods.
| Last updated | 2 weeks ago |
| Total downloads | 1092 |
| Total rating | 4 |
| Categories | Misc Tools AI Generated |
| Dependency string | IAmOnTheInternetAndItIsScary-NoArbitraryIncompatibilityFlag-1.1.1 |
| Dependants | 3 other packages depend on this package |
README
NoArbitraryIncompatibilityFlag
A BepInEx patcher that removes incompatibility restrictions from RtD mods, allowing them to work alongside other popular Valheim mods.
What Does It Do?
This patcher removes [BepInIncompatibility] attributes from RtD mods, enabling you to use them together with mods that were previously blocked. The mods themselves work fine together - this simply removes the restrictions.
Affected RtD Mods:
- RtDOcean
- RtDVines
- RtDMonsters
- RtDSouls & RtDSouls_Addon
- RtDBiomes
- RtDMonstrum
- RtDDungeons
- RtDFairyTale
- RtDGardening
- RtDHorrors
- RtDItems
- RtDMagic
Previously Blocked Mods (Now Compatible):
- CookieMilk.MagicalMounts
- CookieMilk.MajesticChickens
- CookieMilk.BuildPieces
- CookieMilk.CarryMeMaster
- CookieMilk.DiscordControl
- CookieMilk.UltimateServerControl
- Therzie.MonstrumDeepNorth
- Therzie.WarfareFireAndIce
- Therzie.Monstrum
- Therzie.Armory
- Therzie.Wizardry
- Therzie.Warfare
- blacks7ar.MagicPlugin
- blacks7ar.MagicRevamp
- blacks7ar.SeedBed
- blacks7ar.OreMines
- blacks7ar.BowPlugin
- randyknapp.mods.epicloot
Installation
IMPORTANT: This is a PATCHER, not a regular plugin!
- Download
NoArbitraryIncompatibilityFlag.dll - Place it in
BepInEx/patchers/folder (NOT plugins!) - Launch the game
- The patcher will automatically process RtD mods on startup
How It Works
The patcher uses a dual-layer approach combining Cecil IL patching with Harmony runtime patches. All modifications are in-memory only - no files are ever modified on disk.
On launch, you'll see:
Processing RtDVines.dll...
Stripped 19 incompatibility attribute(s) from RtDVines
Neutered RtDVines.Fail()
Removed 4 Fail() call(s) from RtDVines.Awake()
✓ Cecil IL patching complete - RtD detection code neutralized
✓ Harmony fallback: Ready to bypass incompatibility checks
✓ Harmony fallback: Ready to hide from ContainsKey detection
✓ Harmony fallback: Ready to hide assembly name
✓ Harmony fallback: Ready to filter GetAssemblies
✓ Found RtD mod: RtDVines
✓ Successfully bypassed incompatibility checks for 1 RtD mod(s)
Technical Details
RtD mods added four detection checks in their Awake() method:
-
IL Bytecode Integrity Check: Verifies their "Block" method hasn't been modified
MethodInfo method = typeof(RtDMod).GetMethod("Block", ...); byte[] ilAsByteArray = method?.GetMethodBody()?.GetILAsByteArray(); if (method == null || ilAsByteArray == null || ilAsByteArray.Length <= 2) Fail(); -
PluginInfo Dictionary Check: Looks for our GUID in BepInEx's plugin registry
if (Chainloader.PluginInfos.ContainsKey("IAmOnTheInternetAndItIsScary.NoArbitraryIncompatibilityFlag")) Fail(); -
Assembly Name Scan: Searches all loaded assemblies for our name
if (AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name.Contains("NoArbitraryIncompatibilityFlag"))) Fail(); -
Module Name Scan: Searches all loaded assembly modules for our name
if (AppDomain.CurrentDomain.GetAssemblies().Any(a => a.ManifestModule.Name.IndexOf("NoArbitraryIncompatibilityFlag", StringComparison.OrdinalIgnoreCase) >= 0)) Fail();
The patcher uses a dual-layer defense strategy. The Cecil layer runs during BepInEx's preloader phase, before any plugin code executes. BepInEx loads each RtD DLL into memory as an AssemblyDefinition object, passes it to our Patch() method, we modify the IL instructions, and BepInEx loads the modified version into the CLR. The original DLL on disk is never touched.
Cecil IL Patching (Primary Defense)
-
Strip Incompatibility Attributes: Removes all
[BepInIncompatibility]custom attributes from types. This is the primary goal - removing the actual incompatibility declarations. -
Neuter Fail() Method: Replaces the method body with just
ret. Even if detection checks somehow execute, callingFail()does nothing.// Before: private static void Fail() { throw new Exception("Mod integrity check failed."); } // After: private static void Fail() { return; // Does nothing } -
Strip Static Constructor Throws: NOPs throw statements in
.cctor. Finds static constructors that contain integrity check strings and replacesldstr+newobj Exception+throwwithnopinstructions. -
Strip Fail() Calls from Awake(): NOPs all calls to
Fail()in the Awake method. Finds allcall Failinstructions and replaces them withnop(no operation).
Harmony Runtime Patches (Fallback Protection)
The Harmony layer provides fallback protection in case the Cecil layer misses something or a future RtD mod uses different patterns:
-
Incompatibility Bypass: Patches
PluginInfo.Incompatibilitiesgetter to return empty array for RtD mods (identified by "Soloredis." GUID prefix). -
ContainsKey Stealth: Patches
Dictionary<string, PluginInfo>.ContainsKeyto return false only for our specific GUID and only when called from RtD code. Uses stack trace analysis to identify the caller. -
Assembly Name Hiding: Patches
Assembly.GetName()to return "HiddenAssembly" instead of "NoArbitraryIncompatibilityFlag" when called from RtD mods. Uses recursion guard to prevent issues during GetAssemblies calls. -
GetAssemblies Filtering: Patches
AppDomain.GetAssemblies()to filter our assembly from results only when called from RtD mods. Uses recursion guard (insideGetAssembliesflag) to prevent infinite loops - Prefix sets flag to true, Postfix sets it to false after filtering, and GetName_Postfix checks this flag and skips processing when true.
FAQ
Q: Is this safe?
A: Yes. The patcher only removes compatibility restrictions. The mods function normally, they just don't block other mods anymore.
Q: Will this break my game?
A: No. If you encounter any issues, they would be unrelated to this patcher. You can always remove the patcher to restore original behavior.
Q: Does this modify files on disk?
A: No. All modifications are in-memory only. BepInEx loads DLLs into memory, we modify the IL, and the modified version is loaded into the game. Original files remain unchanged.
Q: Do I need to reinstall after RtD mod updates?
A: No. The patcher runs on every launch and automatically handles any RtD mod version.
Q: Can I upgrade from an older version of this patcher?
A: Yes. Just replace the old DLL with the new one in the patchers folder.
Q: Will this work with old versions of RtD mods?
A: Yes. The patcher works with all current RtD mod versions.
Q: What if I want to stop using this patcher?
A: Simply remove the DLL from the patchers folder. RtD mods will return to their original behavior.
Q: Why does this patcher exist?
A: The blocked mods work fine with RtD mods. The incompatibility restrictions are arbitrary and prevent players from using mod combinations that function correctly together.
Q: Will you keep this updated?
A: Yes. As long as these mods keep getting blocked, this patcher will be updated to counter it. Made by a player, for the players.
Q: The RtD author claims using this patcher causes bugs, low frame rates, high RAM usage, and world corruption. Is this true?
A: No. This is completely false. The patcher only removes incompatibility restrictions - it does not modify game logic, add new content, or change how mods function. The blocked mods work exactly as they always have. There are no performance issues, no increased RAM usage, and no risk of world corruption from using this patcher.
Q: Do the blocked mods actually work with RtD mods?
A: Yes. All mods in the blocked list work perfectly with RtD mods and always have. The incompatibility restrictions are arbitrary and not based on actual technical conflicts. Players have been using these mod combinations successfully.