Network Simulation
Overview
During development, most tests will be done with really good internet connections. Once released, the clients can encounter higher delays and loss of messages. To prepare a game for real-life conditions, the Photon client libraries let you simulate some effects of internet-communication: lag, jitter and packet loss.
Effects
- Lag / Latency: a more or less constant delay of messages between client and server. Either direction can be affected in a different way but usually the values are close to another. Affects the roundtrip time.
- Jitter: Randomizes the Lag in the simulation. This affects the variance of the roundtrip time. UDP packages can get out of order this way, which also is simulated. The new lag will be: Lag + [-JitterValue..+JitterValue]. This keeps the mean Lag at the setting and some packages are actually faster than the Lag value implies.
- Packet Loss: UDP packages may get dropped. In the Photon protocol, commands that are flagged as reliable will be repeated while unreliable messages get lost (and are hopefully replaced by newer info soon). Loss only applies to UDP connections.
All values are additional to the real network conditions. Packets are held in a queue and delivered by a dedicated background thread that exists only while the simulation is enabled. The delay is accurate to about 1-2ms: a packet may be delivered a few ms later than configured, but never earlier.
If lag and jitter are 0 for a direction, packets of that direction are passed through directly, without delay but loss simulation still applies.
Debug Only
The simulation is only compiled into the debug build of PhotonClient.dll (PhotonLibs/netstandard2.0/debug/), which is the default.
This is deliberate, to prevent shipping a release with simulation enabled.
If your Uniy project defines PHOTON_LIBS_RELEASE to use the release dlls, the settings exist but have no effect.
Using Network Simulation
By default, Network Simulation is turned off.
Turn it on with PhotonPeer.IsSimulationEnabled; the individual values are aggregated in a NetworkSimulationSet, accessible via realtimeClient.PhotonPeer.NetworkSimulationSettings.
The settings belong to the peer's internal connection object, which is kept as long as the transport protocol stays the same.
A Realtime client switching from Master Server to Game Server keeps its simulation settings (only LostPackagesIn / LostPackagesOut reset per connection), but a switch of the protocol resets them to the defaults, simulation turned off.
That happens with the default AuthMode.AuthOnceWss, where the Name Server is contacted via WSS and the Master Server then with AppSettings.Protocol (UDP by default).
Configure the simulation in OnConnectedToMaster rather than before connecting, and it will stick.
Disabling flushes the queued packets by sending / delivering them immediately, so it may take a few cycles.
- On UDP,
Disconnect()temporarily turns the simulation off, so the disconnect command and anything still queued goes out without simulated lag or loss (the setting is restored right after). The socket is closed immediately afterwards, and a lag-delayed disconnect would never make it out. On TCP and WebSocket there is no such flush: packets still waiting in the queue are dropped when the socket closes. - The simulation thread is torn down when the process exits, and outgoing packets still in the queue are not sent.
To send pending data and disconnect gracefully on application quit, set
IsSimulationEnabled = falsefirst (this flushes synchronously), thenDisconnect().
C#
using Photon.Client;
using Photon.Realtime;
RealtimeClient client = new RealtimeClient();
PhotonPeer peer = client.RealtimePeer;
// Activate / Deactivate:
peer.IsSimulationEnabled = true;
// Raise incoming lag (default: 100ms per direction):
peer.NetworkSimulationSettings.IncomingLag = 300;
peer.NetworkSimulationSettings.IncomingJitter = 50; // lag becomes 250..350ms; default jitter is 0
// Add 10% of outgoing loss (default: 1%):
peer.NetworkSimulationSettings.OutgoingLossPercentage = 10;
// These properties count the actually simulated loss:
int lostOut = peer.NetworkSimulationSettings.LostPackagesOut;
int lostIn = peer.NetworkSimulationSettings.LostPackagesIn;
// A summary of all current values:
client.DebugReturn(LogLevel.Info, peer.NetworkSimulationSettings.ToString());
Simulating a Connection Loss
To just cut the connection and run into a client timeout (including the resulting IConnectionCallbacks.OnDisconnected callback), RealtimeClient has a shortcut.
It sets incoming and outgoing loss to 100% and enables the simulation, so it overrides any simulation settings made before:
C#
client.SimulateConnectionLoss(true); // false ends the simulation again
To run into a server timeout instead, set OutgoingLossPercentage = 100 and IncomingLossPercentage = 0 yourself: the server stops hearing from the client while the client still receives.