Category Archives: General

Thoughts on Google Play Game Services and games

I recently updated the Google Play Game Services library of Freebloks 3D for Android and the BaseGameUtils, as recommended by Google. Not reading the ChangeLog, I was confused that my game tried to auto log in to Google on the start, disrupting the user experience I built around that. Even after dismissing the login dialog once would show the dialog again in the next Activity that is derived from BaseGameActivity or uses a GameHelper object.

Searching the Interwebs I found the FAQ, which explained the change of behaviour, and I am sad that the game itself once again becomes more and more insignificant:

The default behavior of BaseGameActivity and GameHelper is to show the user the sign-in flow (consent dialogs, etc) as soon as your application starts. Naturally, once the user signs in for the first time, they won’t see the consent flow again, so it will be a seamless experience. […]

The first time a game is started, the user will be prompted with a full screen dialog asking the user for consent to post on their behalf to Google+.  The user hasn’t seen anything of my App yet and still Google tries to put itself into the foreground. After the user signed in, this might become a seamless experience but being prompted with this dialog does not seem like a good experience. Especially because there is no warning or explanation of what this dialog does.

It is important for the user to sign in as early as possible so your application can take advantage of the Google Play Games API right away (for example, saving the user’s progress using Cloud Save, unlocking achievements, etc).

I noticed that usually I want to explore the game a little before signing in to Google. I’d like to find out if the game is a game I’d continue to play and once I get engaged with a game, I am willing to sign in to use the additional features. I know I am not an everyday user and I am aware that logging in to Google gives up some privacy. And before I haven’t decided to continue playing a game, I do not want any information to leak or social activity to be generated.

Obviously this reads to me as:

it’s important for the developers and Google to get user generated activity and data as soon as possible.

And is again another step towards games telling the users what to do.

If the user cancels the sign-in flow, BaseGameAcitivity/GameHelper will remember that cancellation. If the total number of cancellations reaches a predefined maximum (by default, 3), the user will no longer be prompted to sign in on application startup. If that happens, they can still sign in by clicking your application’s Sign In button, if you provide one.

Is not signing in to Google not a choice anymore but an error? If I dismiss the dialog because I do not give consent, is that assumed to be an error? Do I have to be prompted again even though I made the choice to not log in? Do I really have to dismiss the dialog 3 times until the game believes me that I do not want to log in?

The games are taking over!

I noticed the trend of games beginning to control users, of being needy, wanting attention, and developers seeing games only as a way to generate a stream of content or resources back to the developer.

Games these days:

  • show popup notifications that they want to be played.
  • make the user attend the game by long running tasks in the background that finish whenever. Building a building may take 5 hours, after which I have to open the game again.
  • want you to share everything on Facebook or Google+ (“Your creature took a dump. Share on Facebook?”). This is not to make you happy or to provide a game element, it is purely to attract other people and make them install the game.
  • tell you exactly and in detail how to use it. A lot of games begin with a 10 minute intro (“now click here”, “now buy upgrade”, “now shoot”) to make sure that the user understands the concept of buying upgrades and in game currency. This leaves very little room for experimentation and explorations, because users need to follow the strict predefined path that generates revenue.
  • lock you in. Using In-App-Purchases basically makes you rent the game, it is like Prepaid and the decision to stop playing a game is harder, because you have money that will expire. When you buy a game and own it, you have the freedom of choice to not play it. Buying your right to play the game over and over will most likely leave you hanging in an awkward spot when you decide to stop. Oddly enough these games are advertise as Free or Free2Play or, less often, Pay2Win.
  • use gamification to seem more interesting. Most games implement achievements in a way, so that they are not game elements. The Google Play services offer achievements that are outside of the game, meaning they don’t change the game flow, giving the user no actual value of an earned achievement. While the wording suggests the user benefits from earning an achievement, this is likely to drive engagement with the game but will not result in higher user experience or even fun. I fear the day users wonder about the motivation to achieve anything.
  • artificially restrict themselves but still take over your time. Why does building a house takes 5 hours sometimes, while the game does not any other game elements during that time? I’s making me hooked, telling me to go on with my day but of course I will always have the game on my mind and I have to come back after 5 hours. The game dictates when the user can play with it and when he can’t. It is not the users decision anymore to play and spend time with the game.

