ESPACIO PUBLICITARIO DISPONIBLE · HABLEMOS

Arquitectura de modding en Unity: BepInEx en Mono frente a IL2CPP, ganchos de Harmony y parcheo de ensamblados

365Finds Editorial
11.430 artículos Wiki recopilados

Usa 365 Wiki con tu IA

Copia el prompt de abajo, pégalo en la IA que ya usas y haz tu pregunta.

Descargar el Skill completo

Pruébalo primero con el prompt. Si usas 365 Wiki a menudo, instala el Skill completo de 365Wiki y no tendrás que volver a pegarlo. Si no tienes una IA habitual, también sirven las versiones web de Gemini o Microsoft Copilot.

Introducción: Los fundamentos del modding en el motor Unity

El motor gráfico Unity sustenta una porción masiva de los videojuegos independientes y de escala media para PC, desde éxitos cooperativos como Valheim y Lethal Company hasta simuladores complejos como Cities: Skylines II y Dyson Sphere Program. A diferencia de otros motores que dependen de paquetes de recursos monolíticos o de sistemas de registros declarativos de plugins (como los archivos esp/esm de Bethesda), las obras desarrolladas en Unity están profundamente integradas en el ecosistema .NET y el lenguaje C#.

Modificar un juego de Unity rara vez implica sobrescribir archivos originales en el disco duro. El modding moderno en este entorno opera mediante la interceptación de métodos en memoria y el parcheo dinámico de ensamblados en tiempo de ejecución. En el centro de esta arquitectura convergen dos herramientas fundamentales: BepInEx (Bepis Injector Extensible), un entorno modular de carga e inyección de plugins, y la conocida biblioteca de ganchos dinámicos Harmony, desarrollada por Andreas Pardeike.

No obstante, los usuarios y creadores de mods se topan a menudo con bloqueos críticos y fallos al cargar modificaciones. El origen de estos problemas reside en una bifurcación técnica capital en el compilador de Unity: la insalvable distancia arquitectónica entre el clásico backend administrado Mono y el backend precompilado a código nativo IL2CPP (Intermediate Language to C++).

La división de backends de scripting: Mono frente a IL2CPP

Cuando un estudio exporta un proyecto de Unity para PC, debe elegir entre dos métodos de compilación radicalmente distintos:

