Game On! is a competition ladder mobile web-app for two player games like Table Tennis, Pool, Chess, Tennis, Street Fighter and so on. Players on the ladder are ranked using the Elo Rating system, made famous by the FaceMash website on The Social Network.

About the code

I started Game On! as a hobby project to see how quickly I could build a web application using every RAD trick in the book that is available to the ASP.NET MVC stack. I wanted to learn Razor and play around with some MVC 4 and .NET 4.0 features. And I wanted to build the thing as quickly as possible so that I didn't get bogged down and bored. I had also been reading Eric Ries' Lean Startup book that promotes a "lean" methodology, starting with only the absolutely neccessary features and pushing a product out to "market" as soon as possible.

One decision I made was to not use a TDD methodology. Not because I don't believe in it, I do (I use TDD every day in my day job and run courses on it). I decided to take a break from TDD so that I could explore and invent without even having to consider my usage. I may add unit tests later on (that's not TDD by the way, that's just unit testing), but for a hobby project with only a few classes I am happy with my more extreme approach.

If you're in to ASP.NET MVC development with .NET 4.0 and C# then read on for some features I have demonstrated in this project that may be of interest to you.

SQL Compact Edition and Entity Framework 4.0.

I didn't want the app to ship with a dependency on a SQL Server install; I wanted the app to be as self-sufficient as possible, so I chose SQL CE, a simple single-file database. This is my second project using SQL CE and with version 4.0, things have got a whole lot easier, including full support in Entity Framework.

There is nothing that I could write about SQL CE that has not already been written by ErikEJ. Erik's contributions to the developer community via his CodePlex projects and blog are outstanding.

My co-contributor John and I ended up scripting the GameOn database schema in SQL, and creating the database using SqlCeCmd40.exe (which ships with this project). Then we create the EDMX from the database, which is a cinch with Entity Framework 4.0. The advantage of using EF is that it gives you a Domain Driven Design with entities that are generated from your data layer. The problem of how these data layer entities are mapped into domain entities is ignored in this single-tier project (the entities are referenced directly from web views), which saves a lot of boilerplate mapping code. Obviously this would not work well in an enterprise application.

Domain Driven Design

This project goes once over lightly with domain driven design (DDD). Entities are enhanced with custom partial classes - there is even an enforce invariants method on the Match entity. A thin logical Service layer has been added to segregate the web layer from any business. The services access the entities directly without the need for a repository. Linq extension methods are used as strategy specifications. The code tries to adhere to an ubiquitous language wherever possible, sometimes writing statements the long way so that they read well.

ASP.NET and .NET

I get sick of writing PagingParameter objects, so I decided to use a dynamic type to mimic JavaScript object notation, so that you can code:

model.Matches = MatchService.GetMatches(playerId.Value, new { PageSize = 100 });

Ivan Towlson would be proud! The magic unicorn1 bit is the new object that sets PageSize = 100. What type is it? What type is PageSize? What if I spell it wrong? The answer to all of these questions is "who cares!" If PageSize does not exist, is spelt wrong or is the wrong type, we just ignore it and you get all of the records instead of just the first 100. For parameter objects that, when wrong won't debit your bank balance, I think this is a cool approach and saves a few more classes.

While we're on magic unicorn dynamic types, have you used ViewBag? That is a nutty object that you can set properties of in a controller method at runtime, and your View will just have to handle the jandle if it's not there. Great for simple view models where you just don't need a full blown view model class.

I'm a big timeline and messaging fan, so I have included a TimelineService class and a TimelineMessages class that I have been formulating for a while now. TimelineMessages uses a static ConcurrentQueue from the System.Collections.Concurrent namespace as a store. If you haven't seen these amazing threadsafe collections yet (new in .NET 4.0), check them out.

Up to 20 timeline messages are held in in-process RAM at a time. When the queue contains the maximum 20 messages, the oldest is evicted when a new one is added. The 3KB or so of RAM that the queue consumes in RAM is a small price to pay for the reduction in complexity and overhead of database persistence for messages that no one is going to care about tomorrow.

Another hobby-horse of mine is custom views - implementing System.Web.Mvc.IView. It's easy and is the best way to keep good separation of concerns when dealing with non-HTML views. I use a custom view to render the Player-Match summary data as CSV. The guts of it is less than 10 lines of code.

Razor

I was Razor's harshest critic when it came out. I still think it is a marketing play to lure PHP CMS developers over to ASP.NET, which is fine by me as long as Microsoft support the language for 10 years. However I thought I had better put my money where my mouth was and give Razor a fair trial and... I love it.

If you come from an HTML web development background (as opposed to a Web Forms background) then Razor is for you. It's concise, clean and looks natural alongside HTML markup. It's also intuitive - I found it easy to learn quickly.

In this project I use Razor to render jQuery Mobile views, so there is very little markup - as I will explain next.

jQuery Mobile

This brilliant library magically creates views that work and look great in mobile web browsers. The markup is very concise, requiring only a few tags to create complex interactions and transitions. I would highly recommend jQuery Mobile for prototyping work as you often don't even need a server-side script to get mock ups working. However I can see complex mobile UIs hitting the wall with jQuery Moble when you want to heavily customise views.

For the purposes of this application, jQuery Mobile is just right. I was able to create views in a very short period of time, in fact going back to desktop views feels cumbersome by comparison. I also used jQuery and jQuery validation.

jQuery Sparklines

I love Sparklines, and I finally found an excuse to use them in a project; they portray the trend of a player's ratings over time.

Collating all of the data for every player's Sparkline is quite a considerable database hit, and could cause some wicked lazy-loading related issues if not done right. So I decided to move this query out of the initial page request/response and get the page to request the Sparklines data via AJAX once the initial page has loaded. This has the added benefit of the Sparklines data being naturally cached by the browser, reducing the load on the SQL CE database.

If you look at the span's with class = "sparkline" you will see a data-playerid attribute which my custom JavaScript function uses to match with the data returned from a jQuery AJAX code. Thanks to jQuery and Sparklines, this is all of 10 lines of code.

Elo Rating System

Finally the Elo algorithm. I borrowed Luke Durrant's C# Elo implementation and adapted it for my needs, mostly just simplifying and using my own Match DTO. DurrantEloRatingHelper implements IRatingHelper so that you can swap out your own implementation of any ranking algorithm you like, if you wish.

It really works too. We have been using Game On! at work and Elo does a great job of fairly ranking players on a ladder, based on the relative ratings of each player, which can only be built up by playing matches.

If you're interested in the mathematics in the Elo Rating System, read this fascinating blog about computing your skill by Jeff Moser.


Here are the slides from a session I did on jQuery Mobile MVC SQL CE at Code Camp NZ 2012.

If you have any comments or contributions on the code at all, don't hesitate to get in touch via the Discussions page.

1 Hat-tip to Scott Hanselman

Last edited Sep 10, 2012 at 9:22 AM by DanielLarsenNZ, version 16

Comments

No comments yet.