robburke.NET
© 2010 Robert Burke
All Rights Reserved.

If you’re authoring multimedia applications in Silverlight, you might be interested in how each of the core game engine services for Legend of the Greasepole is now implemented for the Silverlight 2 Beta.

From C/C++ to a Provider Model-Based .NET Engine

Some brief history to explain how we got here: Greasepole’s first incarnation was manky C/C++ stuff that I’d perf-optimized to bits back in 1997-98. Trainwreck stuff.

Migrating that C/C++ mess to a C# mess involved writing a lot of Visual Studio 2008 macros. These macros could gain surprising insight into non-compiling half-C++, half-C# code, in order to sweep through and perform laborious changes.

What came out the other end of the refactor was a C# core engine for the game that required the implementation of five platform-specific services:

  • RenderingService,
  • SoundService,
  • InputService,
  • GameTimerService, and
  • GameSettingsService.

I previously implemented those services for the XNA version. Now let’s look at the Silverlight versions of these services.

Silverlight RenderingService

When each frame is rendered, the engine ultimately requests that the RenderingService draws a series of sprites from particular “frame descriptions” or “FrameDesc”s (a vestigial name, essentially meaning bitmaps with metadata) at given (x,y) coordinates:

public void DrawBitmap(TSprite associatedSprite, FrameDesc frameDesc, int nScrx, int nScry, byte[] replaceRGB, byte[] substituteRGB)

The bitmaps themselves are stored as Resources in two assemblies (SilverLegendAssetsMenu.dll and SilverLegendAssetsGame.dll) that I download on-demand using WebClient. This has the advantage of dramatically reducing startup time, and only requiring the game engine to manage the downloading of two files over the web after startup. An equivalent option would have been downloading archives full of bitmaps, but I was concerned that this would require decompressing the bitmaps at runtime.

The RenderingService pre-caches the URIs for the bitmap associated with each FrameDesc (e.g. “SilverLegendAssetsGame;component/Graphics/Frosh4a.BMP”) so that the bitmap can be looked up without string manipulation whenever it is requested by a sprite.

Each game sprite is assigned its own System.Windows.Control.Image by the RenderService, which is initialized by having its UriSource Property set to a System.Windows.Media.Imaging.BitmapImage. When the FrameDesc for the sprite changes (and therefore the sprite’s bitmap appearance has changed), the Source Property of the BitmapImage, a URI, is changed to the appropriate cached Uri. (It looks as though you’re not permitted to re-use BitmapImage instances across multiple Images.)

Mirrored images are achieved by setting a MatrixTransform on the sprite’s Image’s RenderTransform.

Z-Ordering is performed by using the ZOrder property on the Images.

After each frame is rendered, the RenderingService iterates through all the Images on the Canvas, looking for any that weren’t rendered during that frame and therefore should be removed from the Canvas.

But what’s with the byte[] replaceRGB, byte[] substituteRGB parameters on the DrawBitmap call? In all the other versions of Greasepole, the characters became multicultural by performing color-key swapping of their solid skintones. The DirectX engine used two BitBlts, and the XNA engine uses custom shaders. Achieving this in real-time with Silverlight 2 is something I haven’t yet figured out.

Silverlight SoundService

Sounds assets are stored as MP3 Resources in the previously-mentioned download-on-demand assemblies SilverLegendAssetsMenu.dll and SilverLegendAssetsGame.dll.

Just as with with RenderService, the SoundService pre-caches the URIs to all the sound files.

The SoundService keeps a static collection of MediaElements around. These are added as children to an invisible Canvas called SoundCanvas. When the engine requests that a sound is played, the SoundService finds an unused MediaElement in the static collection, sets its Source Property to the correct URI, and Play()s it.

The MediaElement’s MediaEnded event is handled to either loop the sound by either (1) setting .Position=TimeSpan.Zero and calling Play() again, or, (2) if it’s not looping, to add the MediaElement back to the static collection of available Media Elements.

Incidentally, this whole MediaElement juggling trick was a highly unstable process in the Silverlight 2 Alpha which seems to work reliably in the beta.

Silverlight InputService

In the Silverlight 2 Beta, handling input was a piece of cake. Mouse and Keyboard events are handled for events on the main Canvas to inform the InputService of human interaction.

Unfortunately for game developers, keyboard input is more or less crippled when Silverlight is in fullscreen mode. Luckily, we’d designed Greasepole to be playable with just one mouse button.

I also wish I could use the right mouse button for input, but instead it brings up the Silverlight Configuration menu.

Silverlight GameTimerService

To create a game loop, Greasepole uses the “empty Storyboard technique” outlined at Silverlight Games 101. The game loop calls Update enough time to ensure a constant 24 updates-per-second update rate, and Render whenever possible, which triggers the RenderingService (see above).