Where did the games go that gave power and freedom to the players to do what they want to do? With room to explore? With having game elements to actually fill 5 hours of time, then waiting and being ready when I come back to it? Where did the love go to provide the user with a fun way to pass his time?

This is not about the user anymore. He is not the customer, he is the good to be sold, the “conversion” to be made. The game is just the means and additional game elements are in the way. Games became a pure medium for developers and Google to say to users: “Give me your money”.

Where was I? Oh yes, disable the auto-login.

Easy enough the above behaviour can be reverted by

getGameHelper().setMaxAutoSignInAttempts(0);

but that’s not the point. Give the power back to the user!

Sony Xperia Z2 Tablet with touch screen problems

Last week I decided to buy a tablet with Android. After looking a while I decided to go with the Sony Xperia Z2 Tablet, which in my opinion is an awesome tablet. It is powerful, light, high quality finish, even waterproof and incredibly thin. Being definitely in a high price range, this is a professional tablet, which cost me roughly 420 EUR.

Only after buying and using it at home for a while, I occasionally experienced erratic touch screen behaviour. Touches would be not recognized, sometimes swipe gestures would be detected as taps, multitouch gestures would stop and break in the middle and sometimes middle touches would only be detected, if pressed very hard. And even then the touches would not be detected reliably, resulting in random taps, performing undesired actions. This is usually with the tablet laying on a flat surface, quite often over night. I know that electric fields while charging a device quite often disturb the touch screen, but with the Sony Xperia Z2 this happened without the charger connected. I had the latest available software installed, the 17.1.1.A.0.402, which obviously did not fix the issue.

Turning the screen off and on usually fixed the situation temporarily, but that is not a solution as it would randomly happen again.

I downloaded a touchscreen test app and also found that the tablet has a very hard time recognizing touches, when two fingers are exactly in a horizontal or vertical line. It would simple drop both fingers. This is not acceptable multitouch behaviour, where one touch affects the other.

Confused I searched the Internet and found quite some people reporting the same issue, even a YouTube video demonstrating the problem, making me believe this is a systematic design flaw, not just a flawed device:

Sony Support recommended me to install the latest software (this was already the case) and then said, my device might need repair. This issue has apparently been around since several month and still Sony did not confirm the problem.

But I believe my device wasn’t actually broken but suffered from design flaws, I returned it for a refund. I am not willing to try different devices until I find one that actually works. Not with so many people complaining about the touch screen. Not for this price.

Sorry, Sony, you made the Xperia Z2 Tablet too thin and you have problems to get it to work properly. I’m sorry my first experience with a Sony mobile device had to be a negative one and with this issue not even publicly confirmed, I can’t recommend buying it. Too bad, it could have been such an awesome tablet.

moosic.fm in google play

The client app for moosic.fm is available in Google Play. It is by far my most polished and stylish app, that I developed for the German start-up moosic.

moosic.fm in Google Play
moosic.fm in Google Play

With moosic.fm you can keep track of the music that’s running in your favourite location. Browse past playlists or see what’s playing right now, all together with previews and cover pictures.

In the backend, the moosic listener listens to music in the background and uploads the recognized songs as a playlist. Users can browse these playlists using either the nice web frontend or the native Android App.

Note that the technology is currently being tested and evaluated. Kodus to T O-12 in Stuttgart for being available for the beta test and to Gracenote for their music recognizing api. For questions, don’t hesitate to contact the guys at moosic.de.

Screenshots

Chicken Tournament for Android in development

