Ok, for anyone ever wandering into this part of internet seeking answer - I did it. You HAVE TO ASSURE that all the clients pause before the host. I did it using RPC calls (since you’re working around the pause-all-logic place, OnRep variables are unreliable and often do not get replicated at all). Goes as follows:
- Client asks the host to pause the game through a Server RPC (if the host is the one pausing you skip this step)
- Host iterates over all the client controllers calling a Client RPC with requesting pause (sending the original client who asked along in form of his player state)
- All clients set their “pauser” property in worldsettings and call a Server RPC with “confirmed” message (with the received player state)
- Host receives the confirm message, checks whether all controllers are ready, if so proceeds to pause his game
Analogous for unpause logic. I have not seen any bugs with unpause being unsynchronized, but I prefer deterministic solutions. If you plan on doing all this in PlayerController, then remember that on host there are all of them and certain data you may want to keep static (for me it was bool for “I am during all that logic, do not interrupt me and ignore all other requests for pause” and cached current pauser - player state of the one issuing the entire chain.
You could theoretically always set the pauser to be yourself on clients and never send it through the Client RPC, but then you have no data at all, and I needed some idea on who’s doing it.
It does cause minor desynchro (fixing itself upon unpause), but works very good besides that - connection is kept, timeouts are received etc. Following this logic I have not experienced any “player keeps moving in some direction” nor “player stuck”.
Interesting to note however is, that all the user input is processed, so your character can move around despite the fact that the world is paused. Block it in some way, and you’re done for the most part. I ended up adding more features (writing out who paused/unpaused the game, counting down some time to make sure others can unpause if the pauser goes AFK too long, etc.) Good luck.