Developers guide to writing a simple Silverlight game
Introduction
In order to learn a little about Silverlight and how to co-ordinate development with a designer I joined forces with Hannah at Clear Breeze Design to write a fun little game called Olop. I thought I'd share some of the problems and tips we discovered along the way.
The Game Loop
The 'game loop' is the typical mechanism used to bring all the parts of a game in synch and display them. The difficulty with developing a game loop is to ensure that you create such a synchronization point. I'd considered using a timer (which is possible) but previously I've found them to be unreliable given a typical "desktop timer" resolution especially as stresses on the system can result in timer messages disappearing (or never arriving) from the queue. So it was of great interest that I read Bill Reiss' Silverlight Games 101 about using a Storyboard with a duration of 0. What I like about this solution is that it's at the level of the animation engine so, hopefully, many of the timer resolution issues should already be taken care of (however it is an assumption nevertheless). NB. If you do read the tutorial you'll see that Bill has included the dispatch timer method as an alternative.
I've included the initialization of the basic game loop here;
void Page_Loaded(object sender, RoutedEventArgs e)
{
StoryboardGameLoop storyBoardLoop = new StoryboardGameLoop(this);
this.gameLoop = storyBoardLoop;
storyBoardLoop.Update += new GameLoop.UpdateHandler(storyBoardLoop_Update);
}
NB Since RC0 was released creating the storyboard is easier and there is a new render event which can be used as yet another alternative
So the synchronization of the game is handled by the Update event on the storyboard, so now we've got the basic foundations for a game. However, one of the problems with using non-game dedicated hardware/software is that other things can take priority. We've all seen it, even when playing DirectX games in full screen, suddenly everything slows as the Virus checker kicks in or an email arrives. Bill uses a smart technique where the game loop times the delta between the current and the last Update. The idea is that you can use this duration to calculate the "missing" frames. E.g. You fire a shot and it moves smoothly from point A->B. Suddenly there is a delay of 1 frame where we should have rendered the shot at C, but because of the delay we didn't get chance to. Therefore when the next Update arrives we calculate that now we should be at D. The technique is great but in my experience when the game did suffer such a delay the stutter was amplified rather than disguised so I ended up completely removing the compensation. I also recently attended a Silverlight User Group where Richard Costal & Pete McGann gave a great talk about recreating Manic Minor in Silverlight. They used the delta method so I was interested in seeing how the game played. What I discovered was that for me the game suffered from the same glitches and the delta made things doubly worse. Not only did it become more noticable (as it did for Olop) but because they're using pixel-perfect detection the characters would skip detection. The made it very difficult to play because the characters would move into obstacles, miss platforms, etc. I guess like anything in software you need to see what works best for you rather than take some bloggers point of view ;). NB. It played great on the PC though.
Keyboard support
The funny thing with Silverlight is the simple things are often the hardest. Although it's easy to catch the keyboard event you have to take special care to capture them (especially when the key is constantly pressed) when the system is stuttering around. Again Bill's keyboard handler is excellent so I happily used it and can recommend it.
