Game design patterns, any pointers?

It’s not the first time that it happens to me that when my project grow big enough, or if i retake it after some time, i get lost into it really easy, not knowing why whas i doing the things that way or what was i doing here aor there in the code. It has happened to me right now, i’ve finished finals and i’m retaking my litle worms clone, but i don’t know how to handle it.

That’s definetly because my designs are very thin, i mean, i only do a couple of scraps on paper and then begin coding, changin the desing on the fly to fit the part of the game i’m working on each moment, ending with a very complicated thing to work with.

I haven’t had any luck on my recently finished exams so there could be a couple of years until i study something about software enginering, so i need some pointers on desing paterns, and if there is any particularity on game desing.

Thanks :slight_smile:

Shawn Kendall’s blog had some stuff on this and a good link to http://www.gamearchitect.net/Articles/GameObjects1.html
which talks about component vs inheritance architecture.

I’m having the same problem too. The bigger & more fleshed out my game gets, the more I find myself re-engineering my game engine to be more simple & flexible. The best thing I read was to program to an interface, not an implementation. ie, only call methods of interfaces, not methods specific to classes.

A recent problem I was having is trying to get access to, say, the GameWorld from its member Rock object. I ended up just making the current GameWorld a static member of the Main class so that I can always get access to it without having every Rock keep a reference to its GameWorld.

I’ve done this (in fact Quix still does this) but long term it’ll cause more problems that it solves. I’ve been slowly refactoring Quix away from using it and the code has definately got better as a result.

Globals? Just say no. And don’t even think about using a singleton, that’s just sweeping it under the rug. >:(

that’s exactly what happens to me, i allways find myself coding for the implementation and not for the interface.
I’ll try to do what the article says

quote program to an interface and not to an implementation and (2) favor object composition over class inheritance
[/quote]
i’ve also been looking at some design documents templates on gamedev.net and gamasutra and they are all oriented to the market instead of giving some gidelines for the implementation.

here is a pointer http://www.gamasutra.com/features/20040510/adams_01.shtml

sorry for the double posting :wink:

I have just recently begun studying the intersection of game programming and design patterns. I welcome any links that others may provide. My results are preliminary, but thus far, I have found the State and Visitor patterns to be easily applicable to game programming: State to maintain sprite and game status and Visitor to encapsulate class-specific behavior outside of the inheritance hierarchy. These two patterns are defined in the classic GoF book (Design Patterns, Gamma et al.), although I highly recommend the presentation in Holub on Patterns (Allen Holub). Depending on how the rest of the summer goes, I’m hoping to start writing a paper on this subject, and I’ll try to remember to post a followup then. In the meantime, feel free to check out my eeclone game, which was designed specifically to explore some design patterns in game programming: http://www.cs.bsu.edu/~pvg/games/eeclone.

Regardless of how well one does on tests, I believe that it is never to early to study design patterns. Don’t put it off until an undergraduate course on software engineering – it is one of the most interesting and applicable aspects of modern computer science, and it is generally not given its due in education. (In fact, I will be teaching our introductory computer science course next semester with an early emphasis on OO principles and patterns.)

The “program to interfaces” concept is central to design patterns. Even if you don’t have the opportunity to delve into design patterns now, keep that idiom in mind, and you will probably trip across patterns without knowing it.

It is also worth noting that “design patterns” has a wider usage than I am discussing here. My interest is in design patterns for software engineering, specifically for software design. This seems to be the domain of your question. Others have discussed design patterns for game design, which has little or nothing to do with game implementation. For example, one could apply good game design patterns to create a board game, since they deal with game flow, keeping player interest, fun, etc.

Also, there is nothing wrong with singletons if they are used correctly. Like any pattern, it should only be used when applicable. A misuse of any programming idiom or pattern will lead to headaches! For example, the sound engine in EEClone is a singleton. There is only one interface to the sound card that I use, and I need to manage what sounds have started or stopped, the number of pooled threads, etc. Singleton is a natural fit.

Cheers!

I have yet seen a use of a singleton that was justified other than someone being lazy. Singletons are ‘sexy’ in that they’re an easy pattern to understand (at least trivally) and implement, and they provide a way for people to revert to procedural programming, except they can claim to be doing OOP because “look, it’s got classes and everything!”.

On to your example:

  1. The fact that you have one sound card is irrelevant. Thats an implementation detail that is managed by the OS, not your code.

  2. Without knowing what your sound ‘engine’ does I still bet there will be usages which will require more than one. Even if you only use one, that doesn’t mean you should enforce it.

  3. Everyone forgets the proper definition of singleton, it’s not “only one instance”, it’s “only one instance, which is accessible everywhere”. I don’t know what your crazy code is doing, but I sure as hell don’t want (eg) my low level controller code touching the sound output. Or my networking. Or 90% of my code which doesn’t care about sounds. But suddenly with a singleton I can no longer make that assumption, because anyone, anywhere can mess with it’s state without my knowing. That makes for hard to debug code.

  4. Singletons make unit testing a whole heap more difficult, even if you managed to work them in somehow you end up only testing a small amount of the possible code paths that you could of done otherwise. What if I’m testing some code on a machine without a sound card? I could use a mock sound engine which does nothing, but because you’ve welded your code so tightly I can’t easily do that.

You want only one sound engine? Fine - Just Create One.

See also: Singletons Are Evil and Singleton Considered Stupid

Pragmatic programming says that any fixed rule like “Singletons are Stupid” is probably wrong ;). If it works for your situation - then great - if proved to be a problem just refactor it out - and thats where singletons are useful (well sorta not these days with modern IDESs):