After more than 10 years I decided to port Chicken Tournament to current Android smartphones. Due to the differences between the platforms, this will result in a new game and a new engine, but because of lack of time and resources, I will reuse the models and most of the textures. OpenGLES 2.0 though allows me to massively improve the quality of the graphics.

The PC version and the android version will not be compatible.

Please follow the official Chicken Tournament facebook page to receive more information and updates. A very early development version allows driving the harvester over a plain using the accelerometer to steer. The chicken are nicely animated using vertex shader.

Development screenshot of CT for Android
Development screenshot of CT on my S3

Freebloks-1.5 for PC available

While I have frequently improved and updated the network compatible Android version of Freebloks, I have always neglected the Windows version. The Android version gained features like player names and the ability to choose the colors to play with. While the Windows and Android version always stayed compatible, the PC version simply did not offer these features to connecting Android devices or when connecting to a dedicated server.

Now Freebloks-1.5 for Windows is available, which lets connecting Android devices use all features and offers the player to choose his colours as well as to choose a name (which is not displayed in the game but on connected Android devices). If you frequently play Freebloks over the Internet, it is recommended to download the new version here:

isatapd package for android

I created and published an android app that bundles my ISATAP client daemon and provides a configuration front end. To run the binary on android, it requires root access, i.e. a rooted device or phone.

Screenshot_2013-09-26-10-41-13On my Galaxy S3 with Cyanogenmod 10.2 I successfully get a IPv6 address using the app. 😀

If you have a rooted phone and an ISATAP infrastructure close by, please feel free to give it a try:

The app is open source, with code being available on GitHub: https://github.com/shlusiak/isatapd-android

The source tree also contains a pre-compiled isatapd binary to be used in your own distribution or scripts.

Freebloks VIP – donate version of Freebloks

Freebloks 3D for Android is free software, it’s open source, completely free of charge and you can modify it to any extent. Free software however does not mean it has no value. That’s why Freebloks comes with the feature of in-app donations to support the developers.

You can choose how much Freebloks is worth to you, you can donate any amount you like or you can purchase the new published version called Freebloks VIP, that is identical to the free version but paid to show the support to the developers. The only visual difference is the coin in the app icon indicating your support.

Please don’t take free software for granted.

Screenshot_2013-07-31-08-57-00

In-App Donations in Freebloks 3D

Freebloks 3D for Android is the Android port of the PC version of Freebloks 3D for Windows and Linux. Like the PC version, the Android port is completely free software, available for free in the Google Play Store and the source code being available on GitHub.

I strongly believe in Open Source software and that it can help to make the world a better place by making knowledge and power available to everyone. While many hours of work went into the Android port, I feel good to completely open the software for others to study, to modify or contribute. A lot of my knowledge and skills come from the study of others work and my contribution to open source software is my attempt to give something back in return.

If you like Freebloks, please be encouraged to contribute, send be feedback, work on the code or support the developers with a donation. The recent update makes in-app donations available for users. These in-app items acknowledge the work of the developers and are completely voluntary. Freebloks will always be free but relies on your contribution!

So if you think, the game has some value for you, please consider a donation of your choice.

Screenshot_2013-05-05-10-01-35

Dropshadows for Freebloks for Android

The latest update of Freebloks 3D for Android adds nice drop shadows to falling stones. Instead of “correct” shadows using shadow volumes in a stencil buffer, the android version renders a pseudo drop shadow texture on the board. The shadows are not always correct, but it is much easier to add individual tinting, alpha or scale effects, depending on the distance of the stones. This adds a more realistic look and is easy on the hardware, because there is no need to recalculate the shadow volume each frame.

Screenshot_2013-04-18-12-01-57

Much improved AI speed for Freebloks for Android using jni

For the port of Freebloks 3D to Android I rewrote all code from C to Java. While that was working fine and resulted in greatly simplified networking code, the speed of the AI was not so great. It took up to 10 seconds on a fairly powerful SGS 2 for the computer to find a good move.

