Web-based Multiplayer Game

Supervisor: Dr. Vincent Lau
Students: Takumi Takeshige (3035374242)
Hyunse Yoon (3035343281)

Introduction

In this project, dubbed "Web-based Multiplayer Game", the plan is to develop a multiplayer game that is played on a web browser, and has a primary focus on inducing role-playing. The game is a two-player turn-based board game, taking elements from chess, but also taking elements from Dungeons and Dragons, namely the theme and the availability of modification of the "chess pieces", in terms of what they can do. The game also offers what many games call a "match-making system". This system tries to arrange a pool of players into a game such that the playing field is equal, and therefore would increase the enjoyability of the game. In this project, the match-making system will also take into account player behaviour when doing its task.

Project Progress

Period Objective and Milestone Status
Sep. 20 ~ Sep. 30 Obtain relevant resources Complete
Oct. 1 ~ Nov. 21 Game development in Java Complete
Nov. 22 ~ Dec. 22 Translation to web browser on local host Complete
Dec. 23 ~ Jan. 10 Game testing & balancing Complete
Jan. 11 ~ Feb. 11 Translation to server
Login system
Direct matching system
Complete
Feb. 12 ~ Mar. 11 Match-making system Complete
Mar. 12 ~ Apr. 19 Final testing & debugging Complete

Documentation


project-plan.pdf

Methodology

This project will be carried out in two steps in broad terms: game development, and then implementation of an MMS.

Game development

This section introduces the hows of the development of the game, and is further partitioned into subchapters, each of which covering a module or a combination of them that plays an independent role in the overall product that is the game.

HTML, CSS and JavaScript

This trio, Hypertext Markup Language (HTML), Cascading Style Sheets (CSS) and JavaScript, is commonly seen in many web development, and it is no different in our project given the fact that the game is web-based. Much of the game development is surrounding JavaScript, being the component that is responsible for making a web page dynamic. As such, the majority of the modules discussed in the ensuing Chapters are those aiding in the development in JavaScript, with the one exception being Pug, as discussed in the next subchapter.

Having the game development mostly occur on JavaScript is beneficial thanks to the fact that JavaScript is an Object-Oriented Programming Language, or OOPL, which is a programming language structured around Object-Oriented Programming (OOP). OOP is the idea of taking the concept of real-life entities into programming by arranging an entity into a data structure.

Utilizing OOP for the game development has three advantages. The first of which is that the independence of each components means that one can isolate each component to work on individually with minimal fear of influencing another. Ultimately, this allows for great modifiability, which is helpful in adjusting the game in the long run to keep the game balanced and enjoyable, an imperative feature to have for an educational game.

The second benefit is that OOP is a rather intuitive concept to implement. Effectively, one merely would translate a real-life concept into JavaScript, allowing for more time allocated to other aspects of the project.

Lastly, the OOP structure and the independence of each component in it means that the project can be split into two parts to be assigned to the two members of this project to be worked on independently, allowing for greater efficiency through effective work distribution.

Pug

Pug.js, or Pug as it is referred to most commonly, is a template engine for Node.js and browsers that enables easier generation of HTML files. This allows for HTML files to be created in a more comprehensive and less exhaustive manner through a syntax closer to other programming languages than HTML. This cuts time spent in the project in tediously formatting numerous HTML files, allowing for more focus on the main objectives of this project, one of which being the game development aspect.

Jquery

This module provides a convenient bridge between HTML, CSS and JavaScript. JQuery is a JavaScript library primarily used for its assistance in simplifying DOM traversals and event handling. Having this will make for a more fluid and intuitive interaction between the big trio, which will prove to be crucial in a web-based game.

Node.js and Express.js

These two modules, Node.js and Express.js, are what provides an environment for a server for the game to operate on. The former is an open-source server environment for JavaScript, whereas the latter is a framework for Node.js web applications to ease the use of Node.js. In a project with a game that relies on heavy continuous interaction between clients and the server, these two will facilitate in this.

Nodemon

Nodemon is a nifty addition to Node.js that has a simple functionality: reload and restart the server automatically upon a file change. This makes development of the game a little more convenient by providing an automated shorthand.

Socket.io

Socket.io is a JavaScript Library allowing for real-time web interactions between clients and a server, which is fully abundunt in an interaction-heavy web-based game. Socket.io has what are called "rooms", where clients can join to interact within the same field. Each game played can be structured as a room that players join, making implementeation of multiple simultaneous games much simpler on the server end.

