Delivering Assets
to Your Mobile Game
https://ari.games
Ari Arnbjörnsson
Note
These slides are from 2018, so they’re missing some newer info like Android’s App Bundles (AAB), Play Asset Delivery (PAD), and Play Feature Delivery, which have replaced the legacy OBB files.
Other than that most points still stand. Reading these slides and the above resources should bring you up to speed.
Types of Asset Delivery
Games with small amount of updateable assets.
Don’t need complicated asset delivery strategy.
Types of Asset Delivery
Games with many ad-hoc updateable assets.
More complexity, need some strategy.
Types of Asset Delivery
Games with many/large updateable assets needed for gameplay.
Need a solid asset delivery strategy.
What this talk is about.
Benefits of Dynamic Asset Delivery
Deliver updates to users immediately by skipping app-store updates.
App store submission reviews can take up to a few days.
Benefits of Dynamic Asset Delivery
Deliver updates to users immediately by skipping app-store updates.
Users might not have automatic updates enabled.
Automatic updates happen when convenient for the device, not your app.
Benefits of Dynamic Asset Delivery
Be sure the user always has the most up-to-date assets and configs.
Essential for online/multiplayer games.
Make Your Assets Dynamically Loaded
Support downloading assets instead of statically linking them.
Usually done via code.
Give each asset an ID and store it in a text file.
Make Your Assets Dynamically Loaded
The Master List
Contains all asset IDs, their hash and where to download them from.
Packaging Your Assets for Delivery
Different methods suit different projects.
Let’s look at
Packaging Your Assets for Delivery
Per File
Packaging Your Assets for Delivery
Per File
Packaging Your Assets for Delivery
Bundled by Category
Packaging Your Assets for Delivery
Bundled by Category
Packaging Your Assets for Delivery
Bundled by Update
Packaging Your Assets for Delivery
Bundled by Update
Compressing Bundles
Different methods suit different projects.
Compressing Bundles
Compress for size (zip, lzma)
Better compression with a speed disadvantage.
Compressing Bundles
Compress for read speed (LZ4, LZO)
Less compression with amazing read speeds.
Compressing Bundles
Using the best of both worlds.
Compress bundles with high compression to deliver from your server.
As the client downloads the bundle, re-compress it on device to high read-speed format.
Cache that version of the bundle on the user’s device.
When to Download What?
Client needs to sync with server.
Check according to the Master List from the server.
Only download the Master List when it changes.
No need to calculate asset hashes on the client, trust the server.
Saving Cached Assets - iOS
Save all downloaded assets to Library/Caches/
iOS may delete them if the system is running out of storage space.
Saving Cached Assets - iOS
Other custom subfolders within Library/ also work.
MUST be excluded from backups via NSURLIsExcludedFromBackupKey flag.
Saving Cached Assets - iOS
Don’t use the Documents/ folder.
It’s only for user data and gets backed up.
Saving Cached Assets - iOS
Don’t use the tmp/ folder.
Not for persisting files.
Saving Cached Assets - Android
You ‘should’ use cache/ as reported by getCacheDir(), but don’t!
Gets cleared between every app run for some users.
Apps, Android flavors and users can clear it pretty aggressively.
(NOTE: This was true in 2018, might have changed since then)
Saving Cached Assets - Android
Use files/ directory as reported by getFilesDir().
Doesn’t get cleared by OS or user unless uninstalled.
Initial Download Experience
Downloading content 11.6/120 MB (13 mins left)
Initial Download Experience
The first session is the most important.
Users don’t mind the store download times. They DO mind your in-game download times.
Initial Download Experience
Fix: Include current version of all assets/bundles with the store binary.
OS handles wifi-only downloading.
OS downloads the game and its assets before the game is even opened.
Bonus: less hosting bandwidth cost.
Initial Download Experience
Fix: Include current version of all assets/bundles with the store binary.
Q: Doesn’t that invalidate the whole point of dynamic asset delivery?
A: No, the point is to be able to deliver/update any asset.
Include Assets/Bundles - iOS
Simply ship your assets/bundles in your .ipa file.
Your engine might handle this for you with special directories (eg Unity: “StreamingAssets”)
For Xcode simply add the assets/bundles to the project.
Include Assets/Bundles - iOS
Simply ship your assets/bundles in your .ipa file.
.ipa files are already compressed, no need to add extra compression.
.ipa files get extracted during app installation.
Max iOS app size is 4GB (before .ipa compression)
Include Assets/Bundles - Android Google Play Store
You can ship files in your .apk*
.apk files don’t get extracted, all assets reside inside the .apk file on device.
Make sure your assets/bundles aren’t stored compressed in the .apk file by using the -0 parameter for aapt.
Include Assets/Bundles - Android Google Play Store
You can ship files in your .apk*
Your engine might handle this for you with special directories (eg Unity: “StreamingAssets”)
For Android Studio projects use res/raw/ or assets/ folders.
*Play Store .apk size limit is a hard 100MB. If you need more space you’ll need to use expansion files.
Android Expansion Files
Two .obb files (main and patch) that you can upload with your .apk.
Max 2GB each.
Formatless, can be whatever you want.
Can be encrypted with Android’s JOBB tool.
Downloads with the .apk seamlessly.
Android Expansion Files
Won’t be re-downloaded during update if nothing changed.
Put rarely changing stuff into the main file, updates into the patch file.
Android Expansion Files
Might be missing on game launch.
Saved on shared/external storage, so users can remove or delete them.
Google Play might be unable to download them in some scenarios.
Android Expansion Files
Your game must take into account that they might be missing.
Download them in-game from the Play Store.
Android Expansion Files
Use Google Play's Application Licensing service to request a download URL.
The URL expires shortly.
Can only be generated for apps downloaded from Google Play.
Android Expansion Files
Might not be readable.
Need READ_EXTERNAL_STORAGE permission before Android 4.4 (API level 19).
Some implementations of Android 6.0 (API level 23) also need read permission due to a bug.
Android Expansion Files
Might not be readable.
Ask for READ_EXTERNAL_STORAGE permission if the file exists but you can’t read it.
User can dismiss all future requests for a permission after two dialogs.
If the user declines, simply re-download them.
Include Assets/Bundles - Android Amazon Appstore
Amazon Appstore doesn’t have an .apk size limit.
[NOTE: It seems to have a 2.5GB Size limit in ‘24]
Recommends 100MB or less.
Doesn’t deliver expansion files.
Files bigger than 150MB need to be delivered via sftp.
Include Assets/Bundles - Android Amazon Appstore
Just include the assets in the .apk file.
Or even the expansion files, for code reuse.
Remember to disable zip compression for those files.
Putting Everything Together
THANKS!
Any questions?
https://ari.games
Presentation template�by SlidesCarnival