Online highscore system for Haxe NME

Hello everybody.

Long time no blog, so here’s a quick catch up: I got a job at a small start up doing many varied and interesting things. The first project I was given built on my experiences with game development, and somewhat outstandingly I got to start writing a new game in Haxe NME! I can’t go in to details about the title right now, but it’s 99% complete and looking good.

One desired aspect of the game was an online leaderboard of some sort, so we can assign rewards to weekly/monthly winners. I’d never even looked at NMEs web function before, vaguely deciding I’d worry about highscores in Tower Defence “at some point”.

To my relief it’s super simple to use, and with a few php files on a server I’ve got a nice simple highscore system running… Someone’s bound to find this useful since I couldn’t find any complete samples online, so here we go…

Let’s first look at the Haxe code for submitting our data. To begin, we create a URLRequest object and give it the URL we want to load. You can then specify options for the request, GET/POST, mimetype, etc, in my code I just specify GET.

var req:URLRequest = new URLRequest(url + "?score=" + score + "&key=" + hash + "&name=" + name + "&level=" + level + "&email=" + email);
req.method = URLRequestMethod.GET;

Next we have to bind our request to a URLLoader which actually does the business, as well as setting event listeners for when we receive a response from the async call.

var loader:URLLoader = new URLLoader();
loader.load(req);

Main.eventMgr.addEvent(loader, Event.COMPLETE, this.scoreSubmitComplete);
Main.eventMgr.addEvent(loader, IOErrorEvent.IO_ERROR, this.ioError);

Simplez, our request will now fly off and things will happen. In the sample code I did see while developing I found people using IOErrorEvent.NETWORK_ERROR as well as IO_ERROR, but this gives me a compile error when building for Windows so I’ve left it out, but bear in mind it may be required on some platforms.

Now let’s worry about handling the response. Obviously in the event of an IO error you have no response, and you’ll probably just want to prompt the user to check their internet connection.

But on a successful query we can grab the response from URLLoader.data and do what we want with it. In my case, the remote php script which saves your score returns your rank and the total number of scores in the database as a JSON array, so we can display “You are X out of Y players.” This is easily parsed by haxe.JSON.parse(). On error, my PHP returns a negative number, so before we use JSON.parse (which will throw a fatal error if the JSON is badly formed… i.e, if its not JSON but just a number) we parse the value to an int to make sure it’s legal input.

private function scoreSubmitComplete(e:Event) {
  var response:String = untyped { e.target.data; };
  var intval:Int = Std.parseInt(response);

  if (intval < 0) return;

  var data:Array = Json.parse(response);
  // do something with data!
}

The flexibility of JSON makes these simple few lines of code really quite powerful – we can effectively receive huge blobs of data from a server, containing all sorts of complex objects and structures. For example in my implementation I make a second request to a second script after this initial one is complete, which returns the top 5 scores for the current level.

But now I hear you asking, “Well, what’s going on on the server?” A simple php script recieves the data and takes it’s GET parameters via mysqli_real_escape_string, this goes in to the database before it reads out the data we need to return and echos it.

And that’s all she wrote! A really simple way to do online high scores with NME. Have fun with it people!

– B