Lobby platform
Here we describe the development of the lobby platform that helps you find other players.
Contents
Motivation
Continuing the Escapeling project, our group reflected on aspects of the platform that could be missing for a better experience. One identified problem was the exclusion of users lacking others to play with. As seen in the flowchart of the original interaction there was the precondition of finding three other people to play with, without any problem (Fig. 1). Our design proposal was therefore to implement an alternative step for those who need to find random people to play with. First, we explored the option of whether this could be carried out completely on the same platform, through telegram. However, this turned out to be difficult, since we could not find an effective method to make the current telegram bot do this. Therefore we decided to choose a separate web-based lobby platform where users can communicate with each other and share a link to the Escapeling game.
Figure 1: Shows the original interaction flow and the proposed flow with usage of the lobby platform
Design
Since the project had both time and participant limitations, we set on making an MVP (minimum valuable product) that would include the most crucial features a chat application needs to be able to work. This required some decision-making on what functionalities to include and what functionalities to disregard or consider to be additional tasks if there was any time left.
Crucial requirements
As we explored the concept of the lobby, we discussed functions that would be essential and improve the user experience. We began by deciding that the lobby platform would consist of chat rooms with a one to four person capacity. Each room was also going to be presented with instructions on how to create a game. We also decided on including the option of leaving a chat room and being able to communicate with each other through text messages.
Since the user experience already involved having to change between the Lobby Plattform and Telegram, we aimed to make the rest of the interface as straightforward as possible. Further, we also knew that the lobby would be used by students of all ages, including children. This resulted in the decision of “easy joining”, where users only had to decide a personal chat name and then press “join”, automatically being assigned to a chat room. The name of a room is randomly chosen between ten different names referring to astronomy.
Another concern was deciding which user to assign responsibility for creating and inviting the others to a game. Once again, we decided to go in a simplistic direction and automatically assign the role of being host to the first person to join a lobby room. This decision helps to avoid unnecessary discussions between users and multiple people taking on the host role simultaneously.
Lastly, we decided that the instructions are not presented to players inside a room until the least necessary number of people that are needed to play the game had joined. This provides a natural decision flow that a game can only be played with a minimum of three persons. These instructions are only presented to the host, the others are presented with information that the host is setting up the game and how to join as soon as the registration code is shared.
Limitations
Our original design concept involved an option to join a random lobby. The idea was to present an “advanced settings” option, where a user could create their own lobby and allow others to join through a lobby ID. This was discussed to include the rare case of two persons wanting to play together but seeking more participants to be able to play. We decided that this unique case was too uncommon and thus this function was less relevant. In this unique case, the two persons would have to make sure to join at the same time, which increases the chance of joining the same room and we decided this to be sufficient enough for an MVP.
Another idea was to automate the escapeling bot game creation. Once enough players are in a lobby room, the server requests a new Escapeling Bot session and posts the registration code into the chat. This would support the responsibility of the host, not making that person have to set up the game with the bot all alone. A brief investigation showed that this might be too difficult and time-consuming. We also decided that this was not crucial for the MVP.
Technical Details
In the following section, technical details about the chosen implementation and technical decisions are presented.
Architecture
To make the process of finding other players as easy as possible we decided to implement the lobby platform as a web application so that users can simply open the lobby platform in a browser. The web application is structured with a client-server architecture, meaning that the application consists of two parts: a server and a client. The server is written in Python and the client in HTML, CSS, and JavaScript, or, more specifically, TypeScript. The client is implemented as a single-page application (SPA), whereas the initial design with HTML and CSS was taken from a Traversy Media tutorial.
The overall principle by which the application operates is that one or multiple users who interact with their respective browsers can be considered clients. These clients initially request an HTML file and additional resources as soon as the URL of the lobby platform is entered. A user’s browser receives the requested HTML file and additional resources like CSS and JavaScript files from the server. These files are processed by the browser so that the single page application is displayed to the user. The application allows the user to enter a user name or send chat messages. These or similar user actions will trigger the sending of events to the server. Next, it is explained how the server processes these events and how the communication between client and server works.
For example, two things happen when a yet-unknown user enters a name and clicks the ‘Join Chat’ button. First, a WebSocket connection between the client and server is established. Second, the client sends a join
event to the server. The server then checks all rooms for an empty seat and assigns the user to the next available room. All clients that are a member of this room are informed about this new user by sending them a user-connected
event with additional data. For example, the text ‘USER_XY just joined the chat!’ will be shown to all members of the room. The disconnection of users or the sending and receiving of chat messages are propagated in a similar fashion.
For sending WebSocket events the library Socket.IO
is used. For the client, the JavaScript version is used, and for the server the Python equivalent Flask-SocketIO
. Both are compatible with each other and implement the same API. The library is a relatively thin layer above the bare bone WebSocket API which simplifies the implementation of real-time communication features. For example, room functionalities for adding clients to a room or broadcasting events only to clients of a particular room are already provided. While the server uses the Flask framework as the only mention-worthy package, the client uses several technologies to ease development.
On the client side, TypeScript is used, which is a superset of JavaScript and allows us to write JavaScript with additional type annotations. These types allow tools in the background to statically analyze the code and show immediate error feedback in an IDE while developing. Thereby errors are detected early on and our confidence in the correctness of the code is higher. Additional productivity features like better autocompletion increase the development experience. The code is split into 4 files: index.ts
, LobbyMachine.ts
, UpdateUI.ts
, and Constants.ts
, where the latter only defines constant variables. Details of these files are explained below.
LobbyMachine.ts
contains a finite state machine and the majority of the application logic. The state machine is implemented with the library XState and ensures that the application is always in a single state. This guarantees that only the exactly defined behavior is possible, thus avoiding bugs. Furthermore, index.ts
registers event listeners and creates a service of the state machine so that any user interaction events are forwarded to the state machine. Depending on its current state the state machine then decides if a transition to the next state happens or if any side-effects should be executed. In our case, side-effects are updates to the user interface like displaying a chat message. They are located in UpdateUI.ts
. Below an image of the application user interace can be seen (Fig. 2).
Figure 2: Screenshot of the application user interface
Server
On the server-side, a new Room
class was created. This class has several attributes and methods for handling processes that are involved in the joining and disconnecting of users, the display of instructions, and the storage of all messages exchanged so far. Each user message within a specific lobby room, along with additional information necessary to identify messages like the time and user id, is stored within different instances of this class. Before a new user connects to a specific room the chat history, which includes all messages from when the joining user wasn’t present, is distributed to the user. When a user joins the room, other users are notified and the join event is documented within the chat history.
The Room
class also entails basic logic any chat room needs. Before a user joins a specific chat room the server validates whether the upper limit of players is already reached and therefore needs to create a new room. If the player can join an existing room and the number of players reached the minimum limit to play a game of Escapeling, instructions for the initialization of an Escapeling mission are automatically displayed for all the players within the room. Within each room the first player that joined the lobby is the admin. The instructions for the admin are different compared to other players, as the admin needs to create a new Escapeling mission and share the registration code, which the other players then have to paste into their telegram chat with the Escapeling bot. The optimal number of players for an Escapeling mission is a minimum of 3 players and a maximum of 4, constants were set accordingly.
When a user decides to leave the current room the user can click the ‘Leave Room’ button on the top right, which allows the user to join another room, or just close the browser tab. The server is notified via a socket event and the user is removed from the associated lobby room and the other users are notified about the disconnect via a server message within the chat. The lobby room is then available to be joined by another user. If the admin of a room leaves, the user that joined right after is the new admin, or if no player is left, the admin role is left empty and the next player that joins the room will be assigned.
Build process & Deployment
To make TypeScript files interpretable for browsers Webpack is used to compile and bundle them into a single optimized JavaScript file. For the configuration of Webpack we used the webpack-boilerplate template by Tania Rascia which already comes with a local development server and a build process to optimize bundling for production. The Webpack loader ts-loader was added so that Webpack is able to compile and bundle TypeScript files. Additional dependencies like xstate
and socket.io-client
were added to the package.json as well. For additional information on Webpack refer to Tania’s tutorial or the official Webpack documentation. The Webpack production built process is also run when the application is deployed to Heroku where the application is hosted on the free tier. The necessary steps for deployment are somewhat documented by this commit. The lobby is publicly available here: https://escapeling-lobby.herokuapp.com/.
Outlook
Although the implementation of the lobby platform covers the basic needs and several edge cases for a chat application, there are certain ways to improve the user experience. When the instructions for each user are displayed the chat messages are extended to the lobby-chat until it reaches across the lower screen border. This creates two scroll bars, one within the chat and one for the entire website, which leads to a poor user experience. To fix this issue, different CSS elements have to be changed within the website template, and parts of the messages and instruction text visualization need to be adapted, too. This tedious process wasn’t conducted during development, as the focus was on important aspects of the lobby, like properly handling the disconnect of a user and covering all edge cases that are associated with the disconnect. Another aspect to increase the user experience is that when a user clicks the ‘Leave Room’ button a warning message like “Are you sure to leave?” should be displayed. This would ensure that the user wants to leave for sure, as re-joining a specific room isn’t possible so far.
Priority-wise, one problem should be focused on during the improvement of the lobby platform. When the user loses connection to the server (e.g. no internet connection) the user is thrown out of the lobby, but there is no indication for the user that this happened. The ability to send messages or interact with the UI is still working, however, messages or mouse click events are not sent to the server anymore and the client does not receive any web-socket events triggered by the server. One possible solution is to display a popup window with a connection lost message, which gives the user notice about the lost connection, hinders him from interactions with the UI, and should allow the user to reconnect to the same lobby. On the other side, the disconnect event is registered adequately by the server and thus informs other users within the lobby room about it.