Tag Archives: dynamic delivery

Improve Your Game with Texture Compression Format Targeting

Posted by Yafit Becher, Product Manager & Dan Galpin, Developer Advocate

Play Asset Delivery downloads the best supported texture for the device

Google Play Asset Delivery allows you to publish an Android App Bundle to Google Play containing all the resources your game needs. It offers multiple delivery modes, auto-updates, compression, and delta patching, all hosted at no cost to you.

As of today, you can use Google Play Asset Delivery to include textures in multiple texture compression formats in your Android App Bundle and Google Play will automatically deliver the assets with the best supported texture compression format for each device. With Texture Compression Format Targeting, you can start using ASTC for devices that support it while falling back to ETC2/ETC1 to devices that don’t. The Adaptive Scalable Texture Compression (ASTC) format offers advantages, such as improved rendering performance, faster load times, a smaller in-memory footprint, better battery life, and improved visual quality. You can even dramatically reduce your download size and on-device footprint by optimizing the tradeoff between size and quality.

Higher bandwidth version of much of this information

Android App Bundle will be the required publishing format for all new games and apps as of August 2021, which means that Google Play Asset Delivery will be required for new games that want Google Play to host more than 150MB of assets. Texture format targeting provides value even for smaller games due to the advantages of newer texture compression formats.

Texture compression

Texture compression is a form of lossy image compression that allows the GPU to render directly from the compressed texture using specialized silicon blocks, reducing the texture memory and memory bandwidth required to render the texture. As GPUs have gotten more advanced, more sophisticated texture compression formats have been developed, but not all GPUs can take advantage of them.

ASTC was released in 2012 to give developers more flexibility in trading compression size vs image quality. It compresses using fixed 128-bit block sizes, but allows for variable block footprints from 4x4 (8 bits per texel) to 12x12 (.89 bits per texel).

Texture compression format image  Texture compression format image Texture compression format image

Googleplex from Google Earth at 12x12 (.89 BPT), 6x5 (4.27 BPT), 4x4 (8 BPT)

This allows almost any type of texture to be used in compressed form, and allows for textures to occupy much less space in RAM — up to 36x less space compared to uncompressed 2D textures depending on quality. Smaller textures also take less time to load, making games start faster.

Memory bandwidth

Since the GPU needs to do fewer reads from texture memory in order to render the texture, the memory bandwidth required to render the scene is reduced, often substantially when texture caches are taken into account.

Texture compression formats in Android

The top compression formats in Android are ETC1, ETC2, and ASTC.

texture compression image

Top texture compression formats with device penetration as of September 2020

ETC1 is supported on practically all devices. It has no transparency support; games can use a second texture for the alpha component. It has quality issues with sharp transitions such as edges and text.

ETC2 is supported by all devices that support GLES3. It supports multiple transparency modes and improves quality compared to ETC1.

ASTC is a more recent format that's more flexible; it supports many different kinds of textures, allowing for just about any texture in your game to benefit from compression. In addition, it supports various block sizes with different associated compression ratios. Using this format is a good way to optimize the size, image quality, and performance of your game.

Asphalt Xtreme Gameloft image

When experimenting with ASTC on Asphalt Xtreme Gameloft found that they could reduce the size of their game by up to 30%

Using texture compression format targeting

Once you've implemented Google Play Asset Delivery in your game, adding texture format targeting is an incremental step. Inside your asset packs, make sure you have a directory that holds just your textures, such as [assetpackname]/textures. This directory will be used to hold default textures (probably in ETC1 or ETC2 format).

Then, create additional texture directories with a suffix representing the additional formats you wish to support.

[assetpackname]/textures#tcf_etc2
[assetpackname]/textures#tcf_astc

Finally, update your app build.gradle file to enable texture splits in asset packs:

// In the app build.gradle file:
android {
    ...
    bundle {
        texture {
            enableSplit true
        }
    }
}

Google Play strips off the texture suffixes so your game reads its assets from the default directory, regardless of what textures are delivered to the device.

