Successful apps are sticky; they make us want to come back again and again, whether it’s to check in on Foursquare, send a Tweet, or get a quick answer from ChaCha. Of all the types of apps, games can be the stickiest – Angry Birds anyone? or in my case Wordament!  A great idea and implementation are obvious ingredients for success, but you also want to capitalize on opportunities to get your users re-engaged when they aren’t running your app or game.

Enter notifications, which come in two main flavors – tiles and toast – and the great thing is that your application doesn’t have to be running to receive them! A tile can update itself on a regularly occurring interval, and an external service can push information at any time to your users via the tile or by triggering a toast notification. The more engaging and dynamic your application tile is, the more likely it will beckon the user to re-launch it from the Start screen. Likewise, the more compelling and personalized a toast message is the more likely the user will switch to your app from whatever they are doing.

It’s this latter scenario we’ll take a look at in this article – specifically in the context of an HTML5 game. What could be a stronger call to action to drop what you’re doing and re-play a game than just being informed that someone has knocked you out of the top position on the leaderboard!

During the course of this post, I’ll cover four primary themes, with supplementary materials available from the right sidebar:

  1. Connecting to the cloud – setting up a Windows Azure Mobile Service
  2. Setting up the HTML 5 Sample Game – modifying the sample game to use the mobile service
  3. Adding a leaderboard – creating a very rudimentary leaderboard in the mobile service
  4. Trigging the notification – triggering a toast notification to the user that was ousted from first place

Connecting to the Cloud

It should come as no surprise that you’ll need some sort of centralized repository for managing game assets that are shared by all the users – like the leaderboard. The cloud, Windows Azure specifically, is a great place to host common data with little work on your part: the cloud provider, Microsoft in this case, manages all of the hardware assets and provides guaranteed uptime backed by Service Level Agreements. And with the newly launched Windows Azure Mobile Services, you can set up both storage and push notification capabilities with minimal coding on your part – freeing you up to concentrate on your game!

To take advantage and explore the possibilities, get yourself a free 90-day Windows Azure Trial Account and be sure to activate the Windows Azure Mobile Services feature as shown below. The feature is currently in preview, so it does not appear automatically when you view the various services in the management portal.

Activating the Mobile Services Feature

I’ve found the option is provisioned nearly immediately, so you should be able to create a new Mobile Service right away.

Create a new Mobile Service

The key elements you need to supply to create the new service are highlighted in the two wizard screens below.  Each service will have a public endpoint – mine is simplegame.azure-mobile.net. There is also a Windows Azure SQL Database supporting this service with the admin login I provided. Both the database and the services are located in the East US data center, which is currently the only data center available in this phase of the preview.

Windows Azure Mobile Service creation

After the service has been created, take note of the Application Key, which is accessible via the menu bar at the bottom of the portal. You’ll need that and the unique service endpoint URL (*.azure-mobile.net) later.Mobile Service access key

Setting up the HTML 5 Sample Game

Sample HTML 5 gameTo keep the article focused on the notification theme, versus the game itself, I opted to start with the HTML 5 JavaScript game sample on the Windows 8 Dev Center. It’s pretty simple: you simply see how many times you can touch the bouncing ball before time runs out, and it does maintain a local leaderboard which we’ll expand into the cloud.

After you’ve downloaded and installed the Mobile Services SDK, add a reference to it within the sample application.

Adding reference to Mobile Services

You’ll also want to insert a reference to the Windows Runtime Component in the default.html file as follows:

 7:      <!-- WinJS references -->
 8:      <link rel="stylesheet" href="//Microsoft.WinJS.1.0/css/ui-dark.css" />
 9:      <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
10:      <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
11:      <script src="/MobileServicesJavaScriptClient/MobileServices.js"></script>
12:   
13:      <!-- App references -->
14:      <link rel="stylesheet" href="/css/default.css" />
15:      <script src="/js/assetManager.js"></script>
16:      <script src="/js/movingAverage.js"></script>

