Although your core game logic in Unreal Engine is written in C++ or Blueprints,
Android packaging compiles Java and Kotlin bytecode (classes.dex) to handle
GameActivity lifecycle events, Google Play services, billing, audio, and
analytics plugins.
R8, the default code shrinker and optimizer in the Android Gradle Plugin
(AGP), removes unused classes and methods and optimizes bytecode. This not only
decreases your package download size, but also reduces the runtime memory
footprint of memory-mapped (mmap) DEX pages and baseline Java process
overhead, mitigating physical memory pressure and low memory killer (LMK)
terminations. Google Play also monitors your game's DEX optimization levels
through the DEX code optimization metric in Android vitals.
Default behavior and Unreal Engine version support
Starting in UE 4.22.0, Unreal Engine's UEDeployAndroid.cs injects
minifyEnabled true into the generated Android Release build configuration
(buildAdditions.gradle) by default. Because UE 4.25 upgraded the bundled
toolchain to AGP 4.0.0, R8 is enabled by default (true) on all Release
(Shipping and Distribution) builds in UE 4.25 and higher without additional
setup.
| Unreal Engine version | Bundled AGP | Release default | Debug default | Behavior |
|---|---|---|---|---|
| UE 4.21 and earlier | Legacy Gradle or Ant | Disabled (false) |
Disabled (false) |
No minifyEnabled configuration injected by the engine. |
| UE 4.22 to 4.24 | Earlier than 3.4 | Enabled (ProGuard) | Disabled (false) |
minifyEnabled true enabled by default in Release builds (runs ProGuard). |
| UE 4.25 to 5.3 | 4.0.0 | Enabled (R8) | Disabled (false) |
AGP 4.0 adoption runs R8 by default in Release builds. |
| UE 5.4 to 5.7 | 7.4.2 | Enabled (R8) | Disabled (false) |
AGP 7.x removes legacy useProguard options; R8 runs exclusively. |
| UE 5.8 (5.8.3+) | 8.13.0 | Enabled (R8) | Disabled (false) |
Uses AGP 8.x and modern R8 optimization pipelines by default. |
Release and Debug build differences
UnrealBuildTool (UEDeployAndroid.cs) configures the generated
buildAdditions.gradle file differently for Release and Debug builds:
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
signingConfig signingConfigs.debug
}
}
- Release (Shipping or Distribution): Sets
minifyEnabled trueand appliesproguard-rules.proby default, running R8 code shrinking and obfuscation. - Debug (Development): Enables
debuggable trueand omitsminifyEnabled(defaulting tofalse) to preserve fast build iteration and symbol debugging.
Add keep rules using Unreal Plugin Language (UPL)
Because R8 runs automatically on Release builds in UE 4.25 and higher, you must
preserve Java classes reached only through C++ JNI (JNIEnv->FindClass,
GetMethodID) or the manifest. Classes without Java call sites are treated as
unused and stripped by R8, which can cause features that work in Development
builds to fail with ClassNotFoundException or NoSuchMethodError in Shipping
builds.
Use the <proguardAdditions> tag in an Unreal Plugin Language
(UPL) XML file to merge custom keep rules into
proguard-rules.pro during packaging. Add the following block to your project
or plugin *_UPL.xml file:
<root xmlns:android="http://schemas.android.com/apk/res/android">
<proguardAdditions>
<insert>
-keep class com.epicgames.unreal.** { *; }
-keep class com.example.plugin.** { public *; }
-dontwarn com.example.plugin.**
</insert>
</proguardAdditions>
</root>
Troubleshoot common issues
This section describes how to resolve common packaging and runtime issues when using R8 in Unreal Engine.
Temporarily disable R8 for debugging
To isolate whether a Release-only crash is caused by R8 stripping required
classes, insert DISABLE_MINIFY=1 under <gradleProperties> in your UPL file.
When present, UEDeployAndroid.cs generates minifyEnabled false:
<gradleProperties>
<insert>
DISABLE_MINIFY=1
</insert>
</gradleProperties>
Missing classes detected while running R8 packaging errors
In UE 5.4 and higher (AGP 7.4.2+), R8 enforces strict missing-class checks. If
packaging fails with this error, inspect missing_rules.txt in your
intermediate build directory (under
Intermediate/Android/.../gradle/app/build/outputs/mapping/release/missing_rules.txt)
and add the missing library dependencies or required rules to
<proguardAdditions> in your UPL file.
R8 full mode compatibility with third-party SDKs
In UE 5.8 and higher (AGP 8.13.0+), R8 full mode is enabled by default to perform more aggressive optimizations. If a legacy third-party Android SDK fails at runtime due to reflection issues, update the plugin's ProGuard rules or revert R8 to compatibility mode by adding the following property to your UPL file:
<gradleProperties>
<insert>
android.enableR8.fullMode=false
</insert>
</gradleProperties>