Mirror
  • Mirror Networking
  • API Reference
  • Development Blog
    • A Brief History of Mirror
  • User Manual
    • General
      • Getting Started
      • Script Templates
      • Change Log
        • 2024 Change Log
        • 2023 Change Log
        • 2022 Change Log
        • 2021 Change Log
        • 2020 Change Log
        • 2019 Change Log
      • Deprecations
      • Migration Guide
      • Integrations
      • Timestamp Batching
      • TCP and UDP
      • CCU
      • SyncDirection
      • Round Trip Time (RTT)
      • Connection Quality
      • Lag Compensation
      • Client Side Prediction
      • History Bounds
      • Tests
      • NetGraph
    • FAQ
      • Execution Order
    • Transports
      • KCP Transport
      • Telepathy Transport
      • WebSockets Transport
        • Reverse Proxy
          • Windows
            • IIS
          • Linux
            • NGINX
            • Caddy
            • Apache
            • HA Proxy
        • SSL
      • Multiplex Transport
      • Latency Simulation Transport
      • Ignorance
      • LiteNetLib Transport
      • FizzySteamworks Transport
      • FizzyFacepunch Transport
      • Encryption Transport
      • Edgegap Transports
        • Edgegap Relay
        • Edgegap Lobby
    • Components
      • Network Animator
      • Network Authenticators
        • Basic Authenticator
        • Device Authenticator
      • Network Behaviour
      • Network Discovery
      • Network Identity
      • Network Manager
      • Network Manager HUD
      • Network Ping Display
      • Network Profiler
      • Network Rigidbody
      • Network Lerp Rigidbody
      • Network Room Manager
      • Network Room Player
      • Network Start Position
      • Network Statistics
      • Remote Statistics
      • Network Transform
        • Snapshot Interpolation
      • Deprecated
        • Network Proximity Checker
        • Network Scene Checker
        • Network Match Checker
        • Network Owner Checker
    • Interest Management
      • Spatial Hashing
      • Distance
      • Scene
      • Scene + Distance
      • Match
      • Team
      • Custom
      • Legacy
    • Guides
      • Authority
      • IDs
      • Attributes
      • Time Synchronization
      • Data types
      • Serialization
      • Synchronization
        • SyncVars
        • SyncVar Hooks
        • SyncEvent (Obsolete)
        • SyncLists
        • SyncDictionary
        • SyncHashSet
        • SyncSortedSet
      • Communications
        • Remote Actions
        • NetworkManager Callbacks
        • NetworkBehaviour Callbacks
        • Network Messages
      • GameObjects
        • Player Game Objects
        • Custom Character Spawning
        • Custom Spawn Functions
        • Scene GameObjects
        • Pickups, Drops, and Child Objects
    • Examples
      • Additive Levels
      • Additive Scenes
      • Basic
      • Billiards
      • Multiple Additive Scenes
      • Pong
      • Room
      • Tanks
      • EdgegapLobby
  • Server Hosting
    • The Pragmatic Hosting Guide
    • Cloud Hosting Guides
      • AWS
      • Google Cloud
      • Oracle Free Tier
    • Hosting with a Remote Desktop
    • Edgegap Hosting Plugin Guide
  • Security
    • Security Overview
    • Cheat Protection Stages
    • Cheats & Anticheats
  • Community Guides
    • Community Translations
    • Video Tutorials
    • Resources
    • Mirror Quick Start Project
    • Unity for MMORPGs
    • Unity Canvas HUD
    • Odin Inspector Support
    • Ready Up And Die!
    • iOS AppStore
    • Mirror Docker Guide
    • Gitbook Guide
    • Mirror Branding
    • Contributors Agreement
    • Documentation License
Powered by GitBook
On this page
  • Why Lag Compensation
  • Lag Compensation with Mirror
  1. User Manual
  2. General

Lag Compensation

Learn about Mirror's Lag Compensation for fast paced games.

PreviousConnection QualityNextClient Side Prediction

Last updated 1 year ago

Lag Compensation (aka Rollback) is needed for fast pace / first person shooter games.

For MMORPGs, card games, round based games, strategy games, etc. this is not interesting.

Why Lag Compensation

Let's look at the most common reason why games need lag compensation.