I was trying to move the CPU intense routines of the AI to C again, using jni as a bridge between Java and C. The simple network routines should stay in Java.

But the transfer of relevant game data to C and back to Java turned out to be very ugly, yet the solution was incredibly simple:

The Freebloks code was always split in two parts, the GUI/client part and the AI/server part, with the client and server always communicating using network sockets. Yes, even the single player version starts a network server and connects to localhost. The original source code always contained a package for running a dedicated server.

It was incredibly easy to copy the dedicated server code into my project, compile the C code with the NDK and connect it to Java with only a single jni call. It was running out of the box, with almost no change of the original C code at all! Since the server is running in a thread started from the native C code, there is no additional jni call neccessary and no data transfers except for the sockets.

The average duration for the AI to calculate a complete game dropped from 87 sec to 28 sec on my SGS 2. The version 0.0.2 in the Google Play Store supports ARMv5, ARMv7 and x86. Grab it now! You may also download a free apk file here.

And please don’t forget to give feedback.

Screenshot_2013-02-11-14-27-24

USB write performance drop on Fritz!Box 7170

I want to attach a USB stick to the AVM Fritz!Box 7170 to use as USB storage and be able to write to it using the integrated ftp server. When writing a bunch of files, the write performance drops to under 50 kb/sec, while the stick can easily handle 512 kb/sec. Why the bad performance and why the drop?

I replaced the stock AVM firmware with Freetz but got similar results. What got my attention is a drop in performance after copying 4 files, that does not recover after time. The following tests were done using the Freetz modification with Linux kernel 2.6.13.1-ohio.

Performance drop when writing

Look at these numbers when copying a bunch of files to the stick using scp:

$ scp tmp* root@fritz.box:/var/media/ftp/uStor00/
tmp1                          100% 2048KB 682.7KB/s   00:03    
tmp2                          100% 2048KB 512.0KB/s   00:04    
tmp3                          100% 2048KB 512.0KB/s   00:04    
tmp4                          100% 2048KB  55.4KB/s   00:37    
tmp5                          100% 2048KB  38.6KB/s   00:53

Each following transfer would then be at only 55KB/s. Issuing a sync command to flush out dirty buffers makes no difference, so the speed is not throttled by the USB stick being busy.

Let’s have a look at the VFS cache

The Linux kernel reveals some interesting cache and memory information in /proc/meminfo. These are numbers taken after a fresh boot:

# cat /proc/meminfo 
MemTotal:        30204 kB
MemFree:          9632 kB    # unused, completely free memory
Buffers:           280 kB
Cached:           6280 kB    # memory used for cached files
SwapCached:          0 kB
Active:           8652 kB
Inactive:         1524 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:        30204 kB
LowFree:          9632 kB
SwapTotal:           0 kB
SwapFree:            0 kB
Dirty:               0 kB    # memory waiting to be written to disk
Writeback:          0 kB    #  memory actively being written to disk
Mapped:           8040 kB
Slab:             6028 kB
CommitLimit:     15100 kB
Committed_AS:     5724 kB
PageTables:        240 kB
VmallocTotal:  1048560 kB
VmallocUsed:      4056 kB
VmallocChunk:  1043636 kB

While copying the first files, the highlighted numbers read like this:

MemFree:          1716 kB
Cached:          13704 kB
Active:           8976 kB
Inactive:         8928 kB
Dirty:            6836 kB     # lots of data waiting to be written
Writeback:         444 kB    # lots of data being actively writting

We see that the cache is filled up quickly with buffers also marked to be written on the stick (marked dirty) and that the pdflush daemon already started to write out chunks of consecutive data to the usb stick. Remember that usb sticks have good performance when streaming out data chunks that fit into the physical structure but bad performance, when writing out small chunks because a lot of the flash memory keeps being reread and overwritten. The performance is good here, because there are a lot of dirty buffers the kernel can optimize the writing out.