Crafty

Crafty is what provides the visual appeal to the game. It is a JavaScript framework for game developers offering support for collision detection, map generation, and so on, and in this project is the driving force to the display to the game. The obtained isometric tile assets to be used in the game can be arranged very conveniently with Crafty, which is another benefit.

Graphical assets

Certain external resources were required to be acquired for the graphical asset. Obtaining pre-made graphical assets eliminates the need to manually design our own, providing more time and effort on the true objectives of this project. There are two types of assets obtained: those of the sprites and those of the tiles.

The above show a few of the sprites obtained from a website called CraftPix.net, which offer a variety of graphical assets for game developers.. The three are visually distinct, aiding in distinguishing between the different roles the pieces will inherit in the game. From the left, the sprites represent the roles of a wizard, a fighter and an assassin.

The tiles, which are the building blocks for the board that the pieces will traverse, were obtained from a blog organised by Unity.

The MMS

This section talks about the methods for implementing the MMS component of this project. It further divides into three subsections: the login system, the matchmaker module and finally the players skill rating. The last is referred to in this project report as Match-Making Rating, or MMR for short.

The login system

One of the function of the MMS is to identify the skill of a player, and in order to achieve this, a login system will be required to identify individual players. To aid in this implementation, several modules come to play: MongoDB and Mongoose, socket.io-auth, bcryptjs and isemail.
With regards to the first of the four, to be precise, MongoDB is the database and mongoose is the module that allows access over the former. These two are responsible for storing the account information and allowing the server to have access over them. MongoDB is a well-recognised NoSQL database, and mongoose is a module allowing for a schema-based structuring of a MongoDB database. Using these two to store player information is valuable for this project for one particular reason: MongoDB is a NoSQL database that allows for high flexibility for developers, which comes into great use when, for example, a new player information may prove itself to be useful and thus is desired to be stored. Only one schema is present in the database: The User schema, that stores player information ranging from the username to the later discussed MMR.
The second mentioned module is socket.io-auth, which is an intuitive and secure solution to adding authentication to socket.io. This is the module of choice for enabling secure authentication because of its simplistic approach to authentication for socket.io, which is the module used for server-client communication for the game as is.
Unfortunately, the previously mentioned module is not enough to guarantee security when logging in. Bcryptjs can fill that gap by securely hashing the password to be stored in the database, avoiding the need to store users' passwords that could be a potential security hazard.
Finally, isemail is a straightforward module that, given a string, can check if that string is a feasible email. This is used to prevent new users from registering with an invalid email address.
Thus, the authentication process with these modules begins firstly with the registration. Upon receiving from the client the necessary information for an account registration (username, email and two password inputs), the server first checks the validity of the input, such as whether the email is valid with isemail, checking whether the inputted username exists already in the MongoDB database with mongoose or if the two password emails are matching to ensure they inputted the password correctly. After everything is checked, the password is hashed with bcryptjs and the hashed password alongside the username and email is stored in the database. Finally, the user is directed to the main menu where they are free to navigate the webpage from there on.
In the case that a user has already registered, they will instead log in with their username and password. The server receives this information, finds a User document with the same username, and uses bcryptjs to compare the password with the hashed password stored in the database. Once all operations are over successfully, the server yet again directs the user to the main menu much like in the registration process.

The matchmaker

Matchmaker is a simplistic module that can match two players given a certain policy. The simplicity of this module allows much of the control over the matching to be done by the programmer, allowing us to determine our own rather distinct MMS. Principally, the module operates with four components: start(), push(), on() and policy.
Start() is a function that starts the engine to this module, allowing the other three components to come into effect. Push() puts a player into a queue given the player as the argument. What happens once the module finds two appropriate players to be paired is defined in on(), in which the players are put into a room to play together. How the module deems two players as appropriate to be paired is defined by assigning a function to policy. Within policy is where the heart of the operation of the MMS occurs.

The MMR

