April 12, 2015
When we develop games for Android or iOS, at some point we must wrestle with the very real limitations imposed by mobile devices. Despite taking massive leaps forward, mobile device performance still lags behind that of console and desktop systems. It’s frustrating and disconcerting to discover that your shiny new mobile game waddles in at 20 fps or falls flat in the face of RAM or disk space limitations. How do we make our mobile game run at a decent frame rate? How do we ensure that our game doesn’t exceed a device’s memory limitations? How do we avoid making a prohibitively large installation footprint?
Although there is no single solution to any of this, I have put together a sort of mobile quickstart guide to help tackle some of these issues. Caveat emptor: I’m going to focus on 2D games using Unity simply because those are the sort of projects I’ve been working on the past couple of years. Nonetheless, many of the lessons here will apply to all types of game development. Neophyte mobile developers, use this guide as a starting point to address these common questions:
– How do I improve my mobile game’s frame rate?
– How do I optimize scenes to reduce memory usage (to avoid frame lag or even crashing)?
– How do I optimize my mobile build to reduce the installed size (which means faster download, user is less likely to uninstall the app when freeing space on their device, don’t have to deal with Google Play 50 MB APK limit, etc.)?
Set Target Frame Rate
Let’s start with the obvious. In Unity, we need to set an application target frame rate. The application target frame rate sets an upper-bound on frame rate. You may be surprised to discover that the default frame rate on some platforms is 30 fps. I like to make this call in the Start function of my game management object:
Application.targetFrameRate = 60; //set to desired maximum frame rate
Load Game Objects when the Scene is Loaded
It’s easy to instantiate and destroy objects when needed, but creating and freeing resources requires expensive, time-consuming operations that can result in a drop in frame rate. Whenever possible, instantiate Players, Enemies, Objects, Projectiles, Particles, Backgrounds, Platforms, Power-ups, and other objects when the scene is loaded (whether this is done at design time or programmatically depends on the specific game architecture). If we create or destroy game objects while cycling through the main game loop, then we need to be prepared to deal with potential frame hiccups and lag.
If you’re making games, you’re probably already familiar with the practice of using object pools. If not, now that we’re working in mobile, it’s a good time to start. As mentioned above, when possible, we create a majority of our game objects when the scene is created. However, we obviously don’t want to make 5,000 bullets for our shmup or 1,000 platforms for our endless runner. Instead, create an object pool for each unique component that would typically be created and destroyed during the lifetime of a game scene. An object pool is a data structure containing a collection of objects that are constantly recycled to avoid unnecessary allocation and deallocation. The internet is filled with resources explaining how to implement an object pool, so I’ll only give a brief example. Imagine that we are building a Contra-style platformer, and we want to pool the player’s bullets. Pooling bullets works kind of like this:
- pick a data structure to hold our bullet objects (I like to use Lists, but an Array or any sort of flexible storage data structure can be used)
- determine the maximum number of objects that will appear at a time during a scene, and populate the storage data structure with that many objects. If we determine that the maximum number of bullets that will ever appear on-screen at any given time is 20, we’ll create 20 bullet objects and populate our storage data structure with these objects (I like to add a little slop space above my estimate).
- create a flag that marks if a bullet is in use or not in use. In our example, we might make a BulletScript class, add a boolean inUse member, and attach it to a bullet object.
- write a management function that accesses the bullet pool to get a “new” bullet. In other words, if the Player presses the shoot button, we search through the bullet pool (we can user a linear search with a for or do-while loop or implement a more complex search algorithm based on the structure and layout of our storage data structure), find a bullet with inUse == false, and then update the state of the pooled bullet so that it is put into use in our game (turn on physics, turn on collision, make visible, set position, etc.).
- when a bullet would typically be destroyed (collides with enemy, goes off-screen), return it to the pool. Mark the bullet as inUse = false, and update its state so that it is not in use (turn off physics, turn off collision, make invisible, etc.)
Load Prefabs from Resource Folder
Upfront loading and object pools work great in *some* cases, but are not always a plausible option. Is it worth loading 50 MB of images when there is no guarantee that the user will ever access the portion of the scene that displays those images? What if loading the entire set of scene assets causes an enormous memory burden and the application runs out of RAM and crashes? In real-world development, we’re often forced to load some scene assets only when needed. The obvious route in Unity is to store game “chunks” as prefabs, a game object complete with components and properties, that we can selectively create and destroy when needed. Instantiating a prefab is easy. Add a reference to your prefab in script, attach the prefab to the script by dragging it from your asset folder to the inspector, and use the Instantiate function to create an instance of the prefab:
public GameObject myPrefab;
GameObject myobject = (GameObject)Instantiate(myPrefab, new Vector3 (0, 0, 0), Quaternion.identity);
Destroying the prefab instance when it is no longer needed is equally simple using the Destroy function:
Once an instance of a prefab is created, any assets (textures, sounds, etc.) associated with the prefab will also be loaded into memory. However, destroying a prefab does not automatically unload the associated assets. Instead, these assets are unloaded when the scene is unloaded. This causes an obvious problem. Imagine we have 3 prefabs all of which contain a unique set of high resolution image assets. If our game flow permits only 1 prefab to be loaded at a time, we would hope that unloading a prefab would also free any associated assets from memory to reduce our memory burden (why have the assets from multiple prefabs loaded if only 1 prefab instance can ever be displayed at any given time?). When all instances of a prefab are unloaded, its associated assets will *still* occupy space in memory. On mobile devices where memory is at a premium, this is unacceptable. We can work around this, however, with a simple trick. Loading the prefab from the “Resources” folder and explicitly freeing resources will ensure that any underlying prefab assets are freed when the prefab instance is destroyed.
Now with a minor tweak to our code, we can load prefabs directly from the prefab folder rather than connecting them to a script in the inspector (note that I like to make a “prefab” subfolder in the “Resources” folder):
GameObject MyPrefabFromRes = Resources.Load
MyPrefabInstance = (GameObject)Instantiate(MyPrefabFromRes,new Vector3(0,0,0),Quaternion.identity);
When the prefab instance is no longer in use, we can destroy it AND free all associated assets by explicitly requesting that unused assets are unloaded and then manually calling the garbage collector:
What we gain with this technique is simple yet powerful. We can now ensure that any associated prefab assets (textures, sounds, etc.) are ONLY loaded when an instance of the prefab is loaded. When the prefab is destroyed, the associated prefabs assets are unloaded from memory (assuming that they are not loaded on some other game object or prefab instance). This sort of asset juggling is paramount to creating mobile game scenes that need to load and unload a wide array of assets in response to a variety of user interactions.
Monster Heart Medic: players can choose from a variety of mutually exclusive tests that require massive, high resolution images to be loaded. Once a test is completed, these images are unloaded using the above technique.
In part 2, I’ll talk about Sprite Packing and coding methods that I use to increase mobile game performance.
March 30, 2015
3 years ago we competed on The Next Game Boss, an IGN/YouTube game development reality show. We ended up winning The Next Game Boss by creating Washington’s Wig, a quirky, irreverent runner set during George Washington’s historic crossing of the Delaware River. From the beginning Washington’s Wig *felt* like a mobile game, and naturally we intended to release it on both iOS and Android. However, with Fist Puncher and then Reagan Gorbachev in the pipeline, we never found the time to port, publish, and market another game. Until now, that is. We’re happy to announce that Washington’s Wig is now available for iOS and Android! Washington’s Wig features multiple play modes, a cast of cute dogs, and a little bit of U.S. history (but not that much so don’t worry). Washington’s Wig is completely free and can be downloaded from both the App Store and Google Play. Enjoy!
March 19, 2015
Great news for OUYA owners. Fist Puncher & Reagan Gorbachev are now available for the price of 1 with the new Team2Bit OUYA Game Bundle! For the price of a single game, you can have Ronald Reagan swing a samurai sword and Dr. Karate unleash justice on the seedy underbelly of San Cruces. Power up your OUYA console for more details.
March 6, 2015
It’s true. After a successful run on the OUYA console, Reagan Gorbachev will next be coming to Xbox One. Reagan Gorbachev is a cooperative, action-stealth game set in an alternate 1980s timeline. Control world leaders Ronald Reagan and Mikhail Gorbachev as they battle through dozens of grueling levels and fight their way to freedom. We’ll have more information about release date and new features in the upcoming weeks. Stay tuned!
October 30, 2014
We sat down for a quick interview with the good folks at Ghost Volta to talk about our studio and our latest game, Reagan Gorbachev. Read the interview if you want to hear us sound all professional and what not.
October 21, 2014
Our latest game, Reagan Gorbachev, is out today on the OUYA console. Reagan Gorbachev is a top-down stealth game for one or two players. Set in a 1980s alternate timeline, historical icons Ronald Reagan and Mikhail Gorbachev have been kidnapped by militant extremists during their famous Reykjavík Summit. Armed with everything from poisoned darts to katanas to high-powered rifles – sneak or slash your way through dozens of deadly levels in your quest for freedom. Available NOW on OUYA.
October 10, 2014
The first day of Reagan Gorbachev showing at IndieCade is now over. The sun was blazing hot, the sweet tea was flowing, and gaming pals were everywhere. For those that missed it, here’s a terse (twitter-speak), image-based overview.
October 6, 2014
Great news! We’ll be bringing Reagan Gorbachev down to IndieCade later this week in sunny Southern California. You’ll find Reagan Gorbachev in the OUYA booth with some other swell titles. Come check it out if you’ll be at the festival!