Why is it necessary to correct the start time on each heartbeat? How does the start time change?
Well, it's not necessary. But it's better to do, and it's easy. So why not?
Basically it handles this situation:
Client receives a "game started" event. Client records the time it got the game started. 5ms later, the server says "the game has been running for 150ms".
With this information, the client can know that the "game started" event was lagged out (e.g. network problems). It can safely update the "game started" time to be 145ms earlier than it previously had it.
"So the client basically has two options..." Could you perhaps elaborate more on this? I don't really understand what you ment.
What part of my explanation didn't you get?
So if I understand correctly the only purpose of the game tick is telling the client the game is still running, esentially a heartbeat.
In case the client does not receive a game tick it can show a 'reconnecting' animation or something similair. I completely understand that and it makes much sense to me. However why is the including elapsed time necessary in this event?
Earlier you said this is used for correcting the start time, why not just send a unix timestamp when game emits the start event? This way desync can never happen since the client has the start time of the game and does not calculate this time itself. If the game start event is emitted 5 second later, the client will still receive the correct unix timestamp when the game started since this does not change in the backend.
So instead of sending: game_tick: 1041, why not send game_tick: true (assuming this is only used as a heartbeat you explained earlier).
I don't see the need of the elapsed time here.