Local flash game leaderboard tutorial

Update I’m stopping updating my whole blog and don’t have time to fix the confusing points of this post so if you get stuck there are some questions about this post answered on This StackOverflow question.

This tutorial is about how to create a local leaderboard in ActionScript 3, the principles will work on mobile in AIR or on the web. See completed project at the end of the post.

In AS3 ais used to store data to the player’s computer. In the case of a local leaderboard we want to store high score’s between games and then display them in a sorted order. Note since we’re only storing data locally ( as opposed to networked ) this will only show score’s on that machine and more complex methods would require a server component.

1. Initialize where data will be saved

Main.as 

private var m_FlashCookie:SharedObject;
private function init(e:Event = null):void
{
  //...
  m_FlashCookie = SharedObject.getLocal("LeaderboardExample");
  //...
}

2. “Play Game” and store the results of that player’s session. In the case of the example this is simply done using static variables in the Main document class.

StateGame.as 

Main.EntryScore = parseInt(m_InputBoxScore.text);
Main.EntryName = m_InputBoxName.text;

3. Fetch our saved leaderboard object of high scores. shared_object.data[“KEY_NAME”] will return null if nothing has been stored with that key.

StateLeaderboard.as

// Shared Objects store everything as untyped objects so we cast it back to an array as we will store it later
var arr:Array = Main.Inst.getSaved("TopScores") as Array;
if ( arr == null)
  arr = new Array();

//----------------------------

Main.as
public function getSaved(key:String):Object
{
  return m_FlashCookie.data.key;
}

4. Push the latest score that the last gameplay session added into the array storing the leaderboard data

StateLeaderboard.as 

// create the object that stores the data that just got created from our last gamestate
// we can add multiple stats in here if we wanted, for example "enemies killed" and "coins collected"
// in this case we just use score as an example so we have only one number to sort on
var latest_score_object:Object = {
  name: Main.EntryName,
  score: Main.EntryScore
};
// push the last score onto the list
arr.push( latest_score_object );

Note: this means that we might now have 11 scores in the array instead of the top 10.

5. Sort the leaderboard so it’s in the order we want it to be in

StateLeaderboard.as 

// sort the list from highest to lowest based on the "score" figure.
// the key here can be anything stored in the lastest_score_object entry.
arr.sortOn("score", Array.NUMERIC | Array.DESCENDING);

6. Remove extra entries in the array so we only save the “top 10”

StateLeaderboard.as 

// if adding the score from the last game made it so there were more than 10 items of the list, remove the last #11.
// since the array was sorted on the line above that means that the last score will be in the right place regardless
if ( arr.length < NUM_SCORES_SAVED )
{
  arr.pop();
}

7. Flush/Save the new leaderboard This makes it correct for next time.

StateLeaderboard.as 

// This key name must match the name we used above in step 3.
Main.Inst.saveData("TopScores", arr);

//--------------------

Main.as

// Function to store data by key.
public function saveData(key:String, dataToSave:Object):void
{
  m_FlashCookie.data.key = dataToSave;
  var flushStatus:String = null;
  try
  {
    flushStatus = m_FlashCookie.flush(10000);
  }
  catch (error:Error)
  {
    trace("Error...Could not write SharedObject to disk\n");
  }
  if (flushStatus != null)
  {
    switch (flushStatus)
    {
      case SharedObjectFlushStatus.PENDING:
        trace("Requesting permission to save object...\n");
        m_FlashCookie.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
        break;
      case SharedObjectFlushStatus.FLUSHED:
        trace("Value flushed to disk.\n");
      break;
      }
    }
}

8. Loop through all the leaderboard data and display it in a human readable way.

StateLeaderboard.as 

// In this example implementation we display all our data in a single textfield.
// In a real game we'd probably work with an artist to put these on seperate lines or a grid
var myHTML:String = "";
var total_stored_scores:int = arr.length;
for (var i:int = 0; i < total_stored_scores; ++i)
{
  // loop through every entry, every entry has a "name" and "score" field as that's what we save.
  var leaderboard_entry:Object = arr[i];
				
  // is this the last score that was just entered last gamestate?
  if ( leaderboard_entry == latest_score_object )
  {
    myHTML += (i+1) + ". <b><font color=\"#0002E5\">"+ leaderboard_entry.name + " " + leaderboard_entry.score +"</font></b><br>";
  }
  else
  {
    myHTML += (i+1) + ". "+ leaderboard_entry.name + " " + leaderboard_entry.score +"<br>";
  }
}
m_TF.htmlText = myHTML;

9. Rinse, repeat and observe.

DOWNLOAD EXAMPLE:
Flash Develop or Flash Pro CC project source of the complete example.

Speedy Free Flash Game Programming Review

I’ve been away from flash for a few months and decided it was time to do a quick review. But after being a professional flash developer for several years what to do? Also I had the additional problem that I didn’t have access to useful tools like oh I don’t know the Flash Authoring tool.
I wanted to do something that was easily skinnable so it had the feel of a normal flash game that suckers would buy you would see on normal portals.

This is what I came up with after a day: FIV Find it

I used a few public domain images, FlashDevelop IDE, Paint.NET, and goldwave. I’d recommend this combination to any exploring programmer with limited art resources. Making an entire hidden object scene in a few hundred lines of code.

As for the numbers you get on Kongregate for putting less than a day of work in something and not having an artist: 200 plays and 17 cents after 3 days. Fun fact. This is with only facebook shares and being briefly listed on the new games section.

Making this tiny game was fun enough where I’ve rejuvenated my plan of constant side projects.