At first you think its a bunch of utility methods - so you make it a bunch of static methods. Later you realise you want some state in there and multiple versions of that state. Now you get to go round everywhere you use the static methods replacing them with calls to an object to be passed in. Part of this problem goes away if you’d been using an instance (albeit a single instance) of the class all along (i.e. the singleton) - some of the assumptions still hold true.

Note sure when the last time I read the GOF book was, but I don’t remember anything about a singleton being “accessible everywhere”? This http://en.wikipedia.org/wiki/Singleton_pattern doesn’t seem to mention it - but like I said its been a while. I don’t see anything wrong with limiting the scope of the accessor to a singleton. Unit testing, maybe you could make the constructor package level access instead of private - then unit test it locally to the package. Yes this would break the mould a bit - but heh, pragmatism.

Note: I’m not “for” singletons - I just think the main problem with designs most of the time is that people sit there worrying about what “rules” there are, and which “patterns” they can abuse - instead of just thinking, what works here. Stick the patterns in your head - and they’ll just sort of pop up when needed :slight_smile:

Re: GameObjects in GameWorld. I had this problem with every game I started for ages - and it came down to me learning to break a rule that I’d got stuck in my head. When you’re designing a tree structure outside of games - you tend towards not letting the children know the root of the tree (at least not directly). This is generally so nodes can be moved about and put in other structures without pain. Game’s code is far less transient and far less likely to be reused (at least game objects are). I just took the step that you can’t create a game object without the world in which it lives - the game object can always just use its reference to the world. Saves me a whole lot of hassle and hasn’t added any headaches.

Kev

I use this :slight_smile:

http://www.laputan.org/mud/

I’m totally with kevglass on the “no rule is absolute” side of things. There are times when a Singleton is less convoluted than the alternatives and the more readable your code is the more likely it is to get finished.

I do kind of agree with the Steve Yegge article linked above- there are a lot of ways to misuse any tool, and the world is full of “when you only have a hammer every problem looks like a nail” situations, especially when you’re newly graduated and know about 1/100th of what you think you know. However I’ve just realised I don’t hold with the “you can’t do this because it’s a bit like procedural programming” argument. As I understand it, your processor is going to be running procedural code no matter whether you write it in an Object Oriented, Functional or procedural way. I think if SteveY is going to criticise slipping bits of the procedural paradigm into object-oriented programming he may be on shaky ground when he goes on about slipping bits of functional programming into the object-oriented paradigm, which happens a lot in his other articles…

I think clean, efficient, human-readable code is more important than tying yourself into any single paradigm, model or specialisation. I also think that doesn’t really relate to the actual topic of the thread, so maybe I’ll stop typing now…

So how are each of you letting the GameObjects have access to their GameWorld? I changed to having a global static GameWorld reference because I’m sick of having to pass around GameWorld references to all GameObjects. Having a centralised GameWorld seems to make sense. I can see 3 options:

use a static global reference/singleton, ie Main.getGameWorld();
give every GameObject a reference to its GameWorld in the constructor, ie new GameObject(gameWorld);
pass the GameWorld reference as a method parameter like: gameObject.update(gameWorld);

Cheers :),
Keith

At first view the second way seems more oo than the two others to me. I was using globals too, but i’m thinking of refactoring now

[edit] it comes to my mind that swing and awt components work in a fourth way, all of them have a getParent method, so they save a reference to their container, we should just create a GameObject and add it to the world GameWorld.add(new GameObject()) and that add method could set the “parent” for this GameObject[/edit]

Do you really interact with the whole Gameworld? or is it part of the gameworld? I don’t think it’s as much defining global var beeing as bad, and defining states ‘globaly’ well in a sence that you should evaluate if the state or stuff your sticking in gameworld is really that global/genetric should the scope perhaps be smaller.

on a side note every interaction pattern has to do with references, but we don’t call them reference patterns because they are about interaction(next from the name 'reference pattern will be come confusing 'these are the reference patterns for the reference patterns xD) The need for reference comes forth out of the need for interaction.

ps. There is also the wiring ‘option’ (IoC / DI / aop - approch of things)

I don’t think there are specific game patterns, well to a degree, if you disect it you’ll probebly end up with a ‘normal’ pattern.

something interesting to look at is perhaps the immutable pattern. but I think that most if not all could well be used in a game but as outlined before ‘use wenn needed’

This is the typical singleton argument: “But I really do need this everywhere! I can’t be bothered passing it around all the time!”. It’s also usually wrong.

