To GameComponent or not to GameComponent

XNA provides a neat little system for you to organize your game’s different parts in: GameComponents. You can use them to modularize your game’s subsystems, eg. have a GuiComponent, PhysicsComponent, SceneGraphComponent etc. so you avoid having all that code in your Game class, or can use them for your actual game objects in smaller games.

However, the GameComponent and DrawableGameComponent classes provided by XNA force you to reference the Game class. This is unfortunate if you want to use those components in a WinForms-based XNA application and gets in the way when you try to write unit tests for your components because now you have to create a dummy Game instance as well (and better hope that component won’t go shopping for references in the Game‘s Components and Services collections as well).

UML class diagram of the GameComponent and DrawableGameComponent classes

Luckily, the GameComponentCollection used by XNA to store your components manages IGameComponents and updating/drawing are based on the IUpdateable and IDrawable interfaces alone, so there’s nothing preventing you from rolling your own components without referencing the Game class.

That’s exactly what I did when I started writing an editor for my Island War game. I simply reimplemented XNA’s GameComponent and DrawableGameComponent classes, minus the Game reference. I named them Component and DrawableComponent (cleverly removing the ‘Game’ from the name to show that these no longer reference the Game class):

UML class diagram of my earlier Component and DrawableComponent classes

Users of my components (like my GUI and particle system classes) wouldn’t notice any difference and could use the classes like normal GameComponents, but the custom base class allowed me to use this components in a WinForms environment.

Lately, I’ve been tinkering around with SunBurn, Synapse Gaming‘s lighting and rendering framework for XNA. Here you have drawable things that do not access the GraphicsDevice. Instead, they will modify SunBurn’s scene graph. Thus, carrying around the GraphicsDevice reference in my DrawableComponent became essentially dead weight for the components involved.

So I decided to make a variant of my DrawableComponent that would still do all of the uninteresting stuff managing the Visible and DrawOrder properties, firing events and so on, but not handle the GraphicsDevice for me. What I ended up with is this:

UML class diagram of my new Component, DrawableComponent and GraphicsDeviceDrawableComponent classes

In retrospect, this turns out to be a much cleaner design, too: The DrawableComponent only handles the implementation of the IDrawable interface instead of doing both that and managging the GraphicsDevice. And the GraphicsDeviceDrawableComponent (excuse the long name, haven’t found anything more concise yet), deriving from DrawableComponent, only handles the management of the GraphicsDevice.

This will be a breaking change in the next Nuclex Framework release, but all you have to do is paste "GraphicsDevice" in front of your "DrawableComponent". I think this is nicer than having some DrawableComponentWithoutGraphicsDevice class :). I’d wager that in larger games (which is what my Nuclex Framework is designed for) a scene graph or something comparable is probably used in the majority of cases and direct GraphicsDevice access only happens in some corner cases.

Download

Nuclex.GamelessComponent.Demo.7z (17 KiB)

These classes are part of my Nuclex Framework and can also be found on its Project Page on CodePlex.

Leave a Reply

Your email address will not be published. Required fields are marked *

Please copy the string QrknDB to the field below: