So you created a little game and published it to the marketplace pretty pleased just for getting something out there. Soon users through reviews are asking for an online leaderboard. That’s what happened to me and my “tetris” game, Metro Blocks. First you think of building one yourself, thinking it can’t be that difficult. But then you think about hosting, scaling, security and domain and you start thinking that it might be better to check out what people have done. A colleague of mine pointed me to the http://www.mogade.com who provides a free service to casual game developers. And the rest of my post is dedicated to using mogade as leaderboard.



Step 1: REGISTER

Go to https://www.mogade.com/manage/accounts/register to register an account. NB the confirmation is LUIGI for those not familiar with the Nintendo classic.



Step 2: SETUP GAME INFO

Log in to mogade and Create your game first and then your leaderboard. Should be straightforward. Notice that your game has an id and a secret key assigned. We will use them later when we setup the code.



Step 3: DOWNLOAD LIBRARY

Now you have your account setup, you’ll need to get the library/sdk to integrate it into your solution. Go to https://github.com/mogade/mogade-windowsphone to download the latest version. If you are not familiar with git just download the latest zip file with the solution. Then it’s just a plain old Visual studio solution. Remember to unblock the zip file before unpacking it if you have Windows 7.

After unzipping, open the solution and compile. In you bin/debug or release you will find 3 dlls that you are going to reference in your solution. So open your game and add references to:

– Mogade.Windows.Phone.Core.dll

– Mogade.Windows.Phone.dll

– Newtonsoft.Json.Silverlight.dll (Used for serializing json)



Step 4: INTEGRATE CODE

The nice thing about Mogade library is that it does the heavy lifting for you. No need for xmlserialzing, calling webservices or such. We will just use the api provided for us. All the code samples are taken from a demo game I made called Armageddon which full source code is attached.

First I wrap the Client/Provider in a custom class called MogadeCommunicator. It basicly just acts as a singleton to be used by my scoreservice.

public class MogadeCommunicator { private const string GameKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Replace with your game key private const string Secret = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Replace with your secret private static IMogadeClient _client;</code> public static IMogadeClient Client { get { if (_client == null) { _client = CreateClient(); } return _client; } } private static IMogadeClient CreateClient() { // Initialized the configuration our client should use to uniqly identify the user. // We'll choose the recommended combination of Phone's unique Id + username. MogadeConfiguration.Configuration(c => c.UsingUniqueIdStrategy(UniqueIdStrategy.DeviceId)); _client = MogadeClient.Initialize(GameKey, Secret); if (NetworkInterface.GetIsNetworkAvailable()) { _client.Update(null); _client.LogApplicationStart(); // This is only needed if you want reporting on usage. } return _client; }

With our client setup, let’s move over to our leaderboardservice. It pretty simple and provides 3 methods : GettingLeaderboards, GetUserRanking and SaveScore which basicly all you need for a leaderboard. Worth noting is it that I use another great framework MVVM Light to act as a publish/subscribe messeging system. That means that the responses from Mogade are wrapped into my custom events and published. That means you can subscribe to when leaderboards are recieved and put the result out to the user.

Another thing to be aware of is that I use the Deployment.Current.Dispatcher.BeginInvoke() to marshall the data back to the gui thread. That is because my game is in Silverlight.

public static class LeaderboardService { private const string LeaderBoardKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Replace with your leaderboard key private static readonly IMogadeClient Client = MogadeCommunicator.Client; /// <summary> /// Retrives the ranking of user and raises UserRankingRetrievedEvent when retrieved /// </summary> public static void GetLeaderBoards() { // Doing it easy, get all leaderboards since we aim to display them. Client.GetLeaderboard(LeaderBoardKey, LeaderboardScope.Overall, 1, OverallScoresRetrieved); Client.GetLeaderboard(LeaderBoardKey, LeaderboardScope.Weekly, 1, WeeklyScoresRetrieved); Client.GetLeaderboard(LeaderBoardKey, LeaderboardScope.Daily, 1, DailyScoresRetrieved); } /// <summary> /// Retrives the ranking of user and raises UserRankingRetrievedEvent when retrieved /// </summary> /// public static void GetUserRanking(string userName) { if (string.IsNullOrEmpty(userName)) return; Client.GetLeaderboard(LeaderBoardKey, LeaderboardScope.Overall, 1, userName, UserRankingRetrieved); } /// <summary> /// Saves a Highscore to Mogade, and raises ScoreSavedStatusEvent when completed (successfully / or not) /// </summary> /// public static void SaveScore(Highscore highScore) { var score = new Score { UserName = highScore.UserName, Points = highScore.Score, Data = highScore.GetScoreData() }; Client.SaveScore(LeaderBoardKey, score, ScoreSaved); } private static void UserRankingRetrieved(Response e) { if (e.Error != null) return; if (e.Data.User == null) return; Deployment.Current.Dispatcher.BeginInvoke(() => { var payLoad = new UserRankingRetrievedEvent { ScoreWithRank = e.Data.User }; Messenger.Default.Send(payLoad); }); } private static void ScoreSaved(Response e) { Deployment.Current.Dispatcher.BeginInvoke(() => { var payLoad = new ScoreSavedStatusEvent { Success = e.Success, Ranks = e.Data }; Messenger.Default.Send(payLoad); }); } private static void OverallScoresRetrieved(Response e) { if (e.Error != null) return; RaiseLeaderBoardEvent(e.Data.Scores, LeaderboardScope.Overall); } private static void WeeklyScoresRetrieved(Response e) { if (e.Error != null) return; RaiseLeaderBoardEvent(e.Data.Scores, LeaderboardScope.Weekly); } private static void DailyScoresRetrieved(Response e) { if (e.Error != null) return; RaiseLeaderBoardEvent(e.Data.Scores, LeaderboardScope.Daily); } private static void RaiseLeaderBoardEvent(IEnumerable scores, LeaderboardScope scope) { if (scores == null) return; // Make sure we invoke the response onto the GUI Thread Deployment.Current.Dispatcher.BeginInvoke(() => { var highscores = new List(); int rank = 1; foreach (var item in scores) { var highscore = new Highscore(); highscore.Ranking = rank; highscore.Score = item.Points; highscore.UserName = item.UserName; highscore.UpdateWithScoreData(item.Data); rank++; highscores.Add(highscore); } // Setup and publish leaderboard event var payLoad = new LeaderboardRetrievedEvent { Scores = highscores, Scope = scope }; Messenger.Default.Send(payLoad); }); } }

So that is basicly the 2 classes needed to get started. To see the full interaction download the source code. It’s a very basic game and I think the code shouldn’t be to complex. It’s created for demo purposes but published to the Markeplace (with some deservedly bad reviews :)) . For other Silverlight coders I think there is some Helper classes that can be useful.



Quick Summary:



MVVM Light – Laurent Buignon’s lightweight MVVM framework. Mogade – http://www.mogade.com – Excellent Free leaderboardservice brought to you by Karl Seguin. Also make sure to read his ebook “Foundations of Programming”.MVVM Light – Laurent Buignon’s lightweight MVVM framework. http://mvvmlight.codeplex.com/



Myself

Just an average developer, more graft than craft. Trying to give something back to the community after spending my career picking up snippets from the web. Feel free to ask me anything:



Here is the solution, remember to rename file extension to .zip (It’s a bit big ca 20mb)