The most inspiring green screen you will ever see
While Haskell, Idris and other Functional Programming (FP) languages enable writing elegant code, the road to production is, well, bumpy. Writing code for industrial environments has added costs that make certain products too expensive and infeasible in practice. That is why, when a new business model is available for FP-ers, the community wins. That is why you are about to see the most inspiring green screen you will ever come across.
The importance of reaching users
One of the most important aspects if we want to make Haskell succeed is to reach customers. The process of creating software does not stop when programs are written: we must reach users, we must help solve a real problem. That’s precisely the most expensive part in Haskell: software may be robust, tidy, and elegant, but much of the cost lies elsewhere. Deploying to the desktop, for instance, requires compiling for various OSs, architectures and versions of each OS, which may include compiling against several versions of some libraries. Then the program must be packaged, which also is OS (and version) dependent, and the package tested on a fresh installation (same deal).
For some programs and customers, that is quick and easy. For the general public and for applications such as Keera Posture, full recompilation and packaging is hardly automatic and takes at least a full day of work. And then you need to find the users. That’s why Haskell is more likely to succeed in the server than in the desktop: deployment is easier and cheaper. That’s why it’s so important to have one standard channel and platform through which we can reach customers.
At Keera Studios we have experimented with all sorts of ways of writing FP apps and games for mobile. From Prolog to Scala to AJHC’s Android backend, every path so far has been possible, but costly. But today, the field has changed. We have reached a turning point for Haskell.
Haskell on the go
The idea of writing Haskell code that runs on mobile phones, tablets and other portable devices is incredibly seducing. Computing is changing, CPUs are now omnipresent and unnoticeable. It’s an exciting time to be a programmer. The way people install and buy small applications on mobile platforms now makes it much easier for users to reach programmers and for programmers to reach users. If Haskell can be used in this new mobile reality, it will enable business models that may help us prove, once and for all, that FP is the next best paradigm.
A great part of the the way has already been paved by the existing support for iOS on GHC and GHC’s Android backend. But, to the best of our knowledge, commercial exploitation of such backends is currently minimal (for reasons that we are not equipped to discuss).
Keeping it simple: doing graphics with SDL
SDL (Simple Directmedia Layer) is a multimedia game programming API that has been used in commercial games (such as Angry Birds) and is simple enough to enable using backgrounds, sprites and simple 2D graphics that we can design ourselves. 3D graphics are much more expensive to produce, and without the infrastructure of a large gaming studio, we cannot afford to do 3D.
Our current games & engines are all implemented in SDL 1.2, but SDL2 is officially supported on Android and easier to get running. So, the first thing we had to do was to port software to SDL2. This might seem irrelevant at first, but Haskell’s SDL1.2 API is clean, tidy and maintained, and for SDL2 there are several, partially incomplete bindings. (The question of API coverage is often asked by professional programmers who want to try Haskell and one of the aspects that worries them most, so it’s important to understand how mature the bindings are.) We decided to use hsSDL2, and SDL-image, SDL-ttf and SDL-mixer as linked from that project, instead of the current API available on hackage which does not include Audio and Font support. While the chosen bindings do not cover all of SDL2, it was nearly enough to get most of our game running, and we only had to write a few more definitions. Porting the game and completing the missing SDL API took about two full days of work.
Compiling Haskell code for Android
GHC officially supports iOS now, but we happen to use mostly Android. That’s not a commercial decision as much as a fact of life: at Keera Studios, we all have Android phones. Our first attempt was to use AJHC, but that’s a no go. AJHC seems to work well and the OpenGL example showing a rotating cube certainly is impressive, but many language extensions are not supported.
Because most projects use those extensions, we had to ditch AJHC in favour of GHC’s android backend. GHC’s backend is not officially supported, but it works very well, and the instructions on the README file allow anyone to get a working installation very, very easily. We tried them in several computers, and they’ve always worked.
Writing Haskell code that runs on Android is actually quite trivial. Once the compiler is in place, and inside the chroot in which you have installed GHC for ARM, the following works fine:
$ cat Test.hs
main = putStrLn "Hello world"
$ ghc --make Test.hs
Now from outside the chroot, you can run:
$ adb push ghcandroid/debian-chroot/home/androidbuilder/Test /data/local/Test
$ adb shell
It was incredibly exciting to see that happen. But we wanted to see more, we wanted to use every library available on Hackage, and we wanted to make games.
Writing SDL apps in Haskell
If we compile our programs statically and run them manually from the command line, then the procedure is exactly the one described above: just compile, push and run. The problem is that Android applications to be deployed on the market cannot be written this way. At least when it comes to SDL games, a Java application creates the drawing surface and calls SDLmain, which in turn executes our program. That means our program must be converted into a library, and our main (the Haskell program’s entry point) renamed.
The procedure is not incredibly complex, but it takes a long, long time, both to explain and to execute. It also involves several manual steps to find, compile and include all Haskell libraries, so we’ll leave that for a future post.
But here’s the amazing part. After a lot of work, and once we had created an Android project with all libraries, including a demo Haskell module that painted the background screen, we installed the Android APK file on a Galaxy Tab and this is what we saw:
When that happened, we were quite thrilled. To the inexperienced, this may look just like any green screen. But it meant much more. It meant that Haskell was running on an ARM Android device, and that Java was calling Haskell as C via it’s Foreign Function Interface (FFI), which in turn was executing correctly (including its Runtime System), and calling SDL’s C API also via the FFI. It meant all communication between Android, Java, Haskell and C was working fine, we were not missing any libraries, and the packaging script was producing valid APK Android packages.
Running a real game
We wanted to go one step further and run real games, with graphics, with pictures, loading resources, fonts, menus… the whole nine yards.
We are going to save you the tension, but every new program that we ran on the tablet, each testing just one more feature, made us ever more excited. After several days of work, we were able to see the following screen:
What you see it not a screenshot of a static program, but a full breakout game implemented in Yampa, with menus, sound, levels, lives and power-ups. That was quite a thrill.
The desktop version of this game can optionally be controlled with a wiimote and a kinect, and you can follow the progress here: https://www.facebook.com/keerastudios.
We didn’t make an effort to improve the performance of this program. The code was compiled with -O2 optimisation level. The Android version runs a bit slower than the desktop, but the current performance is more than enough for games produced with Gale IDE. For real-time arcade games, such as the one above, we’ll need to optimise the code and improve the architecture, both to increase the FPS and to handle low FPS with no serious precision loss.
Present and future
The big picture, as you can probably imagine, is exhilarating: Haskell is now one of the very few statically-typed, high-level, functional, compiled languages that work, without substantial changes to the code, on Linux, Windows, Mac, Android and iOS. Even more than that: we can write full games in this language and start targeting all platforms. It is not theoretical anymore, it is not a long-term goal or a dream, it is a reality.
We are currently working on a full version of a Haskell game for Android (we’ve been at it for a while; we have a working internal demo, and we are improving the gameplay and the graphics). All the code that involves general purpose libraries (SDL2-*, Yampa, hcwiid, freenect, etc.) will be released as Open Source as we go along. Eventually, we’d like to make the game’s code open too. But for that, we need your help. We need people to follow our progress, to tell others about what we are doing and when the time comes, to have fun playing the game.