Replication¶
Now that we understand how connections work under Strix, we can move on to the replication features Strix provides. To do this, let’s log in and create a Replication map, but don’t connect the second player quite yet.
We are currently connected and have a player character we can run around with. You will note that our character’s color strength is changing over time. There are many other values with which you can and may want to replicate in your game; however, for this example, we are going to focus on the color value. So, let’s get started by connecting to the room with the second player.
As we connect, take note that we print the name of the current Room Owner. Now we should see both players replicated. Not only does each player exist on each client now, but they can also be moved around, and their color strength is being replicated. Here, we draw the remote player (i.e., the other player in the room) blue and the local player (i.e., you) red. Now, let’s go over how we perform the replication of values and Actors. We’ll cover movement synchronization later in this sample. In the ReplicationBP > Blueprints folder, open the ThirdPersonCharacter Blueprint.
You should see a number of comments explaining the different features in this Blueprint. Of interest to us are the Strix Replicator, Movement Synchronizer, and the Notification Listener components. The Strix Replicator is used to replicate Actors across each client, the Movement Synchronizer synchronizes their movements, and the Notification Listener listens for network events.
Note
One thing you will have to be aware of when replicating, is that the replicated Actors are running the same logic as the originals. Because of this, when we set values we want to be replicated, we only have to do this on the local Actor; otherwise, the replicas would overwrite the changes. In order to facilitate this, Strix provides the Get Is Owner function which returns true if the Actor is the local Actor. You will see this check used throughout this sample.
Note
In addition to the above, it is always a good idea to double check your general logic on replicated Actors. The reason for this is that your logic may have actions that are performed per tick or on begin play that only need to be called once, such as teleporting to a spawn location or a player controller related function. If these types of actions are left on the replicated Actors, they will be called twice, which may produce undesired behavior or simply be inefficient.
To replicate our character and its values, all we have to do is attach a Replicator Component and set the variables we want to replicate to Replicated under the Replication option in their Details panel. If we wish to print that somebody joined the game, we print out that information from the Room Join Notification Event. The Replicator Component will automatically sync the Replicated variables for us; however, if auto register properties is disabled, this will not take place and you will have to manually register properties inside C++ code.
If you look at the level GameMode, you will see some logic for printing the Room Owner information. The Replicator Component has some of its own events, On Sync Begin and On Ownership Received. On Sync Begin is called when the Replicator begins syncing with the server, and On Ownership Received is called when this client becomes the Room Owner. On these two events we print the Room Owner’s name.
The Strix Replicator has a few settings which are explained in the Replication section. The setting we are interested in here is the Instantiable By setting. Note that it is set to Anyone on the player and Room Owner on the GameMode. Strix has the concept of the Room Owner: the first client that created the room. The Room Owner provides an authority for actions in the room. When replicating, the Anyone setting allows each client to create the Actor, which is then replicated. If set to Room Owner, only the Room Owner creates this Actor. All other clients create a replica of the Actor (a remote) but not their own (a local). This means we can have a single game mode instance on every client, and this allows us to restrict the setting of variables to the Room Owner and ensure our logic is called once per client. Also note that the Connection Closed Behaviour is Change Ownership on the GameMode because we want this GameMode to survive even if its owner disconnects.
The Room Owner can change during gameplay, usually when the Room Owner leaves, and a new client will be automatically chosen to lead the room. You can use the Room Owner to perform authoritative actions, process information and replicate to clients, or replicate Actors that aren’t controlled by any player, such as moving platforms, NPCs, etc.
All the examples here use movement synchronization.
To sync an Actor’s location, just add the Strix Movement Synchronizer and tweak the settings to your liking. Here we use a Movement Synchronizer for basic character ground movement.
From here, create a flying movement map.
The flying example simply shows a different use of the Strix Movement Synchronizer Component which requires different values. You can open the FlyingPawn Blueprint in the FlyingSyncBP/Blueprints folder to see these values and play around with them.