Bitmite Blitz! A Postmortem of sorts

Posted by (twitter: @coinflipgames)
May 1st, 2014 3:15 pm

31135-shot0Hey, folks. Coin Flip Games here to tell you about our entry for LD29, Bitmite Blitz. We’re incredibly proud of this game and wanted to make sure YOU got a chance to play it. If you’re not convinced, here’s some of our favorite reviews we’ve gotten so far!

“Super fun game. I have highscore! for now :P” – tehryanx (Still has the high score, btw)

I love games that put me in a perspective I never would have thought to explore. Great game!” – greysphere

This is definitely one of the most polished games I’ve seen in the LD. Having an achievement system is an impressive addition, given the time constraint.” – StencylTuo

Good game, it gives me the same feeling as Flappy bird which is a good thing.” – Sparrow

So go give it a shot already!

 

Back? Okay. I wanted to talk a bit about how we accomplished the global leaderboard. I’d love to see more games with this feature because I think it adds a whole new dimension.  So, to start, you can implement this in any language or game engine you would already be using. Some (like Unity) will make it easy than others, however. You need 3 things, a server to host the scoreboard api and scores, you game and a communication layer between them. Ideally, you want to have something in place to prevent people from adding fake scores as well. Screen Shot 2014-05-01 at 2.46.38 PM

 

Set up a database of some sort. Use whatever you would feel comfortable with and if you’re not comfortable with anything, use MySQL or sqlite. You can get away with, as a bare minimum, a single table: scores, but that’s not so much fun, is it? You can easily use this in a bunch of games if you do it right the first time.

  1. Set up your database engine (mysql in our case)
  2. Add a database and user. Make sure that the user permissions make sense. Don’t give them GRANT access to anything. Ever.
  3. Add the tables as below:

Screen Shot 2014-05-01 at 3.48.16 PM

Alright! Done with the database for now. Now we need to setup the API. I’m going to leave the actual implementation up to you (as an exercise or something), but the functionality you’ll need is…

  1. To receive input from the web in some well defined format. I used PHP to get data as JSON. You could use Ruby, Python or whatever fancy language you want. You could use XML too if that’s what you’re into.
  2. Check the input to ensure that it’s valid. (Did this come from a legitimate source? Does the input make sense?)
  3. Sanitize the input. (Can’t stress this one enough)
  4. Perform some action on the data. (Run the command ‘getScores’)
  5. Return results in some well defined format. (Package up the results of the command as JSON and pass it back)

And on the client-side (game) we need to do the same thing, but in reverse. The client needs to build these requests and be able to parse the responses. Since I used JSON, I’ll show our request as an example.

{

cmd: ‘Leaderboard/getScores’,

api_key: ‘…’, (I’ll get back to these)

signature: ‘…’,

time/token: ‘…’

}

And the server would spit back

{

[‘name’: ‘Awesome Bitmite Blitz Player’, ‘score’: 100000],

[‘name’: ‘Awesome Bitmite Blitz Player 2’, ‘score’: 10000],

}

 

Easy enough. The trickiest part is ensuring that the scoreboard can’t be tricked into allowing scores that aren’t legitimate. That’s where the API key and secret come in. For every game that will use this leaderboard, generate some random string for the API key and some random, hard to guess string for the secret. The database knows what these are and your API can check them out no problem. You’ll also need to let your game know what these are and if you’re lucky enough to have a compiled language, they’ll be safe from curious eyes. (if you release the source code for your game, strip both out).

So now the server API and the game both know the API key and secret. Great. Now let’s use them to generate a signature for all the requests that the game client will make.

 

Screen Shot 2014-05-01 at 4.06.22 PM

So the idea is that both the client and server can construct the signature independently and compare them, but prying eyes cannot. The key, secret and a time/token are needed so that requests to the same API resource (getScores) won’t always generate the same signature. It’s secure because the secret is… well… secret.

(There might be some of you that recognize this pattern. It’s basically the same model that Amazon Web Services uses.)

So that’s the basic idea. Here’s some resources to use if you want to implement it yourself:

Cheers! I hope someone can get some use out of this!

Tags: , , ,


5 Responses to “Bitmite Blitz! A Postmortem of sorts”

  1. Great post, just can’t help but put in 2c re: malicious-user security:

    >> if you’re lucky enough to have a compiled language, they’ll be safe from curious eyes.

    Er, that’s not quite true. Even native assembly is pretty readable these days. Make sure to base relative to a checksum of your binary or something to try and detect tampering. Ultimately, though, you’re trusting the client since you’re not computing scores on an authoritative server.

    Another way to make this wall higher is to return a valid response even if the validity or sanitization checks fail – that way hackers *think* they’ve spoofed the system , even when they haven’t.

  2. Sparrow says:

    Very useful information. Might try adding something of a scoreboard for the post-compo version of Sand Runner Arena. Also thanks for using my comment and adding a link to my game ♥.

  3. @little_polygon: True. That’s a really good point. There are always going to be ways around a security measure. The methods you suggest definitely would help if put into action.

    @Sparrow of course!

  4. jimmypaulin says:

    Hey thanks for this! Something that concerns me – even in a C program you can run “strings ” on the binary and any string liberals will pop out e.g “mysecret1234banana”

    Also what is the difference between api key and secret in your example if u don’t mind?

    Thanks again!

  5. jimmypaulin says:

    Ps I used a similar system to log analytics last LD in case you are interested 😉

    http://www.ludumdare.com/compo/2014/01/06/midnight-minigun-analytics/

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]