The tech talk: Jewels edition

As promised in my last post: let's dive in to find out what makes Jewels 2 tick (up to 60 times per second ;)). To better understand where we are coming from, here is a "brief" recap on how Jewels (the original) came to be, and frankly — why it sucks on technical level:

History of original Jewels

Back in late 2007 (or was it 2006? Not even sure any more!) I decided to try C# and XNA programming, just for fun. I needed something simple to try, and I didn't want to do Asteroids yet again (I've done at least three versions, the best of which is Ultimate Steroids, from 2001), so I picked a match-three gem swapping game. After a month or so Jewels was released as an alpha version (I finished it about 5-6 months later). That was for the XNA platform, PC only.

Alright, fast forward to 2009. I wanted to try Android programming and got myself a brand new HTC Hero. After a few weeks of hacking I had ported the XNA game to Java and Android 2D Canvas APIs (in retrospect, should have used OpenGL ES from the get go). The game was released to Android Market (nowadays known as the Google Play Store) and became a surprise hit.

I kept fiddling with the game, adding new things, fixing bugs, but there was no denying it had become a bit of a mess, code-wise. The thing was never designed to work in such an environment where the game could be suspended at any time and later resumed. Or be killed. Also, when I was working on the game Cupcake (Android 1.5) was the norm and I had of course not prepared to support resolutions other than 320×480 (remember it was a practise project), that came with Donut (Android 1.6). That has haunted me all these years: the support for various resolutions and aspect rations in Jewels was — and still is — horrible! And yes, I have done it better for the sequel. ;)

To further explain why the Android-Jewels is so lame: when you port existing code base from platform A to (very different) platform B, there is great potential for awakening some serious bugs and problems. This probably happened with Jewels: somewhat hacky XNA written-for-practise code, hastily converted to shady Java code.. Let's just say it would not necessarily yield the most stablest of code bases to build upon. :P

Personally I had tested the game on several devices without much problems (excluding obvious bugs I have fixed), yet there is loads of people with these same (as well as different) devices having all kinds of problems, crashes (force closes as they're called in Android), freezes and what not. I do take the blame for these problems, the code being the mess it is, and me having to learn all these mobile programming things/quirks that I have not encountered when coding for the PC. It's been a huge learning process for me, but there is light at the end of this tunnel: all the hair pulling has forced me to write more robust systems for the sequel. :)

* * *

Onwards to the sequel!

Now that we've "briefly" covered the murky origins of Jewels, we can talk about what I did for Jewels 2, to avoid many of the problems listed above.

Somebody may wonder: what about iJewels (the iOS-version, that is)? Wasn't that rewritten in C++ and much better than the Android-version? Yes, it was rewritten and used OpenGL ES as the original should have used as well. The game was much better performer, and quite stable, but the actual game play logic code is still the same (although ported from Java). For Jewels 2 99% of the code is new.

