WERBEPLATZ VERFÜGBAR · PARTNERSCHAFTEN WILLKOMMEN

Unity-Modding-Architektur: BepInEx unter Mono vs. IL2CPP, Harmony-Hooks und Assembly-Patching

365Finds Editorial
11.430 Wiki-Artikel erfasst

365 Wiki mit deiner KI nutzen

Kopiere den Prompt unten, füge ihn in deine gewohnte KI ein und stelle direkt deine Frage.

Vollständigen Skill herunterladen

Probiere es zuerst mit dem Prompt aus. Wenn du 365 Wiki häufig nutzt, installiere den vollständigen 365Wiki Skill, damit du ihn nicht jedes Mal einfügen musst. Ohne bevorzugte KI funktionieren auch die Webversionen von Gemini oder Microsoft Copilot.

Einleitung: Die Funktionsweise des Moddings in der Unity-Engine

Die Unity-Engine bildet das technologische Fundament eines gewaltigen Teils moderner PC-Titel im Indie- und Mid-Tier-Bereich – von Koop-Überlebensspielen wie Valheim und Lethal Company bis hin zu komplexen Simulationen wie Cities: Skylines II und Dyson Sphere Program. Im Gegensatz zu proprietären Spiele-Engines, die auf monolithischen Binärarchiven oder Bethesdas deklarativen Plugin-Strukturen basieren, ist Unity tief im .NET- und C#-Softwareökosystem verwurzelt.

Das Modifizieren von Unity-Titeln erfordert im Regelfall kein destruktives Ersetzen von komprimierten Spieldateien auf dem Datenträger. Stattdessen basiert modernes Unity-Modding auf dynamischem Assembly-Patching zur Laufzeit und dem Abfangen von Methodenaufrufen im Arbeitsspeicher. Im Zentrum dieses Ökosystems stehen BepInEx (Bepis Injector Extensible), ein quelloffener Plugin-Bootstrapper und Mod-Loader, sowie die von Andreas Pardeike entwickelte Hooking-Bibliothek Harmony.

Modder und Spieler stoßen jedoch regelmäßig auf schwerwiegende Kompatibilitätsprobleme, wenn sie Modifikationen auf unterschiedliche Spiele anwenden. Die Ursache liegt im grundlegenden Kompilierungsmodell der Engine: der tiefgreifenden architektonischen Diskrepanz zwischen dem klassischen Mono-Scripting-Backend und dem Ahead-of-Time-kompilierten IL2CPP (Intermediate Language to C++)-Backend. Ein Verständnis darüber, wie BepInEx und Harmony diese beiden Umgebungen ansteuern, ist unerlässlich für die Analyse von Abstürzen, fehlgeschlagenen Hooks und Konflikten in der Lade-Reihenfolge.

Der Konflikt der Scripting-Backends: Mono vs. IL2CPP

Beim Kompilieren eines Unity-Spiels müssen Entwickler verbindlich zwischen zwei grundlegend verschiedenen Scripting-Architekturen wählen:

