Messenger: Loose coupling through Messages and Requests

The code in this article is licensed CC0. Attribution is great, but you don’t have to.

Photo credit: Carla Arenas

Photo credit: Carla Arenas

Loose coupling is a goal drilled into every novice programmer when they’re learning the trade. If you have loose coupling among your classes, it reduces the changes you have to make to a class when you change a class on which it depends. A great way to move towards loose coupling is by abstracting away the dependency of one object on another using a Messenger.

Note: This tutorial is aimed towards Unity users, but the code and approaches are applicable to any system.

The Problem

You’re making the next great indie title. You’re a small team of two programmers and three artists, and you’ve been working on your game for a year. You have your functionality in place and it’s time to start polishing, but polishing takes a long time. It’s a lot of work, you’ve got model code mixed up with the view. Changing even the smallest thing means you have to follow 9 or 10 different references to other classes all over your game. Changing the high score manager means you have to change the high score rendering code, the high score server, the game’s score metric, and the list goes on. You’ve not been a bad developer though, you’re using events instead of polling, but it’s not enough. You want your classes to be more atomic, you want loose coupling.

The Solution

Enter the Messenger. The Messenger is a central hub, like a post office or router for distributing messages from sender to receiver. The sender doesn’t know who (or if anything) will receive their message, and the receiver has no knowledge of who sent it. The objects have loose coupling, but the receiver can still act on data and events from the sender. Importantly, this also means that if it becomes time to replace either the sender or the receiver, no code needs to change in the counterpart class. The sender will continue to send out their messages as they should, and the receiver will continue to act on them as they should.

This implementation of a Messenger is based on the Messenger API from Laurent Bugnion’s MVVM Lite framework, but with a few additions.

In the above example, the player has a Health component attached to it, which when hit reduces the Life variable by 1. We also have a HealthLabel which renders the value in the attached Health component on screen. It does so by checking for the OnHurt event in Health.The Health component it links to is set up in config files (in the case of Unity, it would be in the Editor). This lack of loose coupling is fine, if you never intend on reusing your code.

Let’s say it’s time for your next project and, quelle surprise, you need a health label that maps to your player’s health, but this time Health has different functionality. Health.Life now refers to how much life they gain per second, and Health.HealthRemaining is how much life is remaining, and what’s worse, is there are ten other classes making use of Health.HealthRemaining, and the other developers are used to that system (having not worked on the previous project’s Health components). So what can you do, huh? You can start shouting and writing coding style documents, or you can copy HealthLabel and rewrite it to use Health.HealthRemaining instead. Two weeks later, a major bug is found in your HealthLabel code, and it affects both games. You have to make this change twice, and run your tests on both classes.

10 games later, and the 10 different versions of HealthLabel are becoming a pain to maintain, so what’s the solution?

In this example, Health sends a HealthChanged message using Messenger.Default.Send<HealthChanged>(new HealthChanged(HealthRemaining)) whenever it gets hurt or healed. The Messenger then reroutes that message to whatever has registered for it. In this case, our HealthLabel. The Messenger executes the HealthLabel.HandleMessage  function, which changes the displayed Health value depending on the parameter of the HealthChanged message. A year later, Health is modified to use Life again.  HealthLabel doesn’t have to change at all, we simply fire the HealthChanged message whenever Health.Life is changed. Health and HealthLabel have loose coupling thanks to the intermediate HealthChanged message.

But that’s not all we can do. Now, just like an event, all our other classes with a dependency on Health (for example a red screen flash when you’re hit, or particle effects when you’re healed) can register their functionality to this HealthChanged message. And none of them will need to be changed when Health is modified. Their dependency on the Health class has been abstracted away to only what they need to know – i.e. when the health changes, and by how much.


You may have noticed that up until now, we’ve been using the default messenger, accessed using Messenger.Default. The default messenger is a globally-scoped static messenger than can be accessed anywhere and everywhere, but you can have others. One common use is to create a messenger at the root object of a prefab for inter-prefab messaging without messages being intercepted by other instances of that prefab. A great example for this is if you have a prefab bullet that, when hit, sends a BulletHit message and then destroys the mesh renderer and collider. You have in the same prefab a particle system that shows some hit effects and registers for BulletHit messages in order to do so. If you used the default messenger then every time a bullet hit something, all bullets in the scene would activate their hit effects. It would be chaotic. Instead, create a Messenger at the root of the prefab, and reference it when registering or sending messages,

Inversion of Control

Additionally, the messenger supports the Service Locator pattern. The Service Locator is a way of letting a class get its dependencies from a central location. It’s a type of Inversion of Control which leads to more configurable, generic classes, What’s Inversion of Control? Here’s a quick example:

