Bayesian Skill Tracker in Express.js and React.js

Link to web app: https://leaderboard.seanholloway.com
Repository on GitHub: https://github.com/HollowaySean/Leaderboard

I’ve never played this game, so I just gave names that I imagined people would give to decks in a Magic The Gathering spin-off. If you disagree, email me to tell me how wrong I am at hollowayseanm@gmail.com.

For this project, I decided it was time that I actually dip my feet into modern web development. My previous web project was almost entirely HMTL and painful CSS, with small snippets of PHP and Javascript. While it felt important learn how websites were made back in the 1800s, I was very excited to get my hands dirty with the modern tools of the trade. Along the way I learned a lot about why Javascript is so popular, and managed to wrap my head just a little bit further around my biggest enemy, the front end.

The idea behind the project was suggested to me by a friend who, extremely fortunately, happens to work as a QA lead for software, so specifications and feedback were abundant. This friend is part of a group that regularly plays a multiplayer deck-based card game, both with other members and with strangers, and they hoped to develop a way to track the ranking of individual decks and how those change across matches.

After some research, I came across the documentation behind Microsoft’s adaptation of the Elo system, TrueSkillâ„¢. Linked in the documentation was a great paper by Jeff Moser about the math behind TrueSkill, which filled me in on the important points and convinced me that this was the sort of system I was looking for. Luckily I did not need the entirety of the TrueSkill algorithm, which is designed for skill tracking in multiplayer games, so my algorithm is still legally distinct from Microsoft’s protected IP.

The basic idea is as follows. Assume that a player’s performance in a game is decided by their skill level. We do not know their true skill level, so we assume a normal distribution, which has a mean and standard deviation unique to that player. The results of each round of the game are used to improve our estimate of the player’s skill, using Bayes’ theorem. For non-team-based games, this reduces down to equations which update the mean and standard deviation of the competing players, depending on the mean and standard deviation of the opponents, along with whether they won, lost, or ended in a draw.

Some handy graphs provided by the Rechart library for React.

Learning modern JavaScript was a very enjoyable experience, although intimidating at first. I worked from back to front, first learning the basics of Node.js and Express.js, then setting up a database and using MySQL, and finally developing the user interface in React.js. The front end was by far the hardest step for me, simply because I have a very difficult time grasping any sort of aesthetic design. I hope to remedy this in the future, giving a shot at introductory graphic design courses. The back end, however, was very enjoyable. I studied the network stack years ago in school, but this was my first time actually using HTTP requests, and Express made it quick and easy to get things going.

The biggest lesson that I learned (or re-learned) is the importance of understanding the underlying components before developing too much structure around them. I ended up rewriting my entire code after the first pass was done, since I didn’t properly understand the MySQL library for Node or how to use useEffect in React, and the first pass ended up buggy and slow. On the bright side, the rewrite was pretty fun since everything flew by quickly.

My next project likely won’t be a web app, but I’m now looking forward to the next time I work on a full stack project.

Leave a Comment