Tuesday, April 16, 2013

Adding Mobile Service to Whack-a-bug - PART 1

In a weak (beer influenced) moment on the Microsoft Windows Azure Gaming Summit on April 9th I promised someone that I'd make a point out of how simple it would be to add an online hiscore list to my development tool/game called "whack-a-bug". Since I'm a man of my word I sat down and did so. In less than an hour.

Whack-a-bug is a game, designed and constructed within 8 hours just to prove a point that developing for Windows Store is easy and deployment is fast.

"The game is very simple, whack those bugs and avoid destroying unit-tests."

The features I added was the ability to post your score to an online hiscore-list if your sprint is successful. Authentication will not be included in this first post but my plans are to incorprate that in a subsequent post.

So the outline of my work is

  • Create a Mobile Service
  • Wire up Whack-a-bug to that Mobile Service
  • Post data to a hiscore-table
  • Retrieve the hiscore list
  • Play the game!

And YES I know, since we are not adding authentication, anyone can post using any name at the moment. :)

Create a Mobile Service

The process is pretty straight forward. I browsed to http://www.azure.com and sign in (create account if necessary).

I selected "MOBILE SERVICES" on the left and clicked "CREATE NEW MOBILE SERVICE". The dialog below appeard and I simply typed in whackabug as the URL. A also chose to create a new database, you can also select an existing database. Lastly, I set the region to East US.

The service is then created for you. It takes less than half a minute to have it up and running. When it's done it looks this.

Wire up Whack-a-bug to Mobile Services

It's very simple to wire up you application. Just select the platform you are interested in and read the instructions. In my case it's a Windows Store app and I've already installed Mobile Services SDK. The SDK is also available on nuget.

What I did was to copy the codesnippet to my project as described.

Post data to a hiscore-table

Mobile Services is configured default to accept dynamic schema. That means that we just have to create a simple POCO with our required fields. But you do need to create the table in the portal. I created a table called "HiscoreEntry". The name is important to remember since you need to create a POCO class with the same name.

In the Create New Table dialog you enter the name of the table and then set permissions. For the first part of this blog series will just allow any application with the correct application key to perform any CRUD operation. The application key is a long string that I masked out in the code snippet we copied in the step before.

The POCO I created looks like this.

 public class HiscoreEntry  
   public int Id { get; set; }  
   public int BugsKilled { get; set; }  
   public string Username { get; set; }  

Simple enough! One thing worth pointing out when using dynamic schema is that you must provide a value for nullable types, like string. Otherwise the serializer will serialize this as JSON object with the value set to null. Mobile Services cannot create a column based on null since it wouldn't know the type. Check out this blog post for some more info around this specific tip: http://timrayburn.net/blog/working-with-dynamic-schema-in-azure-mobile-services

Well, back to Whack-a-bug. The UI needed to be modified. I added a textbox for the username and a button to submit the score to the game over control. These are only displayed if the sprint was successful. We also check that we have entered something in the box before posting it.

The post method looks like this:

 private async void SubmitScore(string username, string bugsKilled)  
   var item = new HiscoreEntry()  
     Username = username,  
     BugsKilled = bugsKilled  
   var table = App.MobileService.GetTable<HiscoreEntry>();  
   await table.InsertAsync(item);  

Error handling code is omitted for the sake of simplicity. But you should wrap the insert in an exception-handler.

Retrieve the hiscore list

I needed a placed the hiscore list in a UserControl with the pinned note background. The data is displayed in a grid. After that I wrote some code to retrieve the hiscore list. For this we need to query mobile services for the top eight players. Why eight? I didn't feel like redrawing the background! :)

I also make use of the wonder that is await/async when I populate the data into the grid.

 public async void ReloadData()  
   var table = App.MobileService.GetTable<HiscoreEntry>();  
   var list = await table.OrderByDescending(e => e.BugsKilled).Take(6).ToListAsync();  
   HiscoreListView.ItemsSource = list;  

