Master client freezes = game state desynced

Because of how Unity3d works with Windows, it can be fairly easy for a player who is the master client to freeze the game state or stop sending RPCs just by minimizing the game when it's in fullscreen. Photon will not kick this player out and they remain the master client. This can result in some severe game state desync issues if you make use of PhotonNetwork.isMasterClient and using the master client to sync certain game variables.

What is the best way handle this issue? Is there a way to make sure certain variables and RPC calls are synced on the server (i.e. round time, game start/end states, who has won a round, respawning etc). or should people try to find solutions which don't use a master client at all?


  • We wanted PUN to be able to keep the connection in background. It's been a while since I put that in but we set Application.runInBackground = true in PUN and at least run a side-thread that keeps the connection. That's done in PhotonHandler.FallbackSendAckThread().

    You should be able to modify this as it's client-side only.
    Use Unity's callbacks to detect when the app goes into background and disconnect the user after a timeout. You can also just disable this thread and a "normal" Photon disconnect timeout will happen.
    Or make sure the Master Client continues dispatch and react to in-game action. So the game state keeps going on.
    Or in "minimize" pause the game via RPC or ...

    Let me know when you decided which solution would be your favourite and if you need help making it happen.
  • Or make sure the Master Client continues dispatch and react to in-game action. So the game state keeps going on.

    This sounds the best, but how can you make sure the master keeps responding when their whole game is frozen? They stop sending RPCs all together until you bring the game back up again at which point it try to react to all the RPCs at once.

    Note that this is different from just Unity's "Run in Background" as it does not run in background at all when it is minimized from full screen:

    If we can't get people to continue sending RPCs how can we just disconnect them by knowing their thread is running in the back?
  • Ah, ok, so this is a known Unity annoyance. I didn't realize that. Actually, then it's more or less impossible to keep the Master doing it's stuff. I imagine it must run the physics, etc, too. Otherwise it can react to RPCs but not calculate anything world-related.

    Does Unity do a callback when fullscreen gets minimized? If so, you have 2 options:
    a) Try using SetMasterClient(). It should be able to inform the others that someone else is the new Master Client.
    b) Call Disconnect. Quick and dirty.

    If the Master elects someone else as (new) master, this will not happen instantly. For a moment, clients will not know about the change of command. Maybe one client has more lag than others, then it will address the new master even later than others will. It's a bit chaotic.
    If you elect a new Master, the server will not recognize that at all. It will assume the player with lowest actorNumber (PhotonPlayer.ID) is still the master, so you have to send RPCs to a specific player (by ID), rather than using the Target .MasterClient.

    I'm sorry that this situation is so messy. It's not easy with lag.