In every other respect, the game timer is the exact same as in the XNA version. DateTime.Now works as advertised!  Here’s to a common set of .NET Framework classes!

Silverlight GameSettingsService

The IsolatedStorageFile API makes it very easy to rapidly save and load game settings in a local sandbox.

See this sample for more information on how to use the virtual file system in Silverlight. The GameSettingsService uses a very similar technique.

One of the reasons I’m pleased with the Silverlight version of Legend of the Greasepole is that it represents a reasonably-scaled multimedia application, and therefore a good way to learn about the Silverlight 2 runtime’s performance.

The Silverlight 2 Beta game engine runs rings around the game engine I tried to create using the Silverlight 2 Alpha. Yes, samples existed during the Alpha days that let you build a simple Silverlight game engine, but I didn’t see any applications that were successfully pushing push over 100 bitmap-animated sprites around the screen. I certainly was unsuccessful.
Although, as evidenced by the current build of Greasepole, the Silverlight 2 Beta situation is dramatically imrpoved, the lack of hardware acceleration is still very noticable when running at higher resolutions. This performance impact is relevant to an Image-oriented application like Legend of the Greasepole.

Can the game’s framerate be improved at high resolutions?

Late last year, I tried to make a version of the game run on the Silverlight 2 Alpha.
While the perf in the game’s menus was passable, the actual gameplay caused the Silverlight plugin to grind to a halt and crash (as 150+ sprites, rendered as Images with opacity blending, were presented simultaneously).

When updating my Silverlight game engine to the Silverlight 2 Beta, changes included:

  • using ZOrder instead of manually re-ordering Images in the Canvas’s Children collection between frames
  • moving bitmaps and sounds from loose, pre-downloaded files to Resources in Assemblies
  • an overall reduction in the number of RenderTransforms in the scene
  • avoiding setting of Width and Height as per Silverlight Performance Tips (in the MSDN docs)

At game time, performance is superb when running in a window of around the game’s native resolution of 640×480. But when the player toggles fullscreen mode (achieved in code by scaling the Canvas on which the 150+ Images are being drawn), it kinda sorta almost looks good. It definitely achieves less than the game’s desired 24 frames per second.

So… Is the Engine Fill-Rate Limited?

Since the game performs so well at reduced resolutions, I’m currently theorizing that the engine is fill-rate limited in Silverlight at high resolutions. That makes sense, because the Silverlight 2 Beta plug-ins for IE7 and Firefox2 aren’t hardware accelerated.

Still, the changes that took place in the plug-in and the engine that were enabled by the switch between Silverlight 2 Alpha and Beta have made dramatic improvements to the game’s performance. They were enough to bring the game to life.

The Legend of the Greasepole is a game that began its life on July 1st, 1996, when a group of Engineering students from Queen’s University in Canada decided they’d create a way to re-live their unexplainable annual tradition from the comfort of their long-suffering computers.

The release of the Silverlight 2 Beta has allowed the game to goop its way to the web! In fact, here it is! (There are sound and fullscreen toggles in the upper-right-hand corner.)

Read the ‘cooks’ (lingo for student notes) for tips. Click mouse to perform actions, Shift to toggle tools, Space to do something silly (try it with beer).

Over the next few days, I’ll write more about how this was possible, and some of the many things I’ve learned about Silverlight development in the process.

For now, though, I’d love to hear how/if the game works for you!

If you didn’t study Engineering at Queen’s, the game isn’t going to make much sense. I mean, honestly, it hardly makes sense to me any more, and I’ve been to six real-life greasepole events myself.

Basically, the premise of the game is that the Frosh (first-year students), who are supposed to learn teamwork through the pole climb event, are a little too keen this year. So, as a thoughtful upper-year student, you need to gently stall the Frosh for as long as you can with whatever you can find as they attempt to (and ultimately do) wrest the tam from the top of the greasepole.

First one to 900 Achievement Points gets a pizza. Really… send me a screenshot and a mailing address.

Related Posts: [updated 30 Jul 08]

Silverlight Greasepole Game Engine Notes

Silverlight 2 Beta Performance

Congratulations to Sci ‘11 for their one-hour, 47-minute conquering of this year’s greasepole!

Can we all just take a moment to reflect on the academic year called “Sci ‘11″?  Man, I feel old all of a sudden.

Just for giggles, here’s the current list of achievements for Legend of the Greasepole.  I wonder how the crowd around this year’s greasepole would have done.