The sample game implementation leverages a game JavaScript template that you could adapt for your own games as well. A key component of the template is the GameManager class, declared at the end of the default.js file. That’s a convenient singleton object to which to add a client reference to the Windows Azure Mobile Services, as shown below:

 WinJS.Namespace.define("GameManager", {
     navigateHome: navigateHome,
     navigateGame: navigateGame,
     navigateRules: navigateRules,
     navigateScores: navigateScores,
     navigateCredits: navigateCredits,
     showPreferences: showPreferences,
     onBeforeShow: onBeforeShow,
     onAfterHide: onAfterHide,
     game: game,
     state: state,
     assetManager: assetManager,
     scoreHelper: scoreHelper,
     gameId: gameId,
     touchPanel: touchPanel,
     mobileService: new Microsoft.WindowsAzure.MobileServices.MobileServiceClient
         ("https://simplegame.azure-mobile.net/", “<<<---- REDACTED ---->>>")
    });

Adding a Leaderboard

The premise of the notification I want to implement is that when you are knocked out of first place in the leaderboard by another player, a notification will be initiated letting you know and inciting you to reclaim your position at the top. That necessitates having at least a rudimentary leaderboard implemented, so to do that, I’ll leverage the data feature of Windows Azure Mobile Services.   There will be a server component, configured in the Windows Azure management portal, and some code added to the existing sample application.

Server component

Player name setting on Game Options flyoutThis leaderboard is quite simple and tracks only the player name, score, and level. This game doesn’t have a player registration system, so the players will be identified by whatever name was supplied on the Game Options on the Settings flyout (see right).

You might decide to incorporate your own player registration system or perhaps tap into existing identity providers like Microsoft accounts, Facebook or Twitter to authenticate player identity.  Windows Azure Mobile Services can help with that too, but that’s a topic for another post!

To store the scores, I created a table within my mobile service called leaderboard. I didn’t provide a schema, because by default the schema will be created dynamically when I add data to the table; however, an unique clustered index column called id is generated for me. In production you’d turn the dynamic schema feature off (via the CONFIGURE tab of the mobile service), but for now it’s quite convenient.

Via the DATA tab of the mobile service, I created a table called leaderboard.  You’ll notice there are options to control the access permissions for the various CRUD operations; this is where you might lock down access to only authenticated users or even allow access to say the leaderboard from other applications. As alluded to previously, for this scenario access to the table data is via the application key, which was used to initialize the mobile service client in the GameManager class earlier.

Creating a new table in Windows Azure Mobile Services

I also created a second table called users to contain additional information needed to implement push notifications, as you’ll see later.

Client Component

With the server table in place, I just needed to hook up the client code to add a new record to the database every time a game has been completed.  The sample code already has some hooks in it for the local leaderboard, so I add just a bit of code in scores.js to add a new record to the leaderboard table. The insert method here is asynchronous, and I did not supply a callback routine, so the actual leaderboard displayed in the game will continue to function as it did previously.

Here I was just interested in sending the score to the mobile service. Creating a user experience for a second ‘global’ leaderboard is beyond the scope of this article, but if you look as the functionality of the sample application (specifically in scoresPage.js), you’ll see there is some infrastructure there for multiple high score tables.

    // Check if a newly achieved score should be added to the score table, ...
    // Return value of 0 indicates the submitted score was not good enough to ...
    newScore: function (score) {

        scoresTable = GameManager.mobileService.getTable("leaderboard");
        scoresTable.insert(
            {
                player: score.player,
                score: score.score
                skill: score.skill
            });


        var newScoreRank = 0;

        // TODO: Update this function to match the sort of your score table

If you were to add this code and play the game a few times, you’d see new records added into table via the BROWSE menu of the leaderboard table as shown below.

Leaderboard data in Windows Azure Mobile Services

Triggering the Notification

In Windows 8, push notifications are handled via the Windows Push Notification Service (WNS), which is hosted and managed by Microsoft.  WNS works in conjunction with the Notification Client Platform, which is part of the Windows 8 operating system, as well as with your Windows Store application and a service that you maintain in the cloud to trigger the notifications. The process is captured by the image below, with a complete explanation of the workflow available on the Windows Dev Center.

Push Notification workflow

For our gaming scenario in particular, the workflow is as follows:

The game requests a push notification channel from the Notification Client Platform on the local machine (1). The Notification Client Platform communicates with WNS (2) which returns the notification channel URI to the application (3). This URI uniquely identifies the device and the application and so will be the endpoint for future push notifications. The URI is opaque and should not be modified; furthermore, it expires after 30 days, so best practice dictates that the application renew its channel each time it runs or even as part of a background task.

The Windows Store application is responsible for maintaining the list of notification channels, which it does typically via a cloud service that triggers notifications at the appropriate times and sends them to the affected application users. In this simple HTML 5 game, the URIs are keyed by player name (4) with each player name associated with the device on which they last played the game. Remember there is currently no authentication mechanism in the game, so the last user to claim a name ‘wins.’  Obviously this would need to be rectified for a production-ready game, but it’s not a critical to understanding the push notification scenario.

When a player completes a game, his or her score is sent to the cloud service, which then checks to see if the new score is the high score. If so, the service looks up the notification channel URI for the player who was just ousted, creates a toast notification, and fires it off via WNS (5). At that point, WNS takes over and delivers the toast to the appropriate client (6) where it is surfaced to the former champion.

The steps to implement push notifications include a configuration step in which the application is registered to receive notifications followed by bit of coding in both the Windows Store application and the “Cloud Service.” In this case, the “Cloud Service” is Windows Azure Mobile Services, but in general any network accessible server that can authenticate with WNS can be used.

Notification Registration

To set up the application to receive notifications, the Package Display Name and Publisher of the application as shown in the Package.appxmanifest are provided to Step 2 of the Windows Push Notifications & Live Connect page:

Push Notification configuration

On Step 3 of the Live Connect page, three values are provided. The first, Package Name, replaces the package name in the Package.appxmanifest within Visual Studio, and the other two are provided to the mobile service (PUSH tab) in the Windows Azure Portal.

Push notification configuration

Client Component

As shown in the workflow diagram, the process starts with the client application securing a notification channel. An applications request the channel, typically at startup, using the asynchronous createPushNotificationChannelForApplicationAsync method. In default.js, I added the following code to set a notificationChannel property on the GameManager when the success callback fires.

    Windows.Networking.PushNotifications.PushNotificationChannelManager.
       createPushNotificationChannelForApplicationAsync().done(
           function (c)
           {
               GameManager.notificationChannel = c.uri;
           }
       );

Since the game provides an option to change player name, it doesn’t make sense to record the notification channel at the start of the application, because no one has yet played a game or registered as score. In fact, it’s possible multiple players might play on that same device, so there may not be a one-to-one correspondence of user and notification channel.

Instead, I opted to store the notification channel with the player name whenever a player completes a game. Since I established the simple rule that the user will be notified on the last device from which he or she played, the easiest way to ‘update’ the users table is issue a delete followed by an insert, right before the code that was added to update the leaderboard table.

        if (GameManager.usersSeen[score.player] === undefined) {
            userList = GameManager.mobileService.getTable("users");
            userList.where({ user: score.player }).read().done(
                function (results) {
for (var i in results) userList.del(results[i]); userList.insert( { user: score.player, uri: GameManager.notificationChannel }); GameManager.usersSeen[score.player] = true; } ); }
 

The usersSeen associative array records the players who have played during the current application execution, so they are not repeatedly registered in the users table every time they complete a game.

Server Component

Default server script for insert actionEarlier in this post, I showed how to set up Windows Azure Mobile Services to send push notifications to the HTML 5 game. The only step left is to trigger those notifications (and craft some compelling notification text, of course).

A notification should go out to the previous top scorer whenever the newly entered score is higher. The easiest place to trigger the notification then is within the insert script of the leaderboard.  Each of the CRUD operations on a data table has an associated server script, implemented via node.js, which can be used to execute custom business logic on the server.

The default insert script (right) simply executes the incoming request, but additional logic can be added, such as to detect when a new high score has been achieved and then push a notification to the dethroned player. The script I used to accomplish this appears below, followed by a line-by-line breakdown:

   1:  function insert(item, user, request) {
   2:   
   3:      mssql.query("select player, score, uri " +
   4:                  "from leaderboard l, users u " +
   5:                  "where (l.player = u.[user]) and " +
   6:                  "(l.player != ?) and " +
   7:                  "(l.score = (select max(score) from simplegame.leaderboard))",
   8:                  [item.player],
   9:                  {
  10:                     success: function(results) { 
  11:                        if (results.length > 0 && results[0].score < item.score)
  12:                        {
  13:                           notify(results, item);
  14:                        }
  15:                        request.execute();
  16:                     },
  17:                     error: function(err) {
  18:                         console.log(err);
  19:                         request.execute();
  20:                     }
  21:                  }
  22:      );
  23:  }
  24:   
  25:  function notify(results, item)
  26:  {
  27:      for (var i in results)
  28:      {
  29:          push.wns.sendToastText02(results[i].uri, 
  30:          {
  31:              text1: "HTML 5 Sample has a new champ!",
  32:              text2: "Hey, " + results[i].player + ", " + item.player + 
  33:                  " just took high score with " + item.score + " points. " +
  34:                  "Time for revenge?!"
  35:          });
  36:      }
  37:  }
Line 1 The insert function takes three arguments: the item to be insert (JSON), the user identity requesting the insert (when authentication is set), and the request object that carries out the insert.
Lines 3 - 7 A query is defined against the leaderboard and users tables.  The players with the highest score are returned along with their associated notification channel URIs (the latter stored in the users table).
Line 8 This JavaScript object array defines the parameters for the query, noted in the query text by ‘?.’ Here the query is passed the name of the player just completing the game. If that player bested her own top score, it doesn’t make sense to send her a notification, hence the clause on Line 6.
Line 10 - 14 success defines the asynchronous callback that occurs when the query has completed. If the player just achieved the high score, the results object will contain the information for the players that were just knocked out of first place. That object is passed to the helper function, notify, defined later in the script.
Line 15 The original request, namely to add the score to the leaderboard for the just completed game, is carried out.
Line 17-20 If there’s some problem with the query, a message is written to the log, which is viewable from the LOGS tab of the mobile service in the Windows Azure portal. The original request to add the new game’s score to the leaderboard is still performed.
Line 25-37 The function notify is called whenever a new high score has been achieved. Passed to the function is the information for the new high score (item) and the information (results) for the players who previously ranked at the top.
Line 29-25 For each player that had or shared the high score, a notification is sent to his device informing him that his reign is over! Here I’ve used a toast notification consisting of one emboldened line followed by two lines of wrapping text. There are eight different toast notification options that might be used, however, with different display characteristics, including images support.

Toast notificationThe experience might look a bit like that on the left for Joe, assuming that Julie just played a game on her Windows 8 tablet, and he was busy doing some Excel spreadsheet analysis at work.

What happens next? When Joe clicks on the notification, the activated event is triggered and so he’ll start up the HTML 5 game in his bid to reclaim the top position.

What if Joe happens to already be playing the game when the toast arrives and he clicks on it?  Well, nothing in this case.  He’s already in the application, so a click on the toast will be ignored (unless there is a launch attribute, which has not been provided in this case).

That does bring up a user experience point to consider: should a toast be displayed at all if the user is already running the application. In most cases, the application should simply absorb the new information into its display without additional fanfare. Think of Outlook for instance. When you are working with your in-box, do you really need to see toast notifications of new e-mails? They are popping up in your in-box already so the toast adds little value and can even be annoying. If you do want to ignore notifications for any reason, subscribe to the pushnotificationreceived event and set the cancel property to true; you can still introspect the notification content and act on it silently.

And that’s it! With just a little bit of coding and some great support from Windows Azure Mobile Services, we’ve put the ‘social’ into a previously solitary and isolated experience and hopefully addicted a few more users to our game!