Unity Engine in Dynamic Feature Module – Here’s How We Did It!

One of the most significant challenges in mobile app development is optimising application size without compromising functionality and UX. In the case of My11Circle, we successfully reduced the app size from 63.8MB to 28MB by employing Dynamic Feature Modules (DFM) for our pre-bundled additional game, RummyCircle. However, this journey was far from straightforward, particularly due to the complexities associated with native shared object (.so) files and the Unity Engine, which does not officially support dynamic features.
This blog post outlines the challenges we faced, the solutions we implemented, and how we achieved this substantial size reduction.
📉THE IMPACT: 56% Decrease in App Size!
Google Play console download size trend over time

Before Optimization: 63.8MB (Single Base Module)
After Optimization: 28MB (Base) + ~35MB (Dynamic Feature)
Extracting Unity components for RummyCircle into a Dynamic Feature Module allowed us to significantly shrink the base APK size while maintaining all essential features for the primary game, My11Circle.
Business Impact 🚀
From a business perspective, every MB saved in app size directly boosts key acquisition metrics like CTL, CTI, and ITL. In this case, reducing the download size by approximately 37MB led to a significant improvement in acquisition, enhancing user engagement and conversion rates.
Dynamic Feature +Unity and Native Libraries
🤔 Why Isn’t This Simple?
At first glance, you might wonder: "What’s the big deal? Shouldn’t it be easy to create a Dynamic Feature and include the Unity engine in it?"
🚨 Well, NO! 🚨
Problem #1: Unity Does Not Officially Support Dynamic Features
A significant hurdle was the lack of official support for Dynamic Feature Modules from the Unity framework. Here is a link to a Unity forum discussion highlighting that there is no direct implementation for dynamic feature modules:
🔗UnityForum Discussion
This resulted in minimal official support, scarce online resources, and numerous dead-end StackOverflow inquiries from previous attempts by other developers. Consequently, we had to manually determine how to dynamically load .so files and assets required by Unity at runtime once the dynamic feature was installed.
Problem #2:Handling Native .SO Files in Dynamic Features

In typical use-case, UnityPlayer automatically loads the required .so
files during initialization, so developers don’t have to worry about it.

💥 But in our case, this didn’t work! (First major setback)
The culprit? Split APKs installation path.
When an Android app uses Dynamic Feature Modules containing native libraries, the Android framework splits the APKs during installation. This means:
- Native
.so
files are placed inside a separate ABI-specific split APK.

- Post Dynamic-Feature installation these files end up in the
/splitcompat
folder insidefilesDir
.

- UnityPlayer failed to locate and load them :error:
To address this, we had to manually extract and load these libraries at runtime after the dynamic feature module was installed.
❌ SplitInstallHelper was of No Help
Google suggests using SplitInstallHelper to automatically locate and load native libraries in dynamic features. However, in certain Android versions, it completely failed to locate the required.so files.
✅ Solution:
We had to brute force locate these files at runtime and manually load them using SoLoader to ensure stability across all devices.
❌ Inconsistent Installation Paths: BundleTool vs.Play Store Installation
Another major challenge was the difference in installation behaviour between:
- Localbuilds using
bundletool
- PlayStore console installation (Internal test track)
The installation path for the split APK (dynamic feature) differed significantly in both cases, leading to build failures when testing via the Play Store console.
✅ Solution:
Since the installed .so file path varied in both scenarios, we had to manually handle .so loading in both scenarios. We had to upload multiple builds on Play Store’s internal test track to ensure that fixes worked across different OS versions and OEMs.
Problem #3: Asset Loading Issue
Another significant issue was that Unity does not recognise the split APK path when loading assets from a dynamic feature. By default, Unity attempts to load assets from the base module, resulting in missing asset errors.
✅ Solution: Overriding getPackageCodePath()
in UnityActivity
After extensive research and debugging, we resolved this by overriding the getPackageCodePath()
method in UnityActivity
. This allowed us to dynamically provide the correct path to Unity, ensuring it accurately loaded assets from the dynamic feature module.
@Override
public String getPackageCodePath() {
if (isDynamicFeatureInstalled()) {
return getDynamicFeaturePath();
}
return super.getPackageCodePath();
}
Problem #4: Unity Engine Load Error
Another unexpected challenge was missing directories upon installation, which caused Unity to fail at runtime. Specifically, Unity would not load correctly unless certain directories were present and detected by the Unity engine.

While the Unity team has stated that they do not support dynamic features, we persevered and ultimately found a solution!

✅ Solution: Adding an Empty JSON File
Through logcat, we discovered that the Unity engine was unable to load the assets prepacked in Unity AAR. Upon inspecting the app installation folder on the device, we found that the required asset directory was missing.
After further investigation, we placed an empty.json
file inside the assets/bin/Data/Managed
directory of our base module. By adding this empty file, we prevented the directory from being deleted post-installation, ensuring the availability of Unity assets after the dynamic feature installation. This allowed the Unity engine to locate these assets and load them correctly.
🎯 The Final Outcome
By implementing Dynamic Feature Module, manually managing native libraries, and overriding Unity’s asset loading behavior, we successfully reduced the My11Circle app size from 63.8MB to 28MB . This resulted in:
✔️ A 56% reduction in app size (from 63.8MB→ 28MB)
✔️Improved acquisition & conversion rates
✔️Faster downloads & updates
✔️A seamless experience for both My11Circle & RummyCircle
💡 Key Takeaway: Unity and Dynamic Feature Modules aren't designed to work together—but with the right workarounds, massive app size reductions are possible!
🚀 Have you tried optimizing Unity apps for Android? We’d love to hear your experiences!
Explore More
Discover the latest insights from the world of Games24x7