Jump to content
  • Advertisement
Sign in to follow this  
Extrakun

Two observers observing each other - bad practise?

This topic is 3609 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am thinking of using the observer pattern to implement my game rules. Suppose I have a class, GameRules, which observes the game-space. The game-space has its own logic for collision detection and etc. Now, the following sequence happens: 1. Player's bullet collides with enemy 2. Game-space's collision logic notifies the GameRules object 3. GameRules object updates relevant data Let say the rules also state that a power-up is to be added to the game-space when a special enemy is destroyed. So... 4. GameRules notifies game-space to add a power-up object Is this a bad practice to use the observer pattern in such a manner?

Share this post


Link to post
Share on other sites
Advertisement
I don't see any problem with this as long as there is no way to make them enter into an infinite loop of updates.

I also think that those objects shouldn't be the observers. One of the things that make observer desirable is that it decouple classes. IMHO you should have a Rules_Gamespace observer class to watch over both instead.

[Edited by - owl on January 10, 2009 11:18:15 AM]

Share this post


Link to post
Share on other sites
It could result in some nasty call stacks going from an object into a second object and then back to the first object again. Then the code must be "self reentrant" or what to say.

You can consider some kind of message system which stores the message as data to a queue and delivers them at a later time. This would keep call stacks more flat.

Share this post


Link to post
Share on other sites
Be careful with patterns.

Something most people don't realize is that patterns were never meant to be prescriptive - i.e. they are not intended to tell you how to write new code.

Instead, patterns should be used when you already have code written and notice that the code you have designed resembles a pattern. At this point you refactor the code so that it more closely fits the traditional pattern. This usually means the code will get cleaner; however, there are times when coding to a pattern actually makes your code worse.

Also, note that patterns are not intended to be complete design guides; you are meant to adapt them slightly to suit your exact usage. This includes up-front design as well as refactoring of existing code. The patterns are meant to show you effective solutions to common problems, and suggest ways that you can improve your own solutions.


In summary, you should not be using patterns as goals. Instead, you should be writing code that solves the problem effectively, and then considering patterns that may help simplify and better organize the code.

If you ever notice that you are writing more code just to use a pattern, you're doing it wrong [wink]


Now, to address the logic sequence you described in the OP... having two tightly coupled classes is not necessarily a bad thing, and in your case it actually makes sense. Both GameRules and GameSpace need to update each other.

The only danger, as has been mentioned, is that you want to avoid infinite loops of calls. However, deep call stacks are not necessarily bad either, provided you don't do them very often (read: a handful of times per frame) and thereby chew up too much CPU time.

In fact, if you code up your GameRules class properly, it should be trivial to integrate a scripting language on top of that so you can write the rules as scripts rather than raw code. (For a small project this isn't really that big of a deal, but if you have a lot of complex game logic it really helps.)


One thing you may consider is deferred response to the events that are sent to GameRules. So, for example, you may not immediately spawn the power-up object, but instead store a "note" somewhere that tells you that the power-up needs to be spawned in the next frame. Then, at the beginning of each frame (before the rest of the game logic runs) you can run through this list of actions and handle them as needed. This should prevent infinite update loops as long as your event/message design isn't totally screwy.

Share this post


Link to post
Share on other sites
You could make a subclass of the GameRules object that defines what happens when the enemy dies - then when the enemy dies, you can call an instance of this and have it run through the actions you want it to on death.

The advantage of this is that these specific rules can then be owned by the enemy class instance and hence stops coupling problems.

Share this post


Link to post
Share on other sites
Quote:
Original post by ApochPiQ
One thing you may consider is deferred response to the events that are sent to GameRules. So, for example, you may not immediately spawn the power-up object, but instead store a "note" somewhere that tells you that the power-up needs to be spawned in the next frame. Then, at the beginning of each frame (before the rest of the game logic runs) you can run through this list of actions and handle them as needed. This should prevent infinite update loops as long as your event/message design isn't totally screwy.
Deferred response is particularly important when removing/deleting objects, where it is essential to prevent other objects/subsystems from accessing a deleted object.

I have found it even more useful to fully defer the event queue - your milage may vary if you have non-trivial dependencies between events.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!