TrueSync Tutorial Part 4
Tutorial Contents
This tutorial series explains how to use Photon TrueSync to build a simple multiplayer game in Unity from the ground up. In parts 1, 2 and 3, we showed basic setup and code to connect to photon, and how to create a physics-based, player-controlled game object, and how to deterministically instantiate and destroy game objects.
What To Expect From Part 4:
A working lower-latency multiplayer game client with a faster response from the player-controlled boxes. Players can now move their boxes around and shoot at each other with faster reaction times.
The Magic of Rollbacks
The gameplay code is now complete, but there's a noticeable lag between a key press and the response from the player box (either movement or fire).
This happens because TrueSync is a lockstep system, and the input queue adds latency to the local player actions, so it can wait for the corresponding remote players' actions to be received before running the simulation.
For certain action games, this lag might be detrimental to the player experience, so we developed a rollback system to compensate that.
What a rollback system does is advance the local simulation even before remote players' input is received, so the game has faster response times for the local objects. For that, TrueSync tries to predict what the remote players' input values will be.
When the actual remote input is finally received, TrueSync compares it to the predicted value and acts according to the following rules:
- If actual input is EQUALS to predicted value: proceed normally with simulation;
- If actual input DIFFERS from predicted value: restore (rollback) the simulation to a previous known state, and re-simulate at once all ticks/frames that were wrongly simulated in advance.
When used right, a rollback system is a powerful mechanism to hide latency in multiplayer games. Now lets see how you can enable this feature in your TrueSync game.
TrueSync Global Settings
TrueSync has a global settings asset that you can find at the "TrueSync/Unity/Resources" folder:
The following variables are important to understand:
- sync window: this is the size of the input queue;
- rollback window: this is the maximum amount of frames that TrueSync is allowed to advance the simulation with predicted input values;
- panic window: maximum amount of missed frames/ticks before a remote player is removed from simulation due to being unresponsive (not sending input values anymore);
- Locked Time Step: time per frame for TrueSync's game loop;
Lets say a game client has a ping (round trip time) of 60ms to Photon Cloud servers, and we're using the default locked step time of 0.02 (20ms time per frame).
In a lockstep game, we need the input queue to compensate that lag from the remote players by adding an equally big latency to local input.
This means that the sync window size shall be at least 3, so we add 60ms (3 frames X 20ms per frame) to all input.
Hiding Latency with Rollbacks
The issue is that ping can fluctuate a lot, so a safer value would be a sync window of 5 or 6. However, this can be too much for certain games, so the option is to increase the rollback window instead:
Using a sync window of 4, and a rollback window of 4 as well gives your game 8 frames of latency protection (meaning it will still run smoothly even with 160ms peak ping times).
Change the global settings and use these values (4 and 4) for sync window and rollback window respectively (removing the default value of 10 for sync window).
Now test-run the game scene. Notice that the player box is a lot more responsive now. You can also do an online test with two builds already and see the result, but there might be issues with the death scores and cooldown times (we'll take care of that now).
Adding State Tracking
One issue with rollbacks is: besides restoring the state of TrueSync's internal physics engines, etc, we also need to keep track of custom variables the you add to the simulation such as health, scores, xp, counter and timers.
Imagine a projectile hits a player box during a simulation with predicted input values, causing it to be respawned and its death counter to be incremented.
Now imagine that a rollback was needed, and with the actual input values received the player box was not hit at all because the player dodged the projectile. The respwan will be correctly overridden by the physics state restore, but the death counter will not, and the simulation will proceed with wrong values.
To protect against these issues, TrueSync has a state tracking system that allows the developer to add any custom attribute or object to be automatically observed and restored to previous values during rollbacks.
For our tutorial, we need the following attributes to be tracked to safely use rollbacks:
- Weapon cooldown timer in "PlayerWeapon.cs";
- Projectile destroy timer in "Projectile.cs";
- Death counter in "PlayerMovement.cs";
To add an attribute to TrueSync's state tracking system, just add the "[AddTracking]" annotation to it and register the component to the state tracking list. The code bellow shows part of the "Projectile.cs" script, now with its destroy timer marked for tracking. Do the same for the other two attributes.
C#
[AddTracking]
private FP destroyTime = 3;
public override void OnSyncedStart() {
StateTracker.AddTracking(this);
}
Final Testing
Please, make sure both scenes (Tutorial/Menu and Tutorial/Game) are included into the build settings, and that Tutorial/Menu is the first one (the one Unity will load at start up).
Create a build of your choice and run two copies of it, or one copy and run the Menu scene from inside the Unity editor.
You should now see both clients connecting to Photon, and then loading the game scene, where each client controls its own box and can shoot at each other. The response from player input should now be faster than before.
Tutorial Sources
You can download the complete sources for the tutorial from here: Unity Package Download.
The sources do not include TrueSync and PUN, so if you want to use the package, please import it into a project that already contains the TrueSync library in it.
Back to top