lijim / monks-and-mages

Monks and Mages is a TCG-game built on React and socket.io
https://www.monksandmages.com
MIT License
17 stars 0 forks source link

Major Feature: Allow rejoining games after disconnect #428

Closed lijim closed 1 year ago

lijim commented 1 year ago

Problem: Players experiencing a disconnect caused the entire game to be abandoned, resulting in a loss and a frustrating player experience.

Tech Solution: After some groundwork in https://github.com/lijim/monks-and-mages/pull/427 and https://github.com/lijim/monks-and-mages/pull/426, we've refactored our server side (and to an extent client-side) code completely to allow for players to rejoin games they've been disconnected from (either through inactivity, computer going to sleep, etc.)


1. Introduction of roomStore

This update introduces the roomStore for our server-side socket.io code, moving the stateful logic of managing games and lobbies over from the socket initialization logic and into a separate manager.

This makes refactoring the logic of managing lobbies and games easier to iterate on, for instance we have utilities for broadcasting the state of lobbies / games / retrieving players+spectators for a game, etc.

2. Moving from socket.io room as source of truth to roomStore

Before, our lobby logic was inherently tied to socket.io's room construct. Lobbies existed for each public room. Socket's in socket.io can subscribe and listen to different rooms, but when they get disconnected, they leave the room automatically. Now we have the server initialize lobbies separately as the detailedRooms variable in createRoomStore. The logic for joining the room to listen to updates is separated out from the players being remembered as in the room.

3. socket.id -> socket.userID refactor

We had to disentangle player ID's from being socket.id (which was ephemeral) to one based on a randomly-generated and persistently stored userID. In the case of auth0-based logged in users, this userID is sent directly from auth0. This work was started in the prior PR's mentioned above, but finished in this one. Without it, we would not have been able to allow players to re-join, because players would have a different socket.id every time they refreshed the page


Video demo:

https://user-images.githubusercontent.com/1839462/226220044-100648af-69f9-45c4-bca3-104fe0155d82.mov