When the server needs to notify the client that something significant is happening, it sends it a server event. Examples include incoming missiles, the fact that the player’s ship is destroyed, or a chat message.
Like actions, events have types that identify them over the wire. They are also property holders so they can contain whatever information they need. To keep the client and server in sync and avoid having different names for the properties (which is hard to detect at compile time), we rely on server event decorators to wrap access to the properties. These decorators are referenced by both client and server which allows us to make changes to either of them without worrying that the other would go out of sync (as long as they are both built together).
When the client receives an event, it is sent to the currently active ServerEventHandlerFactory to construct its event handler. The ActionManager tracks the active ServerEventHandler, and the SceneManager will swap it depending on the currently active scene to allow different handling of the same event based on the context of the game. For the factory to create the correct action, the event has to be added to the factory explicitly.
An event handler is just a client action. For convenience we have the ServerEventHandler derived class which simplifies the structure by allowing us to specify the decorator as a type parameter. In most cases the handling code would just exist in the Start() method of the action and we’ll return false to terminate the action at that point.