Writing file ‘tmp1’

Let’s go back and look at the numbers exactly after tmp1 has been written (2048 kB):

MemFree:          7100 kB    # before: 9632 kB
Cached:           8456 kB    # before: 6280 kB
Dirty:               0 kB
Writeback:           0 kB

The buffers have all been flushed, so the stick is idle. Our cache grew by 2048 kB taken from the free memory, containing now also the file tmp1.

Writing file ‘tmp2’

Copying file tmp2 (2048 kB) is fast and the memory info after copying is no surprise:

MemFree:          5084 kB    # 2048 kB less
Cached:          10504 kB    # 2048 kB more
Dirty:               0 kB
Writeback:           0 kB

Neither is tmp3 (2048 kB), because there is still unused memory left. But now it’s getting interesting, because write performance with tmp4 drops drastically.

Writing file ‘tmp4’ with no free memory

While writing tmp4, and the performance dropping to 30 KB/sec, the numbers look like this:

MemFree:          1148 kB
Cached:          13988 kB
Dirty:              12 kB
Writeback:          36 kB

Of course free memory is useless, we’d rather have everying to into the cache. The cache stays filled (we have tmp1, tmp2 and tmp3 in the cache), but the values for Dirty and Writeback are too low.

Before, the file to be written was completely loaded into the cache first and marked dirty.The pdflush daemon was started deferred and found rich caches to be written to disk.

The number of blocks marked dirty now never seems to exceed 50 kB. The pdflush daemon can only flush out small chunks of up to 36 kB at once (usually less), resulting in a lot of USB operations and overhead and low performance.

Clearing the cache helps

The Freetz kernel unfortunately does not expose /proc/sys/vm/drop_caches to drop all cached buffers. But what happens, if we rm tmp1:

MemFree:          1604 kB
Cached:          14004 kB

Nothing. tmp1 is not in the cache anymore and most likely tmp4 has taken it’s place, because it is newer. But tmp2 is still in the cache, so let’s rm it:

MemFree:          3464 kB     # rm tmp2 frees up the cached memory
Cached:          12152 kB     # the rm'ed file is removed from cache

Now we have over 3 MB free and unused memory and the file is not in the cache anymore.

Writing tmp5

Now let’s copy tmp5 (2048 KB). These are numbers from during the copy to see the values of Dirty and Writeback, so the file is only partly transfered yet:

MemFree:          2204 kB
Cached:          12948 kB
Dirty:             152 kB
Writeback:         424 kB

We again see high numbers for Dirty and Writeback as parts of the copied file are moved to the cache and dirty. The pdflush daemon gets huge chunks of buffers again to be streamed to the medium and we get a fairly high transfer rate.

Broken kernel behaviour

This is the fairly old Linux kernel 2.6.13.1-ohio from Freetz. The behaviour of the VFS and pdflush seems to be broken and thus result in very poor write performance:

  • when there is no free memory available, why doesn’t the kernel free more old cache memory for the new buffers to be marked dirty?
  • it seems, the pdflush daemon is forced to write out as soon as there are dirty buffers and memory is low (= no free memory). Why does the kernel seem to prefer to free memory by writing out dirty buffers instead of clearing the read cache to make room for more dirty buffers?
  • allocating new buffers seems to stall while pdflush daemon is freeing up dirty memory
  • new buffers are still taken from old cached files, so after copying the whole file, it is completely in the cache. why not put if completely in the cache before starting to write out and stall allocation of new buffers?
  • rm’ing a file that is in the cache, frees up the cache, resulting in performance boosts, until that free memory is used by the cache again and the pdflush daemon writes out much smaller chunks. Practically that won’t happen and a normal Linux system should never have large amounts of free memory.

This is a kernel bug preventing Fritz!Box 7170 from ever achieving good write performance on my USB stick and other mediums.

