Nebula Launcher is structured as four cooperating layers: a phone-friendly Android UI (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Nebula-Modmakers/Nebula-Launcher/llms.txt
Use this file to discover all available pages before exploring further.
dev.tates.nebula), a Java bootstrap orchestrator (dev.allofus.fusioncore), a C++ native runtime (libfusion.so), and a thin JNI bridge (libnebulahook.so). Together they prepare the device environment, patch the class loader and Unity player, boot the .NET CoreCLR runtime, and hand off to BepInEx so that IL2CPP plugins load inside Among Us without modifying the game APK.
Component Layers
Each layer has a clear responsibility and communicates with adjacent layers through defined interfaces.1 — Nebula UI Layer
Package:
This layer manages Nebula accounts (with automatic session refresh and a limited offline grace period), optional Among Us account linking for the supported online flow, per-profile plugin storage,
dev.tates.nebulaThe user-facing Android application. Key activities:| Activity | Purpose |
|---|---|
SelectorActivity | Main screen; shows the active profile and the Launch button |
ProfilesActivity | Creates, selects, and deletes mod profiles |
ModStoreActivity | Browse and install packages from the Nebula mod catalog |
FileBrowserActivity | Inspect Nebula and BepInEx files; light text editor for supported files |
SettingsActivity | Nebula account, Among Us account linking, verbose-launch toggle |
UpdatesActivity | Checks for Nebula launcher updates |
.npkg package download and installation through NpkgInstaller, and the in-game utility menu (triple-tap bottom-right edge).2 — FusionCore Bootstrap
Package:
dev.allofus.fusioncoreBootstrapActivity orchestrates the entire launch sequence on a background thread:- Verifies the installed Among Us package version against the required build (
2026.6.5, version code7045) - Copies Unity game data assets (
bin/Data) into private app storage - Detects the exact Unity engine version from the copied data
- Downloads and caches a matching
libunity.sowhen needed (falls back to the game’s own copy if the download fails) - Extracts and updates the bundled ARM64 .NET and BepInEx runtime ZIPs only when their SHA-256 fingerprint has changed
- Registers all game, FusionCore, and data native libraries with
NativeLibraryManager - Installs
ClassLoaderHooks,PackageManagerHooks, andUnityPlayerHooksto redirect library resolution and wrap the Unity player context - Hooks the launcher activity’s
onCreateviaNebulaHookto initialise FusionCore before Unity starts - Writes the active
FusionConfigtobootstrap/active.cfgviaFusionConfigStore - Starts the game’s launcher activity and finishes itself
FusionConfig carries all directory paths and the Unity version needed by the native layer. It is serialised to a key-value text file that the C++ runtime reads at init time.3 — Native FusionCore Library
Binary:
libfusion.so (ARM64, loaded via JNI)The core C++ runtime responsible for all low-level hooking and .NET hosting:fusion_stage_from_config_path— readsbootstrap/active.cfg, resolves library paths, hookslibunity.soloading, and patcheslibil2cpp.sowith an injected trampoline poolfusion_bootstrap_from_libmain— called fromlibmain’s JNI namespace; installs theil2cpp_inithook using Dobby via SafeHookil2cpp_init_hook— intercepts the IL2CPP domain initialisation call; sets allFUSION_*andBEPINEX_*environment variables; initialises .NET CoreCLR viacoreclr_initialize; creates a delegate toBepInEx.Unity.IL2CPP.FusionCoreEntrypoint.Startand invokes it- EOS hook — uses XDL to locate
EOS_Connect_Loginacross linker namespaces and rewrites placeholder credentials for the Android AuthFix token substitution flow
| Library | Role |
|---|---|
| Dobby | Inline (trampoline) function hooks for native code |
| LSPlant | ART method hooks for Java/Kotlin via libnebulahook.so |
| XDL | Dynamic linker symbol resolution across Android linker namespaces |
| .NET CoreCLR | Embedded managed runtime; hosts BepInEx and IL2CPP interop |
| BepInEx Fusion | BepInEx build targeting the FusionCore Android entry-point |
4 — NebulaHook JNI Bridge
Binary:
libnebulahook.soA thin C++ JNI library that initialises LSPlant against libart.so (resolved via XDL) and exposes two JNI methods to the Java layer:NebulaHook.nativeInitialize()— openslibart.sowith XDL and callslsplant::Initwith Dobby as the inline hookerNebulaHook.nativeHook(Member target, HookRecord record)— delegates tolsplant::Hookto install an ART method hook
NativeLibraryManager, UnityPlayerHooks, and BootstrapActivity go through this bridge. The NebulaHook.Callback interface provides beforeCall and afterCall intercept points, and CallFrame lets hooks read arguments, short-circuit the original call, set a return value, or invoke the original method explicitly.Launch Sequence
User taps Launch
The user selects a profile in
SelectorActivity and taps Launch. ProfileManager.stageActive() copies the active profile’s plugin DLLs from files/profiles/<name>/plugins/ into the shared FusionCore plugin directory, replacing whatever was there before.BootstrapActivity starts
SelectorActivity fires an Intent targeting BootstrapActivity with EXTRA_TARGET_PACKAGE = "com.innersloth.spacemafia". The bootstrap screen appears and a background thread begins runBootstrapFlow.Game version check and data preparation
BootstrapActivity verifies that the installed Among Us package matches version 2026.6.5 (version code 7045). It then copies Unity bin/Data assets to private storage and detects the Unity engine version from the copied data. If a matching libunity.so is not already cached, it is downloaded from the FusionCore CDN; if the download fails the game’s own copy is used instead.Runtime extraction
BepInEx-arm64.zip and dotnet-arm64.zip are extracted from the app’s bundled assets into the private data directory. Extraction is skipped when the SHA-256 fingerprint of the packaged ZIP matches the stored marker file, keeping the existing BepInEx.cfg intact across updates.Native library registration
Every
.so file in the game’s native library directory is registered with NativeLibraryManager. FusionCore’s own libraries (libmain.so, libfusion.so) and data libraries (libil2cpp.so, libunity.so) are registered separately. NativeLibraryManager.setupLibraryHooks then hooks the class loader’s findLibrary method via NebulaHook so that load requests for these names are redirected to the correct paths.Hook installation
Three hook groups are installed:
ClassLoaderHooks— patches the game’s class loader to make FusionCore classes visible inside the game processPackageManagerHooks— intercepts package-manager queries to normalise metadataUnityPlayerHooks— hooks everyUnityPlayerconstructor that accepts aContextargument; replaces theContextwith aCustomContextWrapperand restores the originalActivityreference in Unity’s fields after construction
Game process launched
BootstrapActivity hooks the game’s launcher activity onCreate with NebulaHook. When the hook fires (before Unity initialises), initializeFusion writes the FusionConfig to disk and libfusion.so is given a chance to stage its config via fusion_stage_from_config_path. The game activity starts, BootstrapActivity finishes, and a transparent overlay on the game window monitors BepInEx log output for progress.BepInEx boots and plugins load
Inside the game process,
fusion_bootstrap_from_libmain installs the il2cpp_init hook. When IL2CPP initialises its domain, the hook fires: environment variables are set, CoreCLR is started in the FusionHost AppDomain, and BepInEx.Unity.IL2CPP.FusionCoreEntrypoint.Start is invoked. BepInEx generates IL2CPP interop assemblies if needed (this takes up to several minutes on first run), then discovers and loads plugin DLLs from the staged BepInEx/plugins directory. The overlay disappears once Chainloader startup complete appears in BepInEx/LogOutput.log.Key Directories
The following paths are the most important on-device locations. Paths underfiles/ are inside Nebula’s private Android data sandbox; FusionCore/ is in shared external storage.
Private app data
Nebula’s internal storage, inaccessible to other apps without root.
| Path | Contents |
|---|---|
files/profiles/<name>/plugins/ | Per-profile plugin DLL storage |
files/profiles/<name>/.nebula/packages/ | Installation records for managed packages |
files/<package>/Data_copy/ | Copied Unity game data for the target package |
files/<package>/BepInEx/ | Extracted BepInEx ARM64 runtime |
files/<package>/dotnet/ | Extracted .NET CoreCLR ARM64 runtime |
files/<package>/<abi>/libunity.so | Cached Unity library for the detected Unity version |
files/bootstrap/active.cfg | Active FusionConfig key-value file read by libfusion.so |
Shared FusionCore data
Accessible to the file browser and shared between Nebula and the game process.
| Path | Contents |
|---|---|
FusionCore/com.innersloth.spacemafia/BepInEx/ | Shared BepInEx runtime and configuration |
FusionCore/com.innersloth.spacemafia/BepInEx/plugins/ | Active staged plugins (overwritten on each launch) |
FusionCore/com.innersloth.spacemafia/BepInEx/LogOutput.log | BepInEx runtime log for the most recent session |
FusionCore/com.innersloth.spacemafia/BepInEx/interop/ | Generated IL2CPP interop assemblies |
The shared
BepInEx/plugins/ directory is completely replaced each time a profile is staged. Changes made directly to that folder between launches will be lost. Manage your mods through Nebula’s profile system or the mod store.