The HiscoreListView is a simple ListView with an ItemTemplate defined like below.

     <ListView x:Name="HiscoreListView" Width="200" Canvas.Left="59" Canvas.Top="66">  
           <Grid Width="170" Height="30">  
               <ColumnDefinition Width="1*"></ColumnDefinition>  
               <ColumnDefinition Width="1*"></ColumnDefinition>  
             <TextBlock Grid.Column="0" Text="{Binding Username}" FontSize="18" Foreground="Black" />  
             <TextBlock Grid.Column="1" Text="{Binding BugsKilled}" FontSize="18" Foreground="Black" TextAlignment="Right" />  
         <Style TargetType="ListViewItem">  
           <Setter Property="Height" Value="30" />  

That's it!

You can download it by clicking on this link!

Of course, the obvious problems with this example is that we don't have any error handling and no user authentication. The error handling will be added before I submit the final version to the store. When I do so, I'll edit this post and add what I did below.

Wednesday, April 10, 2013

Microsoft Windows Azure Gaming Summit

Just got home from an amazing event at Heathrow. The visit started of with some beer in the bar the night before the offical event. Had a great talk with Peter Warman, CEO of Newzoo. That guy know what he's talking about and opened up my eyes on the importance of market analysis. His talk at the summit the day after was even better! Might have been the best talk of the event.

Rob Craft from Microsoft also delivered a great talk about the cloud and games. It amazing to watch the transformation of Microsoft to the open alternative that it is today.

Also a couple of sneak previews of some great upcoming games, like Galaxy Fire and League of the Damned.

And what I would see as one of the coolest games out right now, Galactic Reign from Microsoft Studios. Check it out!

I also promised at a week moment to write a blog post of how easy it would be to start using mobile services by adding a leaderboard to my game Whack-A-Bug (created in 8 hours to test out the Windows Store Certification experience). So I'd better get started on that aswell.

Also we got a lot of new input on the subject of our game WordRoom and where we should take it in the future.

Friday, April 5, 2013

TFS, Git and Xamarin Studio (on Mac)

Two things that could be handy to know if you are trying to use TFS Git and Xamarin Studio on Mac.

1. The username cannot contain @
2. If you mistype your password, you have to remove the keychain entry (http://forums.xamarin.com/discussion/2514/change-version-control-credentials#latest)

Both will fail with an UnauthorizedException and no further info.

And for the first part to work you must specify an alternative login. This is well documented when you've created your repository however.

EDIT: Still some trouble with pushing to remote GIT. Everytime I want to push I have to:

 1. Delete the keychain entry
 2. Enter my credentials
 3. An error message is displayed, but the changes are pushed anyhow

Hopefully this will be fixed in the 4.0.4 release!

Thursday, April 4, 2013

Accessing non-Mobile Services tables in Server Scripts

This is a useful how-to if you are using Mobile Services as an addition to an already existing system. When setting up Mobile Services you need to specify a database. If you specify an existing database you can access the data from the tables within it but you must allow access to the Mobile Service user.

The problem is that you cannot use SQL Server Management Studio's nice graphical tools to do so since this is Sql Azure. It's time to write some queries!

Prereq - you are familiar with Mobile Services Server Scripts. If not, check out this great video from Nick Harris.


The Scenario

Let's say you have a table in Mobile Services called Notification. (The tables are named directly after the POCOs, hence no pluralization at the moment). The main function of this table is to allow us to intercept insertions to it and send out notifications.

What we also can do is to query other tables within this script.

    var sql = 'select Name from Users where Id = ?';
    mssql.query(sql, [item.UserId],
         success: function(results) {
              console.log("The name is " + results[0].Name);
         error: function(error) {
             console.log('Error querying sql: ' + sql, error);

If you run this directly you will get an access denied message looking like this:

Error querying sql: select Name from Users where Id = ? { [Error: [Microsoft][SQL Server Native Client 10.0][SQL Server]The SELECT permission was denied on the object 'Users', database 'YourDatabase', schema 'dbo'.] sqlstate: '42000', code: 229 }

The fix is to grant rights to this user.

Step 1 - Identify the Mobile Services user

Open Sql Management Studio and select the database (in this case 'YourDatabase' in lack of better example naming.


select * from sysusers where isSqlUser = 1 and hasDbAccess = 1

This will return a number of users. Look for the one having a name simular to AMJCKxGdWNLoginUser. (a bunch of random letters and the LoginUser).

Step 2 - Grant rights to this user


THAT'S IT, you are good to go!

In addition, if you need to insert or delete data then grant the appropriate permissions.