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.
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.
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.
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.
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
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 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
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.
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.
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.
I tried to replace the legacy 2D rendering code of WordMix, which uses the native Android canvas methods, with an OpenGL renderer to allow for fancy effects and animations.
Because the tiles are simple rectangles with round corners, I created a texture with gimp and rendered a quad in OpenGL. The texture had no mipmaps and was filtered linear for both, minimizing and magnifying. When rotating that quad, I got the typical “staircase” lines, because I did not use anti-aliasing / multisampling. The result looks rather horrible:
You can see two effects, one if it being the clear staircase borders, where the texture is not linear filtered, and you see the round corners of the texture with a grayish border, I’ll explain in the next paragraphs.
Multisampling emulation to remove “staircase”
So how to achieve multisampling in OpenGL ES 1.1? The answer I found is quite simple and easy on the hardware: use a texture with a transparent border and linear texture interpolation will do the rest. So I modified the texture to include a transparent border and rendered the quads slightly bigger to fill the same amount of pixels.
The result looked better but I was not satisfied with the borders. I saw the interpolations but there is still a very visible “staircase”. Plus it seems, that the borders are blended with a black color, which can be seen on the overlapping tiles:
This is in fact due to my texture, which had the transparent pixels assigned the color black. The OpenGL interpolation would just average two neighbour pixels, which would calculate like
So how to create a texture, where the transparent pixels have the color white? Gimp seemed to screw up the color of transparent pixels even though when exporting my work as png file, it offers to keep the color of transparent pixels.
The trick: combine all visible planes, create an alpha channel and change the color layer. If you have uncombined planes, the result is unpredictable and the colors are screwed up.
So now I had a texture with a white but fully transparent border (value 0x00FFFFFF) and I’d expect the calculation to be
The post suggests a workaround to not use GLUtils to load the Bitmap into an OpenGL texture but use the original GL10.glTexImage2D(). While the code in that post is not very efficient, it does result in nice and smooth blended borders. Of course the use of mipmaps helps too to make the texture smooth when minified:
Several culprits were found to make antialiasing work with an Android App using OpenGL ES 1.1:
Create textures that have transparent borders, so linear filtering emulated oversampling at polygon borders
Make sure the transparent border of your texture contains color values, which will “bleed” into the border pixels of the texture.
If you use mipmaps, make sure you have enough transparent border pixels or set GL_TEXTURE_WRAP to GL_CLAMP.
Double check result, because gimp does screw up when having multiple layers, that are merged when exporting as png image.
Androids Bitmap loader and Canvas code seems to zero out the color values when alpha is 0. The workaround to keep the color values on load: Use colored pixels with alpha value of 1 (of 255).
The next WordMix and WordMix Pro release will include support for Russian, Portuguese and Dutch as dictionary languages. I had a lot of fun with the Cyrillic encoding of characters and especially the database for the words as I learned that a lot of Linux tools are still not ready for handling multi byte character sequences correctly.
Mostly the tool tr kept me busy, when I tried to convert lower case letters to upper case. The normal approach of
tr [:lower:] [:upper:]
only seems to work for the ASCII character set. If manually used on UTF-8 data, it screws everything up even more, like in the command:
The trick was to use tr on the original KOI8-R encoded data (which is 8 bit), for which I also had to pass KOI8-R encoded parameters to the tool, which was a pain inside an otherwise UTF-8 encoded shell script. So I tried to read the KOI8-R encoded parameters from a file before passing it as arguments so I don’t screw up my shell script.
It took me several hours and attempts to find that out and to get all the encodings right, so now a working Russian dictionary is available. 🙂 It won’t be shipped by default though, so it needs to be fetched from the Internet once by the game, on first use.
Starting from Android 3 (API level 11), there is a hardware renderer for 2D graphics, which drastically increases performance. The hardware acceleration was disabled by default and had to be enabled by the developer by declaring in his AndroidManifest.xml file:
This is true for some devices (like the HTC Sensation with Android 4.0.3), but does NOT apply for the Samsung Galaxy S2 with official Android 4.0.3 and 4.0.4.
Applications without above attribute explicitly set to true are not hardware accelerated automatically on that device. On the HTC Sensation they are.
So don’t forget to declare that attribute in your AndroidManifest.xml file, if you want hardware acceleration on all devices.
Users can force-enable the use of GPU rendering in the developer options, which can be used as a workaround with the risk of incompatible applications yielding render errors.
WordMix 2D view must not use hardware acceleration
Currently, the 2D view of my WordMix game uses some features of Canvas, that are incompatible with hardware acceleration and results in display bugs. These glitches did not occur on my Samsung Galaxy S2, because it was not hardware accelerated as stated above, but occured on another device, a HTC Sensation with Android 4. Took me a while to figure out, what exactly was going on, but after declaring
By default, an Android application requires the feature android.hardware.touchscreen, which is then used for filtering in Google Play, so only devices, that have touchscreen capabilities, will be able to install that app.
Besides that, there is a more basic feature, android.hardware.faketouch; android docs state:
If your application requires basic point and click interaction (in other words, it won’t work with only a d-pad controller), you should declare this feature. Because this is the minimum level of touch interaction, your app will also be compatible with devices that offer more complex touch interfaces.
If the application does not require touchscreen features, it is recommended to set android.hardware.touchscreen to not be required, but declare android.hardware.faketouch instead, so I did this for WordMix, which should work with faketouch devices, too:
If you do that, check the results on Google Play, which shows the number of supported devices:
touchscreenrequired, faketouchnot required: 1500
touchscreennot required, faketouchrequired: 860
neither required: 1800
That is odd and not according to the documentation. For example a Samsung GT-S5360 seems to support touchscreen, but not faketouch. The Samsung Galaxy S2 supports both. You can include all devices by setting touchscreen to be not required, which then includes all faketouch devices, but also all devices that have even less input capabilities.
I just pushed a first playable version of Freebloks for Android, a port of Freebloks 3D to the Android system. It’s a very early development version and very rough, but you can start a single player game and join a network game and place stones. The user interface still needs a lot of love, but I might push a preview version on Google Play soon. Please get involved on GitHub, if you want to contibute.
I tried using the Blender modelling software to create a new featured image for WordMix in Google Play, but I just can’t wrap my head around it. The software has such a horrible UI, that after several hours of trying, I still was unable to create a dice looking object. The learning curve is very flat, I wish I had more time.
This is the result with 3dsmax instead:
The previous image was created with Gimp, based on a screenshot of the game, which I took in a tabet android emulator. It sure did look poorly modified and, compared to the screenshots in Google Play, it did not add anything more:
WordMix Pro arrived in the Google Play Store. While WordMix will stay free of charge, selling a pro-version will support the developing of the game and helpkeeping the free version adfree. So far the Pro version does not have much to offer but some more background images for the game. I do not intend to make the gameplay differ between the free and the payed version.
A 3D OpenGL interface for the game is under development and will be available in the pro-version soon.
I’m currently trying to port the Freebloks game to Android. The core of the game is actually pretty easy to convert from POSIX C to Java for Android and I’m already done migrating the client code and the model, so my app is able to establish a connection to a remote server and display the state of the game.
The display is still very simple, only meant to visualize the state of the core and there is no user interaction possible yet but I plan to port the OpenGL interface too, which does need some rewriting of the logic.
I’m working on keeping the network protocol intact so you can use play together with people using Freebloks 3D in Windows, Linux or MacOSX.
I hope to have a test version around for download, as soon as I have the server portion ported too, so one can play it without connecting over the data connection.