Turning Manchester's Bus Data into an HTML5 Game

April 27, 2013

Pac-Manchester Screenshot

Last month (23rd - 24th March 2013) we took part in Future Everything's 24 hour Routes to the future: An Innovation Challenge hackathon. The goal was to

“build new, useful applications from TfGM’s data that will improve the public transport experience for people of Greater Manchester”.

So we stepped into our programming pentagram and summoned from our keyboards two digital demons:

Click to Pac-Manchester Pac-Manchester (3D/Laptop/Desktop). Made in the weekend, not as much a game as a visualisation.

Click to Pac-Manchester Super Bus Odyssey (2D/Mobile/Laptop/Desktop). A mobile-friendly version, that took us a bit longer than a weekend, not as much a visualisation as a game.

Is HTML5 the right technology for games?

We wanted everyone to be able to play our game (note, that's different from everyone wanting to play our game), so we chose to make it an HTML5 game, the theory being there would be less coding and more rolling in a pit of money.

Property Pros Cons
Runs in the browser Will work on any device with one (desktop, laptop, mobiles, tablets and whatever nostril controlled devices they have in the future). Native code will probably always run faster.
Only write the code once Writing for the browser not an operating system. Browser quirks. Dealing with different implementations of HTML5 can eat hours of your life, especially when developing for mobiles.
No installation User just visits a URL. No plugins or downloading of files needed. Game isn't actually installed. A user will need to bookmark the application or you will need to wrap it up as native application.

Using open data to create Pac-Man where buses are ghosts

You (a human being in real life) boards a bus, whips out your smart phone and starts playing Pac-Manchester. You enter a familiar, yet fantastic world where:

Chorley cakes, delicious when buttered

  • bus routes are your only path ways;
  • buses are your sworn enemies;
  • your existence is sustained by collecting Chorley cakes.

Is using real world data to create a game a good idea?

Yes, because

  • you can take any correctly formatted data (e.g. bus routes) and create a new world,
  • users may enjoy playing in a world that is familiar to them.

No, because

  • the real world wasn't designed to be fun, it wasn't even designed.
  • data is noisy, you don't get everything for free.

Get dirrty - with data

We used the following datasets:

The bus routes data looks like this in Google Earth. Gotta ride 'em all

From these datasets we derive a graph that describes the bus routes and a set of traversals over the graph that describe the movement of buses throughout the day.

Creating this graph isn't straight forward, as Aguilera et al famously quipped:

“If you ain't dirty, you ain't here to party”.

In this week's issue of Heat!: REAL PEOPLE, REAL DATA

The schedules gives you buses journeys in terms of a sequence of bus stops and timestamps. But it doesn't tell you on which roads the buses travel, so you can't make them travel around a map.

The routes data tell you the path a service follows (sort of), but it doesn't link the path to the roads. So, if two services follow the path, you have two path over the top of each other.

Also, the paths aren't perfect: they are a set of out-of-order non-continuous lines. You can see this in the plot below there are gaps and plenty of duplicate points.

Raw data

To clean this data we created a program that took the raw routes and flattened them into a connect graph with duplicates and overlaps removed (see the plot below). It also mapped the bus stops to the graph, allowing us to move buses around properly.

Cleaned up

Starting in 3D

With our level generated from the data, we needed a way of visualising it. During the weekend hackathon we used three.js to create "Pac-Manchester".

Pac-Manchester Screenshot

At the Hackathon we were lucky enough to win the Developers prize (voted for by the participants) for our creation.

What were we to do with a monkey? Well, we thought it best to buy time to actually make it work on mobile phones. You see, although it ran well on our laptops,on mobile devices it ran at 1fps - which was a big problem as we wanted people to be able to play while they were on the bus.

one frame per second, not quite good enough

Going down to 2D for mobiles

Our criteria was, on the mobile devices we had at hand (Android 2.3, iPhone 3S iOS 6.1.3, Windows phone 7.5), to have a game that ran a playable frame rate of 30 frames per second.

Initially we went loopy on the premature optimization juice, which left us with an unmanageable mess. It did however allow us to pin down what actually made a difference to the frame rate, and it was all to do with drawing on the canvas.

The main things we did to make it run well on the mobile devices were:

  • pre-rendering the background (the roads, nodes) to an off screen canvas and displaying the current view on the canvas,
  • using integer coordinates (as opposed to floating point numbers) to stop anti-aliasing being performed, squeezing out an extra 5 fps out in some cases,
  • using a small view port: 320 by 320 pixels.

permanent alpha


Since the move to mobile meant we were dealing with pixels, we decided to add a little charisma to our circles and give them a fresh lick of sprite art. We render them to their own canvas then on each frame copy the corresponding portion to the world canvas.

Here's the player sprite map.

The player

And a Boose.

A nasty boose

We created them using Aseprite

Finally, a note on Microsoft oddities

In a past life, Microsoft gave us devices running Windows Phone 7. We were foolish enough to to try and make the game run on them. And again Microsoft succeeded in sucking away a day of our lives, to save you the time brave traveller,

  • width=device-width doesn't work.
  • They don't issue touch events, the just do click with a massive delay making it almost unplayable.

For now, forget mobile gaming in Internet Explorer, Satan couldn't be bothered with implementing anything useful.