CLM logo How Ours Yummy Games Are Made

About

CLM is a small, indie game development company.

This devlog will allow us to share a little bit of our knowledge and experience. We'll try to keep it simple, short and interesting.

If you are looking for the official site, go to clmgames.com.

Search

Monitoring CPU usage on Android

Wow, almost year since the last entry? Time to fix that, especially when it’s such an important day — Anodia is available in the Apple AppStore for the exactly 1024 days! :)

Today I would like to share some of our experience with CPU usage on Android. As every platform is different, there are system specific aspects that we need to take care of. We noticed that Anodia on Android is using lots of CPU power when suspended, even though we’ve done the same logic as on iOS and Windows Phone. It turns out that we faced two problems:

First was related to our usage of OpenAL. Unfortunately there is no native support for OpenAL on Android, so we used apportable openal-soft port. It uses OpenSL as a backend, but as it turned out, OpenSL thread is quite busy even when all audio sources are suspended (~25% CPU usage on Sony Xperia Tipo) . Fortunately calls to alcSuspend/alcResume in game activity onPause / onResume methods solved this issue.

Second issue was related to listening for accelerometer data. On Android it’s required to unregister all listeners when suspending an activity. Otherwise it will consume CPU even when application is not used. In our case listening to accelerometer data caused ~3% CPU usage on Sony Xperia Tipo.

And that’s all, there is one simple lesson: adb shell top -m 10 and monitor tool from sdk are quite useful when it comes to monitoring CPU usage.

Hexbee for Windows 8

It’s amazing how time flies — there was no devlog entry in the last two and a half months!

In the last entry we told you that Direct3D 11 support isn’t a Windows game/port announcement. It’s time to change that, just a couple of days ago we released Hexbee for Windows 8!

screen

It took some additional effort to adapt our framework for Windows 8 and probably we’ll make some posts about that in the near future. In the mean time, have fun and don’t forget to let us know if you encounter any issues.

Abstraction is your friend

We are quite busy with adding support for additional platforms in our 2D engine/framework, Wombat. One of the biggest issues is support of rendering. Recently, the only supported renderer was OpenGL ES 1.1 (with possibility to run on full fledged OpenGL on desktop machines). Now, I’m proud to say that it also supports the same rendering capabilities with Direct3D 11 (don’t get too excited though, this is no windows game/port announcement).

What is so hard about supporting different graphic APIs? Differences in concepts and data types, at least this is my personal opinion. For example, in OpenGL texture in client code is just one GLuint, but in Direct3D it’s ID3D11Texture2D*, ID3D11ShaderResourceView* and shared ID3D11SamplerState*. How to address this? Our approach is to use handles to hide concepts and underlying data types. Handle might be simply an integer, which is mapped to proper data in the subsystem that manages it — clients have no idea what it really means.

For example, part of texture handling in OpenGL renderer might look something like this:

TextureHandle Renderer::LoadTexture(const TextureData& td)
{
    GLuint textureHandle;

    //... texture loading ...

    return textureHandleManager.Register(textureHandle);
}

void Renderer::FreeResource(TextureHandle handle)
{
    GLuint texture = textureHandleManager.Map(handle);
    glDeleteTextures(1, &texture);
    textureHandleManager.Unregister(handle);
}

void Renderer::SetTexture(TextureHandle handle)
{
    GLuint texture = textureHandleManager.Map(handle);
    glBindTexture(GL_TEXTURE_2D, texture);
}

This way client code uses only TextureHandle and there are no dependencies to OpenGL API. Need Direct3D support? Just implement the same interface and you’re done (yup, I know that this is an oversimplification).

The lesson is to avoid being API dependent, which will allow changing the underlying implementation and libraries, and that is a great deal.

iOS 6 adaptation, part 2

It has been almost two months since iOS 6 became available. We already covered the iOS 6 adaptation after one week, but we promised to get back to you after information from couple of weeks is available.

The chart below shows OS versions in Anodia sessions from the last two months:

It’s surprising, but the most sessions are still from iOS 5 (46,7%), than from iOS 6 (42,9%) and the third place goes to iOS 4 (still almost 9,7%). We’ve suspected that till now iOS 6 will take over most of the iOS 5 share. One of the explanations might be that the first generation iPad hasn’t received the upgrade, but according to our statistics, this device is used by only 4% of the Anodia user base. What a conundrum!

Transparency Optimization

During the implementation of a 60 FPS support we noticed that a few levels were not working as fast as they should. After digging a little deeper we found out that our bottleneck was the rendering.

In one of those cases, the texture we used looked like that:

What’s wrong with it? It’s 128×128 (16384 pixels), but it’s quite easy to notice that lots of pixels on the sides of it are transparent. After a few moments of trimming it down we got 108×108 texture that looks like this:

108×108=11664, so the new texture contains almost 29% less pixels It’s a quite good optimization! When a few dozens of sprites are rendered on the screen this might make a significant difference for your fillrate.

