Monday, September 3, 2012

Rollin Droid

I have been working on prototypes for games for a while now. I tried doing:
  • a game where you rotate a shape and avoid projectiles
  • a game where you race in between planets
  • an isometric-real-time-chess game on an infinitely large board where you move a knight
but there was always something in the gameplay that didn't feel right.

Luckily, after playing Line Runner I finally did a prototype that deserved to be turned into a complete game. Line Runner is incredibly addictive, but there are several things that I would have done differently:
  • the player isn't allowed to make mistakes: one mistake and it's an immediate Game Over.
  • you play on a horizontal line. It would be better if you could move up or down.
Here's what Rollin Droid (my interpretation of Line Runner) currently looks like:


During the development I realized that I could implement wall jumps which allowed players to climb up tunnels and change direction.
Wall jumping unfortunately creates a big problem: if the player mistakenly wall jumps somewhere he's not supposed to, he ends up going in the wrong way and is very frustrated of not being able to change his direction until he finds a place where he can wall jump again. This problem isn't yet entirely solved, but can be mitigated with smart level design.



The main character is a little bugdroid that skates and collects donuts. In the game, he's a ragdoll animated using box2D, so his body/head/arms/accessories correctly reacts to his movements :-)
I doubt Apple would be very happy if I released the game on the App Store with a bugdroid as the main character, so the game on iOS (and the other non-android OS) will probably feature an other character.

Friday, June 29, 2012

"as seen at the Google IO"

I was watching the live broadcast of the Google IO when I got the pleasant surprise of seeing PewPew 2 as the (currently displayed) recommended app.

Completely unrelated, and much more importantly, Sébastien Huss has ported PewPew 2 to the Pandora consoleI've been meaning to port it to this console for a long time because it has 2 physical joysticks.
I really want to thank him as he did all the work quickly, and without any of my help.


It should be noted that porting PewPew to the Pandora would have been totally impossible had I used any closed component (Unity 3D, UDK, Marmelade, ShiVa3D...) ;-)

Thursday, April 12, 2012

Memcaching the right stuff

I am hosting PewPew's scores on the Google App Engine. I chose the GAE because it was free for small websites that stay under a free quota. Unfortunately for me, they recently lowered the free quota, and I started having to pay the minimum fee of $9/month. It's not much, but I want PewPew to keep on working forever, and $9 per month forever amounts to an infinite amount of money, which I don't plan on having.

There were two areas where I was over the free quota: the database was too large (the free quota is 1GB), and I was using to much CPU for the database requests.

Reducing the database size

The database was taking more than 1GB because I never deleted any of the submitted scores/replay. I wrote an handler that erased the lowest scores. Erasing ~400k scores cost me approximately 4$.
If you have a database with tens of millions of entries, doing operations on them can become expensive!
The handler could only erase 1000 entries at a time before timing out, so I "automatized" its call.
Now, I only have ~100k entries left, taking 792 MB. Out of those, 491 MB are used by the replays, which amounts to 23.5 days of non-stop action.

Reducing the CPU usage

I thought optimizing the CPU usage was just going to be a matter of caching the queries. Turns out, there's a right way and a wrong way to do that.

Initially, the scores for the 8 game modes were generated this way:
    for level in levels:
      query_str = get_query(level)
      scores = db.GqlQuery(query_str)
      for entry in scores:
        #write the score, player_name

And to cache the results, I did this :
    for level in levels:
      query_str = get_query(level)
      scores = memcache.get(query_str)
      if scores is None:
        scores = db.GqlQuery(query_str)
        memcache.set(query_str, scores, 60 * 60 * 24)
      for entry in scores:
        #write the score, player_name


But doing this did not improve my CPU usage, and profiling my app showed that I was still doing a lot of database call, even though none appear in my code. I assume I was not caching the entries, only references to the results. Reading the entries still required doing some database calls:



The correct way to do things is to manually put in the cache the strings and numbers you need to store, not references to the entries in your database.
Once this was done, I got the expected 8 memcache calls and divided the response time by 40:


Now the players can get the scores instantly, and I am back to paying $0/forever.

Wednesday, January 4, 2012

Icons

When writing this post I often wrote "iCon" instead of "icon"... Damn you Apple.
Anyway I got a folder full of different icons for PewPew, and I thought it would be cool to look at the evolution.




The first icon shows the classic ship shooting at an enemy, but when resized to 47x47 pixels (the original iPhone's icon size) it didn't look great. I shipped the first version of PewPew with it back in 2009, but quickly iterated on it.


I simplified it and ended up with this.
[Update from 2016: I still like its purified appearance a lot!]
I was pretty happy with it and shipped quite a few versions of PewPew with it, but at some point I decided I need to make it more eye-catching: after all, I want people to download and play the game!

Up to now I was using Adobe Flash (!) to create the graphics. I decided to learn a bit about Photoshop and was able to add a glowing outline and some gradients.
It's interesting to note that the glowing outline is done the same way in Photoshop and in-game: blur the original image and compose the result with the original using additive blending. 


I later found a Photoshop iOS icon template with which I obtained this icon. However it attracted a lot of (deserved) criticism on the Android market, because the iOS glossy look negatively stood out on Android devices.









So I removed the gloss (but kept the roundness), played with the color balance, and obtained the current PP1 icon.


In parallel I was working on PP2 (and its icon). I considered putting 2 ships on the icon, but it would have suggested multiplayer and I did not want to mislead the customers.


It seems that I attempted to unify the icons of PP1 and PP2, and ended up with this. It was a failure and was never used.


After a while I realized that the PP2's icon actually looked very plain compared to other game's icons and realized the power of adding textures. This is the current (and likely final) PP2 icon.



During my last round of experimentations I tried different color scheme and liked this one very much. I ended up not using it, but it inspired me for the Android Market banner.










Edit (23/01/2012): a reddit post complaining about the lack of coherence with the icons on Android made me discover the Android Guidelines for the application's icons.

These are the two new (and hopefully final) icons.



Unexpected Gotchas in Making a Game Deterministic

When aiming for a fully deterministic program, it is common knowledge that you have to deterministically seed your random number generators,...