Skip to main content

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.

FusionCore is the shared Android runtime layer developed by All Of Us Mods that Nebula is built on. It is responsible for every step between the user tapping Launch and BepInEx loading plugin DLLs inside Among Us: preparing the Unity data environment, downloading or falling back to the game’s own libunity.so, extracting the bundled ARM64 .NET and BepInEx runtimes, redirecting native library loading, installing ART and inline hooks, and finally bootstrapping the managed .NET host that drives BepInEx. The Java layer (dev.allofus.fusioncore) communicates with the C++ layer (libfusion.so) through a serialised config file and a thin JNI bridge (libnebulahook.so).

BootstrapActivity

BootstrapActivity is the entry point to the FusionCore launch pipeline. It must be started from an Android Context with two intent extras; everything else is driven internally on a dedicated background thread.

Intent extras

EXTRA_TARGET_PACKAGE
String
required
The Android package name of the application to bootstrap. For Among Us this is "com.innersloth.spacemafia". The activity validates that the package is installed and, when the target is Among Us, that the version matches the required build before proceeding.
EXTRA_USE_ORIGINAL_LIBUNITY
boolean
When true, FusionCore skips the libunity.so download and uses the copy already bundled with the game. Defaults to false. The activity also forces this to true automatically if the Unity version cannot be detected or if the download fails.

Starting BootstrapActivity

Intent intent = new Intent(context, BootstrapActivity.class);
intent.putExtra(BootstrapActivity.EXTRA_TARGET_PACKAGE, "com.innersloth.spacemafia");
intent.putExtra(BootstrapActivity.EXTRA_USE_ORIGINAL_LIBUNITY, false);
context.startActivity(intent);

Internal launch flow

Once started, BootstrapActivity runs the following phases on a background thread, updating a status label and optional download progress bar as it goes:
  1. Version check — confirms the target package is installed and (for Among Us) that the version name and code match 2026.6.5 / 7045
  2. Copy assets — copies bin/Data from the game’s APK assets into files/<package>/Data_copy/
  3. Detect version — reads the Unity version from the copied data; applies any global-metadata.dat override found in the private data directory
  4. Download libunity — fetches and caches a matching libunity.so for the detected Unity version and device ABI; falls back to the game’s original if unavailable
  5. Extract runtime — unpacks BepInEx-arm64.zip and dotnet-arm64.zip from bundled assets into private storage, skipping extraction when the asset SHA-256 matches the stored marker; preserves any existing BepInEx.cfg
  6. Register libraries — enumerates the game’s native library directory and registers each .so with NativeLibraryManager; calls setupLibraryHooks to redirect findLibrary calls
  7. Install hooks — installs ClassLoaderHooks, PackageManagerHooks, and UnityPlayerHooks
  8. Hook launcher onCreate — hooks the game’s launcher Activity.onCreate via NebulaHook; the hook calls initializeFusion, which writes FusionConfig to disk and loads libfusion.so
  9. Launch — starts the game’s launcher activity and finishes itself; a transparent overlay on the game window monitors BepInEx/LogOutput.log for progress
BootstrapActivity forces the display into landscape orientation and hides system bars for the duration of the launch sequence. Do not attempt to use it as a general-purpose activity host.

FusionConfig

FusionConfig (dev.allofus.fusioncore.FusionConfig) is a plain data class that carries every directory path and flag the native runtime needs. An instance is constructed by BootstrapActivity.prepareFusionState and written to files/bootstrap/active.cfg by FusionConfigStore.write. The C++ layer reads that file with fusion_stage_from_config_path.

Fields

gameLibraryDirectory
String
required
The directory where the game’s native libraries are located (e.g. /data/app/<package>/lib/arm64). Resolved from ApplicationInfo.nativeLibraryDir of the game’s package context.
appLibraryDirectory
String
required
The directory where FusionCore’s own native libraries (libfusion.so, libmain.so) are located. Resolved from Nebula’s own ApplicationInfo.nativeLibraryDir.
appDataDirectory
String
required
The root of FusionCore’s per-package private data. Equals files/<targetPackage>/ inside Nebula’s files directory. The C++ runtime stores the EOS device token here and uses it as TMPDIR for MonoMod.
bepInExDirectory
String
required
The directory where BepInEx is installed (files/<package>/BepInEx/). Passed to the native layer as the FUSION_BEPINEX_PATH environment variable; BepInEx reads it on startup.
dotnetDirectory
String
required
The directory where the .NET CoreCLR runtime is installed (files/<package>/dotnet/). Used as the runtime base path for coreclr_initialize.
unityDataDirectory
String
required
The path to the copied Unity bin/Data assets (files/<package>/Data_copy/). Exposed to BepInEx as FUSION_GAME_DATA_DIR.
unityVersion
String
required
The Unity version string detected from the game data (e.g. "2022.3.20f1"). Falls back to "2017.0.0" if detection fails. Exposed as FUSION_UNITY_VERSION.
useOriginalLibUnity
boolean
When true, the native layer loads libunity.so from the game’s own native library directory instead of the FusionCore-provided copy. Defaults to false; automatically set to true if version detection or the CDN download fails.