[Código fuente C#: Lógica del juego]
              │
              ▼
[Compilador C# de Unity / Roslyn] ---> Lenguaje Intermedio Común (Bytecode CIL)
              │
              ├─────────────────────────────────────────┐
              ▼                                         ▼
     [Vía del backend Mono]                   [Vía del backend IL2CPP]
- Empaqueta el CIL en DLLs administradas    - El transpilador IL2CPP convierte CIL a código C++
- Genera Assembly-CSharp.dll estándar       - Compilador nativo genera GameAssembly.dll
- Ejecutado en runtime por la VM Mono JIT   - Metadatos extraídos a global-metadata.dat
- Metadatos intactos y fácil descompilación - Código máquina puro; carece de CLR en runtime

El backend de scripting Mono

En los juegos compilados bajo Mono, toda la lógica de juego, las rutinas de inteligencia artificial y los parámetros de entidades se compilan como lenguaje intermedio estándar de .NET (CIL) en bibliotecas administradas, destacando Managed/Assembly-CSharp.dll.

El backend de scripting IL2CPP

En los títulos generados con IL2CPP, la cadena de montaje de software cambia por completo:

La arquitectura de inyección de BepInEx y el secuestro de DLLs

Para lograr que un proceso cerrado de Unity cargue código de terceros, BepInEx recurre al secuestro de proxies de librerías dinámicas (DLL Proxy Hijacking) de Windows.

La cadena de intercepción con Doorstop

El cargador de Windows busca las librerías dinámicas en el directorio raíz de la aplicación antes de consultar las carpetas del sistema operativo (C:\Windows\System32). BepInEx aprovecha esta prioridad:

  1. La DLL proxy: Se ubica en la raíz del juego una librería con el mismo nombre de un componente del sistema, habitualmente winhttp.dll, version.dll o doorstop.dll.
  2. Desvío del hilo de ejecución: Al iniciarse el ejecutable, Windows carga la librería falsa local winhttp.dll en lugar del componente oficial de Windows.
  3. Arranque del entorno de ejecución: Esta librería ejecuta Unity Doorstop, que a su vez introduce BepInEx.Preloader.dll y BepInEx.Core.dll en la memoria del proceso antes de que la rutina principal de Unity asuma el control.
  4. Carga y despacho de plugins: Una vez establecido el entorno, BepInEx habilita la consola de depuración, activa los registros y explora la carpeta BepInEx/plugins/ para cargar los ensamblados de los mods instalados.

BepInEx 5 frente a BepInEx 6: El puente de interoperabilidad

Ganchos dinámicos con Harmony: Modificación en memoria sin alterar archivos

Una vez que BepInEx ha inyectado el entorno en memoria, la alteración de funciones concretas se confía a la biblioteca Harmony. Harmony prescinde de la modificación destructiva de archivos en disco, reescribiendo directamente los prólogos de los métodos compilados por el JIT en la memoria RAM mediante instrucciones de salto.

Las cuatro modalidades de parches de Harmony

[Invocación del método original: ej. PlayerController.TakeDamage(float amount)]
           │
           ▼
[Parche Prefix de Harmony] ---> Devuelve true (continúa) o false (omite original)
           │
           ▼
[Ejecución del método original del juego: Cálculo de daño]
           │
           ▼
[Parche Postfix de Harmony] ---> Lee o modifica el valor de retorno (__result)
           │
           ▼
[Parche Finalizer de Harmony] ---> Captura excepciones y evita el cuelgue del juego
  1. Parche previo ([HarmonyPrefix]):
    • Se ejecuta instantes antes del método original.
    • Permite inspeccionar y alterar los argumentos de entrada (por ejemplo, reducir a la mitad el parámetro amount antes de aplicar el daño).
    • Control de flujo: Si el Prefix devuelve false, la lógica original del juego se omite por completo.
  2. Parche posterior ([HarmonyPostfix]):
    • Se ejecuta justo al finalizar la rutina original.
    • Permite consultar y modificar el valor devuelto mediante el parámetro especial ref __result.
    • Resulta ideal para desencadenar eventos secundarios (como entregar un logro tras fabricar un objeto).
  3. Parche transpilador ([HarmonyTranspiler]):
    • Es el método de mayor complejidad técnica. Expone el bytecode CIL original como una secuencia enumerable de instrucciones (IEnumerable de CodeInstruction).
    • Permite sustituir, insertar o suprimir instrucciones operativas (OpCodes) individuales antes de la compilación JIT.
  4. Parche finalizador ([HarmonyFinalizer]):
    • Opera como un bloque try/finally dinámico alrededor del método. Captura y neutraliza excepciones imprevistas, impidiendo que errores en el código del mod provoquen el cierre abrupto del juego al escritorio.

Matriz de diagnóstico: Resolución de problemas en mods de Unity

Si sus modificaciones no se ejecutan o provocan el cierre del juego, analice el problema siguiendo esta guía de incidencias:

Síntoma de falloCausa arquitectónica raízIndicador en el sistemaSolución técnica
No abre consola / Mods no carganLa DLL proxy es omitida o bloqueada por WindowsNo se genera el archivo BepInEx/LogOutput.logVerificar la presencia de winhttp.dll en raíz y permisos
Cierre instantáneo al abrir (IL2CPP)Instalación de BepInEx 5 en un juego que usa IL2CPPExiste GameAssembly.dll, pero se usó versión MonoEliminar la carpeta BepInEx e instalar BepInEx 6 IL2CPP
Errores masivos tras parche del juegoDesfase entre el nuevo binario y la caché de interopRegistro con abundantes TypeLoadExceptionBorrar la subcarpeta BepInEx/interop/ para forzar su regeneración
Un mod bloquea a otros silenciosamenteVarios mods parchean la misma función y usan falseUn mod opera pero otros dejan de responderReordenar la carga o usar parches Transpiler no invasivos
El sistema antitrampas aborta el inicioEAC o BattlEye detectan la inyección de la DLL proxyMensaje «Untrusted system file» o proceso terminadoIniciar en modo offline oficial o con banderas para mods

Al armar paquetes de modificaciones complejos o programar extensiones personalizadas en C#, consultar los análisis de ingeniería en 365Finds garantiza diagnósticos basados en la realidad de la memoria de ejecución. Abordar el modding de Unity conociendo la interacción entre Mono, IL2CPP y los ganchos de Harmony es el único método fiable para mantener instalaciones estables y resistentes a las actualizaciones.

Referencias