Consider a first person shooter like Counter-strike.

There are two players on the server: you, and your friend.

The server synchronizes your friend's position to you. It takes let's say 50 milliseconds.

You fire at your friend by using a Mirror [Command] CmdFire(Vector3 direction).

The [Command] takes another 50 ms to reach the server.

The Server then checks if you hit your friend, and applies damage.

In the 100 ms that passed, your friend has already moved two steps to the left.

As result, you'll always miss the shot.

This is why you need lag compensation for high paced / first person shooter games.

Otherwise players will always need to aim ahead of their targets.

On paper, this doesn't sound like a big deal. In practice, players will immediately complain that they don't hit where they aim.

The difference between lag compensation turned on / off is very noticeable to everyone.

Lag Compensation with Mirror

Our Lag Compensation is split into two parts.

LagCompensation.cs standalone Algorithm

First, there's the standalone, Unity independent, C# LagCompensation.cs algorithm with full test coverage:

The algorithm can record and sample any History of type <T>. In other words, you can custom fit it to your needs if you want to. Keep in mind that this is very low level, and it's easier to use the high level component instead!

Lag Compensator Component

The second part: our Lag Compensator component:

This hides all the magic in one component which automatically records a history of Collider snapshots in 3D. Simply add this to your Player object, and it'll handle everything for you!

Next, find the place where your player is firing a weapon locally. There should be a [Command] like CmdFireWeapon() that sends the input to the server. This is where instead of checking if a player hit another player, we first ask Lag Compensation for the other player's position at the time when the player shot it.

You can check our Shooter example to see this in action, it's as simple as:

[Client]
void FireWeapon()
{
    // show muzzle flash, play sound etc. locally
    // ...
    
    // check if anything was hit
    if (Physics.Raycast(camera.position, camera.position + camera.forward, out RaycastHit hit))
    {
        Player target = hit.collider.GetComponent<Player>();
        
        // notify the server
        CmdFiredWeapon(target, camera.position, hit.position);
    }
}

[Command]
void CmdFiredWeapon(Player target, Vector3 originPoint, Vector3 hitPoint)
{
    // check ammo etc.
    // ...
    
    // 'this' fired at 'target'.
    // we need to grab 'target's LagCompensator to find out where it was.
    LagCompensator compensator = target.GetComponent<LagCompensator>();
    
    // next, we can use either of the compensator's 'Check...' functions.
    // viewer is the one who fired, so it's 'this' object.
    // Lag Compensator checks 'this' object's latency and then rewinds 'target's history by that time.
    if (compensator.RaycastCheck(this.connectionToClient, originPoint, hitPoint))
    {
         // valid hit!
    }
}

Note the above code is slightly simplified, but that's really all there's to it other than a few more optional configuration parameters in the LagCompensator's 'Check' functions.

Our Lag Compensator is super easy to use, and you can still add more complex checks to if if needed. What matter is that our standalone LagCompensation.cs algorithm is generic <T>, working with anything you need (2D, 3D, custom physics, etc.).

Our Mirror Shooter demo uses the Lag Compensator. As of February 2024, it is almost complete and soon to be released!

Note: Algorithm Minimal Example

If you prefer to not use the convenience LagCompensator component, then you can check our 'Lag Compensation' demo in the Examples folder. It's super simple, not even networked, and shows only the algorithm without the component.

In other words: ignore this example if you are using the component!

This demo is very easy to understand:

  • The filled white square is an object on the server

  • The outlined white squares are the captures taken every interval.

  • The black square is the object on the client, lagging behind by a few milliseconds

  • You click the black square, which calls a CmdFire() on the server.

  • If it highlights blue, you hit. If it highlights magenta, you didn't hit.

  • The black square is exactly one square behind the white square, which means you'll only hit if it lag compensation functions properly.

This was Lag Compensation part one: the algorithm.

You can use this in games today, you just need to adapt the demo to your needs.

You also need to worry about rolling back the physics world, we don't have a demo for this yet.

For a more in-depth understand, please read through . It's a good read, and worth the time even if you don't understand all of it yet.

Valve's Source Multiplayer Networking article
Mirror's Lag Compensation Example
Where you see your friend, and where your friend actually is. Image from .
Valve's Article