Constructor

FusionConfig config = new FusionConfig(
    gameLibraryDirectory,   // String — game native lib dir
    appLibraryDirectory,    // String — FusionCore native lib dir
    appDataDirectory,       // String — FusionCore data dir
    bepInExDirectory,       // String — BepInEx install dir
    dotnetDirectory,        // String — .NET runtime dir
    unityDataDirectory,     // String — Unity Data_copy dir
    unityVersion,           // String — detected Unity version
    useOriginalLibUnity     // boolean
);

Serialised format

FusionConfigStore.write produces a UTF-8 key-value text file at files/bootstrap/active.cfg:
gameLibraryDirectory=/data/app/com.innersloth.spacemafia-.../lib/arm64
appLibraryDirectory=/data/app/dev.tates.nebula-.../lib/arm64
appDataDirectory=/data/user/0/dev.tates.nebula/files/com.innersloth.spacemafia
bepInExDirectory=/data/user/0/dev.tates.nebula/files/com.innersloth.spacemafia/BepInEx
dotnetDirectory=/data/user/0/dev.tates.nebula/files/com.innersloth.spacemafia/dotnet
unityDataDirectory=/data/user/0/dev.tates.nebula/files/com.innersloth.spacemafia/Data_copy
unityVersion=2022.3.20f1
useOriginalLibUnity=false
The C++ function fusion_stage_from_config_path reads this file. Both gameLibraryDirectory and appDataDirectory must be non-empty or staging aborts with an error.

C++ Exported API

The public surface of libfusion.so is declared in fusion/include/exports.h. All symbols are exported with C linkage and are callable from other native libraries loaded into the game process.
These functions are intended for use by mod code running inside the Among Us process after BepInEx has started. Call them only after FusionCore has been fully initialised. Calling hook or init_bridge_helper before fusion_bootstrap_from_libmain completes has undefined behaviour.

init_bridge_helper

void init_bridge_helper(const char *libraryPath);
Initialises the native bridge helper with the absolute path to the native library that is calling in. Must be called once before any other exported function from that library.
ParameterTypeDescription
libraryPathconst char *Absolute path to the calling library (e.g. the result of dladdr)

hook

dobby_dummy_func_t hook(void *address, dobby_dummy_func_t replace_delegate, bool specialReturnBuffer);
Installs a Dobby inline hook at address, replacing it with replace_delegate. Returns a pointer to a trampoline that calls the original function; store this and call it from inside replace_delegate to preserve the original behaviour.
ParameterTypeDescription
addressvoid *Address of the function to hook
replace_delegatedobby_dummy_func_tReplacement function with the same calling convention
specialReturnBufferboolSet to true when the function returns a struct by hidden pointer (required by some IL2CPP methods on ARM64)
Returns: Original function trampoline, or nullptr on failure.
// Install a hook on targetFuncPtr, keeping a reference to the original
dobby_dummy_func_t original = hook(targetFuncPtr, myReplacement, false);

// Inside myReplacement, call through to the original
void myReplacement(/* args */) {
    // pre-call logic
    ((original_fn_t)original)(/* args */);
    // post-call logic
}

unhook

void unhook(void *target);
Removes a previously installed Dobby hook from target and restores the original bytes.
ParameterTypeDescription
targetvoid *Address of the function that was passed to hook

create_alert

void create_alert(const char *title, const char *message);
Creates and displays an Android AlertDialog from native code using the JNI environment available to the FusionCore bridge. Useful for surfacing fatal errors from native mod code to the user.
ParameterTypeDescription
titleconst char *Dialog title text
messageconst char *Dialog body text

write_log

void write_log(const char *text);
Writes text to the FusionCore log at the default (INFO) level. Output appears in both Logcat (tag FusionCore) and BepInEx/LogOutput.log.
ParameterTypeDescription
textconst char *Log message

write_log_level

void write_log_level(int level, const char *text);
Writes text to the FusionCore log at the specified severity level.
ParameterTypeDescription
levelintSeverity level: 0 = DEBUG, 1 = INFO, 2 = WARN, 3 = ERROR
textconst char *Log message
write_log_level(3, "Critical failure in my native hook — aborting.");

Credits

Nebula is built on the following upstream projects from All Of Us Mods:

FusionCore

The core Android IL2CPP mod-loading runtime that Nebula uses as its foundation.

FusionCore.UnityDependencies

Provides the Unity-version-matched libunity.so binaries downloaded by the bootstrap.

Il2CppInteropFusion

Generates the IL2CPP interop assemblies that BepInEx plugins use to call game code.

BepInExFusion

A BepInEx build with the FusionCoreEntrypoint entry-point targeted by the C++ bootstrap.

AndroidUtilities

Shared Android utility code used across the FusionCore ecosystem.

Build docs developers (and LLMs) love