0

Imagine that I have a game, with Monsters, Missions, Vehicles, and of course their controllers and such, so a Monster class, Mission Controller class, Vehicle Controller class and so on.

Suppose that I need the Mission Controller to talk to Monsters. Why? Let's say when Mission A is triggered, all Monsters now turns color blue, from their original color.

There are many ways to let the Mission Controller talk to the Monster class. One way is to use the Observer pattern. The MissionController would add the Monster to its list of observers, and when the MissionController changes Missions, it tells the Monster using ONMISSIONCHANGED() or something.

The problem with that approach is why should the Monster care about MissionController? Shouldn't Monster not even know that MissionController exist? Suppose that one day, we don't want the Monster to change color, we want vehicles to do it, then we have to get rid of Monsters from the list of observers, reimplement the same thing in Vehicles and add Vehicles to the list, isn't that tedious?

Another approach is to use Singletons, there is some almighty class that has a pointer to Monsters, Vehicles, whatever. And the MissionController can just get a reference to the Monster Class immediately. But Singletons are bad, and just making Singletons for communicating between missions and monsters is just another hack.

My question is then, if the MissionController wants to set/get a property of Monster, how would it do it? How can I avoid Monster from knowing about MissionController, but yet tell the MissionController about Monster?

TL:DR - How do you allow communication between two completely unrelated objects, if you don't want them to know about each other, AND not use the Observer pattern?

EDIT:

So it seems that the idea is to use Mediator and messages, create a Mediator class, call it MissionCommunicator, and it has a list of observers where one of it would be the monster. When the MissionController wants to talk to the outside, MissionCommunicator would pass that message to the outside through IMissionMessage interface or something.

In that case, then Monster would have to implement IMissionMessage to listen to that message.

Now, imagine we have MissionController, VehicleController, AchievementController, AnimalController, etcetera.....

Suppose for some reason, Monster, for the same reason that it needs to talk to MissionController, will have to talk to all those other ones as well.

If we let Monster communicate using mediators, now we have to make a mediator for Vehicle, Achievement, Animal, blahblahblah

and Monster class becomes this:

Class Monster Implements IMissionMessage, IAchievementMessage, IAnimalMessage.....

You can of course use interface inheritance to deal with this, make a parent IMessage interface subclassing those IMissionMessage interfaces if you are using Java.

But what would be a better solution?

  • There are many ways to accomplish this. Have you looked into event frameworks for whatever language you are using? – user22815 Nov 19 '14 at 19:34
  • Yes, if your design has a boatload of coupling points, the implementation will be awkward and unwieldy. This is a sign that your design isn't slicing along the right lines. – Telastyn Nov 19 '14 at 23:27
1

In the example you give (mission controller turns monsters blue), you wouldn't need communication between the controller and the monsters. Instead the monsters could look up the "monster color" in a palette (or color table). The mission controller just sets a different value for "monster color" in the palette when the mission changes. Or switch the entire palette if the mission change affects not only monsters ...

Call the palette a style sheet and you will get the idea that a mission change will be able to change more than just colors ...

However for your other question:

How do you allow communication between two completely unrelated objects, if you don't want them to know about each other, AND not use the Observer pattern?

In my opinion, the best way to achieve this is via events, i.e. in your example:

  • the monsters are subscribed on an event channel for the 'mission change event'
  • the controller issues a 'mission change event' on the event channel, and
  • the monsters change their color when they receive the 'mission change event'

That way both controller and monsters don't have to know about each other. However, both have to know about the (same) 'mission change event' and the (same) event channel.

To achieve a more decoupled design, you could also combine this with the palette approach described above as follows:

  • a palette (or style sheet) manager is subscribed on an event channel for the 'mission change event'
  • the controller issues a 'mission change event' on the event channel, and
  • the manager switches to a different palette (or style sheet) on receiving the 'mission change event'; the palette is chosen based on information transported in the event ...
  • So reading many of the answers here, it seems that the idea is to use Events. But my problem is, what exactly is the difference between the Observer pattern and Events? Don L. 's example of Java EventBus down below just seems like an easier implementation of the Observer pattern to me – Mantracker Nov 19 '14 at 22:58
  • @Mantracker : The event bus (or channel) would be something that you don't implement yourself, but rather use some canned library (e.g. guava event bus, in case you're doing Java), or a service provided by your platform (e.g. EventAdmin in JAVA/OSGi). – Gregor Ophey Nov 20 '14 at 20:16
6

As with all program design, if you have two things that need not know about one another (A and B) then the proper design is to have some mediator C that lives above and knows about both:

  C
 / \
A   B

The mediator can then glue the two together via a generic decoupling mechanism (events, messages, delegates, just passing one into the other, etc). For games, the "game" is usually something that ties the different components/modules into a cohesive form. For big games, you'll usually end up with different layers of abstraction so that C can focus on two things rather than 90 things.

0

You could use an EventBus.

When using a bus system, components in your application can register for events that are fired by other components. This way a monster could fire a MovedEvent ore something that contains the necessary data.

There are several implementations in several languages.

In java, commonly used one is part of guava: https://code.google.com/p/guava-libraries/wiki/EventBusExplained

If you are serious about the whole thing you should also consider using an EntitySystem (that's backed up by an Event bus)

See fir example http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ for more info on that.

You're basically not subclassing, but composing your game entities. That makes it rather flexible. The logic is executed by so called Systems - and these could communicate via an EventBus.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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