Never has it been more desirable to widely port your game. A game created for iPhone and iPad has every reason to move to Android as well. These platforms have the the same form, the same touch interface, roughly the same performance characteristics, and the same graphics system (OpenGL ES 2.0).
But why stop with Android? An active indie game community exists around Steam, so a mere desktop Windows port awaits you and Greenlight glory.
An even broader market is just one more step away, through the Humble Indie Bundle program, which targets Windows, Mac OS X, and Linux platforms.
Even if porting doesn’t make sense for your game, it often makes sense to port your game development tools. In indie game development, if your level editing tool, for example, runs on all the major desktop platforms—or better yet, on mobile devices as well—you can distribute it to a wide variety of level designers and involve them in creating your content.
I recently released my iOS haunted house game House of Shadows on the App Store. I would love to make the game as well as the in-game editor available for people running Windows, Mac, and Linux. So how do I port the game and tools widely? That’s my immediate challenge.
And theoretically, if you develop your game and tools in C++, with OpenGL for graphics and OpenAL for sound, you are 95% of the way toward platform-independent Nirvana.
But it’s always the other 5%, isn’t it?
Despite the inexorable force toward cross-platform game development, an irresistible obstacle awaits you: the lack of an adequate common platform layer.
Most game code is intrinsically platform-independent, particularly when OpenGL and OpenAL provide major interfaces to the hardware. What remains is general application setup, windowing, and input. To make a game work on Windows, for example, a moderate amount of Win32 code must be written to create the game window, attach it to OpenGL, and to deliver mouse, keyboard, and controller input events to the game code. On iOS, the game needs an ApplicationDelegate, a window and view, and touch handling functions—all in Objective-C. Each platform has its own API—sometimes driven by a certain required language—for setting up the main window, connecting it to OpenGL, and processing user input.
A common platform layer is a library that abstracts these platform-specific tasks into a single interface that remains consistent across all platforms. For graphical applications like games, GLUT, SDL, and GLFW are well-known solutions. A library like GLUT, for example, promises that you can write your game code once, without platform-specific finagling, and it will work on a wide range of platforms. A recompile on the target platform is all that’s needed.
At a time when so many similar platforms are so readily available to the developer, you would think that libraries like GLUT and SDL would be having a heyday. Alas, they are not. The major common platform layers are in various states of disrepair and neglect. Here’s a quick review of the various options.
GLUT. Although GLUT itself has not been actively developed since 1998, in the late 2000′s a fairly vibrant development community arose around a new implementation—FreeGlut. This library offers all the essentials—platform-independent window setup, OpenGL integration, and input—that a game developer needs. Written in C, it is pleasantly simple and undemanding, and would seem an excellent solution.
Unfortunately, FreeGlut has some shortcomings that make it unable to help a game achieve wide portability. It supports Windows well, and Mac and Linux reasonably well. iOS and Android support—along with the multitouch capabilities they will require—have not yet appeared, however. FreeGlut hasn’t been updated since January of 2012, and the previous significant update was in 2009, so the project’s development momentum is poor.
If you want a common platform layer that supports both the major desktop and mobile environments, FreeGlut isn’t ready now and may never be.
SDL. SDL 1.2 was very widely used in the mid-2000s, but it didn’t support mobile platforms. SDL 2.0, a successor that has been in development for the last couple of years, looks very promising. It offers support for all the major platforms including iOS and Android.
But a glance at the SDL website tells you something is wrong. SDL 2.0 is barely mentioned. When you find it, behind a link titled “SDL HG”, you see that it’s marked UNDER CONSTRUCTION. This is no idle threat. When I tried it for iOS, Mac, and Windows, I found various failed tests and bugs.
SDL 2.0, like FreeGlut, is promising but unready.
GLFW and SFML. Both of these lightweight alternatives to GLUT are well-maintained and nicely designed. But neither of them supports mobile.
Chrome Native Client. This recent technology is an interesting option for C++ game developers interested in portability. Like all of the above libraries except for SDL 2.0, it doesn’t support mobile. But it allows games to be distributed and to run directly in the Chrome browser, using natively-compiled code, anywhere Chrome runs. So it’s no solution for a fully mobile/desktop common platform layer, but it’s an intriguing technology in its own right. It might be a good choice for platform-independent game tool development, which tends to center around the desktop.
What Else? Alack, we have come to the end of the list. Of the major common platform layers, none of them is both (1) stable and (2) capable of abstracting both mobile and desktop platforms. If you know of a better option, please let us know in the comments below.
In the meantime, this means that the best solution is one of the following.
- Roll your own. This is actually not as hard as it sounds. My own engine, Fresh, until recently supported all the major platforms (including mobile and desktop) by providing its own common platform layer. The implementation for each platform amounted to no more than 400 to 1000 lines per file, most of which was fairly trivial, bureaucratic code. The code itself is not the challenge in writing your own common platform layer: it’s the maintenance. Platforms change constantly, and testing across multiple platforms is a time-consuming exercise. It’s possible to roll your own common platform layer—but I’d rather use somebody else’s.
- Extend an existing library. If you’re feeling altruistic, you could get involved with the FreeGlut project, for example, adding iOS and Android support yourself. Doing so would mean learning FreeGlut pretty deeply, supporting all the features it supports, and conforming to their development process. Or did I mention rolling your own?
- Roll your own while piggybacking. My own engine’s platform-specific code, written about three years ago, directly targeted Windows, Mac, and Linux as separately platforms. If I did it again today, I wouldn’t address each of these platforms independently. Instead I would treat one of the desktop-focused common platform layers that I mentioned above—FreeGlut, GLFW, SFML, or Chrome Native Client—as a single, unified “desktop” platform, and then treat iOS and Android as two additional platforms. That would mean I only need to support three platforms instead of five.
Surely thousands of indie and casual game developers would love to spread their games and/or tools across all the major mobile and desktop platforms. It’s beyond me why a vibrant, fast-moving development community hasn’t sprung up around a simple, portable common platform layer library that supports all these platforms. Maybe I’ve overlooked one?