-
Notifications
You must be signed in to change notification settings - Fork 2
Porting Guide
xAstroBoy edited this page Mar 20, 2026
·
1 revision
This guide covers how to adapt Quest UE4 Modloader for other Unreal Engine 4 games on Meta Quest.
- Reflection system — UE4's reflection is consistent across all UE4 titles
- ProcessEvent hooking — same virtual function table layout
-
Lua API —
Get/Set/Call/FindFirstOfetc. are game-agnostic - sol2/Lua 5.4 — scripting runtime
- Dobby ARM64 hooking — instruction-level hooks work on any ARM64 binary
- Timer system — all timer functions
- File I/O / ModConfig — filesystem operations
- TArray / TMap / FName / FString / FText — UE4 core types
| Component | What to Change |
|---|---|
| Symbol addresses | Different games have different binaries |
| Package name |
com.Armature.VR4 → your game's package |
| Library name | The main game .so to inject into |
| GUObjectArray offset | Found via pattern scan or analysis |
| FName::Init | Symbol or pattern for FName construction |
| ProcessEvent | Virtual function index (usually consistent) |
| Mod scripts | Hooks reference game-specific classes |
| PAK files | Game-specific content mods |
- Install the game on your Quest
- Find the package name:
adb shell pm list packages | grep <keyword> - Find the game library:
adb shell ls /data/app/<package>/lib/arm64/ - The main library is usually
libUE4.soor similar
In src/core/paths.cpp, update:
// Package name for the target game
static const char* PACKAGE_NAME = "com.your.game";
// Mod directory on device
static const char* MOD_DIR = "/sdcard/UE4Mods/";In tools/deploy.py, update:
PACKAGE = "com.your.game"The modloader needs these key symbols/addresses:
| Symbol | Purpose | How to Find |
|---|---|---|
GUObjectArray |
Object iteration | Pattern scan or Ghidra/IDA |
FName::Init |
FName construction |
dlsym or pattern |
ProcessEvent |
Function hooks | VTable offset (usually index 68) |
StaticFindObject |
Object lookup |
dlsym or pattern |
GWorld |
World context | Pattern scan |
The modloader uses a resolution chain: dlsym → ELF phdr scan → pattern scan → fallback.
Update patterns in src/core/symbols.cpp for your target binary.
Once the modloader boots and can access GUObjectArray:
python tools/deploy.py console
> exec_lua DumpSDK()
> exit
python tools/deploy.py sdk # Pull generated SDKThis creates class/struct/enum dumps for the target game.
With the SDK dump, you can see all classes and their properties/functions. Write mods using the standard Lua API:
-- Example: Find game-specific class
local player = FindFirstOf("YourGamePlayerCharacter")
if player and player:IsValid() then
-- Use SDK to know property names
local health = player:Get("Health")
Log("Health: " .. tostring(health))
endEdit tools/deploy.py to match your game:
- Package name
- Device IP (if different)
- Mod directory paths
- Launch activity name
- Start with logging — Get the modloader to boot and produce logs first
- Dump the SDK early — The class dump tells you everything about the game
-
Use the bridge —
exec_lualets you explore interactively -
Pattern scan — If symbols are stripped, use
FindPatternfor key functions - Check UE4 version — The modloader targets UE4.25; other versions may have different struct layouts
- VTable indices — ProcessEvent's VTable index may differ between UE4 versions
| UE4 Version | Status | Notes |
|---|---|---|
| 4.25 | ✅ Tested | RE4 VR |
| 4.26-4.27 | 🔄 Should work | Minor offset differences possible |
| 5.x | Significant struct layout changes likely |
If you successfully port to a new game, please consider:
- Opening a PR with your changes
- Documenting game-specific symbols/patterns
- Sharing your SDK dump (if the game allows it)
- Adding the game to the supported games table
This helps the community and makes the modloader truly universal!