I'm planing to write a small web app where two players can play a chess game with blitz time controls. Here's a small description of how the process of making a move works:
- Player A thinks about what move to make
- Player A sends a move to my server
- My server processes the request
- My server sends a response to the push server
- The push server processes the request
- The push server sends a response to player B
- Player B thinks about what move to make
It makes sense that step 1 will be running on player A's allotted time and step 7 will be running on player B's allotted time. What can I do about the other steps? Is there any way to measure how much time those other steps took and maybe to add the result to both players' clocks?
This can't be done without trusting the client.
The basic problem is that a client with low latency can pretend to have a high latency in order to gain bonus time. A client with 100ms of round trip latency may pretend to have a 3s RTT and use this deception to turn a 6.9s move into a 4s move. There is no practical way for a protocol to detect a client pretending to have high latency, unless the client makes a mistake (e.g. asking for a 3s delay waiver when they took 1s to make their move).
On the other hand, if you do trust the client, you can just estimate their RTT by pinging their machine periodically and deducting that time from their move time. If you really trust the client, have them measure and report the elapsed time with the move data.
There are a lot of ways to manage this trust/latency-penalty tradeoff. You can assume a minimum RTT (50ms?) and deduct that from everything. You can put bonus time on the clocks. You can have the user-facing option of a game being 'secure' vs 'forgiving'.
I've went for Thomas C. G. de Vilhena's idea in the end. In summary:
- the time is measured for each player starting from when he is informed that he has to play and ending when he sends the move to the server
- the time remaining for the opponent is adjusted when the player is informed on the opponent's move
- to prevent users from cheating the javascript that sends the move will be obfuscated and the server response will be encrypted
- a time correction routine is necessary in case players exceed the time alloted
- (optional) a mechanism will be available to each player to detect any (unlikely) attempt of cheating, resulting in logging that hopefuly will allow an arbiter to decide on which side the cheating occured
This insures that a player will see that the server respects his thinking time, and no player will suffer from lag.