If you are a game developer and haven’t heard of Reactive Programming yet, drop everything you’re doing right now and take a few minutes to read on. I am dead serious.

Don’t mind the cats. Read on about Reactive Programming!

So, I got your attention?

Great! I’ll try my best not to loose you.

What is Reactive Programming?

Now, I’m not going to start by boring you with a high-level description of what Reactive Programming is, how it came to be, and why it makes so much sense. I’m going to start you off much more practical.

When you are working with a well designed game engine like Unity3D most of your life as a programmer is fun. You are writing your own script components, construct your objects from those building blocks — and usually everything fits together really nicely. And while you are doing so, the answer to most software design questions come quite naturally to you.

Where do I store my players health?

Inside the Player component, of course!

Where do I store the amount of damage caused by a rocket once it hits the player?

Inside the Rocket component!

Where do I store the time left to play inside a running Level?

You guessed it. Inside the Level component.

Now this leaves us in a very happy place to be in. Everything seems to sit where it naturally belongs, and all is well in our world. But as we all know, it never stays like this for long.

Glue Code — when it starts getting sticky…

Now since we want to make a game that is going to be played by non-developers, our players don’t really care about how neat and tidy their health value is stored internally. All they care about is that they see it displayed in the game UI. So, what do we do?

Easy right? How about inside the Player component we place a reference to the UI label, and we also update the UI every time the health changes?

Moving on. How about the level’s time left to play?

Why not do the same? Inside the Level component we place a reference to another UI label, and we update it whenever decreasing the game time left.

But now that’s not all. Because our designer chose to go extra fancy, and also has a great flashing animation for every time the player’s health decreases.

All right, so why don’t we go back to the Player class, add another reference to the animation, and just start the animation also with every health decrease?

Now wait, what? There is a power-up you can collect that lets you control another player for a period of time, showing that player’s health instead of your own?

Okay, wait a second… argh…

It happens to the best of us…

Reactive Programming to the Rescue!

To understand the real benefit of reactive programming, we’re going to have to get a bit theoretical. But no need to worry, we’ll keep it as simple as possible.

Writing games is mostly done in imperative languages, and writing scripts for Unity3D using C# is no exception to this. Now when we’re talking about imperative languages on the one side, the other side we usually compare them to are functional programming languages. But we’re not going down that route today and are instead talking about another scale.

Imperative vs Declarative

The difference between imperative and declarative languages can be broken down quite easily: while imperative languages describe how something is to be done, declarative languages describe what is to be done.

Now we can’t change the fact that C# is an imperative language. And at the core we can only write imperative using it. However, by using certain frameworks, which internally do all the heavy lifting for us, we can still make use of certain declarative paradigms.

One of these paradigms is Reactive Programming, provided to Unity and C# in the form of Reactive Extensions for Unity (UniRx).

Show me some code!

Enough theory for now. Let’s get our hands dirty!

And we’ll start this by having a look at the Player class example we talked about earlier:

using UnityEngine;

using UnityEngine.UI;



public class Player : MonoBehaviour {

public int health = 100; public Text scoreLabel;



public void ApplyDamage(int damage) {

health -= damage;

scoreLabel.text = health.ToString();

}

}

Now, before we do anything to it, let’s take a closer look, and look for the “glue” inside this component and discuss what makes it so sticky.

using UnityEngine;

using UnityEngine.UI;



public class Player : MonoBehaviour {

public int health = 100; public Text scoreLabel;



public void ApplyDamage(int damage) {

health -= damage;

scoreLabel.text = health.ToString();

}

}

There it is! That sticky stuff.

Now let’s get rid of it and replace it with some Reactive Extensions magic:

using UnityEngine;

using UnityEngine.UI;

using UniRx;



public class Player : MonoBehaviour {

public ReactiveProperty<int> health

= new ReactiveProperty<int>(100);



public void ApplyDamage(int damage) {

health.Value -= damage;

}

}

Now where did the label reference go? We are moving it somewhere else. But let’s first talk about that fancy ReactiveProperty class.

For now let’s just say it’s a special kind of container, that can store anything we would normally store inside a variable (in this case its an integer, but it can also be of any other simple type or reference). We can assign a start value to it, and we can also access and change the value stored with-in it at any time.

The Reactive superpowers of ReactiveProperty

Introducing our new player in the game, the UiPresenter class:

using UnityEngine;

using UnityEngine.UI;

using UniRx;



public class UiPresenter : MonoBehaviour {

public Player player;



public Text scoreLabel;



void Start() {

player.health.SubscribeToText(scoreLabel);

}

}

There is our scoreLabel again. But now wait, what else is happening here?

Let’s start by trying to lift the confusion first.

Remember how we talked about declarative vs imperative, and how somehow Reactive Extensions enable us to be declarative by giving us imperative extensions enabling us to be declarative? Even more confused now?

I did that on purpose! Because if you are confused right now, you are exactly in the right state of mind to soon connect all the dots. And don’t worry, we’ll do that step by step.

Let’s start with what we are doing here actually, or what we are imperatively telling the computer to do (this is the first dot). We are telling it to Subscribe to a ReactiveProperty. And how that is done internally is defined by the Reactive Extensions we are using (so we don’t have to worry about how it works exactly — phew, right?).

So what does that mean? Subscribing to a ReactiveProperty? To answer this question we have to shine light on some concepts first.

A ReactiveProperty is a special kind of Observable, the base class Reactive Properties are built around. You can think of a observable as a stream of values.

This looks awesome but unfortunately is not the kind of stream of values we are talking about