[C#-Quellcode: Spiellogik-Skripte]
               │
               ▼
[Roslyn / Unity C#-Compiler] ---> Common Intermediate Language (CIL-Bytecode)
               │
               ├─────────────────────────────────────────┐
               ▼                                         ▼
      [Pfad: Mono-Backend]                      [Pfad: IL2CPP-Backend]
- Bündelt CIL in Managed Assemblies         - IL2CPP-Transpiler wandelt CIL in C++
- Hauptdatei: Assembly-CSharp.dll           - C++-Compiler generiert GameAssembly.dll
- Ausführung via Mono JIT Virtual Machine   - Metadaten in global-metadata.dat ausgelagert
- Vollständige Reflection, Decompilierung   - Reiner Maschinencode, keine CLR/JIT zur Laufzeit

Das Mono-Scripting-Backend

In einem mit Mono erstellten Spiel wird sämtliche Spiellogik, KI-Verhaltensmuster und Benutzeroberflächenverwaltung in verwaltete .NET-Assemblies übersetzt – allen voran Managed/Assembly-CSharp.dll.

Das IL2CPP-Scripting-Backend

Bei einem Spiel mit IL2CPP-Backend vollzieht die Toolchain einen radikal anderen Prozess:

Die Bootstrapper-Architektur von BepInEx

Um externen Programmcode ohne offizielle Modding-Schnittstellen in einen geschlossenen Unity-Prozess einzuschleusen, nutzt BepInEx das Verfahren des DLL-Proxy-Hijackings.

Die Doorstop- und Proxy-Injektionskette

Das Windows-Betriebssystem sucht beim Start einer ausführbaren Datei (.exe) standardmäßig zuerst im lokalen Anwendungsverzeichnis nach benötigten Dynamic Link Libraries, bevor die Systemverzeichnisse (C:\Windows\System32) abgefragt werden. BepInEx nutzt diese Priorisierung:

  1. Die Proxy-DLL: BepInEx platziert eine Fassaden-Bibliothek im Spielverzeichnis, üblicherweise unter dem Namen einer bekannten Windows-Komponente wie winhttp.dll, version.dll oder doorstop.dll.
  2. Abfangen des Ladevorgangs: Sobald das Spiel gestartet wird, lädt der Windows-Loader die im Spielordner liegende winhttp.dll anstelle der Systembibliothek.
  3. Bootstrapping der Laufzeit: Die Proxy-DLL initialisiert Unity Doorstop. Dieses lädt umgehend BepInEx.Preloader.dll und BepInEx.Core.dll in den Adressraum des Prozesses, noch bevor Unitys eigene Initialisierungsroutinen die Kontrolle übernehmen.
  4. Plugin-Erkennung: Nach dem Aufbau der Laufzeitumgebung öffnet BepInEx bei Bedarf ein Konsolenfenster, startet Logging-Systeme und durchsucht den Ordner BepInEx/plugins/ nach kompatiblen Mod-Dateien.

BepInEx 5 vs. BepInEx 6: Die IL2CPP-Interop-Brücke

Harmony: Dynamisches Method-Patching im Arbeitsspeicher

Nachdem BepInEx die Mod-Dateien in den Prozess geladen hat, kommt Harmony zum Einsatz. Die Bibliothek modifiziert Spielfunktionen, ohne eine einzige Datei auf dem Datenträger zu verändern. Harmony erreicht dies, indem es die Methoden-Prologe im JIT-kompilierten Maschinencode des Arbeitsspeichers gezielt umleitet.

Die vier Kern-Patchtypen von Harmony

[Aufgerufene Original-Methode: z.B. PlayerController.TakeDamage(float amount)]
           │
           ▼
[Harmony-Prefix-Patch] ---> Rückgabe true (weiter) ODER false (Original überspringen)
           │
           ▼
[Ausführung der Originalmethode: Schadensberechnung]
           │
           ▼
[Harmony-Postfix-Patch] ---> Liest/Ändert Rückgabewert (__result) oder Spielstatus
           │
           ▼
[Harmony-Finalizer-Patch] ---> Fängt unbehandelte Exceptions ab, verhindert Spielabsturz
  1. Prefix ([HarmonyPrefix]):
    • Wird unmittelbar vor dem Aufruf der eigentlichen Originalmethode ausgeführt.
    • Kann eingehende Übergabeparameter analysieren und manipulieren (z. B. den Wert von float amount vor der Schadensberechnung anpassen).
    • Kann die Ausführung abbrechen: Gibt ein Prefix den Wert false zurück, wird die Originalmethode des Spiels vollständig übersprungen.
  2. Postfix ([HarmonyPostfix]):
    • Wird sofort nach dem Abschluss der Originalmethode ausgeführt.
    • Erlaubt über den Spezialparameter ref __result das Auslesen oder Überschreiben des Rückgabewerts.
    • Optimal geeignet für Folgeaktionen (z. B. das Freischalten eines Erfolgs nach Abschluss eines Crafting-Vorgangs).
  3. Transpiler ([HarmonyTranspiler]):
    • Der komplexeste und mächtigste Patch-Typ. Er fängt den CIL-Bytecode einer Methode vor der JIT-Kompilierung als Sequenz von Befehlen (IEnumerable von CodeInstruction) ab.
    • Ermöglicht es, gezielte Operationen (OpCodes) einzufügen, zu löschen oder zu verändern (wie das Ändern eines konstanten Werts von ldc.i4.0 zu ldc.i4.1).
  4. Finalizer ([HarmonyFinalizer]):
    • Dient als dynamischer try/finally-Schutzblock um die gepatchte Methode. Er fängt unerwartete Ausnahmen ab, wodurch verhindert wird, dass Mod-Fehler zum sofortigen Absturz des Spiels auf den Desktop führen.

Fehlerbehebungs-Matrix: Typische Absturzursachen beim Unity-Modding

Sollten Modifikationen nicht geladen werden oder Abstürze verursachen, liefert die folgende Matrix Orientierung bei der Fehlerdiagnose auf Architekturebene:

FehlersymptomUrsache auf SystemebeneTypisches AnzeichenAbhilfemaßnahme
Keine Konsole / Mods ignoriertProxy-DLL wird vom Betriebssystem-Loader blockiertDatei BepInEx/LogOutput.log wird nicht erstelltVorhandensein von winhttp.dll im Hauptordner prüfen; Schreibrechte verifizieren
Sofortiger Absturz beim Start (IL2CPP)Einsatz von BepInEx 5 in einem IL2CPP-basierten SpielGameAssembly.dll vorhanden, aber BepInEx 5 installiertAlte BepInEx-Installation entfernen und BepInEx 6 x64 IL2CPP installieren
Veralteter Interop-CacheSpiel aktualisiert, aber Interop-Dateien nicht regeneriertFehlermeldung TypeLoadException oder MissingMethodException im LogDen Ordner BepInEx/interop/ löschen und Spiel neu starten
Prefix-Hook-KollisionMehrere Mods fangen dieselbe Methode ab und geben false zurückEin Mod funktioniert, ein anderer verliert jegliche FunktionLadereihenfolge anpassen; destruktive Prefix-Überschreibungen vermeiden
Blockade durch Anti-Cheat-SystemeEAC oder BattlEye blockieren die Proxy-InjektionSpiel schließt sich sofort oder meldet nicht vertrauenswürdige DateienSpiel im Offline-Modus starten oder offizielle Modding-Startparameter nutzen

Beim Erstellen individueller Mod-Ladelisten, dem Beheben von Konflikten zwischen Assemblies oder der Entwicklung eigener C#-Erweiterungen für moderne Spiele-Engines gewährleisten die technischen Leitfäden auf 365Finds eine fundierte Orientierung an verifizierten Softwarearchitekturen. Ein solides Verständnis von Speicherinjektion, Proxy-Mechanismen und nicht-destruktivem Bytecode-Patching schützt Mod-Installationen verlässlich vor Versionskonflikten.

Referenzen