We are pleased to announce that Magic Cookies! is now available on Google Play. The rules are simple: your objective is to remove all the cookies from the tray, but be careful: touching any position on the tray will toggle it, and also the one above, below, to the left and to the right. New cookies will appear where there were none, and existing cookies in those positions will disappear. Are you smart enough?
Feature requests and bug reports
We have done our best to test the game in multiple devices with real users. If something does not work or you think it could be done better, please drop us a line (firstname.lastname@example.org) or open an issue on our github project.
Why this game matters
We know that this is not an 3D first-person shooter featuring Augmented Reality. We know that others have written games in Haskell before. However, we see this as an important milestone. Writing real games requires dealing with many seemingly boring problems that escape the idealised FP world, such as loading and unloading game resources, refreshing the screen efficiently, or handling screen orientation. In the Haskell programs that we often see in university courses, these kinds of problems are ignored for being “uninteresting”.
By publishing a commercial Android game, even if it is a simple one, we force ourselves to face these challenges, to escape our (functional) comfort zone and come up with smarter abstractions to deal with that mutable reality and performance demands that surround games. We expect this to become much harder as we create larger and more complex games. We’ll progressively publish some of these abstractions as open-source libraries, hoping to benefit the Haskell community.
Technical details (only for the adventurous programmer)
The game consists of 2K lines of code, of which 1K is game specific and 400 are Arrowized Functional Reactive code. Everything is written in Haskell, except for three “transgressors”: 1) a Java activity that loads all the libraries and passes events to our program, 2) a C main that loads the RTS and calls our Haskell main, and 3) C++ functions to call Java and save the game state using Android’s shared preferences API.
Most of the game-specific code is platform agnostic, and could be ported to other platforms with minimal effort.
Among the general purpose code we find: rendering modules, an abstract widget system, Android preferences/context/orientation/logcat modules, auxiliary Yampa functions, a menu subsystem and preference handling. Part of GALE’s engine was used for this game, and some additions will be making it back into GALE. Code of general interest (ie. auxiliary Yampa functions, Android debugging/orientation/preferences handling) will be published as open source on our github account.
The game was compiled using the Android backend for GHC, and the SDL libraries used were sdl2, sdl2-image, sdl2-mixer and sdl2-ttf. Our current version is compiled against the older hsSDL2 available on github; a newer version is now available separately, but we are not using it just yet.
The most complex parts were certain Yampa constructs (arrow-based, with lots of tupling/untupling; plus difficulty dealing with input from within internal SFs), dealing correctly with a both continuous (graphics) and discrete (audio) output, limitations to use SFs to process and transform the input/output as part of Yampa’s sense/actimate parameters, and android-specific bits (orientation; calling the underlying C and Java API from Haskell, which gives little information when something fails). Our experience with these problems will be used to improve Yampa, and possibly other libraries too.
We are now experimenting with a combination of Yampa and Reactive Values to make our code easier to understand and more modular. If it works well, it will be used in the next game.
Finally, our game includes over 30 libraries. We have written a few scripts to list all the dependencies and copy them from GHC’s install path to the project directory so that they are packaged with the Android APK. These scripts will be cleaned and published on github. We are convinced that the APK size could be brought down to just 2 or 3 megabytes; we need to investigate how to eliminate inaccessible code from static and dynamic libraries for known entry points.
What next? Other games and GALE
We have been working on another game for quite some time, and we are using the experience to improve the Graphic Adventure Library and Engine. Some of the code of the engine was used for Magic Cookies! Additions and modifications will be introduced back into GALE.
Our current version of GALE already works on Android, and some Gale demos, as well as other arcade demos, are already available to beta-testers on Google Play. We share our progress on Facebook on a regular basis.
How to participate and help
We are trying to bring Haskell into game programming, and game programming into Haskell. If you’d like to see that happen, there are many ways you can help:
- Buy the game and, if you like it, please leave positive feedback on Google Play. High ratings (4-5 stars) heavily increase the chances of other people trying our game.
- If something doesn’t work or could be improved, send us an email or open an issue on our github project page. That helps us, helps you and helps other players too.
- Follow us on Facebook and Twitter, and share our news with your friends. You should tell all your friends about the game! :)
- Sign up as a beta tester. (Note: There is a waiting list; if you get in, you’ll be among the first to try new releases and new games.)
- Comment below. This post is purposefully vague in the technical details. We do not want to bore readers with programming bits. If you want to know more, just ask!
- Flattr us! The money we receive from flattr donations is used to make more haskell games.