It’s important to remember that transparency comes at a cost, there is no way to discard transparent pixels prior to the texture fetch. Trimming down textures also helps to reduce size of the rendered sprites, which might lead to nice performance increase in GPUs that use tiled rendering (like the PowerVR GPUs used in Apple mobile devices).

iOS 6 adaptation

It has been just a few days since iOS 6 became available, but we think that information about it adaptation by users is interesting.

This chart shows OS version in Anodia sessions from the last week:

It’s easy to notice that most of the users have one of the two most recent OS versions, which is great from the developer perspective. What is more important, it looks that iOS 6 share is almost the same as iOS 5.1.1 share.

Stat tuned! We’re going to provide similar chart when the data from a few weeks will be available.

In-App Purchases piracy

Today I want to discuss one issue that we noticed after introducing Anodia 2.0 version — piracy of In-App Purchases.

For quite some time, we’ve been using Localytics to gather statistics that help us improving our games. One of them counts the number of coin purchases. To be honest, I never supposed that the number of pirated IAP might be so high — just check the graph for Coins Purchase event:

Coins Purchase event was reported almost 10000 times, that’s huge. But, you know what? In the same time we had 150 IAP sales, it means that in our case 98,5% Coins Purchases events are due to piracy. Not to mention that not all players are visible in Localytics (because we send the events only when a player is playing Anodia and is on a wifi).

We’re probably a little bit guilty here as we’re not doing any kind of receipt validation, but I’m personally shocked by the scale of this problem. It’s a little bit sad too, as that additional income from IAP would make a big difference in going indie full time. Unfortunately it’s still not possible.

If you’re interested in per-country details, here they are:

As you can see China is the biggest IAP consumer (even though it’s one of the few countries where Anodia has a 4.5 star rating instead of a 5). If you are curious how many of those real 150 IAP sales were made in China, here’s your answer: 1. The cheapest of course ;) .

We’ll probably introduce receipt validation sometime soon, but I believe that this should be a little bit more protected by the App Store itself.

I would also like to thank everyone who resisted the urge to pirate the IAP and supported us. Thank you, it really means a lot to us!

BTW, Anodia 2.1 is available and it runs in 60 fps on devices with Retina Display and on all iPads. It’s really nice and smooth, you should check it out.

Living in a 60 FPS world

When we released the first version of Anodia we received a few questions about frame rate in our games. To be honest, our target was to have solid 30 FPS on almost every possible device (unfortunately first and second gen devices tend to be a little slower). It seemed that achieving more FPS would be very complicated, especially as some parts of our framework were not prepared for this (i.e. using frames instead of time deltas).

As a first step we decided to check if it’s worth effort at all. We changed hard-coded FPS from 30 to 60 and I personally was shocked — game was running at double speed, but all menus were perfectly smooth! GUI is completely time based so it was possible to make comparison on two devices.

Our logic was already decoupled from rendering, but it was driven by the same TaskManager class. The tricky part is that TaskManager updates were handled by NSTimer with 1 ms interval. It was time to finally use CADisplayLink and trigger rendering from there. After fixing some bugs in TaskManager and implementation changes in Renderer we were able to get 60 FPS without changing game logic (still updated 30 times per second).

This is when the real fun begins — at this point everything looks the same as in 30 FPS, time to interpolate. Framework required adaptation in GUI, ParticleSystem, FadeIn/FadeOut transitions. Just take value from the previous and the current logic update and do linear interpolation to get value in between.

When framework was ready for 60 FPS, updates in Anodia started — after changing bonus manager (those falling down bonuses) and game objects handling most levels are working perfectly fine. There are only a few that require some manual tweaking. As we were aiming in 30 FPS in the beginning, sometimes performance is a bottleneck, but it seems that this should be not so difficult to fix.

What does this mean for players? Anodia and Hexbee updates are coming soon, including smooth 60 FPS on iPhone/iPod with Retina Display and all generations of iPad. Unfortunately we are not able to test it on iPhone 3GS so no promises for this device.

If you are interested in this topic, Noel posted an interesting article that made our quest to 60 FPS a lot easier.

Anodia 2.0 is released!

Anodia 2.0 is available on the AppStore!

The biggest changes in comparison to 1.1 version:
- 48 new levels
- level unlocking in Quick Play mode
- Retina Display support for the new iPad
- unlockable equipment
- iCloud support for score, stars, unlocked levels and equipment
- and… Trevor (as shown below)!

Trevor is optional and can be enabled in the equipment menu. He adds a little personality and cuteness to you paddle.

We hope that You all will like this version as much as the previous one!

Anodia 2.0 is ‘Waiting For Review’

A few days ago we shared an information on our Twitter and Facebook that Anodia 2.0 is ‘Waiting For Review’. Keep fingers crossed for a quick approval!

What does this mean for us? We should finally have more time to write regular entries on our devlog and start prototyping new games. And we sure have a lot of (potentially) neat ideas that we want to try! :)