Tag Archives: object oriented programming

Local dev discovers one neat class to inject value types.

Programmers hate him!

But seriously, for most inversion of control containers, injecting a value type is a bit of a pain. You’ll get it, sure, but you can’t change it and have those changes mirrored back to where it came from. It is a value type, after all.

Well, no longer! Just use this class to wrap up any value type in a reference type you can take with you and alter to your heart’s content!

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.

Scope

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).

Effect Manager – How to manage simultaneous modifiers

HyperGauntlet slow motion vignette using the Effect ManagerIn Hyper Gauntlet, I have recently implemented a vignette system for the edges of the screen. Vignettes are coloured based on the changing game state, with a slow blue fade in and out during slow motion and a red flash when you hit an obstacle. Originally I tweened between colours as needed, but I soon met errors in common scenarios when the vignette colour must tween back to a previous effect colour. As an example, imagine an obstacle is approaching fast. I hold space to engage the slow motion, and a blue vignette appears around the screen. Unfortunately, I cannot move out of the way in time and I hit the obstacle – causing the vignette to fade quickly to red. In a basic system, the vignette would then fade back to a neutral state, instead of returning to the blue to signify that slow motion was still engaged, and this confuses players. Today I present a simple solution tailored for Unity systems that applies to any code base. It’s not just useful for vignettes either, I intend to also apply this system to slow motion (to apply power up-induced slow motion even when the player lets go of space for manual slow motion), and this could also find a use in stacking effect spells in RPGs.

Effect

Let’s start with the simplest class. It’s an effect. It doesn’t really do much at all, you’re meant to extend from it or any of its derived classes with your own, more specialised classes. Effect acts as a catchall for all effects so that they can all be processed. It does support events for tweening in though, as all effects can be gradually applied.

TweenEventArgs

You may have noticed that Effect fires an event, OnTweenInBegin which uses a custom EventArgs implementation called TweenEventArgs. All we hold in TweenEventArgs are the destination colour of the effect being processed and the tween time, which we get straight from the effect itself. The source for this looks like this.

Temporary Effect

This is only a small extension of the Effect Base class. The Temporary Effect will make up most of the effects applied. These effects both tween in and out and have events to handle this, as well as an abstract function IsActive() which the Effect Manager will use to decide whether to keep or discard the effect.

Timed Effect

Finally, we get to the meat of the effects system. The Timed Effect applies itself to an object for a certain amount of time and then the Effect Manager removes it. By its nature it’s a temporary effect, and thus has both tweening in and out, as well as a new field for how long after the tween in completes before the Tween out should start.

Here, Time.timeSinceLevelLoad is a Unity utility field which holds how many seconds have passed since the level completed loading.

Triggered Effect

The Triggered Effect is a temporary effect that begins enabled until it is disabled externally through a function call. This kind of effect is useful for player-controlled effects, such as those dependent on a button being held down, or an effect dependent on more complicated code than simple timing.

Combo Effect

The combo effect allows you to combine effects as needed. For example, if you want to have apply an effect for as long as a button is held down, but at the same time want to restrict how long the button can be held down for (a good example is how Hyper Gauntlet handles the slow motion button). Slightly more in-depth than the previous effects, the Combo Effect allows you to specify a combination operation based on Boolean AND or Boolean OR.

Effect Manager

The Effect Manager handles all active effects for a single property. You might have one for max. health in an RPG, or in the case of Hyper Gauntlet, for the speed of time. An Effect Manager operates a Stack of active Effect objects. When you add an effect, they’re put on the top of the stack, and when the top of the stack becomes inactive, the Effect Manager removes it. This manager supports both cumulative effects (by attaching to the OnBeginTweenIn and OnBeginTweenOut events of the Effects) and effects where the top of the Stack overrides all Effects beneath it (by attaching to the OnEffectRemoved event in the manager and checking the currently active effects stack).

In action

Here’s an example of the Effect Manager being used to manage the vignette system in Hyper Gauntlet. I define the Vignette Manager class as a subclass of Unity’s MonoBehaviour class, and manage colour tweening on the OnBeginTweenIn and OnEffectRemoved events. I don’t handle the OnBeginTweenOut event because I am reverting the colour of the vignette to the top colour on the stack, not removing the effects of the colour (you can think of it as the difference between setting an integer from 6 to 4 or removing a +2 effect on the integer).

Then attached to the same object as the VignetteManager I have a lot of classes that look like the following.

These attach to various in-game events, such as hitting an obstacle in this example, and add Effect objects on the vignette manager. As you can see, it’s incredibly simple to add new vignette effects to this system.

As you can see this is a powerful system for managing a common problem in games. You’re free to use this code however you like, but I make no guarantee that it will work (although it does for me!). On your head be it.

A few helpful classes for text generation

I’ve been in Greece for a conference on biomechanics for the last week, so I haven’t had time to write a proper article. As such, I figured I’d offer a consolation prize by way of a few helpful classes I’ve written while working on my text adventure game What Will You Do Next?.

Word

The Word  class handles text input and output by storing synonyms for a word. When accessing the word, it returns a random synonym, when comparing words, all synonyms are compared.

Example

CombinedText

CombinedText builds upon Word by holding a sentence, paragraph, or other concatenation of words and strings. Every time the combined text’s ToString() function is called, it polls the words and returns different synonyms to add variety to text outputs.

Example

That’s all for now, folks, but come back on Saturday for some new screenshots of Speedrun!