The top class sets the value NumCores in its constructor to 4. Great for everybody running quad core systems. Not so great for legacy systems or the Glorious PC Gaming Master Race running hexadeca core systems. MyClass is Inflexible and depends on NumCores being 4. The bottom class, however, is more free. Our dependency NumCores is set through a constructor, so some other part of the game logic can work out how many cores to support and your fora are no longer filled with the burning vitriol of a poorly-supported PC gamer. In this case, control over the value of NumCores is wrested from MyClass and left somewhere else. Perhaps for a more suitable CoreProperties class to manage. This is a type of Dependency Injection called Constructor Injection.

Back to the Service Locator. The Service Locator is different to the Dependency Injection pattern in that it centralizes where these dependencies are set. Instead of being given its dependency, MyClass would instead ask the Service Locator how many cores should be supported. Provided someone, somewhere had registered the number of cores, the Service Locator would be able to inform MyClass and fill that dependency.

Note: If you don’t mind reflection in your project (which can be slow) then I would definitely recommend a Dependency Injection container over the Service Locator pattern. A good example is Strange IoC. The Messenger makes no use of Reflection for acquiring dependencies by using the Service Locator pattern.

How does Messenger support the Service Locator pattern? By using the Request<R>() function, which checks the dependency list for appropriate values and assigns them. On the other side of this is the Register<T,R>() function, which maps a request of type T to a return type of type R. This lets the user send a parameterised request for a dependency. Here’s a good example of when to use that.

The PlayerManager creates four players for a multiplayer game, players 1, 2, 3, and 4, and gives them unique ids. It then registers a function PickPlayer which takes an id integer as a parameter with the default Messenger. At the same time, the input manager creates 4 Controllers and assigns them each a number based on which slot they’re plugged into. When controller 3 is created it sends a request to the default Messenger  for the player with id 3. Messenger executes the PickPlayer function and returns Player3.

What’s more is that you don’t have to just use the Messenger to request data on start up, you can also use it to get the result of functions from all over the place. For example, you might want to convert one type to another, and you don’t care how it’s done. Just send a Request!

Combine this functionality with the ability to have multiple Messenger scopes, and you can quickly see the flexibility of this system. You can scope your requests to different areas, from the Application scope of Messenger.Default, to Prefab scope or event to GameObject scope.

The Messenger Class

Note: The Async functions cannot be used when a MonoBehaviour has registered to the message type because a MonoBehaviour cannot run on a different thread. An error will occur.

A Unity Helper Class

This little helper class is not part of the main project, but something I’ve found useful when using Unity. It’s a component that, when a certain message comes through, activates a specified game object. The type of message it listens for is converted through reflection from a string, so this one component can be used for any type of message. Note: If you use namespaces, make sure to namespace-qualify the input string (e.g. System.String or Messages.GameOverMessage).

5 thoughts on “Messenger: Loose coupling through Messages and Requests

  1. Paul Scharf

    Interesting read! If I find the time I will look into if I can apply some of the principles to my own games/other apps.

    Some comments about the 4th code box:

    I think there is a typo where you didn’t rename ‘GetPlayer’ to ‘PickPlayer’ in Register().
    That had me a bit confused at first.

    Also, what is going on with ?
    Unless I am not aware of something important, I think you mean ?
    Given that you pass a proper method, you could of course skip the explicit , but given that you did not introduce the Messenger class at that point, having it there definitely helps to understand what’s going on.

    So yeah, nice post.
    Thanks for making me consider things I hadn’t before! :)

    1. Nick Post author

      Hi Paul, thanks for pointing that out! I’ve edited the code box.

      I think there’s something going wrong with the formatting in your comment, I’m seeing this:

      Also, what is going on with ?
      Unless I am not aware of something important, I think you mean ?

      and I’m not sure I understand.

      Glad I could be of some help!


      1. Paul Scharf

        Ah, I did not anticipate that smaller and greater than symbols wouldn’t work and was too lazy to read over the post again. 😉

        Lets try it one more time:

        Also, what is going on with <int, player=””>?
        Unless I am not aware of something important, I think you mean <int, Player>?
        Given that you pass a proper method, you could of course skip the explicit <>, but given that you did not introduce the Messenger class at that point, having it there definitely helps to understand what’s going on.

        *hopes for the best*

          1. Nick Post author

            Oh dear, looks like the Crayon Code displayer for WordPress is trying to convert things between angle brackets into HTML tags! I’ll try to fix that, you’re right, there should definitely not be an =”” in there.


Leave a Reply

Your email address will not be published. Required fields are marked *