Millionsofgames, part three
October 11th, 2005, By Duncan Gough
The code behind Millionsofgames.com.
The MOG codebase is a straight extension of the same codebase that was originally written for Blue Square games (http://bluesqgames.net/). It has since been used to create Chickstop and was then extended to handle the huge load that a redesign to Playaholics required. The code has been running happily and is easily extensible since it’s OOP from the ground up. Using the same codebase for MOG was an easy choice. However, as with all code, over time it’s become crufty. MOG gave me the oppportunity to clean up the code, creating a modular site that should handle a few more iterations of work on Playaholics and Chickstop.
Using PHP was the only option since, when the codebase came into existence, Ruby on Rails and Django weren’t available. Both are serious contenders should we ever move away from PHP though. MySQL however, has always been up to task of handling a popular gaming website, making sure to use InnoDB tables and some sensible caching with Cache Lite, of course. As for a a database abstraction layer, I’ve used Pear DB in the past but MOG runs happily with ADOdb, which, besides a few annoying peculiarities, has been great.
Since MOG makes great use of RESTful urls to make the process of browsing the site and discovering new games user friendly, it made sense to use of a front controller in combination with some mod_rewrite magic. However, as a lot of people have pointed out with regards to front controllers, they can be overdesigned. MOG pulls back from implementing one huge front controller that loads up rules and data for every possible request before processing it (one of the main complaints about Front controllers is that they end up loading large rulesets or XML documents for every request, which is a waste of time and memory). After all, as a few people have pointed out, Apache is the Front Controller, especially when used in tandem with mod_rewrite. For MOG, I was able to break up the domination of the front controler by using multiple controllers, letting mod_rewrite decide which one is loaded. This works perfectly since the site has a few areas that are significantly different from one another and they would have created a single, large, ruleset-laden front controller. Thankfully, having spent some time designing the URLs of the site so that they were somewhat RESTful, breaking up the front controller into smaller components was easy. For example, the main list of games is housed in the /games/ section of the website. Accordingly, the Members pages live in the /members/ url space. By looking at these two key areas of the site, I was able to segregate the two biggest chunks of code into two sepearate front controllers using mod_rewrite rules that delegated the reqeusts as required. In terms of extensibility, doing the same thing to handle RSS feeds was just as easy.
The side effect of this has been two-fold. Adding new components to the site is a clean process since, for example, user inboxes would have their own front controller and mod_rewrite rule to match. From what I’ve seen, it’s a lightweight version of Django’s packages system. More importantly, though, the RESTful urls and multiple front controllers have created a simplistic object mapping system. Having recently read a great article on the different methods of doing this, MOG seems closest to CherryPy. Finally, having a grown up approach to URLs and objects across the website, MOG also has a sensible approach to separation of business logic and rendering. There has been plenty of debate about PHP temaplating solutions such as Smarty and whether they are really needed. I’ve used Smarty and will continue to do so but for MOG, PHP is the templating language. I’ve created a dead simple, OOP based approach that relies on the standard PHP library for rendering the raw data as HTML. And, of course, it’s easy to flip a switch, use mod_rewrite to points all URLs that start with /rss/ to an RSS front controller and let the templating system return the correct, rss based template.
Besides all that, my favourite feature in MOG, the one that I didn’t expect to like, is the link tracking. To help us create a Google PageRank for casual games, we need to track the popularity of each game and to do that would normally means mungeing the URLs so that every external link goes to a tracker page on our site. Doing this is a proven way of tracking external links but it also makes every external link look as ugly as sin as it has to look something like this – http://www.millionsofgames.com/track/?q=http://www.playaholics,.com/play/jewelthief/ – which, I think, should give you an idea why I wasn’t keen on pursing that idea. Furthermore, if MOG is to be of any benefit to the sites and developers that host the games, a clear referring URL is much better than an obfuscated one. However, with the help of Google and a fair bit of searching, I found a nice, clever way of tracking external links without touching the URLs, leaving us with clean HTML and no redirect slowdowns since it uses Ajax behind the scenes (plus it’s a nice way of making use of Ajax without the flashy and uncalled-for UI effects):
Web 2.0 needs Data 2.0
The real problem with tagging web applications, though, is the volume of data. del.icio.us has suffered a few slow downs and I would love to see what hardware that site runs on (well, I’d love a shell so I could watch it real-time, but I just don’t think I’ll get access…). With the benefit of the tagdb mailing list and the tagschema blog, I’ve been able to build MOG with plenty of foresight. For example, tags, in MOG, are first class objects.
For anyone building a tagging website, these two articles are well worth a read:
Following on from which, some cold hard stats from Philipp Keller regarding the performance of several popular approaches to tagging:
Most tellingly of all, the question of scalability is answered with a prediction that meta-sites will start to crop up, providing social bookmarking to specific areas of interest, like Millionsofgames.com does for casual games – http://www.pui.ch/phred/archives/2005/08/does-delicious-scale.html
So where does the MOG database setup go next? The ‘trinity of User, Tag, Item’ as discussed by Nitin Borwankar leads me to believe that fact tables are going to be neccesary for MOG before long. I’m a stickler for 3NF style database tables so this approach is clearly the right way to go.
What else is left, then? For the users, the main hurdle is no longer registration but rather it is adding a game to MOG. The del.icio.us bookmarklet is a clever invention but getting that onto a users’ browser is hard. Which is why we created some screencast style movies for new users to watch:
That’s not enough though, so we’ve got some more ideas on how to streamline that MOG IT! process.
Besides all of that, we’ll have to take a closer look at our popularity algorithm to see if we can turn it into a Google PageRank for casual games. All in all, these are exciting times and I’m pleased to see how Millionsofgames performs as a citizen of both the Web 2.0 and Casual Games worlds.