Reducing build size of Android game in Unreal Engine 4

Unreal Engine 4 is considered to be a big, bulky engine that generates a lot of data and has huge build sizes. Such feature might be a serious issue when making a mobile game. Here are few steps to do at the beginning of Android development in UE4 to avoid problems with enormous build sizes.

At the beginning

For the purpose of this tutorial I was building a C++ version of the "Third Person Example" on the UE4.21.0 built from source. It supports armv7 architecture and OpenGL ES2 only. It uses textures in ETC2 format only.

I selected the "Package game data inside .apk" option (to be found in "Project Settings") to have only one file for size comparsions.

Most of the settings mentioned here are located somewhere in the "Project Settings".

An initial size of a development build was 104,0 MB.

Distribution builds

The initial size looks scary, doesn’t it? But don’t worry, we shouldn’t be bothered by the size of a Development build. Let’s build a Shipping version. The size of a shipping build is 86,6 MB which is much better. When the "For Distribution" option is enabled, thanks to ProGuard, it shrinks to 83,4 MB.

Disabling plugins

But still, this is too much. Next step is to remove everything we don’t need in our game and there are a lot of plugins which we probably don’t need. I’ve disabled all plugins except "Profile Selector", "Online Subsystem" and "Android Runtime Permission" which will probably be used in Android game. After disabling plugins the build size decreased to 70,3 MB.

Removing debug symbols

Debug symbols are stored inside the .so file of the game. They are priceless when we need to read crash logs that comes from the game, but they take a lot of space. To remove them – enable the "Build with hidden symbol visibility in shipping config" option. All symbols will be stored in a separate file which can be used to desymbolicate crash logs later. Without debug symbols the build size should be about 64,3 MB. This option requires the engine to be rebuilt (it requires engine’s source).

Removing and compressing assets

This is pretty much everything we can do to reduce the size of a binary file, but it appears there are a lot of unnecessary assets inside the build. First options to enable are "Exclude editor content when cooking" and "Create compressed cooked packages". With these options enabled, the build size drops to 37,8 MB.

Removing unused maps and assets

UE4 cooks and packs all maps and assets which are inside the Content directory. This might be an issue if there are old, unused assets which are not needed. To cook and pack only those assets that are somewhere referenced check "Cook only maps" option. This will force the engine to cook only maps and all of the assets that are referenced in those maps. If you want to specify which maps you want to cook - use the "List of maps to include in a packaged build".

Sharing Material Shader Code

The "Share Material Shader Code" option, when enabled, will reduce build size to 35,7 MB.

Removing even more assets

Even when the editor content is not cooked inside the .apk there are still a lot of unneeded files inside of it. To check which files are packed we need to find a .pak file inside the .apk and extract it. It should be located in the assets/main.obb.png package (it is in fact a zip file in disguise!). To extract the .pak file use the UnrealPak.exe application. It is located in the Engine/Binaries/Win64 directory. To use it call the following command:
UnrealPak.exe [path_to_pak_file].pak -extract [path_to_dir_to_extract]
As you can see there are a lot of files that are not needed. To exclude them from packaging create a PakBlacklist-Shipping.txt file inside YourGame/Build/Android directory. At this point this is a little "guess which file is not needed" game, but I’m sure that these files and directories can be removed:
../../../Engine/Content/ArtTools/
../../../Engine/Content/EngineSounds/
../../../Engine/Content/Maps/
../../../Engine/Content/SlateDebug/
../../../Engine/Content/Tutorial/
../../../Engine/Plugins/Runtime/LeapMotionController/
../../../Engine/Content/EditorMeshes/ColorCalibrator/
../../../Engine/Content/Slate/MessageLog/
../../../Engine/Content/Slate/Old/
../../../Engine/Content/Slate/Testing/
../../../Engine/Content/Slate/Tutorials/
../../../Engine/Content/Slate/CrashTracker/
../../../Engine/Content/Slate/Docking/
../../../Engine/Content/Slate/Icons/
../../../Engine/Content/Slate/Fonts/DroidSansFallback.ttf
../../../Engine/Content/Slate/Fonts/DroidSansMono.ttf
../../../Engine/Content/Slate/Fonts/LastResort.ttf
../../../Engine/Content/Slate/Fonts/NanumGothic.ttf
../../../[YourGame]/AssetRegistry.bin
After content blacklisting we should reach the build size of 32,4 MB.

Disabling engine modules

At this point it will be more and more difficult to reduce the size of a build and these reductions will not come without a sacrafice of some features. This will also work only if you are using engine built from source. You can exclude some of the engine features from the binary file. To do this, create a Config/Android/AndroidEngine.ini file and type the following configuration:
[/Script/BuildSettings.BuildSettings]
bCompileAPEX=False
bCompileBox2D=False
bCompileICU=False
bCompileSimplygon=False
bCompileLeanAndMeanUE=True
bIncludeADO=False
bCompileRecast=False
bCompileSpeedTree=False
bCompilePhysXVehicle=False
bCompileForSize=True
bCompileCEF3=False
With such build settings the final build size goes down to 31,2 MB.

Disabling Movable Point Lights

If your game doesn’t need movable point lights set the "Max Movable Point Lights" value 0. This will reduce the size of shaders and, in the end, the size of a build, which at this point should be about 29.8MB.

Summary

At this point we can be almosure that we’ve reached the minimum size of the build possible. There still might be some assets that can be blacklisted or engine modules to be disabled, but this depends on the project.

We went from 86,6 MB of the Shipping build to the 29,8 MB of a trimmed build ready for distribution.

Someone might say that it is still quite a lot for a mobile game, but once again – this is big 3D Game Engine we’re talking about.

I hope that in the next UE4 versions getting small build sizes for Android games will be much easier and more effective than now, but currently we have to set the project properly by ourselves. Good luck and happy developing!