Pole in Ten (Years!) - (100) -  Stall the frosh for at least 10 minutes
Show Some Discipline - (10) – Proudly display the Discipline bar on your Engineering jacket.
Desperate Times, Desperate Measures - (10) – Wind up your arm fully, completely before you toss a road apple.
It’s The Jam, It’s All Good For You - (20) – Offer ‘za or a drink to the Engineering Society President.
You’re a Hoser - (20) – Cool down the frosh with water from the firehose.
Golden Soda - (50) – Offer a drink to hard-working Al ‘Pop Boy’ Burchell.
Like Homecoming, But With Lanolin - (50) – Quench the crowd’s thirst ’til they slam their leather jackets.
Dizzying Heights - (50) – Send a frosh flying all the way from tam to pit-water.
Iron Ring Ceremony – (100) – Unleash the power of the mighty Iron Ring.
Double Fisting - (150) – Wear two Iron Rings at the same time!
Exam Avoidance – (50) – Stall the frosh for five minutes without lobbing a physics ’smart bomb’.
Fully Loaded Fun Fur - (70) – Stuff your pockets with 99 apples, 99 slices of ‘za, or 99 Clark mugs.
Secret Achievement - (??) – Keep stalling the frosh to discover this achievement!
Secret Achievement - (??) – Keep stalling the frosh to discover this achievement!
Secret Achievement - (??) – Keep stalling the frosh to discover this achievement!
Secret Achievement - (??) – Keep stalling the frosh to discover this achievement!

Legend of the Greasepole's TetherFroshI’ve posted Windows and XBox360 versions of Legend of the Greasepole 2007 to the Queen’s EngSoc website!

The new version is built with XNA and includes the following new features:

  • Controller support for either the mouse or the XBox360 Controller attached to the PC
  • 3D sound 
  • Modestly enhanced graphics (although we realized it was ultimately a choice between a total revamp or maintaining the “retro” look, and we opted for the nostalgic solution)
  • An installer that can detect and install all prerequisites, and integrate with Windows Vista’s Game Explorer
  • A new version that runs on the XBox360! (!!)
  • “Achievements” which can be unlocked by stalling the Frosh in creative ways.

The Windows version requires a graphics card capable of supporting Pixel Shader version 2.0.  Almost any computer bought within the last couple of years should do.  If your card doesn’t have this support, I’ve also left the Classic Version of Legend of the Greasepole available for download, with a new installer that runs more quickly and also can detect and install the needed prerequisite for Classic Edition (the DirectX runtime).

The XBox360 version is built with XNA and, as such, you currently require a subscription to the XNA Creators Club in order to play it.  If you want to get it up and running on your XBox360, please let me know!

Introducing Legend of the Greasepole Achievements!

For the uninitiated, retail XBox360 games each are gifted with 1,000 “achievement points,” which the game’s designers can divvy up and dish out to players when they accomplish tasks within the game.

Legend of the Greasepole is peppered with “easter eggs” and innovative ways to stall the Frosh that the curious can discover by messing about.  Previously, cleverness would get the crowd roaring and accelerate your earning an Iron Ring.  Adding a more formal Achievement system seemed like an ideal way to further reward a player’s experimentation and creativity, which in fairness is really what The Pole Game (and the actual greasepole, for that matter) is meant to be about.

Our design goal was to create an fun experience rather than a brutally challenging one, including as many references to the memorable traditions of Queen’s Engineering and the Greasepole event as we could possibly cram in.  Hopefully the Achievements will help you find some of them!

XNA doesn’t let you tap into the “official” achievement system, so I had to roll my own.  With thanks to Craig Calvert and McKay Savage, we’ve come up with a first set of achievements and allocated 900 of the 1,000 points. 

If you unlock all the current achievements, we definitely want to hear from you.  (Four of them are secret, the rest are visible from within the game’s main menu.)  If you have ideas for how we should allocate the remaining achievement points, we’d love to hear those too.

Please let me know how you get on with the game, and if you experience any technical difficulties, also please don’t hesitate to let me know, and I’ll do what I can to resolve them.

I have to tip my cap again to the dozens and dozens of Queen’s students who were involved in the game’s production from 1997 through 1999.  It was an enormous amount of fun making this game, and a wash of memories of the very best kind porting it to XNA for re-release.

… in fact it’s probably happening as I type, but I’m three-and-a-half hours down the 401 in Toronto. Sigh.

PCorey's great Greasepole shot

A huge thanks to the folks who have beta tested the re-release of the game.  I had hoped to have it ready for today, but I’ve received some great feedback about a few things to tweak, and particularly in light of the new XBox control mechanism, I need to hold off a few days to find time to finish it up.  Also, my partner-in-crime Craig Calvert, who was Legend’s Artistic Director, still hasn’t weighed in… I hope he’ll have a chance to look at the game soon.

A particularly huge thanks to McKay Savage, principal author of the LegendWeb, whose history of the Greasepole (and even poetry about the Greasepole!) was an integral part of the original CD release, and now can be found online.  He’s really been enjoying the beta testing and wrote about it in his blog, which has the great name The Wind on My Face.  I remember receiving the most amazingly thoughtful and detailed e-mails from McKay back in the day — and now he’s living in India.  I think the blogging medium was made for folks like him.

Odd Greasepole shot

Previous Articles »