public void SetupAndSynchronise(Action onSynchronisedAndReady)
        {
            if (!PhotonNetwork.inRoom)
            {
                throw new Exception("Not connected to photon, could not start synchronisation");
            }

            if (PhotonNetwork.otherPlayers.Length == 0)
            {
                Debug.Log("PhotonNetwork.otherPlayers.Length == 0");

                // Setup mod filter to intercept mods and distribute them before applying them to all instances at once
                EM.Filters.Add(DistributeBetweenPlayersAsyncFilter);

                IntervalTimer.StartTimer(DateTime.Now, TimeSpan.FromMilliseconds(DefaultIntervalMS));
                StartCoroutine(PingCheck());
                onSynchronisedAndReady.Invoke();
                return;
            }

            Action PauseAll = null, RequestES = null, CheckHash = null, SetupLocally = null, UnpauseAll = null;

            // Pause game for all players
            PauseAll = () => PUNPauser.RequestPause(() => NetworkInteractionTracker.WaitUntilCleared(RequestES));

            // Request ES data from one player
            RequestES = () => PUNESRequester.RequestESAndImport(CheckHash);

            // Do hashcode check on data for all players
            CheckHash = () => PUNHasher.RequestHashCheck(SetupLocally);

            SetupLocally = () => {
                // Setup mod filter to intercept mods and distribute them before applying them to all instances at once
                EM.Filters.Add(DistributeBetweenPlayersAsyncFilter);

                NetworkInteractionTracker.WaitUntilCleared(UnpauseAll);
            };

            // Unpause game for all players
            UnpauseAll = () => PUNPauser.RequestUnpause(() => {
                IntervalTimer.StartTimer(
                    ES.GetFirstEventOfType <IntervalStartedEvent>(),
                    ES.GetLastEventOfType <IntervalStepEvent>(),
                    ES.GetLastEventOfType <IntervalChangedEvent>()
                    );
                //IntervalTimer.StartTimer(DateTime.Now, TimeSpan.FromMilliseconds(DefaultIntervalMS));

                StartCoroutine(PingCheck());
                onSynchronisedAndReady();
            });

            // Start
            PauseAll.Invoke();
        }