Stream of values sounds awesome right? But probably you don’t really know how to picture anything useful with that.

So let’s quickly replace that awesome looking image that doesn’t really help us much with something a little less awesome looking but much more practicable:

What do you see? A billiard table!

Yes, What else?

Warning, if you keep reading you might see Observables everywhere!

I see 6 Observables!

Now to understand what observables are, what you have to do is add time to the picture. Imagine the game playing out, and one by one — independently the observables will “emit” a ball. In the following image we see this for each observable hole, with the X-axis of our diagram being the time moving forward:

Okay, so observables are streams of values over time. Now what was that whole thing about declarative programming about?

Well, once we have established what observables are, we can take it to the next level by defining generic operations on top of them.

Going back to our example: think of what happens to the pool balls once they disappear in one of the holes. They start rolling on some pathway beneath the table, and - for the sake of this example - let’s say they end up in one continuos row. So what we want is this:

Now to describe this behaviour we can use the declarative language provided to us by Reactive Extensions like so:

all_balls_in_order = Observable.Merge(h1, h2, h3, h4, h5, h6);

Now the key here is, we are not really doing anything yet. Running this code by itself would have no effect at all. We are not executing anything here that does process any data. Instead we are describing what should happen to the given streams and create a model that can later be used to represent another stream (and that closes our little journey to the theoretical world).

Back to the practical world: reactive superpowers.

Now we can even travel through time!

Only forward that is, though. Sorry for having to disappoint you.

Let’s take another look at our pool ball example and this time we try to simulate the fact, that depending on which hole a ball enters, it takes a specific time until it rolls to the bottom.

all_balls_delayed = Observable.Merge(

h1.Delay(

TimeSpan.FromSeconds(1)

),

h2.Delay(

TimeSpan.FromSeconds(2)

),

h3.Delay(

TimeSpan.FromSeconds(3)

),

h4.Delay(

TimeSpan.FromSeconds(3)

),

h5.Delay(

TimeSpan.FromSeconds(2)

),

h6.Delay(

TimeSpan.FromSeconds(1)

)

);

Now that’s almost too easy, isn’t it?

Still not impressed?

In that case head over to rxmarbles.com and check out how much more awesome stuff you can do with simple built-in commands.

Ungluing the UI example

Remember how actually we just wanted to get rid of some UI glue code, and now somehow ended up talking about time travel? Welcome to the exciting world of Reactive Programming!

But, actually going back to our example from earlier. Let’s talk about the most basic of operations we can define on observables, and how we actually use them after declaring them. So let’s take a look at another version of UiPresenter:

using UnityEngine;

using UnityEngine.UI;

using UniRx;



public class UiPresenter : MonoBehaviour {

public Player player;



public Text scoreLabel;



void Start() {

player.health

.Select(health => string.Format("Health: {0}", health))

.Subscribe(text => scoreLabel.text = text);

}

}

First let’s talk about the Select operator (on rxmarbles and some other Reactive Extension implementation it’s called map). What it does is apply a function to every element in the stream. In this case we are taking all input elements (which are integers) and turning them into a string.

Now what we’re doing afterwards is subscribing to this resulting stream. Remember how we said that just declaring streams doesn’t really do anything yet?

Subscribe actually starts processing a stream, passing all values inside the stream to the callback provided. And we are using this value in the callback to change the text property of our label. The SubscribeToText command we have used earlier is just a shortcut, that does exactly the same thing.

Now let’s extend this example one more time to implement all three requirements we wanted to deal with earlier. First let’s do the animation:

using UnityEngine;

using UnityEngine.UI;

using UniRx;



public class UiPresenter : MonoBehaviour {

public Player player;



public Text scoreLabel;

public Animator animator;



void Start() {

player.health

.Select(health => string.Format("Health: {0}", health))

.Do(x => animator.Play("Flash"))

.Subscribe(text => scoreLabel.text = text);

}

}

That was easy wasn’t it? As you can probably guess the Do operator simply executes a function for every value in our stream, without changing it.

And now finally the third thing, supporting a different active controlled player:

using UnityEngine;

using UnityEngine.UI;

using UniRx;



public class UiPresenter : MonoBehaviour {

public ReactiveProperty<Player> player

= new ReactiveProperty<Player>();



public Text scoreLabel;

public Animator animator;



void Start() {

var playerHealth = this.player

.Where(player => player != null)

.Select(player => player.health);



playerHealth

.Select(health => string.Format("Health: {0}", health))

.Do(x => animator.Play("Flash"))

.Subscribe(text => scoreLabel.text = text);

}

}

Wasn’t that easy? We just turned the player into a ReactiveProperty also, and then take it from there. So instead of writing code that is dealing with one specific player, we just turn the active player from a variable into a stream.

And, as you will soon realise once you dig more into reactive programming: Almost everything can be turned into a stream.

Image taken from The introduction to Reactive Programming you’ve been missing

Wrapping it up

Now, if I haven’t done an all to terrible job writing this article, I should have gotten you at least a bit excited about Reactive Programming and you want to dive deeper into it. And the perfect starting point for that would probably be the documentation of the respective Reactive Extensions that you are going to use. So for Unity3D that would be UniRx.

Also have a look at rxmarbles.com for a really nice visual overview of operations, that are now at your fingertips. But note that the names of these operations don’t always match the ones in UniRx (map for example is called Select in UniRx).

“The introduction to Reactive Programming you’ve been missing” is also a good read.

And finally, if you liked this article, please don’t forget to hit that clap button on your way out 👏

Thanks for reading!