How To Mod Unity Games: Engineering Custom Plugins And Runtime Patches

How To Mod Unity Games: Engineering Custom Plugins And Runtime Patches

[Tutorial] How to hack Unity Games | il2cpp resolver [ Level: Beginner ...

Reverse engineering and modding Unity games involves identifying the compilation backend, extracting game assemblies, and injecting C# runtime patches using standard modding frameworks such as BepInEx or MelonLoader. By inspecting Mono managed binaries or dumping metadata from IL2CPP builds, developers can modify internal game logic through Harmony hooks and alter asset bundles safely. Master this pipeline by mastering memory injection rules, binary decompilation, and patch dependency management.


Game Architecture Inspection and Tooling Prerequisites

Before altering game logic or extracting resources, you must establish an environment capable of inspecting compiled intermediate language binaries and hooking memory addresses safely. Modifying Unity games requires distinct tools depending on whether the target executable was compiled using the legacy Mono scripting backend or the compiled-to-native Intermediate Language to C++ (IL2CPP) pipeline.



Essential Gear, Software, and Analysis Tools



  • Mod Framework Loaders: BepInEx (v5.4 for stable Mono/IL2CPP target builds) or MelonLoader for unified cross-backend plugin loading.
  • Assembly Decompilers: dnSpy or ILSpy for reversing Mono-compiled C# Assemblies; Visual Studio Community Edition for authoring C# plugin projects.
  • IL2CPP Reverse-Engineering Tools: Il2CppDumper for extracting C++ headers, method offsets, and generating dummy C# assemblies from metadata files.
  • Asset Extraction Utilities: AssetStudio for browsing and exporting raw audio, texture, and model files; Unity Asset Bundle Extractor (UABE) for replacing native asset files directly.


Mandatory Prerequisite Standards



  • Advanced operational proficiency in C# and object-oriented programming concepts, including reflection, inheritance, and access modifiers.
  • Direct working knowledge of intermediate code execution, including Microsoft Intermediate Language (MSIL) operational instructions.
  • Familiarity with the structure of Unity runtime components, such as MonoBehaviour lifecycles, Awake and Start initialization order, transform hierarchies, and game object instantiation pipelines.


Execution Benchmarks



  • Target Environment: Windows 10/11 64-bit architecture.
  • Initial Setup & Analysis Duration: 30 to 60 minutes for Mono targets; 1 to 2 hours for IL2CPP targets.
  • Total Project Budget: $0 (utilizing open-source community utilities and free development environments).

Executing the Unity Game Modding Workflow



Step 1: Identify Scripting Backend Architecture

Navigating to the target game directory is necessary to determine whether the application utilizes Mono or IL2CPP compilation. Open the root installation directory containing the executable file and open the corresponding data folder (typically formatted as GameName_Data).

Look for the Managed directory located inside the GameName_Data folder. If this directory contains files such as Assembly-CSharp.dll, UnityEngine.dll, and various system DLLs, the target game runs on the Mono backend.

If the Managed directory is missing, look for a file named GameAssembly.dll in the game's root folder and a folder named il2cpp_data inside the data folder. The presence of these items confirms the target game uses the IL2CPP backend, which compiles C# code into native C++ machine code prior to packaging.



Step 2: Deploy and Configure the Injection Engine

Mod frameworks inject custom code into the Unity process startup sequence without altering the base game files permanently.



  1. Download the architecture-appropriate BepInEx release zip archive (x86 or x64 matching the game executable's architecture).
  2. Extract the contents of the BepInEx archive directly into the game's main root folder, placing the winhttp.dll library alongside the main game executable.
  3. Boot the game once to allow BepInEx to execute its initial file-structure generation, then close the game.
  4. Verify that a BepInEx folder has appeared in the directory containing subdirectories named config, core, and plugins.
  5. Open BepInEx/config/BepInEx.cfg in a text editor, set the Enabled flag under the Logging.Console section to true, and save the file to display a debug terminal during development.


Step 3: Decompile Assemblies and Reverse-Engineer Logic

To write functional patches, you must inspect the game's original C# methods and variable declarations.

For Mono games, open dnSpy and navigate to File, then Open. Browse to the GameName_Data/Managed directory and select Assembly-CSharp.dll. Expand the assembly node in the left-hand panel to view all internal namespaces, classes, methods, and field declarations. Locate the class containing the mechanics you wish to modify (such as PlayerController or InventorySystem).

For IL2CPP games, run Il2CppDumper.exe. When prompted, select the target GameAssembly.dll file first, followed by the global-metadata.dat file located inside the GameName_Data/il2cpp_data/Metadata folder. Il2CppDumper will parse the native memory maps and generate a folder named DummyDll containing stubbed C# assemblies. Open these generated assemblies in dnSpy or Visual Studio to analyze class signatures, field offsets, and method names.



Step 4: Develop C# Runtime Hooks using Harmony

Modifications should be applied at runtime using Harmony, a library integrated into BepInEx that intercepts and redirects execution flows.



  1. Launch Visual Studio and create a new C# Class Library (.NET Framework 4.7.2 or .NET Standard 2.0 depending on the Unity engine version).
  2. Add project references to BepInEx.dll, HarmonyX (0Harmony.dll), and the target game's core assemblies (Assembly-CSharp.dll and UnityEngine.CoreModule.dll).
  3. Create a main plugin class that inherits from BaseUnityPlugin and add the BepInPlugin attribute above the class declaration, specifying a unique GUID, plugin name, and version string.
  4. Inside the Awake method of your plugin class, instantiate a new Harmony instance using your unique GUID and execute the PatchAll method to register custom hooks.
  5. Create separate static patch classes using HarmonyPatch attributes that define the target class type and target method name.
  6. Write Prefix patches to alter method input arguments or cancel base game logic by returning false. Write Postfix patches to execute code immediately after the original game method completes, using special parameter references (such as __instance to access object state or __result to modify returned values).

Pro-Tip: Always inspect method signatures in dnSpy before creating Harmony hooks. Patching overloaded methods requires explicitly defining parameter types within the HarmonyPatch attribute array to avoid runtime binding exceptions.



Step 5: Extract and Swap Raw Game Assets

If your mod targets textures, models, audio tracks, or localized text rather than C# code logic, use asset management utilities.

Launch AssetStudioGUI, click File, then Load Folder, and select the target game's GameName_Data folder. Navigate to the Asset List tab and filter by asset type (such as Texture2D, TextAsset, or AudioClip). Select target files, right-click, and choose Export Selected Assets to save raw resources to your local disk.

To overwrite existing game assets permanently or create replacement bundles, launch Unity Asset Bundle Extractor (UABE). Open the specific .assets file containing your target resource (such as sharedassets0.assets), select the target entry from the list, click Info, select Plugins, and execute the Edit or Import options to swap the file content with your modified version. Save the modified package and place it back into the GameName_Data directory.



Step 6: Build, Inject, and Verify Plugin Execution



  1. Compile your custom Visual Studio Class Library project in Release mode to yield a compiled .dll plugin binary.
  2. Copy the resulting plugin binary directly into the BepInEx/plugins directory located within the target game folder.
  3. Launch the game executable. Ensure the BepInEx terminal window opens simultaneously.
  4. Watch the console log messages for your plugin's unique GUID to confirm successful binding and initialization.
  5. Enter active gameplay to confirm that modified mechanics, overridden values, or custom injected MonoBehaviours execute as designed without throwing continuous null reference exceptions in the log window.

Warning: Modding online or multiplayer Unity games that utilize server-side state checks or client anti-cheat systems (such as Easy Anti-Cheat or BattlEye) can result in account bans or immediate process termination. Restrict custom memory patching strictly to single-player environments or dedicated local servers.


How mods are made for Unity games. Chapter 1: Inject mods into a game's ...

How mods are made for Unity games. Chapter 1: Inject mods into a game's ...

Unity Scripting Backends and Injection Framework Parameters



Metric / Technical Parameter Mono Scripting Backend IL2CPP Scripting Backend Asset Bundle Overrides
Primary Target File Assembly-CSharp.dll GameAssembly.dll & metadata .assets / .bundle files
Code Decompilation Depth Full C# source recovery Class/Method Stubs (No Logic) Raw Media / Deserialized Trees
Primary Decompiler Tool dnSpy / ILSpy Il2CppDumper + C++ Decompiler AssetStudio / UABE
Execution Performance Standard Managed JIT Optimized Native Machine Code Native Asset Serialization
Patching Mechanism In-Memory C# Method Interception Offset Hooking / C++ Intercepts Static Byte/Resource Swapping
Framework Compatibility BepInEx 5 / MelonLoader BepInEx 6 Bleeding Edge / Melon Direct Replacement / Loaders
Maintenance Burden Moderate (Breaks on class changes) High (Breaks on binary recompiles) Low (Breaks on asset schema updates)

Common Modding Failures and Field Remedies



BepInEx Console Fails to Display on Game Launch



  • Root Cause: Architecture mismatch between the downloaded mod loader binary and the target game process, or missing native runtime dynamic link libraries (such as winhttp.dll).
  • Actionable Fix: Open Windows Task Manager while the game is running to determine if the process is 32-bit (x86) or 64-bit (x64). Download the matching architecture package for BepInEx. Ensure that winhttp.dll and the doorstop_config.ini file reside in the exact same root directory as the main game executable file.


Harmony Patch Throws Refactoring or TypeLoad Exceptions



  • Root Cause: The base game was updated, changing the underlying method signature, renaming private fields, or altering method visibility, causing the Harmony patch attribute to target non-existent methods.
  • Actionable Fix: Open dnSpy and re-examine the updated Assembly-CSharp.dll file. Verify that the class name, method parameters, and return types inside your HarmonyPatch attribute match the updated binary exactly. If targeting private fields, update your access strings to reflect the refactored field names.


Injected Mods Cause Endless NullReferenceException Floods in Log



  • Root Cause: Attempting to access Unity objects or component instances before they are fully instantiated in memory (for instance, reading a player transform during the Awake phase instead of Start or Update).
  • Actionable Fix: Add explicit validation checks in your patch logic to ensure object instances exist before execution. Wrap references inside null checks, or transition your execution logic out of structural initialization methods and move them inside Postfix hooks attached to late-stage lifecycle events like Start or Update.


Modified Textures Display as Solid Magenta / Purple Blocks



  • Root Cause: Shader incompatibility or missing material properties occurring when replacement textures or AssetBundles are exported using a different Unity Render Pipeline (e.g., Built-in vs. Universal Render Pipeline/URP).
  • Actionable Fix: Inspect the original game's engine version and active rendering pipeline using AssetStudio. Ensure that replacement assets are packed using the exact same Unity Editor minor version and render pipeline settings as the target game to ensure shader compatibility.

Frequently Asked Questions



What is the primary difference between modding Mono and IL2CPP Unity games?

Mono compiles code to C# Intermediate Language (IL), leaving class structures, method logic, and variable names readable via decompilers like dnSpy. IL2CPP converts C# code into native C++ machine code prior to compilation, requiring tools like Il2CppDumper to rebuild stub assemblies before patches can target underlying memory offsets.



Can I mod Unity games on Linux or Steam Deck systems?

Yes, Unity games running under Proton or native Linux can be modded using BepInEx. You must set a DLL override parameter inside Wine/Proton launch options (specifically setting winhttp.dll to native,builtin) so the operating system routes process initialization through the mod loader library properly.



How do I modify private fields and methods in a Unity game class?

When authoring C# patches, use Harmony's AccessTools library or C# Reflection to access non-public members. Alternatively, inside Harmony patch signatures, you can use the special parameter annotation prefix double-underscore along with the exact field name to bind private fields directly to your patch method parameters.



Do updates to the target game break installed C# mods automatically?

Game updates frequently alter memory layouts, field names, and method signatures within the compiled assemblies. While simple asset replacements might survive updates, C# plugins targeting modified methods will fail safely by throwing injection errors until the mod author updates the target parameters to match the new build.

Advance Your Unity Reverse Engineering Skills

Mastering Unity modding opens the door to game architecture analysis, runtime memory manipulation, and advanced C# development techniques. To take your skills further, explore custom shader injection, intermediate language instruction editing using Mono.Cecil, and deep-level runtime assembly patching. Start building your custom BepInEx plugin today to transform your technical understanding of modern game engines.


[Open Source] ModTool - Mod Support for Unity - Page 5 - Community ...

[Open Source] ModTool - Mod Support for Unity - Page 5 - Community ...

Read also: My Pee Smells Like Buttered Popcorncompany Landing