Lesson 16.1: Adding centralized messaging

Now it’s time to work on better combat logic.

The basic plan is to create a new Battle class that will handle all the combat information – the player, their opponent, their turns, the results, etc.

We’ll add a CurrentBattle property to GameSession and have it store a Battle object. I want to do this in a functional style, like the Inventory class. So, the Battle class will be read-only properties and the combat logic will be in a new BattleService class.

At least, that’s the current plan. As always, we’ll adapt if we see problems during development.

 

When I started looking at the code, I noticed the combat logic sends a lot of messages to the UI.

To make it easier to move the combat logic into its own class, I decided to start this change with creating a separate MessageBroker class that can be used by any object in the game and watched by the UI. The MessageBroker class is a “Message Broker” – a class that separates the publisher and subscribers in the Observer pattern.

Right now, we’ll only have one subscriber, the UI. But, this message broker will give us flexibility for the future, and make it easier to move our current combat code into another class – since we won’t need to create new message events in every new class, and have the UI subscribe to the different events.

 

This is the current structure

 

When we create the Battle class, we need to decide how to send messages to the UI (MainWindow.xaml.cs)

 

We’ll handle messages to the UI by creating a MessageBroker class. It will be a Singleton (only ever one instance of the class, that all other objects in the program will share). The UI will subscribe to the one MessageBroker, insterad of us creating infividual events and subscriptions for each different type of class we might create in the future.

 

 

 

Lesson Steps

 

Step 1: Create \Engine\Service\MessageBroker.cs

Because we want every object in the program to use one shared instance of the MessageBroker, we’re going to use the Singleton design pattern for this class. We’ll do this by:

  1. Making the constructor private, so it cannot be instantiated by any other class (line 13).
  2. Creating a private static variable that will hold the only instance of the MessageBroker class (lines 10-11)
  3. Creating a static GetInstance function that returns the static instance of the MessageBroker object (lines 19-22).

 

Now, any class that wants to use the MessageBroker (as a publisher or subscriber) will call MessageBroker.GetInstance() to store a local reference to the shared MessageBroker object.

 

On line 17, we have the OnMesssageRaised EventHandler that the UI will subscribe to, to get all the messages.

The RaiseMessage function on line 24 is what the publisher objects will use to publish their messages.

 

MessageBroker.cs

 

 

Step 2: Modify \Engine\ViewModels\GameSession.cs

Now that we have our message broker, we’ll add an instance of it to the GameSession class – in the _messageBroker variable on line 10. You’ll need to add “using Engine.Service;” to be able to reference the MessageBroker class.

Then, we’ll change our existing RaiseMessage calls to use the RaiseMessage function on _messageBroker. If I counted correctly, there are 30 calls to RaiseMessage that need to be change to “_messageBroker.RaiseMessage”.

Then, delete the RaiseMessage function that was on line 350 (the last function in the class).

Finally, we can remove the “public event EventHandler<GameMessageEventArgs> OnMessageRaised;” that was on line 11. The UI won’t subscribe to this event any longer. It will subscribe to the one in the message broker.

 

GameSession.cs

 

 

Step 3: Modify \WPFUI\MainWindow.xaml.cs

First, I deleted the useless comments from line 13-15, in case you read this and wonder why your line numbers might be different.

Add “using Engine.Services;”, so this class can see the MessageBroker class.

Create a “_messageBroker” variable to hold an instance of the MessageBroker object on line 16.

On line 27, change the subscription to OnMessageRaised from “_gameSession” to “_messageBroker”, since all new messages will go through the message broker object.

 

MainWindow.xaml.cs

 

 

Step 4: Test the game

Even though we didn’t change a lot of code, we did change the architecture of the program. So, test the game to make sure it still shows messages in the UI.

 

 

Additional links for this project

Source code: https://github.com/ScottLilly/SOSCSRPG

Project plan: https://github.com/ScottLilly/SOSCSRPG/projects/1

Discord: https://discord.gg/AUYXYtH

Return to main page

Leave a Reply

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