If you're using Unity, our Play Asset Delivery plugin for Unity is ready to create app bundles with texture-targeted packs.

Texture compression format targeting is available now

We're committed to helping you serve your entire game through Play with customized dynamic delivery and features such as texture compression format targeting. Documentation at d.android.com will walk you through the integration process depending on the game engine you use, and we also have codelabs ready for both C/C++ and Unity games. We have more information on all of our game related developer resources at d.android.com/games and stay up to date with Google Play Asset Delivery and other game developer tools by signing up for the games quarterly newsletter.

Google Play Instant feature plugin deprecation

Posted by Miguel Montemayor and Diana García Ríos

As of Android Gradle plugin 3.4.0 (included in Android Studio 3.4), we are starting the deprecation process of the feature plugin (com.android.feature) and instant app plugin (com.android.instantapp) as a way to build your instant app. When building your app, you will receive a warning flagging com.android.feature as deprecated. If you have an existing instant app built with the feature plugin, migrate your existing app to an instant-enabled app bundle as soon as possible.

What is changing?

Last year, we introduced Android App Bundles—a new way to build and publish your Android apps. App bundles simplify delivering optimized APKs, including instant delivery, by unifying uploads into a single artifact. Google Play handles distribution by serving the correct APKs to your instant and installed app users—this is called Dynamic Delivery. To learn more about app bundles, visit the documentation site.

Dynamic Delivery is based on the idea of shipping dynamic features (com.android.dynamic-feature) to app users when they need them and only if they need them. There are currently three delivery types, based on the different values you will give the dist:module tag attributes on the dynamic feature module’s manifest file:

    <dist:module
       dist:instant="..."
       dist:onDemand="..."
       ...
    </dist:module>
dist:instant="false" dist:instant="true"
dist:onDemand="false" Dynamic feature delivered at install time Dynamic feature delivered instantly and at install time
dist:onDemand="true" Dynamic feature delivered on demand (beta) N/A

By migrating your instant app to an instant-enabled app bundle with dynamic features, you will be ready to leverage the full power of this new paradigm and you will be able to simplify your app’s modular design.

The migration

Previously, instant apps required creating a feature module that acted as the base module for your app. This base feature module contained the shared code and resources for both your instant and installed application. The rest of your codebase was comprised of:

  • multiple non-base feature modules, which contained the instant app entry points,
  • an application module, which contained the code and activities required only for your main installed application, and
  • an instant app module, which represented the instant app and mapped its dependencies.

With the new app bundle implementation, your base feature module takes the role as your app module (com.android.application), hosting the code and resources common to all features (instant and installed). You organize additional, modular features as one of three types of dynamic feature modules, based on when you want to deliver them to the user. The instant app module disappears, since the dist:instant attributes in the manifest are enough to identify which features will be included as part of the instant experience.

If you don’t have an instant experience added to your app and you’d like to create one, use Android Studio 3.3+ to create an instant-enabled app bundle.

The latest Android App Bundle updates including the additional languages API

Posted by Wojtek Kaliciński, Developer Advocate, Android

Last year, we launched Android App Bundles and Google Play's Dynamic Delivery to introduce modular development, reduce app size and streamline the release process. Since then, we've seen developers quickly adopt this new app model in over 60,000 production apps. We've been excited to see developers experience significant app size savings and reductions in the time needed to manage each release, and have documented these benefits in case studies with Duolingo and redBus.

Thank you to everyone who took the time to give us feedback on our initial launch. We're always open to new ideas, and today, we're happy to announce some new improvements based on your suggestions:

  • A new additional languages install API, which supports in-app language pickers
  • A streamlined publishing process for instant-enabled app bundles
  • A new enrollment option for app signing by Google Play
  • The ability to permanently uninstall dynamic feature modules that are included in your app's initial install


Additional languages API

When you adopt the Android App Bundle as the publishing format for your app, Google Play is able to optimize the installation by delivering only the language resources that match the device's system locales. If a user changes the system locale after the app is installed, Play automatically downloads the required resources.

