Jump to content
  • Advertisement
Sign in to follow this  
CirdanValen

Communicating between two objects

This topic is 2617 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

I've run into this design issue a couple of times now in my project, and I think my solutions could be better. My problem is communicating between objects. In my program I have a GameState class. I derive that class for each state, such as menu or gameplay. I have another class called MissionDirector, which manages everything for the current mission such as dialog sequences, objectives, and spawning enemies. StateGameplay has-a MissionDirector. What is the best way to communicate between StateGameplay and the MissionDirector? For example, when the current mission ends, MissionDirector needs to tell StateGameplay that it's time to load and begin the next mission. My current solutions to this communication problem in other areas of my code have either been to pass the owner object to the member object in the constructor where I can call a pop() method, or I have the owner object perform some sort of isDead() check every frame. Am I doing it wrong, or is that code smell just because I'm new here? laugh.gif

Share this post


Link to post
Share on other sites
Advertisement
The best way depends on what you need.

Personally they seem like poor ways. Events or messaging tend to be more flexible, testable, reusable interfaces for getting information out of objects that shouldn't know about who's consuming the info. But they in turn have their own headaches.

Share this post


Link to post
Share on other sites
I think a good approach is to make something that works well and is easy to understand for the way you're actually using it at the moment (which I think you're doing). Then as usage changes and you accumulate a few more requirements you'd like to add to it, redesign to meet those requirements, and refactor to keep everything working.

Trying to adopt a single method of interacting, for every construct in your code, will lead to pointless convolutions.

Personally, for the situation as you describe it, I would prefer having the owner poll the owned object once a frame. This is the simplest solution, and keeps the owned object from adopting knowledge that's irrelevant to the work it does, like who owns it and message passing mechanisms. Just give the mission director a MissionComplete flag.

Share this post


Link to post
Share on other sites
Imagine you are given a task to create a machine. Users of machine cannot know what the machine does, but they must be able to operate the machine (start, stop, etc.). You want to design the machine's interface, such as that if the machine is going to be repaired, upgraded or downgraded, the interface does not change (or has minimal changes). For example, televisons. Most televisions have these basic buttons: Power, Volume Up, Volume Down, Channel Up, Channel Down, Menu. You go back 10 years ago, TVs have these buttons, and TV nowadays still have these buttons, even though TVs have been going through so many upgrades from tubes to plasma to LCD to LED. Regardless of what's inside, the basic interface to operate TVs remain the same.

Just how TVs are independent of its users (humans, monkeys, elephants, [insert more smart animals here who can watch TVs]), your MissionDirector must be independent of StateGameplay. No such thing as "MissionDirector tells StateGameplay it's time to load new missions". MissionDirector should only display information that "There's no more missions to load. I am done here!". StateGameplay should then act appropriately based on that information. When MissionDirector says "no more missions", should StateGameplay exit to main menu or put players back to briefing room? That's up to StateGameplay to decide.

Share this post


Link to post
Share on other sites
I've started up a fresh game project recently and came up with an architecture like so.

I've tried to design the game as a set of "modules". Each module does something specific, and are fairly coarse. There's a module for handling game logic, one for rendering game state, one for keeping track of game state, one for managing menus, one for dealing with players, etc, etc.

A primary goal I have with these modules is that they seldom need to directly communicate with each other. Since I don't need frequent, direct communication, I've opted for a fire and forget event-based messaging system.

Here's how it works:

Most of my modules are registered as event listeners for a suite of custom events that I've written.
Whenever a module needs something done that is outside its capabilities, it blindly fires off an event and assumes that something else in the program is now taking care of it. Any data that is needed is transmitted within the event itself. The module that fired the event doesn't care who catches it, or if it is even caught, it just goes on its merry way doing whatever.

Here's an example:

At the start of the game my MenuManager loads the main menu.
When the user presses "start game", it fires off a MatchMaker event specifying that a new game should be started. The MenuManager does no further work.
My MatchMaker module listens to MatchMaker events. It catches it, sets up a new game, then fires off a GameStart event (containing the setup game data). The MatchMaker does no further work.
The GameLogic module and GameRendering module both catch GameStart events. The GameRendering module switches my rendering mode to be in game while the GameLogic module spools itself up, activates input handling, all that stuff.

Each module is isolated from all the others. Even ones that work together pretty closely, like the GameLogic parser and the GameRenderer, don't actually know of each other's existence, even though they depend on the same GameState.

The whole reason this works is because of the event architecture and its fire and forget nature. It really makes it a lot easier to manage a big project and expand it. I can write the menu system first, then be like "Meh, I'll just write the match maker later" because the two modules are totally decoupled from each other. The only glue between them is a very small event layer.

Event systems often do have some degree of processing overhead, but I wouldn't worry about it. If your game starts getting really slow, you can fire up a profiler an see how much time events are consuming. If you get to that point, then you can figure out some optimizations.

Share this post


Link to post
Share on other sites
Ah, thanks for the pointers. I setup an event system so MissionDirector can shoot off a MISSION_END event, and whoever is set as it's listener will receive it. I setup StateGameplay to listen for those and events so it act appropriately.

Share this post


Link to post
Share on other sites

Ah, thanks for the pointers. I setup an event system so MissionDirector can shoot off a MISSION_END event, and whoever is set as it's listener will receive it. I setup StateGameplay to listen for those and events so it act appropriately.


Sounds like a good start!

Another big motivation behind decoupling your code like this is making it more resistant to change. If you have really tight relationships/dependencies between classes, then changes to one class can create a ripple effect throughout the entire system that breaks a lot of other stuff. Reducing coupling lets one part of the program undergo drastic re-design without impacting the rest of the system.

Trust me, stuff is going to change. Games have a tendency to change a whole lot, in fact, so always keep that in mind when writing your code.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!