Bolt 103 - Events

In 'Bolt 101' and 'Bolt 102' we learned the basics of getting Bolt running and how get some properties and game objects replicating over the network. In this section we will look at events in Bolt, what they are and how you use them.

The first thing we need to do is to create a new Event, this is done in the same way we created a new State previously. Open up the 'Bolt Assets' window and right-click in an empty area and select 'New Event' from the drop-down menu.

When you create the event Bolt will open it in the 'Bolt Editor' window, the first functionality we're creating is going to be a simple game log which tells everyone in the game when someone joins and leaves.

Rename the event to 'LogEvent' and then click 'New Property' next to the name field. Name our new property 'Message' and set the type to 'String'. Set the 'Encoding & Length' settings to 'UTF8' and '64'.

Before we continue lets examine the two settings on the event asset itself, namely 'Global Senders' and 'Entity Senders'. An event in Bolt can be sent in two different ways: Globally or to a specific Entity.

A global event will be received in the classes which inherits from 'Bolt.GlobalEventListener' and can be sent freely without the need to have an actual Bolt Entity as the target. An entity event will be received only on the scripts which on the entity the event is sent to and that inherit from 'Bolt.EntityEventListener'.

The options for 'Global Senders' and 'Entity Senders' controls who can send the event. Since our 'LogEvent' is going to be a global event, but we only want the server to send it we should switch 'Global Senders' to 'Only Server' and since we never want to send this event as an 'Entity Event' set 'Entity Senders' to 'None'.

Important: To make Bolt aware of our event we need to compile again, either using the green 'arrow' button in the 'Bolt Assets' window or through the Assets/Bolt Engine/Compile Assembly menu.

After we compiled we are going to create a new C# script in 'Tutorial/Scripts' and call it ServerCallbacks. We want it to inherit from Bolt.GlobalEventListener and also decorate it with the [BoltGlobalBehaviour(BoltNetworkModes.Host)] attribute which tells Bolt to only run create an instance of this class on the server. For more information on global callbacks see: In Depth - Global Callbacks.

We also want to implement the Connected and Disconnected callbacks .

The code inside Connectedand Disconnected is identical other than the string we will send in the Message property on the LogEvent.

In Bolt you use EventName.Create(); to create a new event, you then assign the properties you want and call eventObject.Send(); to send it on it's way. The Create method has several overloads with different parameters that lets you specify who the event should go to, how it should be delivered, etc.

The last piece missing now is for us to listen to the event, open up the NetworkCallbacks script from the previous chapters. There is now a new method on it called void OnEvent(LogEvent evnt) that you can implement like this:

Add a new variable to your class of type List<string> and call it logMessages. Make sure you have using System.Collections.Generic; at the top of your file so you have access to the List<T> class.

Inside OnEvent we need to just add the value of the evnt.Message property to the logMessages list:

The whole script should now look like below.

The last thing we need to do is to just display our log, we are going to use the standard unity OnGUI method for this.

We're rendering a box in the bottom center of our screen that is 400 x 100 pixels. And then we just print the max 5 latest messages that arrived in the log. The entire NetworkCallbacks script now looks like this.

And if we run our game and connect a couple of clients, it should look like this:

We're going to implement one more event just to show how entity events differ from the global event we just sent. Create a new event in the 'Bolt Assets' window and call it 'FlashColorEvent'. Set 'Global Senders' to 'None' and 'Entity Senders' to 'Only Owner'. Create a new property and call it 'FlashColor', set the type of it to 'Color'.

We are going to use this event to allow you to flash your own cube in a red color to signal that we are taking some (pretend) damage.

Important: Remember to compile Bolt after you created your event.

Open up our CubeBehaviour script in 'Tutorial/Scripts', we are going to change the baseclass from Bolt.EntityBehaviour<ICubeState> to Bolt.EntityEventListener<ICubeState>, like this:

The Bolt.EntityEventListener<T> class actually inherits from Bolt.EntityBehaviour<T> so all the same methods are available on it as Bolt.EntityBehaviour<T>.

At the end of the SimulateOwner method we are going to add a couple of new lines that lets us send our 'FlashColorEvent' when we press the F key.

The way you send an entity event is almost identical to a global event, except for one detail: You pass the entity you want to send the event on into the Create method.

We're going to add a few more things to our CubeBehaviour class, first we need to keep track of when to stop flashing the color from the FlashColorEvent so we will add a variable called resetColorTime. We also add a variable called renderer and use it to save a reference to the GameObject's Renderer component in the Attached method. This way we don't have to call GetComponent<Renderer> over and over again.

When we compiled Bolt with our new FlashColorEvent a new method was created on the Bolt.EntityEventListener<T> class that is called OnEvent(FlashColorEvent evnt), we are going to implement this in our CubeBehaviour.

Here we set the reset-time of the flash to be 0.2 seconds into the future, and we change our material color to the color we received in the event. The last thing we need to do is to just implement the standard Unity Update method to reset our color when the time has passed.

The entire CubeBehaviour script now looks like this.

And if we play our game and hit F on any of the instances the cube that is controlled by that instance will breefly flash red on all screens.

I higlighted the parts in the Bolt Console that relates to the flash event being sent and received on the different instances, the middle-bottom one is the instance that I pressed F on.

Why two types of events?

This is a question which comes up a lot, why are there two types of events in Bolt? Why not just one like how RPC's work in Photon or Unity Networking?

Global events can be both Reliable and Unreliable by passing in different parameters to the Create method. In general most global events will be Reliable and that is also the default if you don't pass in anything to change it. Global events are intended for things that exist around the game like dealing with authentication or handling stuff like player inventories, etc.

Entity events are always Unreliable, they are intended for small one-off effects like showing a damage indicator or maybe playing an explosion, things that are ephemeral and if one player misses it it doesn't matter.

 To Document Top