Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm currently working on a 2D game engine in XNA, and I am very interested in architecture, and how best to let my game objects communicate.

I know a lot of people use a Singleton design but I believe that this is more of a "counter-architecture" way of doing things, as every class will have access to the Singleton.

I was comtemplating using a Service-type architecture to allow for my Input, Sound, etc Manager classes to be available, but this is essentially the same problem as the Singleton as all the Classes are available to 'whoever' wants them.

I could of course pass references to the objects when they are needed, but this is bloated.

I wonder if making the 'Services' only allow certain objects to subscribe would be possible?

So is there a better way to make your classes available?

Or am I searching for an answer that doesn't have a question?

share|improve this question
3  
Take a look at gameprogrammingpatterns.com. Programming patterns are explained from a game programming perspective. –  smack0007 May 27 '11 at 11:04
    
3nixios: I added an answer to answer the question you asked in someone's answer's comments. –  Olhovsky May 27 '11 at 12:30
    
The term you are looking for for singletons and the like is anti-pattern :) –  The Communist Duck May 27 '11 at 18:19
    
Have a look at the component-based architecture, gamedev.stackexchange.com/search?q=%5BC%23%5D+component –  Daniel Little Jan 27 '12 at 5:10
add comment

6 Answers

up vote 8 down vote accepted

When you're writing a game, you're better off writing a game than worrying too much about having the perfect architecture. There's nothing really wrong with having singletons and global variables in a game. Far better to have less and more flexible code than for it to be perfect.

I personally find that Singleton is a pattern to be avoided. Most of the time you should be using a static class or member instead of a singleton. See, for example, the Mouse and Keyboard and MediaPlayer classes in XNA. These are all simply static classes which are globally accessible.

I would query your need for a "sound manager", seeing as SoundEffects are stand-alone. And ContentManager is already the only thing you need to "manage" them.

You don't really need to write a services architecture, because XNA already provides one (see Game.Services).

If it seems like it would help, there's no reason why you can't just add a public static MyGame theGame member to your Game class and effectively turn it into a singleton. For the simple reason that there is never reasonably going to be more than one instance of your game class. Then you can make its members public (Content and Services already are) and access them globally, if it makes sense. This is simple. You can always change it to something more complicated later!

Making only your Game class a globally accessible also keeps the global access point localised to one place in the code, making it easier to locate when you want to "un-globalify" something later.

What I would very much avoid is making true Singleton classes that can only be instanced once. For example: don't make a map class that you can only create one instance of: what if you want to add background loading of the next map later? (Or the player class - for multiplayer, and so on).

The best example of this "global but not singleton" in XNA is ContentManager. You've got Game.Content which is effectively global. But you can also create more instances of ContentManager, which can be owned by whatever you like (levels, screens, whatever) and will operate independently.

share|improve this answer
    
Russel: I do believe sir that I like your view on things. I would agree in general but the idea is to make an architecture for rapid gameplay prototyping, it is therefore much easier for me to have Managers that are accessible via Properties for example. So I guess this is answered. I have now reached a sense of tranquility. –  Jonathan Connell May 27 '11 at 12:43
    
Andrew Russell: Since you asked about the need for a sound manager... My sound manager manages sound resources (with an object pool) and automatically chooses appropriate sound fading between players in splitscreen. The sound manager also allows you to "fire-and-forget" sounds, for sounds that are short, so there is no need to get a new sound instance from the object pool and release it when it's done playing. You can simply do SoundManager.Play(Sounds.Beep2); If you don't put this type of functionality in a "SoundManager", then where do you put it? –  Olhovsky May 27 '11 at 12:51
    
@Olhovsky: It sounds like your use of a sound manager is appropriate, if XNA's built-in fire-and-forget functionality does not meet your needs. Whether you make this a simple static class with a static pool, or you make it instanceable (and then what "owns" it), will depend on your game. –  Andrew Russell May 27 '11 at 13:00
    
Static classes in languages where they can hold state, i.e. have private static fields, are singletons. The problem is that some people are too inexperienced and believe that the pattern as implemented in other languages is some kind of golden rule, which it is not. If you program pattern oriented you are just over-engineering, not actually solving the problem at hand which in most cases is very specific. Patterns serve solving a common problem not the other way around. Need some data that has to be accessed globally? You'll either endup passing it as argument everywhere, or make a singleton. –  Trinidad Jun 16 '11 at 20:41
add comment

I think you can use mutiple inhertence for your need and have some game object like these :

class KeyboardReader
{
    protected :
    static KeyBoard* keyboard;
};

class MouseReader
{
    protected:
    static Mouse* mouse;
}

class gamecontroller:public KeyboardReader, public MouseReader
{

}
share|improve this answer
    
