In Game Development
Streamlined game development that reaches more screens - read the full article about game development trends, Game Development and from Android Developers on Qualified.One
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 its 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.
Android Developers: Streamlined game development that reaches more screens - Game Development