An MMR is simply the numerical representation of player proficiency for this MMS. The value of a player's MMR is proportional to the player's perceived skills in the game according to the MMS; in other words, the higher a person's MMR, the more skilled the MMS deems that person to be in the game.
The idea to the MMS on how it pairs players is that players of close enough MMRs should be paired together. To put in technical terms, the policy in the MMS to consider whether two players should be matched finds the absolute difference in their MMRs and matches them together if said difference is under a certain threshold φ, which remains a constant. This is implemented within policy.
One may ponder how the MMS would handle new players who intuitively are not assigned an MMR at first. Instead of attempting to calibrate with a series of "placement matches" that are separate from games that priorly registered players play as some games would do it, the MMS simply sets a default MMR ℛ to new players. They are then queued into game the same way any other players are. The nature of performance-based Elo rating system like this MMS means that though this default value ℛ may not, and will likely not, reflect a new player's proficiency, their MMR will quickly be adjusted to what will be considered correct. This way, there is no segregation between brand new players and experienced players that placement matches would otherwise pose and hence would likely cause a divide between these two players.
At the end of each game, the MMS will deem the winner of the game as deserving of being placed higher than the loser, and thus will readjust their MMR accordingly. Precisely, it calculates the change in MMR, and adds that to the winner's MMR and subtracts it from that of the loser. In order to achieve the behaviour of the MMS, this change in MMR δ will decrease as the game becomes closer, and the opposite occurs if the winner seemed to dominate the loser with ease. δ is calculated as follows:

δI is the initial change in MMR, or the maximum to this change. From that, a product is continually subtracted. Each product is that of εi and ωi, which are a certain statistical value from the game, or stat, and its corresponding weight, respectively. The latter is effectively how relevant the former is when considering how close a game was, and the former, to reflect the intended behaviour of δ, increases if the game was closer, and some of them are the previously mentioned behavioural stats. δ is then bound minimally by δf, the floor of this change. δI, δf and ωi are constants whereas εi will vary from game to game. Each player in a game is attached a stats object on the server side that will continuously track certain statistics throughout the game and is later used for εi.
Using the above equation has three main benefits. Firstly, it is capable of fully reflecting the many different "kinds" of proficiency thanks to the multiple stats affecting the MMR. To explain with examples, if football players' ability in football was compared solely by the number of goals a player has scored, this would lead to goalies, despite perhaps being genuinely skilled, being deemed as less skilled than a striker.
Secondly, having various aspects that affect the MMR prevents the manipulation by players of their own MMR. Some players may desire to alter their own MMR so that the MMS will pair them with opponents not of their calibre, affecting the quality of the game for both players. Having just a single or a few variables influencing the MMR grants a way for those players to predictively manipulate the MMR by playing their games in a way that will inflate or deflate these variables. On the contrary, having numerous variables poses a challenge to merely boost a few stats, without other stats not put into consideration that may counter their intention.
Finally, updating the MMR this way gives a sizeable amount of agency towards the developers, essentially allowing them to tweak values as finely as possible. This is important to ensure a truly accurate representation of player skills through a numerical representation that is MMR. In the case that, after some trials, it is revealed that a certain stat is over-represented, the developer can simply decrease the weight of said stat accordingly to have it skew the MMR less. Alternatively, if a new stat that correlates with player proficiency is discovered, appending said stats to the MMR calculation is rather simple.

Result

The webpage

The first part to cover is the web page, comprising everything visible to the client when visiting the website. The following is all implemented on localhost and should function identically provided a proper server for the webpage to be mounted on. The subsequent subchapters are in the order of the pages that the user is greeted with upon visiting the webpage: The login and registration page, the main menu and the game, respectively.

Login and Registration

Login system is integral to the implementation of the MMS for user identifiability, and thus is a requirement for any visiting user before they are granted access to the rest of the web page.

The above figure shows the login page that the user is first greeted with upon visiting the site. A user is required to input their username and password to be able to move on to the main menu and therefore the game. In the case that the user does not have an account registered, the user may press the registration button to register for an account in the registration page.

The above is the registration page that users are redirected to. Upon submitting a username, an email, a password, and the "confirm" field which is an input field to input the password again to ensure the correct password was inputted by the user, the server checks if the information is valid, and if it is, a new account with said information is created and the page opens to the main menu. The user may use this username and password to login in the future instead of registering for a new account.

Main Menu

The below figure shows the page that the user is greeted with upon successful authentication in the login/registration page. Two buttons are the most important, which are the "Start Game" button and the "Logout" button. The latter simply logs the user out and redirects the player back to the login page. The former places the user in a queue, where the MMS then would actively look for other players in the queue, and once a suitable opponent is found, the user is directed to another page.