Thanks but my question is more about global architecture, not inheritence. –  Jonathan Connell May 27 '11 at 11:25
    
and that's what my answer is all about, for all your resources you have a base class that can use that, and every class that need to use resources, should inherit from classes that provide them, in these architecture there is no need for singleton but you still have some static variables in your code. in this approch the keyboard value in KeyboardReader is once initialized by some class, (for example main function) and after that it's that value is shared with all the classes that inherit KeyboardReader. without passing keyboard to them or defineing Keyboard as a singleton. –  Ali.S May 27 '11 at 12:41
1  
-1 because c# doesn't support multiple inheritance –  Tetrad May 27 '11 at 17:01
2  
Also this is exactly the kind of overuse of inheritance that people have been shying away from. A game controller should not have a "is a" relationship with an input manager. At the very least you should make the inheritance private. But a less messy solution (for example, to avoid multiple inheritance name collision) would be to use composition, but since in this case you're using static instances you'd have to make them public anyway, the composition members wouldn't actually do anything, so you might as well make them globals. –  Tetrad May 27 '11 at 17:16
    
-1 What will you do with a Trackball, Multitouch Screen, Gamepad? Inherit from them too? What about a second Game-Pad? Really terrible design! –  Maik Semder May 27 '11 at 17:54
show 5 more comments

The major difference between the singleton approach and the service locator approach is that the components are more loosely coupled. If Foo accesses Bar as a singleton, any changes to Bar affect Foo indirectly.

With a service locator you can communicate through an interface though, IBar say. You can change Bar all you want as long as it fulfills the IBar contract. If you decide that the class Baz should now fulfill the IBar contract, you can just swap it out. With the singleton, you can't do that so easily.

share|improve this answer
    
Good point ^^. I do much prefer the Service Locator, only I can't help but think to myself that it's kindof like making your services globals or using Properties to access them, which is horrible :). –  Jonathan Connell May 27 '11 at 11:18
    
I honestly prefer constructor injection. It makes it clear what dependencies a given object has. With a service locator, it can be hard to know which components depend on which other components. –  smack0007 May 27 '11 at 13:54
add comment
I could of course pass references to the objects when they are needed, but this is bloated.

No, that's completely how it should be done. If you find doing this untenable, then your design is broken.

Passing references makes for the easiest, most obvious control and encapsulation. Global data is bad, whether you want to call it a "Singleton" or a static Manager. You shouldn't even need an InputManager or a SoundManager.

share|improve this answer
1  
Why shouldn't I need an InputManager or SoundManager? I don't want all Input & Sound code directly in place whenever I need to check someting... Of course encapsulation would be easy if we only have a few classes... –  Jonathan Connell May 27 '11 at 11:56
    
@3nixios: If you make a Sound object, then it is your responsibility to keep it around as long as you still need it. Sound-related code goes in the Sound class. What exact function are you hoping for your Manager to achieve? The same is true of Input. –  DeadMG May 27 '11 at 12:08
1  
@3nixios: So make a SoundBank class that holds a SoundBank, and have it create Sound objects from cues within that bank. There's still no need for global data- if you can't conceive of a manager-less design, then pass the managers as references. –  DeadMG May 27 '11 at 12:23
2  
@Gajet: Your comment. Global accessibility and single-instance objects are really two separate issues. Global accessibility is fine. Single-instance is a very bad idea. Strictly speaking, a class that is "Singleton" is not necessarily globally accessible. (This is the basic thrust of my answer.) –  Andrew Russell May 27 '11 at 14:38
4  
Gajet: Actually you usually want more than one object pool (I have dozens typically), and having a singleton isn't really necessary for ensuring that you only have one graphical API. In fact, why do you need to ensure that at all? –  Olhovsky May 27 '11 at 17:40
show 12 more comments

My advice is that a good programmer isn't dogmatic. Passing things by reference is good, singletons are also good. A good programmer uses every weapon in his arsenal, they don't rely on using a single tool, a hammer can't solve every problem.

For instance I would say it is a bad design to be passing around the same reference to a single object everywhere.

Singletons aren't counter-architecture, they're part of the GOF patterns and it is an extremely useful pattern. As all architecture, they have a proper time and place, architecture for its own sake is a common mistake. A singleton is appropriate when there should only ever be one instance of that class in your application and that instance is referenced everywhere.

You want to restrict access to singletons? A good design is not just about classes, its also about appropriate packaging. By using the internal C# access modifier you can limit use of a singleton to within a particular package/assembly.

share|improve this answer
add comment

This is a problem throughout all of software development, and there are several common solutions.

Fortunately, you don't really need to pick one - XNA already has a built-in service locator!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.