Summary

  1. When copying files to the Fritz!Box, the kernel caches these files in it’s cache only when free memory is available.
  2. It writes out the cached files to storage, with good performance because there are big chunks to be written. The files remain in the cache in case they are read.
  3. With a full cache and no free memory, new files aren’t cached anymore but directly written to the medium, resulting in a lot of small writes with big overhead and bad performance. The file is still in the cache after writing is done.
  4. Clearing up the cache results in free memory and write performance boosts until the cache is saturated again.
  5. Because the cache is only freed up on unmount, the situation almost never happens, making writing data to USB sticks a pain.

External harddrives might work better, because of fast integrated hardware caches that can take lots of small chunks. But on a USB stick without hardware cache, performance is killed by the small writes.

It is unlikely that this bug will be fixed by AVM or by Freetz for the Fritz!Box 7170 because it seems to be a flaw in the used Linux kernel and AVM does not update the 7170 firmware anymore.

Is this a known bug and is this fixed in newer kernels?

Out of Memory in GLSurfaceView on resume

The Symptom

After publishing WordMix with the OpenGL accelerated 2D game view (using GLSurfaceView), I received weird crash reports from some devices, mostly out of memory from within the GL context:

android.opengl.GLException: out of memory
 at android.opengl.GLErrorWrapper.checkError(GLErrorWrapper.java:62)
 at android.opengl.GLErrorWrapper.glGenTextures(GLErrorWrapper.java:350)
 at [...]

From the very limited information the Google Play Developer Console gives me about crash reports, I assumed it only affects devices running Android version 3. Modifying the code only caused the out of memory exception to be thrown at random other places, even at GL10.glClear(…)!

I also found out, the crash only happens when the user finishes a subactivity that would leave to the activity containing the GLSurfaceView. Users were complaining about the crash happening before starting a second game, which puzzled me, because all my rendering code seemed to be working fine on all devices running Android 4. Everything worked fine without the GLSurfaceView as well.

Looking that the source code for GLSurfaceView, nothing interesting was changed between Android 3.2 to Android 4, so the GLSurfaceView was hardly to blame, but more the hardware, drivers or specific OpenGL implementation.

The problem

The actual problem was very hard to track down and took me several hours and was particularly hard because I did not have an Android 3 tablet for debugging:

Up to Android 2.3, views were drawn in software and later composited using the hardware. Android 3 introduced an alternative hardware accelerated drawing engine for everything that uses Canvas classes. This alternative render path is disabled by default in Android 3 and supposedly enabled by default in Android 4 (previous blog post).

When I found out, that the Samsung Galaxy S2 does not enable hardware acceleration by default, I did set

<application android:hardwareAccelerated="true" ...>

in the AndroidManifest.xml for all activities that should support hardware acceleration. Using hardware acceleration for the activity with the anyway hardware accelerated GLSurfaceView did not make much of a difference. But accelerating the results or preferences activity, for example, gave a nice performance boost on my SGS2.

It turns out that the crash happens in Android, when an activity, that contains a GLSurfaceView, is paused for a fullscreen activity, that is hardware accelerated. When that hardware accelerated activity is finished, the underlying GLSurfaceView is screwed up, throwing out of memory exceptions, even though the GL context is completely reinitialized correctly.

The solution

Yes, I should have tested more the effects of hardwareAccelerated=”true”.

Leaving that attribute entirely unset is recommended for Android 3, especially when you use a GLSurfaceView, and should not hurt Android 4 devices as well. Setting a reasonable default value is then up to the manufacturers.

Summary

  • If you use a GLSurfaceView in an activity
  • and suspend that activity by starting another fullscreen activity
  • and that activity is hardwareAccelerated by setting so in the AndroidManifest.xml
  • and you target Android 3 devices
  • expect weird behaviour like out-of-memory exceptions

Welcome to fragmentation. Just let hardwareAccelerated be unset.