The Game

The figure below shows the first page that the user is greeted with once an opponent is found and is where the user can modify their team composition. The four large button will lead the user to a page to create each piece, and once the selection is made, that piece is displayed on that button.

Upon pressing one of the four large buttons in the above figure, the user is lead to a role and action selection page in order to modify their pieces. The leftmost container is where the user can select roles, with the six buttons with a letter representing the initials of the roles (Cleric, Fighter, Ranger, Assassin, Druid, and Wizard respectively). Below the six buttons is where the image of the sprite will lie, and below that, a brief description of the role is shown. The larger container next to it is where the actions for this piece is selected. There are six sets of a button and the name of the action. These actions vary depending on the role selected, and the user may select four of the six actions by pressing the button. The user may find more information on the action in the container above by pressing on the name. Each action has a name, range, type, value and effect. Name is simply the name of this action and the range is how far from the piece the action can take place (see the later paragraphs for further explanation). Type indicates what the action does and has four kinds: attack, heal, buff and debuff. The value shows the amount at which the previous four actions occur. Effect shows any addiction effects that this action has. Finally, the user can save the piece with the "Save" button at the bottom.

When the user saves a piece, the page returns to the team creation page. Within this page is also where you can assign a name for the piece below the sprite. Once the user has formed all four pieces, the user can press the "Ready" button, and upon the opponent also doing the same, both are directed to the game.

While the game loads, the players are shown a screen that show the settings that the game takes place in, seen in the figure below.

After some time, the game finally commences. The pieces selected previously are placed on the board, and the first turn is given randomly. In this case, the red player starts first, indicated by the text "It is your turn" on the bottom left. On each turn, the player can select a piece, and that piece can do two things each turn: move and use an ability.


The above shows what happens when this used selects the wizard. The tile that the piece stands on is highlighted, and below it, the set of actions that the wizard can commit is shown. The left four are the abilities that this wizard can do, the top right is the "Move" action and the bottom right is to end the turn. With the exception of the "End Turn" button, pressing the buttons will show the range that this action has (see below), which vary from actions and roles. In the bottom left, the assigned name and the health points of this piece is indicated. Once the health reaches zero, this piece dies and is eliminated from the board.

Above shows the range for the "Move" action for the red wizard. In essence, within these highlighted tiles are where the wizard can move to. Upon selecting one of the highlighted tiles, the piece will move there, seen below.

Once this user has finished what they wanted to do during that turn and ends the turn with the "End Turn" button, it is now the opponent's turn, shown below. The opponent will carry out the same procedures and once they end the turn, the cycle repeats. This continues until one of them have all of their pieces die, at which point that person loses and the other wins.

The below image shows the chat system that players can use to communicate and role play with each other. The bottom field is where the user can input a message and once the user presses enter, both the user and their opponent will see that message displayed above. These messages are colour-coded to reflect the colour of their pieces.

Arguments for MMR Derivation

This Chapter covers the values assigned after some tests made for the variables responsible for deriving the MMR, as well as the reasoning behind why said values were assigned. Each subchapter in this Chapter covers an individual variable, in the order of the default MMR ℛ, the MMR difference for the policy φ, the initial MMR change δI, the minimum bound to MMR change δf, the stats in consideration for the MMR ε and each stats' weight ω.

Default MMR ℛ

ℛ is the default MMR that all players start with, and in a sense defines, albeit not definitively, what should be the average MMR for an average player. Since this value is set as an integer, too small of a value will not be able to represent the lower percentiles very accurately. To exemplify, if ℛ=10, the lower half of the player base can essentially only be divided into 10 levels of skill, and a larger number is required to represent more levels. On the other hand, setting too large of a value will make trying to monitor the MMR behaviour tricky, much like how hyperinflated prices are inconvenient for the general citizens to track prices. As such, ℛ has been set to 1000 to strike this balance. The other following values revolve around this value.

MMR difference φ

This is the variable to defining the maximum difference between two players' MMR when considering pairing them together, defined within the policy function. This variable effectively has control over how quickly an opponent can be found: the smaller φ is, the harder it is for the MMS to find another with an MMR with a difference no less than φ, the longer it the player waits to find an opponent. Thus, φ should be sufficiently large to allow the MMS to find an opponent at a reasonable time, while also being sufficiently small as to prevent queueing two players with too large of a proficiency difference, diminishing the quality of the game. The final chosen value is φ=100.