Some developers choose to decouple the app's display language from the system locale by adding an in-app language switcher. With the latest release of the Play Core library (version 1.4.0), we're introducing a new additional languages API that makes it possible to build in-app language pickers while retaining the full benefits of smaller installs provided by using app bundles.

With the additional languages API, apps can now request the Play Store to install resources for a new language configuration on demand and immediately start using it.

Get a list of installed languages

The app can get a list of languages that are already installed using the SplitInstallManager#getInstalledLanguages() method.

val splitInstallManager = SplitInstallManagerFactory.create(context)
val langs: Set<String> = splitInstallManager.installedLanguages

Requesting additional languages

Requesting an additional language is similar to requesting an on demand module. You can do this by specifying a language in the request through SplitInstallRequest.Builder#addLanguage(java.util.Locale).

val installRequestBuilder = SplitInstallRequest.newBuilder()
installRequestBuilder.addLanguage(Locale.forLanguageTag("pl"))
splitInstallManager.startInstall(installRequestBuilder.build())

The app can also monitor install success with callbacks and monitor the download state with a listener, just like when requesting an on demand module.

Remember to handle the SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION state. Please note that there was an API change in a recent Play Core release, which means you should use the new SplitInstallManager#startConfirmationDialogForResult() together with Activity#onActivityResult(). The previous method of using SplitInstallSessionState#resolutionIntent() with startIntentSender() has been deprecated.

Check out the updated Play Core Library documentation for more information on how to access the newly installed language resources in your activity.

We've also updated our dynamic features sample on GitHub with the additional languages API, including how to store the user's language preference and apply it to your activities at startup.

Please note that while the additional languages API is now available to all developers, on demand modules are in a closed beta for the time being. You can experiment with on demand modules in your internal, open, and closed test tracks, while we work with our partners to make sure this feature is ready for production apps.

Instant-enabled App Bundle

In Android Studio 3.3, we introduced a way to build app bundles that contain both the regular, installed version of your app as well as a Google Play Instant experience for modules marked with the dist:instant="true" attribute in their AndroidManifest.xml:

<manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
    <dist:module dist:instant="true" />
    ...
</manifest>

Even though you could use a single project to generate the installed and instant versions of your app, up until now, developers were still required to use product flavors in order to build two separate app bundles and upload both to Play.

We're happy to announce that we have now removed this restriction. It's now possible to upload a single, unified app bundle artifact, containing modules enabled for the instant experience. This functionality is now available for everyone.

After you build an instant-enabled app bundle, upload it to any track on the Play Console, and you'll be able to select it when creating a new instant app release. This also means that the installed and instant versions of your app no longer need different version codes, which will simplify the release workflow.

Opt in to app signing by Google Play

You need to enable app signing by Google Play to publish your app using an Android App Bundle and automatically benefit from Dynamic Delivery optimizations. It is also a more secure way to manage your signing key, which we recommend to everyone, even if you want to keep publishing regular APKs for now.

Based on your feedback, we've revamped the sign-up flow for new apps to make it easier to initialize the key you want to use for signing your app.

Now developers can explicitly choose to upload their existing key without needing to upload a self-signed artifact first. You can also choose to start with a key generated by Google Play, so that the key used to locally sign your app bundle can become your upload key.

Read more about the new flow.

Permanent uninstallation of install time modules

We have now added the ability to permanently uninstall dynamic feature modules that are included in your app's initial install.

This is a behavior change, which means you can now call the existing SplitInstallManager#deferredUninstall() API on modules that set onDemand="false". The module will be permanently uninstalled, even when the app is updated.

This opens up new possibilities for developers to further reduce the installed app size. For example, you can now uninstall a heavy sign-up module or any other onboarding content once the user completes it. If the user navigates to a section of your app that has been uninstalled, you can reinstall it using the standard on demand modules install API.

We hope you enjoy these improvements and test them out in your apps. Continue to share your feedback as we work to make these features even more useful for you!

How useful did you find this blog post?