OK. So you let me have one more day, and I took 3. But I got it working. After 6 days of work, I can show you Simon Squared in all its Windows Azure powered multi-player glory:
So what took me so long? Surely after getting the Windows Phone 7 emulator to talk to the Windows Azure emulator, finding a UI library for XNA and enabling multiple instances of the WP7 emulator to run at once, everything else should have been easy? If only!
Here’s what happened.
Day 4
9:00 Start by setting up a Windows Azure subscription, making use of my MSDN subscription benefits: it's pretty generous: 750 hours/month of Compute Time, 10 GB storage, 7/14 GB traffic in/out.
I get a little worried when the sign up screen tells me that I'll receive an activation email "within 24 hours" - but I'm relieved to see that within a couple of minutes of being redirected to the Azure management console (very swish Silverlight app) my subscription appears, and I can start creating deployments.
10:11 Got side-tracked into a discussion with my boss about possibilities for future products and offerings based on the work we've been doing here
12:45 Implemented the phone side behaviour for running the count down to the games beginning. Making heavy use of the Reactive Framework (which comes built into WP7) for hiding away the messiness of asynchronous calls.
13:45 Problem with WCF REST: if I return a derived type of message from my operation, the client only receives the properties defined on the base type. This is the problem that the KnownType attribute solves elsewhere in WCF, but it doesn’t seem to be working for WCF REST.
15:22 Discovered that WCF REST uses XmlSerializer by default rather than DataContractSerializer - so KnownTypes woudn't work. Also discovered that RestSharp is using XmlSerializer when sending data to the server, so not serializing inherited types in the way that DCS is expecting.
15:39 Now got inherited message types passing correctly: WCF Rest and RestSharp are both pretty pluggable, so I was able to implement a custom ISerializer in RestSharp, and a custom MediaTypeProcessor in WCF Rest, both using DataContractSerializer instead of XmlSerializer
17:30 Caught out by Http response caching. The symptom was that I’d launch a fresh HttpWebRequest, but get back stale data. Investigation showed that the requests weren’t ever leaving the phone – it never showed up in Fiddler. I spent ages prodding my Reactive Framework query, convinced that it wasn’t issuing the requests properly. Then I remembered Http Caching. In my haste, and newbie-ness, I solved the problem by putting a NoCache on all the responses on the server side. A better way would probably have been to set the WebRequest.CachePolicy.
Day 5
09:00 Thought occurs to me that I might get on faster if I don't have to keep waiting for the Azure Emulator to start up and shut down every time I build my server. Why not just run my server project directly in IIS? I try it – and WCF Http stops working. I eventually discover that the CTP bits I’m using don’t yet support HTTPS, and I had a HTTPs binding configured on my default Website in IIS.
10:30 Fortunately Cassini works - why did it take me an hour and half to discover that!
10:43 Start work on refactoring puzzle generation, so I can do it on the server side. The goal is that the server will generate rounds of 5 puzzles, and send them out to all the players in advance. Within a round, the server will send out a message saying “start puzzle X at Time T” – and thus synchronize the experience of each of the players
12:00 Working on updating the Phone side to play the puzzles that server sends out.
13:16 Finished refactoring the Game screen so that it is backed by a GameController - allowing me to implement a SinglePlayerGameController and MultiPlayerGameController.
17:20 Got some simple state machines working on the client and server. It looks something like this:
17:40 With two instances of the emulator running, I can now see the same puzzles displayed on each. The problem is, they’re horribly out of sync – player 1 might get the puzzle two seconds ahead of player 2, which for small puzzles means he’s certain to win!
Day 6
09:21 Implemented Christian’s algorithm to estimate the clock skew between server and phone. The implementation is pretty straight-forward using the Reactive Framework, and quite elegant, if I do say so myself. Remind me to show you, sometime.
10:33 Couldn’t figure out why changes I was making in the code weren’t having any effect when I ran the game. Then discovered that Visual Studio had some how set itself to “Never Build on Run”.
12:00 It’s working! Multiple players now receive the puzzles beautifully in sync, one after another. As soon as one player completes a puzzle, it vanishes from all the other players screens, and the count-down to the next puzzle begins
13:20 Implemented a scoreboard to show the position at the end of each round
14:30 Having deployed the game to my phone, I challenge Vinod to a dual – me on the emulator, him on the phone. I now discover a serious downside to being a games developer: once a game reaches playability, you inevitably get sucked into playing when you should just be testing.
15:35 Use Expression Design 4 to recreate a game logo that Neil designed using Word. What do you think?
17:05 Spitting and polishing. Tidying up the various screens. I might not have time to make them pretty, but at least I can make the buttons big enough to touch. That’s the downside of testing with an emulator using a mouse – it doesn’t alert you to the imprecision of fat fingers!
17:30 Waiting for Windows Azure to deploy the server. Visual Studio 2010 is supposed to be able to package and deploy your project straight into the cloud, but I couldn’t get that to work (something about it not being able to resolve the URL of my storage account). Instead, I uploaded the package manually.
17:45 Still waiting for Windows Azure to start up my role instance. Give up and go home.
21:00 Wife gives me permission to interrupt our traditional Thursday evening film (The Prestige last night, – recommended) to see whether the Azure role has started up yet. It hasn’t, so in the time-honoured way I tell it to reboot – and that fixes it. A few minutes later, she’s thrashing me – mainly because she’s using the phone, and I’m using the emulator over Remote Desktop (my laptop is old, and doesn’t support XNA games in the emulator) – in that setup the emulator doesn’t respond to my mouse moves!
What I need is another phone.
Ah, what’s this I see – the Windows Phone Marketplace Developer Newsletter, announcing Windows Phone 7 Handsets for Developers. The Newsletter says that local evangelists have codes for free phones to give away. I think Mike Ormond is the WP7 evangelist for the UK …