Firstly (as with the sound engine example) you don’t actually want to use the object everywhere, you just think you do. Start passing it around and you should find that it doesn’t need to be shared quite as much as you think. If your code is using it everywhere then your code needs refactoring. Typically you’ll find yourself missing a few interfaces to decouple the modules. Or your code from one module is reaching out and tinkering with another module it should be, and instead you need a proper delagation/event/something in between. For my game object-y stuff they tend to “do stuff until finished”, at which point the owner (which might be the level itself) removes then and tidies up - this way you never need to know about the owner explicitly. Taking the time to rework your code without the singletons and globals almost always results in better quality code overall - but you have to be willing to give it a try to actually see the results yourself.

The final little trick I like is the ‘environment’ struct. Instead of having long argument lists you can wrap common ex-singletons in a small class with them as public members. Eg. you might have a GameEnvironment which has your current level, hud, player settings, etc. which makes it obvious that certain bits of the code require a specific environment to operate in.

I didn’t want to hijack the thread to defend my use of Singleton for a sound system, or Singletons themselves, but you must appreciate the irony that you’re encouraging the use of public members here, perhaps the most egregious way to inject procedural thinking into an OO system. Think of the children!

Now you’re just nitpicking, :wink: we all know Never is Never Never. But while singletons may be valid sometimes, they’re much overused and cause lots of problems of there own (which is basically what the last bit of “singleton considered stupid” says). Theres a whole world of difference between “singletons are great, use them for your game world” and “use them very, very carefully”. Things like changing access levels are a symptom of the problem - yes you can just about work around things, but in the end you’re just making things harder for youself when you really didn’t need to.

I agree, which is why “just create one” (despite the pattern-alike name) is so good. You don’t worry about patterns, you don’t fret about whether you do need to enforce one instance, you just create one object and use it. It might not be fancy, but it’ll work. And it’ll be easier to change in the future.

A few observations:

  • If you use a factory class (not a pattern per se, but a powerful idiom for abstracting object creation), then you can easily change your design later without modifying your clients. As long as you factory has a reference to the (current) game world, then you can easily switch between #2 above and the swing-style approach mentioned elsewhere.

  • If you have a large number of very similar objects, consider the #3 above (send the object as a parameter). If you discover that managing the large number of objects is a bottleneck, then you can easily refactor to a Flyweight. A good example is the cell renderer in Swing’s table or list API: rather than have a separate renderer for each table cell, one (or few) renderers are shared among cells, and each takes the cell as a parameter when drawing.

  • “Premature optimization is the root of all evil.”

I don’t see the problem - we’re only talking about a little mini struct here, it’s not bolted on to an existing class but exists on its own with no operations at all, it’s almost a value class. You can do without it if you want, as it’s mostly syntactic sugar in a language where long parameter lists can get unweildy. Theres nothing procedural about it.

Although I feel we’re getting off topic somewhat now…

Great discussion here, I’m going to miss Australia v Italy while typing this. :o

Good points - OO programming says a Shoe has as its members a ShoeLace and an Owner, but the shoe need not have the Universe. (That’s kind of like the Swing getParent() tree approach I suppose).

That strict OO design which I’m going to call the need-to-know approach is elegant & the GameEngine package of classes/interfaces shoud definitely abide by this simple pattern since the GameEngine has code you want to re-use.

But back to Kev’s point about how game object code is rarely re-used, for the actual game code which is built on top of the GameEngine, having a global GameWorld that can be accessed by any GameObject is a massive plus for flexibility when dreaming up the game logic/objects. But everything within the GameWorld should not be able to reach out of the GameWorld to reference the GameEngine (in keeping with the need-to-know idea).

So when the scope of the game has been defined (ie a 2D platformer & not a MMOG :)) and the GameEngine bones are coded, scrap any thought about elegance and just code away since the game logic/objects are not going to get any deeper, there isn’t any need for extensibility. I think that’s what I’ll do - no globals/singletons for the GameEngine package, but definitely a global GameWorld for all of the GameObjects to access.

I need to scratch that into my screen.

Sorry if it came off that way, I was simply hoping to give some constrast to another “Singletons” are bad discussion. Personally, I seem nothing wrong with using them where your talking about utlities (SoundSystem seems reasonably to me for instance) - I find their contemptable when used as part of the actual model - i.e. the bit you’re modelling on your game’s environement.

I use the constructor, I consider it part of the object integretity - a GameObject cannot exist anywhere outside of the GameWorld - to enforce this you can’t create one without a GameWorld.

Although in my case you need place the name “GameWorld” with the “Map” which is facet of the game world. As Mr_Light mentions - I like to keep what my game objects can access controlled so they only need to access parts of whats in the game world.

In the past I’ve used the term “GameObjectContext” where the constructor of the abstract super class of all game objects looks like:


public GameObject(GameObjectContext context);

And where GameObjectContext is an interface that is implemented by GameWorld and gets added to as I discover the GameObject’s need more facilities.

Worked for me at least :slight_smile:

Kev