Multiplayer - GameLabGraz/Maroon GitHub Wiki

:warning: Deprecated: We are currently updating Mirror, information on this page is outdated

With Jannik Hildebrandt's master thesis, a multi-user network was added to Maroon. This page explains where to look in case of errors and how to add multi-user support to existing or new experiments.

Network Implementation

The network is implemented using Mirror. The NetworkManager manages most of the network part. It is a singleton and part of the global entities that are automatically created in each scene. If anything of the network part is broken, the NetworkManager is the first place to look.

Adding Multi-User Support to Experiments

The simplest way to create multi-user support is to mirror the actions of one client to all other clients. In our case, this client is called the client in control and it is stored in the NetworkManager. The base class ExperimentNetworkSync provides basic functionalities. You only have to derive from this class and adapt it for your experiment. It synchronizes the starting and stopping of experiments by adding a listener to the simulation controller's associated events. The virtual functions OnGetControl and OnLoseControl are called when a client gains control or loses it. You can use these functions to enable and disable user interactions. The class also provides the functions AddListeners and RemoveListeners, and automatically calls them. Listeners are a key part of synchronizing the user input. Each user interface element has some event attached to it, such as an onClick event for buttons or an onValueChanged event for sliders. You can add listeners to these events that do not change the rest of the experiment's behavior. They listen if there is any user input and allow sending this user input to the other clients.

The way that Mirror is designed, clients can only communicate with the server and not directly with other clients. Therefore all the information has to be sent to the host first. As each client can be the client in control, we created a method to distribute the user input from any client to all other clients. The base calss provides this SyncEvent method. It takes the name of the action method as a parameter. You have to create a listener on the event that they want to observe, and inside this listener, you call the SyncEvent method, passing the name of the action method. For each event, you have to implement this action method, which has to have the return type IEnumerator so it can be started as a subroutine. The SyncEvent method implements all logic needed for a client to be in sync with the client in control. Yopu should add listeners to the overwritten AddListeners method and remove them in the RemoveListeners method to prevent problems when leaving the server while still being inside an experiment. The SyncEvent method is provided for different input types that are linked to the events. Besides having no additional parameters, it currently supports float, integer, bool, and string. Other methods can easily be created on demand, using these methods as a guideline.

Unfortunately, not all user inputs trigger an event that you can capture using a listener. In these cases, you must find a custom solution and implement synchronization yourself, using Mirror's network tools. There are various examples in the existing experiments that you can use as a guideline. For example, you can have a look at how we synchronized the magnet position in the Faraday's Law experiment.

Guideline for Adding Multi-User Support

We created the following list, that outlines all actions that you have to take, to enable multi-user support for an experiment:

  1. Derive from the ExperimentNetworkSync base class and implement
    1. all user input fields as serialized fields.
    2. the corresponding listeners using the provided SyncEvent methods.
    3. the action methods triggered by the listeners.
    4. all custom synchronizations.
    5. the control handling methods, overwriting the provided methods.
  2. Place the script on an empty game object in the scene and link all the input fields.
  3. Add the network.xml file to the experiment's language manager, so all the network-specific texts can be displayed.
  4. Add the scene to the enabled experiments in the NetworkManager. This allows users to enter the scene while in multi-user mode.