codeday-hom / hit-or-miss

Hit or Miss game - online version
0 stars 1 forks source link

Game can be played on a mobile browser #42

Closed robmoore-i closed 9 months ago

robmoore-i commented 11 months ago

Playing the game on mobile is often the easiest way to show some "look what we made!". Currently though, it doesn't work for technical reasons. The website designs works fine, but the game transitions don't work.

The core problem that prevents this from working currently is the fact that the game cannot recover from dropped websocket messages, and also can't deal with a refresh of the web page.

Sometimes, we have seen that websocket messages are lost in transit. This has the effect that a player gets stuck in one phase of the game and is left behind as the game progresses through its phases without them. This prevents the game from working correctly.

It should be possible for a player in a game at any time to refresh their browser and get a refreshed current state of the game from the server, which will take them to the game phase that they need to be in, and they should have all the correct information about the current category/dice roll/word etc. if it's not their turn. If it is their turn, then they should be take to the correct phase where they can continue with the current turn.

This will require the server to hold more information about each game. The server also needs to be able to identify when a client request is the result of a browser refresh.

Review

https://github.com/codeday-hom/hit-or-miss/pull/48

Tests

robmoore-i commented 9 months ago

Mini-specification

How the game works currently

Problems

The name is stored in memory and not persistently

This means that upon a client refresh, the clients identity is lost and cannot be reclaimed. It means that the game cannot recover from a page refresh.

Lack of mechanism for clients to recover from dropped websocket messages

In order for a client to be able to resume from a point in time in the game, it needs to be able to immediately jump to the right point in the game. At the moment, this would require several websocket messages sent and received in the correct order, and possibly messages also coming from the client. This is too fragile to work, realistically.

Proposed lightweight solution

Store name in a cookie

Store the name as a cookie in the client, probably connected also with the game id. When a client enters a game, they look for a cookie of the form "=". If they find one, then they set their client username to the value of .

This will require updating GameContext so that it can read the clientUsername from a cookie, instead of from a redirection state parameter from React Router. The other data that is set by GameContext will be updated by the Game component when it creates a new websocket connection and has its state updated.

A more robust and comprehensive solution

Transmit the current state of the game when making a websocket connection

When a websocket connection is opened, send not only a list of all the current players in the game, but also the current state of the game if the game has started. This should use a new websocket message type called ON_CONNECT. If the game hasn't started, then the state should be NOT_STARTED. If the game has started, then the state should correspond to a GamePhase.

The client, upon receiving an ON_CONNECT websocket message after connecting to the server, should inspect the state returned in this message:

To fulfill its purpose, if the ON_CONNECT websocket message has a GamePhase as its state, then it should contain the following additional data: