Hi, I’m Dan Galpin, and I’ve spent the past 11 years
working with the Android team and with many of you to help bring
great gameplay experiences to Android users,
starting on the ground floor of a revolution into how people play games
and fit games into the fabric of their lives.
Android users have many device choices from our hardware partners
with a range of sizes and capabilities,
and we’ve been working hard to help you make
your game available to as many of these devices as possible,
while streamlining your game development.
Let’s begin with what we’re doing to streamline your development.
Most Android APIs are designed to be called from managed code
in languages like Kotlin,
while game engines are primarily written in C and C++.
And this is why we support simultaneous debugging of your C and C++ code
along with your managed code at Android Studio,
allowing you to set breakpoints on both the managed code, like Kotlin,
and the C side to help you follow code between both programming environments.
You can even step between managed code and native code.
Android Studio speeds up your editing with code completion,
and can write JNI function prototypes
to help you efficiently work in both environments.
We support composite build trees using Cmake and Gradle to
help you leverage portable builds.
And for those of you that spend your time developing
cross-platform games in C or C++ on Microsoft Windows and Visual Studio,
we further streamline your development with the Android Game Development Extension,
or AGDE, part of the Android game development kit we launched this July,
empowering you to reliably build directly for Android
within your existing Visual Studio environment with support
for C and C++ debugging and performance tooling,
so you can work with your desktop, console,
and Android targets without having to move to a different toolset and build system.
And it's easy to configure.
After installing the extension, head over to your Visual Studio project
and add the Android APK template.
A toolbar will provide quick access to critical Android tools,
such as the SDK and NDK manager, the Virtual Device Manager
for the emulator, the Device File Manager, Logcat, and Profilers.
AGDE integrates with multiple build systems and your Unreal Engine workflow,
effectively allowing you to use the same tools to build and debug for
desktop, console and Android
And most importantly, once the project is set up with an Android target,
Android development works like any other Visual Studio target platform.
You can build, deploy, and debug.
With debugging, you can set breakpoints, step into disassemblies,
look at registers and view values within memory blocks,
and view concurrency through parallel stacks.
And of course, you get access to a searchable, filtered Logcat.
AGDE also provides quick access to standalone versions of
the CPU and memory profilers from Android Studio.
We’ve recently enhanced these tools with a new UI
and support for native memory sampling.
The combination of Android Studio and the Android Game Development Extension
gives you a rich set of tools to streamline your game development.
Now, having tooling is a great start, but it still takes work to integrate
with Android’s managed code APIs.
So to help out, we launched new C and C++ libraries as part of AGDK,
the Android Game Development Kit.
GameActivity is almost a drop-in replacement for
the Android platform native activity.
It integrates smoothly with our Android Jetpack libraries
and the broader Android UI toolkit, allowing you to write
your game loop completely in C or C++, while easing
the integration of libraries built on Android Jetpack.
Because GameActivity renders into a surface view, you can easily mix Android UI elements,
such as WebView, MapView, and views required by
ads, SDKs, and other services.
The only managed code you need to run your game loop is
a single class with a line of code to load your C or C++ game library.
This metadata in the activity tag in your Android manifests
lets GameActivity know which library to start your game loop from.
GameActivity gives you native callbacks that match Android
lifecycle events, but make it easier to integrate with a typical game loop.
We provide a small, static native_app_glue library offering a different execution model.
In this case, android_main() gets called in a
new, distinct thread from the activities main thread.
You can get the lifecycle events from an ALooper
that’s associated with the thread.
And you can also use that same ALooper to listen to FDs.
Once you’ve implemented GameActivity, you can then choose
to render to your surface using OpenGL/ES or Vulkan.
Regardless of which API you choose, the Android Frame Pacing library
will help you have smoother rendering by
synchronizing your game’s logic and rendering loop with
Android’s display subsystem and the underlying display hardware.
Of course, great games need great audio, and the Oboe audio library
provides a single C++ API that works in Android 4.1 and higher.
Oboe helps your game achieve the lowest possible audio latency
for a given device and Android version combination
by using AAudio on devices running API level 27
For devices running lower versions, Oboe uses OpenSL ES.
Oboe also includes workarounds for some known audio issues,
while adding new features, such as resampling, format conversions,
and performance-based channel-count conversions.
We also provide two libraries that interoperate with Game Activity
to handle soft-keyboard and game controller input.
GameTextInput does most of the hard work to hook up
an Android soft input method to your in-game text editor,
including showing and hiding soft keyboards.
If you use the library with GameActivity, with or without native_app_glue,
much of the setup work is done for you.
The library notifies you of input state changes so your editor
can properly reflect the IME state.
The Game Controller Input library helps your game
take advantage of physical game controllers.
It notifies you when controllers are connected and disconnected,
giving you information about the
button layout, axes, and other key controller metadata.
It does much of the heavy lifting to normalize how controllers respond
in Android to make it easy for your game to work seamlessly
with the most popular controllers, and it even supports mouse input.
Supporting controller, mouse, and keyboard input is one way
for your game to reach more screens, but reaching the most
screens means thinking outside the little glass and metal box.
How about TV?
If your game can work with basic D-pad input and operate in landscape mode,
it can reach many TV devices.
You’ll need to make sure to declare that your game doesn’t
require a bunch of unsupported, but usually standard, Android hardware features
first in your AndroidManifest file, like touchscreen, camera,
and sensors like accelerometer.
You can also let the TV platform know that your game supports
a gamepad controller by including the following entry in your Android manifest.
Check for a game controller at startup
when running on TV, if you require it.
Chrome OS is now the number two desktop operating system
with a growing community of game players,
and it runs Android games and has the Play Store.
Chrome OS devices work best with titles that can support rendering and landscape.
While many Chrome OS devices have touch screens, and ones without touch will emulate
touch with a mouse or trackpad,
directly supporting mouse and keyboard input can improve the experience.
You can capture the mouse or trackpad cursor for
precise controls on API level 26 and above.
Of course, you’ll want to do the work to take advantage of
the physically larger screens on tablets, foldables, and Chromebooks.
Ideally, you want touch elements that your user interacts with
to be a relatively constant physical size across the different screen sizes and
densities, particularly the size of virtual controls.
You can get the display metrics for the current display,
and then get the density and pixels per inch
for the x- and y-axes for precise scaling.
You can also get an approximate scale factor using
dm.density and dm.scaledDensity, where 1.0 is 160 DPI.
ScaleDensity is used to help Android apps scale fonts
according to user preference,
and if your game uses it, your users will thank you.
Now, you might have a maximum density
that you want to target for performance reasons.
Android will automatically, and inexpensively, scale your surface for you,
if you like, using surfaceHolder.setFixedSize,
allowing you to use less RAM and shade fewer pixels, which also uses less
battery and produces less heat.
You can also scale automatically from C and C++ code.
In either case, you’ll also have t adjust touch events to
match your new surface, since they’ll still be in screen coordinates.
Game engines can also scale rendering to improve performance.
Unity can scale the backbuffer several ways.
The easiest is to set a maximum DPI in the Android Player Settings,
set FixedDPI and choose an appropriate target maximum DPI.
Unreal Engine 4 supports a mobile content scale factor that
has a few options other than the device’s native resolutions,
and Godot lets you scale output in multiple ways,
using a base window width to avoid rendering
at very high DPIs,
and also has the screen DPI available from scripts.
To unlock even more of the Chrome OS
ecosystem, you’ll want to make sure you include
x86 and x86_64 builds alongside ARM device builds.
If you’re using a game engine to build your Android game,
it likely supports x86 and ARM builds.
All officially supported Unity versions starting with 2019 LTS
will have x86 and x86_64 support and Chrome OS improvements.
You just select the additional architectures and upload to the same Play listing,
streamlining the process of reaching Chrome OS screens.
Android App Bundles, the Android app publishing format,
lets you include libraries that support multiple architectures
without increasing dowload size,
since Google Play will deliver a customized APK for each architecture.
Play Asset Delivery, or PAD, extends the Android app bundle,
so you can publish a single artifact to Play,
including all the code and resources your game needs.
We do a lot with PAD to streamline your game distribution.
When you use PAD to deliver your game’s assets,
it will always keep them up to date, just like it does with your game’s binary.
When your users open the game, they have the freshest binary
and assets with no wait to update resources.
Play’s auto updates also take care of
delta patching, delivering only the bytes that have changed
from the version the user has on their device.
PAD supports multiple delivery modes to let you optimize your download
into assets that need to be there when your game first loads,
assets that can follow that download,
and assets to download on demand.
You can separate the content in these packs by
texture compression format, and Play will serve the most
appropriate textures to each device, ensuring the most
efficient, highest quality textures to allow your game to
work best on the most screens.
We’re working on Device Tier Targeting, to let you to subdivide
your asset packs by device tiers.
You tell us which devices belong to each tier, segmenting them by their RAM size,
model, or another hardware trait, such as the physical screen size,
to let you to extend your reach with smaller, more efficient downloads.
We’ve covered getting your game functional across a wide range of
hardware with reasonable density choices, optimized textures, and more.
In parallel with this work, it’s important to measure
performance, so you see how your choices pay off
and increase your reach and what you should focus
on next to target the widest user base.
Android Performance Tuner, or APT, is part of the
Android Game Development Kit libraries.
It unlocks game performance insights in Android Vitals,
giving you a way to measure and optimize
the graphical fidelity, loading time, and frame rate of
your game across the Android device
ecosystem, all on real devices with real users.
The APT library relies on tick functions being called for each frame.
If you’ve already integrated the Android Frame Pacing Library,
you pass in a Swappy_injectTracer function from the
Frame Pacing API initialization to enable automatic frame time recording.
If you’re using Unity, you can import our custom package
and configure it from the Window, Android Performance Tuner, Setup menu.
You initialize it from your app setting script.
See our Unity codelab for all the instructions.
Once you’ve done the basic integration, the next step is to define
annotation parameters and tie them to quality levels,
scenes, or other areas of interest in your game,
and make calls in the appropriate places to inform the APT API.
If you’re using Unity with the Android Performance Tuner plugin,
you’ll get a scene annotation that maps the scene being played,
a LoadingState that you’ll need to hook up in your scripts,
and the UI to define additional annotations.
In a C or C++ engine integration, you’ll define these annotations
with a protocol buffer.
Check out our codelab for more on how this works.
Then you make calls to the APT AP to inform it of contextual changes.
Once the library integration and annotations are in place,
enable the Android Performance Parameters API in the Google Cloud Console
to start collecting data.
Short loading times are also critical in keeping users
engaged with your content, and APT now helps you understand
how loading times impact your ecosystem.
startRecordingLoadingTime creates a loading time event
associated with a given metadata and annotation, and fills in a handle
to use with the stopRecordingLoadingTime() function.
While stopRecordingLoadingTime is used
to end a previously-started loading time event,
the event will be uploaded at the next session flush.
Loading time events contain metadata to help us correctly characterize
loading issues, such as whether it’s the first time the app is run,
a typical cold start, the app was backgrounded,
or if a new level is being loaded.
It covers the loading source and the network type if it’s a network load.
You can also add annotations to your loading time recordings
to help pinpoint performance problems.
You can create loading groups to represent larger tasks
that involve many individual trackable elements, such as downloading assets
off a CDN, and then extracting the content.
And these groups can also have annotations.
For example, you see what’s causing a specific scene to load slowly
Now that the Android Performance Tuner integration is complete,
your metrics will show up in Android Vitals within the Google Play console.
In the loading times views, you can track first runs,
cold loads, warm loads, and inter-level loads.
You learn whether users are abandoning your
game because of overly long loads,
and you can drill into data to see which devices
and annotated levels might be problematic.
Frame rates work in a similar fashion.
You’ll see which devices aren’t performing well enough
and which scenes cause the most frame rate issues.
Most importantly, you can prioritize your
optimization resources to have the greatest impact on
your user base and get your game to as many devices
To help you make better decisions about
devices, geographies, and testing or optimization across
the lifecycle of your game, we recently launched
Reach and Devices in Play Console.
We give you the distribution and trends for installs, crash rate, and ANR rate metrics
for insight into users and their issues.
You can explore these distributions across a number of dimensions,
such as SOC, system on chip, and Graphics API, OpenGL and Vulkan.
You can compare your own data with peers to spot
opportunities in your current games and plan for quality
reach in your next game before you start development.
We give you country filters for more precise launch
and expansion planning.
And you can export this data.
So now that you know which users and devices to optimize for,
what else can you do?
Well, last year, we released the first beta of Android GPU Inspector,
that gives you a trace of events from system activities
and high frequency hardware counters while the game runs,
plotting on a timeline, similar to our systrace tool.
We then added GPU memory support, OpenGL ES support through
ANGLE, new supported devices, and the Frame Profiler,
which allows you to deep dive into a single frame,
providing timing information breakdowns at the render pass level.
It also lets you explore textures, geometry,
shaders, render pipelines, and more to let you analyze
what’s going on in that frame.
And we’re working with OEMs such as Samsung and Oppo to add
more supported devices.
All devices released with Android 12 will support AGI out of the box.
So now that you’re reaching more screens, it’s time to let players
seamlessly progress through your game, no matter what device they’re using.
The Play Game Services SDK gives you a convenient way to
sign in players and save their game progression.
This enables you to retrieve player game data and allows
returning players to continue from their last save point from any device.
You can also integrate popular features, such as achievements and leaderboards.
We’re continuing to invest in Play Game Services with
an updated sign-in API, now in early access,
that allows a one-line implementation.
We’ve also simplified user setup,
combining the Google Play Games install and profile creation in one step,
so people can get to their game quicker,
even if they don’t have Play Games installed.
We’re streamlining the process of opting in to
auto sign-in for an even smoother experience for returning users.
Starting in 2022, Play Game Services will no longer require installing
the Google Play Games app.
This will allow 2 billion users to sign into your
Play Game Services-enabled games with a zero-touch experience.
More details will be coming soon.
We are committed to making Android a great platform
for both game developers and game players,
and that extends to Android 12.
Select Android 12 devices will support Game Mode APIs that
allow your game to respond to whether the user wants
the best overall performance, balanced performance, or the best battery life.
It’s likely that your work in making your game adapt to
various device classes can be used to respond to user preferences.
For users, Pixel 6 integrates the new Game Dashboard experience,
which offers control of the game mode, along with gaming utilities,
like frame rate counters and integrated YouTube Live streaming.
Android 12 includes Play as You Download to reduce
download friction and let users start playing your game faster.
To support it, you need to use App Bundle as your distribution vehicle
and avoid operations that do assays of assets before they’re used,
such as some older ads SDKs.
It’s been quite a journey over these past 11 years.
I’ve both enjoyed working with you and getting to play your games.
And I know game development isn’t easy, but we’re doing more
than ever support what you do throughout your development journey,
beginning with great tools to streamline development,
libraries to simplify Android integration, and solve deep technical challenges,
flexible distribution that allows you to take
best advantage of device hardware across a wide variety of form factors,
and tools, libraries, and services for you to analyze performance
across your user base and show how best to target your resources.
For more on what we’re doing for game development on Android,
check out our games and Android Game Development Kit documentation.
Subscribe to our Game Developer newsletter to get regular updates.
For the fastest updates, follow our Twitter and YouTube Android developer accounts.
Thank you for building great games, and I look forward to seeing
where your creativity takes us in the next 11 years.
And let us know how we can help.