For the sequel, I had some (technical) design goals:

  1. The game should work across variety of resolutions and aspect ratios.
  2. The game should work across variety of devices: phones, tablets, budget devices, high-end flagship devices.
  3. The game should work across different operating systems with least amount of effort: Android, iOS, QNX (Blackberry Playbook), …
  4. The number of 3rd party components kept as minimal as possible
  5. The game should start up as quickly as possible
  6. Particle effects. :D Gotta have particles!
  7. The game should be robust and stable, and preferably not crash too often, losing player progress. I've reduced repeating memory allocations and used pools, which help avoid trashing the heap as much.
  8. Probably more goals that escape my mind at the moment. (I hadn't written these down before.)

Let's open up some of those points.

Number 1. Resolution independence. This is must for any game, and something the original clearly lacked. I've spent quite a bit of time making sure the game scales up properly from 240×320 to 1536×2048, for example. I had to give up being pixel perfect (like iJewels is on Retina-display), though, due to long list of resolutions in use in today's devices. It is not perfect by any means: I don't really support landscape mode, since the game just works and looks better in portrait, but I do have some compatibility code in place to have it run letter-boxed on landscape (tablet) devices. This is mainly for things like keyboard docked Android-tablets.

Number 2. Device compatibility. Partly covered in point #1, but I have also tried to keep the code fast enough to run on lower end devices as well as higher specced devices. I test the game regularly across 15+ devices and it just works on all of them. For example the game runs (and is playable, >30 fps) on Samsung Galaxy Pocket and HTC Explorer (about ~100 EUR devices), all the way up to Galaxy S3, HTC One X and 3rd gen. iPad! The only requirement is support for OpenGL ES 2.0, which rules out some older devices (including iPhone 3G, and my old HTC Hero), but even most of the budget devices support GLES 2 these days. (I could probably work in support for GLES 1.1, but currently I'm not doing it since it is lots of extra work and well, it's 2012 after all.. :P)

Number 3. Supported operating systems. Instead of having separate and different looking versions for different platforms, I wanted to have a common code base with as little platform-specific code as possible. For the base I chose to use BatteryTech (v1.1), which helped getting the Android and iOS projects up quickly. I actually ended up not using much from BT but the platform specific game loops (with modifications), (some of) the audio code, asset loading for iOS (for Android I rewrote the asset loading in native code to avoid JNI usage) and some utils, like a hash table implementation (again with some modifications).

So currently I have Android and iOS versions working nicely, and these are the main platforms I am going to release for, when the time comes. I'm hoping to integrate the Blackberry Playbook OS support from the next BT so I could release for the Playbook as well.

What about Windows Phone? Well, WP7.x is out of the question as it will not support native code (C++). WP8 is an option, but it is not a trivial port since I'd need to rewrite the rendering to utilise Direct3D instead of OpenGL ES. Not a show stopper though. Should the good people at Microsoft, Nokia or HTC be reading: I'd love to have a WP8 device for testing (say, a Lumia 920 or HTC 8X) — I would definitely want to have Jewels 2 for Windows Phone as well! :)

Number 4. 3rd party components. I've had a fair amount of problems with various 3rd party libraries: ad libraries, social components, etc. So I will try to integrate as little 3rd party stuff as possible. As for ads: I plan on releasing a paid version (or an in-app purchase) to get rid of the ads, as I know many people don't like them and would rather pay for the game.

For social component (i.e. online leaderboards, score sharing, perhaps achievements), I'm still unsure what to do. At the moment I'm planning to use only the platforms own service: that would be Game Center for iOS, Game Circle for Amazon Kindle, Scoreloop for Playbook, etc. There is one huge problem though: unfortunately Google doesn't have any game services to offer as of this moment, which is quite peculiar if you ask me. I feel that tightly integrated gaming service will only do good for the platform, as long as it's optional and not intrusive. I have my hopes up for Google to unveil something eventually, just not sure if I get the game out before that! Feel free to comment: should I use platform specific services (will lead to better UX and more stability IMHO), or should I utilise Scoreloop or Gree or something else that is common across platforms?

Number 5. Quick start up. With this kind of casual games I feel it's important to get the player quick into the actual game play (something that certainly is not the case with original Jewels), so I have tried to make the game start up faster. I implemented a multi-threaded resource loading system that offloads texture and sound loading to another CPU core, added some custom texture formats that load faster etc. Granted, the game is not yet done (not all of the resources are there yet), but so far the start up is quite fast even on lower end devices.

Number 6. Particle effects. Do I really need to expand upon this? I have some cool particle systems just recently implemented and they're awesome! :D

* * *

So that was some of the ways I've tried to improve the tech behind the game since the first one. I must say I'm really happy how the game "just works" now; I try various low-end devices with weird CPU/GPU combos expecting it to crash, but instead it works, shaders and all! :)

I'm confident Jewels 2 will be much better experience for lots of people with wide range of different devices, compared to the first one. Technically speaking (i.e. the game working and not crashing/freezing all the time). Not to mention there's loads of game play, sound and graphics improvements coming as well, so stay tuned for more! :)

* * *

TL;DR: The original Jewels was crappy, Jewels 2 is better! :D Also, someone at Microsoft/Nokia/HTC: please send me a Windows Phone 8 device! ;)