Dalam ekosistem modifikasi dan reverse engineering game berbasis Unity Engine, transisi dari arsitektur Mono ke IL2CPP (Intermediate Language to C++) menghadirkan paradigma baru. Artikel ini membahas secara mendalam bagaimana membangun plugin pertama Anda menggunakan BepInEx 6 (IL2CPP), bahasa C#, dan pustaka HarmonyX.
1. Memahami Perbedaan Mono vs IL2CPP
Sebelum menulis kode, penting untuk memahami apa yang terjadi di balik layar saat game Unity dikompilasi:
Unity Mono
Kode C# dikompilasi menjadi IL (Intermediate Language) standar di dalam berkas Assembly-CSharp.dll. Mudah didekompilasi menggunakan perkakas seperti dnSpy atau ILSpy.
Unity IL2CPP
Kode IL diubah menjadi C++ native kemudian dikompilasi menjadi binary mesin (GameAssembly.dll) bersama metadata (global-metadata.dat). Membutuhkan interop unhollower untuk merekonstruksi kelas C#.
2. Persiapan Lingkungan Pengembangan
Pastikan Anda telah memasang perkakas berikut pada komputer Anda:
- .NET 6.0 SDK atau yang lebih baru: Diperlukan untuk membangun pustaka kelas C# (Class Library).
- IDE: Visual Studio 2022, JetBrains Rider, atau Visual Studio Code dengan ekstensi C# Dev Kit.
- Game Target: Game Unity berbasis 64-bit IL2CPP.
- BepInEx 6.x IL2CPP Bleeding Edge (BE) build yang sesuai dengan arsitektur game (x64 / x86).
3. Instalasi BepInEx 6 ke Direktori Game
Lakukan langkah-langkah berikut untuk memasang BepInEx ke dalam target game Anda:
- Unduh arsip rilis BepInEx 6 IL2CPP (contoh:
BepInEx-Unity.IL2CPP-win-x64).
- Ekstrak seluruh isi berkas zip langsung ke dalam folder utama game (tempat berkas
Game.exe dan GameAssembly.dll berada).
- Jalankan game sekali hingga muncul menu utama, kemudian tutup game.
-
Pada tahap ini, BepInEx akan menjalankan Il2CppInterop untuk menghasilkan rakitan C# unhollowed di dalam folder
BepInEx/interop/.
4. Membuat Proyek Plugin C#
Buka terminal Anda dan buat proyek Class Library baru menggunakan .NET CLI:
dotnet new classlib -n MyFirstIl2CppPlugin -f net6.0
Buka berkas MyFirstIl2CppPlugin.csproj dan konfigurasikan referensi paket NuGet BepInEx 6:
net6.0
enable
true
5. Menulis Kode Utama Plugin
Di dalam BepInEx 6 IL2CPP, kelas utama plugin harus mewarisi BasePlugin dan menggunakan atribut [BepInPlugin]. Buat berkas Plugin.cs:
using BepInEx;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using UnityEngine;
namespace MyFirstIl2CppPlugin
{
[BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)]
public class Plugin : BasePlugin
{
public const string PLUGIN_GUID = "com.unreliablecode.firstil2cpp";
public const string PLUGIN_NAME = "My First IL2CPP Mod";
public const string PLUGIN_VERSION = "1.0.0";
public override void Load()
{
// Log output ke konsol BepInEx
Log.LogInfo($"Plugin {PLUGIN_NAME} berhasil dimuat!");
// Menerapkan semua patch Harmony yang dideklarasikan
var harmony = new Harmony(PLUGIN_GUID);
harmony.PatchAll();
Log.LogInfo("Harmony patches berhasil diaplikasikan.");
}
}
}
6. Melakukan Hooking Method Game dengan HarmonyX
Harmony memungkinkan kita untuk mencegat, memodifikasi parameter, dan mengubah perilaku fungsi internal game tanpa perlu mengubah binary asli.
using HarmonyLib;
using UnityEngine;
namespace MyFirstIl2CppPlugin.Patches
{
// Contoh melakukan patch pada method TakeDamage di kelas PlayerController
[HarmonyPatch(typeof(PlayerController), nameof(PlayerController.TakeDamage))]
public static class PlayerDamagePatch
{
// Prefix dijalankan SEBELUM method asli dieksekusi
[HarmonyPrefix]
public static bool Prefix(ref float damageAmount)
{
// Modifikasi nilai damage: God Mode (0 damage)
damageAmount = 0f;
// Return true agar method asli tetap berjalan dengan nilai baru
// Return false jika ingin membatalkan eksekusi method asli sepenuhnya
return true;
}
// Postfix dijalankan SETELAH method asli selesai
[HarmonyPostfix]
public static void Postfix(PlayerController __instance)
{
// Mengakses instance komponen game
Debug.Log($"[Mod] Status Pemain: {__instance.name} menerima damage.");
}
}
}
7. Kompilasi dan Pemasangan Plugin
Untuk mengompilasi plugin menjadi berkas binary .dll:
dotnet build -c Release
Ambil berkas MyFirstIl2CppPlugin.dll dari folder bin/Release/net6.0/, lalu letakkan di dalam folder BepInEx/plugins/ pada direktori game Anda.
8. Praktik Terbaik & Penanganan Masalah IL2CPP
- Hindari Menggunakan Reflection Berat di Dalam Update Loop: Panggil cache MethodInfo di luar loop utama untuk menjaga FPS tetap stabil.
- Gunakan Il2CppInterop Types: Jangan tertukar antara tipe dasar sistem (
System.String) dengan representasi interop saat berinteraksi dengan API internal C++.
- Periksa Console Log: Aktifkan konfigurasi
[Logging.Console] Enabled = true di BepInEx/config/BepInEx.cfg untuk mempermudah pelacakan error secara realtime.
Ringkasan
Dengan BepInEx 6 dan HarmonyX, modifikasi game Unity IL2CPP kini dapat dilakukan secara elegan melalui C# tingkat tinggi tanpa harus menyentuh instruksi assembly x86/ARM secara manual.
Discussion (0)