Initial MMR change δI

This variable δI is the maximum bound to how much an MMR can change per game, and also due to how the MMR change is calculated, is also the initial MMR change before accounting for the rest of the variables. Setting a maximum bound to the change is useful to minimize overfluctuations in the MMR that can lead to inaccuracies over the course of time. For ℛ=1000, the value is found to be best set at δI=100.

Minimum bound to MMR change δf

Regardless of the performance of the loser in the game, it is desirable that any loser in a game will lose a certain amount of MMR, and the same goes to the winner. It would be counterintuitive to punish the winner and reward the loser even if the loser did statistically better. The role of this minimum bound δf is to ensure the above. Setting this value too close to δI would defeat the purpose of having a performance-based MMS, as the performance of players would have much less impact. As such, the minimum bound is set to δf=20.

Stats ε

This variable, or variables to be precise, is the statistics obtained throughout the game and is the core of the performance-based MMS. It is desirable to normalize this variable to range between 0 and 1, so the behaviour it has on the MMR is more predictable and trying to find an appropriate value for the weight ω becomes more intuitive. Depending on the statistics however, how we want to convert the obtained raw values to correspond with how the MMR changes differ. In this implementation, there are three different ways to convert a raw value to the desired ε, which will be presented as category 1, 2, and 3 respectively.
The first kind is a linear version. These statistics are directly related to how well a player did, and thus can scale linearly to MMR change. An example of that would be kills-to-deaths ratio, or KD, which is the ratio of how many pieces a player killed over how many of that player's pieces got killed.
The second is a logarithmic version. These statistics are not linearly correspondent to skill, and instead as the value increases, has less on an impact on the change in MMR. An example of that is total number of turns taken in the game. The comparison between two games that ended in 5 turns and 6 turns is relatively more significant than if we were to compare two games of 50 and 51 turns, even though both games have a difference of 1 turn. The best way to scale this kind of statistics in the desired way is to scale it logarithmically. In essence, for a value 𝓋 obtained directly from a game,

where b is an extra variable associated with this stat that has two purposes. Firstly, it is the base of the logarithmic operation and can control the logarithmic curve of ε over v. Secondly, it is the maximum bound to v. As priorly stated, ε should be bound between 0 and 1, thus b ensures the logarithm will not go over 1.
The third is a logarithmic difference between the two players. This is alike to the earlier version due to both of these's logarithmic nature to have the stats affect the MMR in a logarithmic manner. Unlike the earlier one however, these kind of stats must compare the difference between the two players, as it does not share the same value between the two players like the second one does. An example of this is damage dealt. Understandably, the damage dealt of the two player are different. On top of that, simply finding the difference is not helpful in determining the difference in performance, as, to exemplify, two players who have dealt 10 and 20 damage respectively have a more considerable difference in skills than those with 100 and 110 damage dealt, hence the logarithmic scaling. In mathematical terms, for two values v0 and v1 of two players obtained directly from a game,

where b is an extra variable associated with this stat that has the same purpose as the ones stated in the previous paragraph. To ensure normalisation of ε, the difference in the logarithm is added by 1 then divided by 2, since the logarithmic operation is bound by 0 and 1. Which variable v0 and v1 is the winner or loser depends on whether an increase in this value corresponds to a closer game.
Aside from these three categorisation of statistics, there are further two subcategories: behavioural statistics and definitive statistics. The latter are the typical stats used in many performance-based MMS due to the direct correlation they have with performance, whereas the former are the statistics that monitor player's behaviour, as this project targets. In total, this means there are six total categories. The tracked statistics, alongside which category they belong to, are as follows:

kd, as previously mentioned, is the kills-to-deaths ratio, specifically that of the loser. turns is the total number of turns the game took. dmg_dealt refers to the difference between the two players in damage dealt to the opponent. avg_clicks is the difference in the average amount of clicks made in a turn. turn_time is the difference in the average time taken per turn.
For categories 2 and 3, each stats is assigned a value b. The assigned value b for each of the category 2 and 3 stats are as follows:

Weights ω

Assigned to each stats ε is its weight ω, which controls how much this stats should affect the MMR. The larger the weight for a stat, the higher influence it has on the MMR. The weights for each of the stats are as follows: