Developing iPhone Games for Longer Battery Life
game frame rate battery fps time screen loop games
- Lowering the frame rate of a game increases the battery life by a significant amount.
- Games do not need a high frame rate when displaying a static screen, or a simple 2D animation.
- Our game actively throttles down the frame rate according to what animations are playing at any given time. This reduces the battery consumption by a small, but not insignificant amount.
- Most commercial games do not make any attempt to lower the frame rate when displaying static screens, wasting battery life.
A lot of game developers bring the PC mind-set with them when they start developing for mobile devices. For PC games the target is to achieve the legendary 60 frames per second rate. This is fine when the hardware is connected to an electrical outlet, but power consumption becomes an important factor when your device is running from a battery.
Rather than thinking of speed alone, you need to think of entertainment value. Imagine two people on a 3 hour flight who are playing games on their iPhones to pass the time. One has a 60 FPS game, but the battery runs out mid journey. The other is playing a game that is capped at 30 FPS and the battery lasts the whole journey. Which of these two people gets the most entertainment value?
You don't actually even need 30 FPS a lot of the time. At certain points during the game it might be showing only a static menu, or a simple animation – for instance a blinking light and you do not need 30 FPS for that.
To play an animation smoothly you need a frame rate that's twice the frame frequency of the animation. For instance, a simple 2D flag animation that has 3 frames and repeats every second only needs 6 FPS to play smoothly. Anything above that is overkill.
Apple themselves consider battery consumption to be an extremely important issue. Their own developer guidelines advise the following:
Do not draw to the screen faster than needed. Drawing is an expensive operation when it comes to power. Do not rely on the hardware to throttle your frame rates. Draw only as many frames as your application actually needs.
But, we decided to take this idea one step further.
Frame rate throttling
The technique we developed works by adjusting the frame rate according to what is being displayed on the screen at each instant. Each object displayed on screen indicates what frame rate it requires and the game loop controller picks the largest frame rate requirement. The screen-shots below illustrate this more clearly:
After each frame is rendered both the CPU and GPU of the device sleep until the next frame needs to be rendered. The lower the frame rate the more that the CPU and GPU sleep and this is what saves battery life.
The following devices were used:
iPhone 3GS, OS ver 3.1.3
iPod 1st Gen, OS ver 2.2.1
All measurements were done with the device fully charged, the auto-lock disabled and screen brightness at 80%. Only comparative measurements on the same device are valid, as the battery life varies widely between devices, depending on the age of the battery.
How much does the frame rate effect battery life?
We want to measure the effect of the frame rate on battery life, so we fully charged the devices, and let it run until the 10% warning message pops up on screen.
Armageddon Wars normally runs at 33 FPS during battle sequences and then throttles down to 1 FPS when animation stops. We changed the game to hard code the frame rate to various settings, 60 FPS, 33 FPS, 25 FPS and 1 FPS. (Note: the 60 FPS test could only be run on the iPhone 3GS - The iPod touch is too slow)
Real world tests
Next we tried measuring the actual battery consumption while playing the game.
Our game is a turn-based strategy. The user needs time to consider their next move and while they are thinking usually the scene is static; only after they make their move are animations and special effects played: explosions, fire, smoke etc. When the animations are playing the frame rate is at maximum, but when the scene becomes static again the frame rate is throttled down. So, the average frame rate will be below the maximum rate, depending on how long the player needs to make their move. The following diagram illustrates this more clearly:
We did an epic game play session of 2 hours on each device, both with and without the power save setting. It had to be for a long length of time for accuracy. When the power save is switched off, the game tries to maintain a constant 33 FPS (however the iPod Touch isn't quite able to make that rate.)
So, on the iPhone 3GS battery consumption was reduced by 11% and average frame rate by 16%.
On the iPod Touch the battery consumption was reduced by 35% and average frame rate by 20%.
The reduction was more apparent on the iPod touch because 2 hours represents nearly its entire battery life.
You have to bear in mind these figures are subjective. The figures above are for an experienced player. For inexperienced players the average frame rate would be lower, because they would spend more time making their move.
Compared against other games
The power saving technique works better for strategy games, where there is a tendency to have more static screens, so we tested against some strategy games from the App Store. Each game was put on a static screen and let run until the 10% warning message appeared on the screen.
For all games the battery lasted for a much smaller time than Armageddon Wars running at 1 FPS, indicating that the frame rate is higher than it needs to be.
I'd like to give you a brief overview of how the power save technique was implemented. These diagrams have been simplified for clarity.
Firstly, the game had the following class structure:
As you see, the game consists of several screens, all inherited from the same base class. The member currentScreen points to the current foreground screen. Each screen is composed of several objects derived from DisplayableObject. These could be sprites, user interface items, or particle managers.
And this is the call diagram of the game loop, which shows how these objects interact:
The main view renders the game and measures the time taken. It then queries the game object for the required frame time. The game object in turn calls the current screen's getReqFrameTime function. Each DisplayableObject knows what its required frame rate needs to be. The current screen returns the shortest required frame time of all DisplayableObjects. Then the main view calculates the sleep time as the difference between the required frame time and the time taken to do the render.
Changing the standard iPhone Game loop
The default OpenGL ES iPhone template uses a NSTimer object to update the game loop. The timer is set on initialization of the game to call the game loop once every 1/60th second. The OS is responsible for making NSTimer call the game loop. If a timer event triggers while the game loop is still running, that event will be ignored and it'll just wait for the next NSTimer event. Because the timer events are not synchronized with the game loop, this method is a bit inaccurate.
For our power saving technique to work we need a more precise way to control the game loop. What we do is create a special game loop thread during app startup. Basically, the game loop looks like the following:
The green blocks are called by the main application thread, while the red blocks are called by the game loop thread. Because two threads are accessing the same information we have to use a mutex, to only allow one thread at a time to access the game object.
From the tests run on Armageddon Wars there is undeniable evidence of significant battery life savings. The exact value is impossible to measure exactly, but seems to be in the 25% range.
Armageddon Wars is an OpenGL ES game. Games that do not use the GPU would probably see a smaller power saving benefit because only the CPU is sleeping when the frame rate is throttled.
This technique works better for strategy games, or board games. Action games get a lesser benefit from this technique, because the player is not looking at static screens most of the time.
Cost of implementing the technique
As you may expect, it requires extra effort to make your game "battery friendly". Firstly, you need to modify the game loop as shown in the "Technical details" section, but this this is a good idea in general, because it gives you better control over your game's frame rate. We implemented the technique at a early stage of the development and because of that most of the the issues were ironed out well before the time of the release. However, some subtle bugs did creep in because certain game objects calculated the required frame rate wrong and that required extra time to fix. Still we think the extra effort justified the benefit to the user.