Checkers: A social ranked experiment.

Hey, it’s been a minute since my last article - progress on project has been paused for the foreseeable future but I still plan on continuing and publishing the title at some point.

This Dev-Log is all about Checkers - A discord bot I’ve recently created that aimed to highlight the social aspects of competitive gaming. During this article I’m gonna breakdown the systems created and the results of trial run I did with some volunteers last weekend.

A promotional poster for the pre-alpha test.

I think it would be beneficial to elaborate on the reasons I felt I wanted to explore this idea for the sake of context in this Dev-Log. My personal ranked experience is pretty lack-luster, and although I see others creating solutions to improve the quality of competitive matches, they primarily cater to high-ranked players, of which my friends that I play with are most definitely not.

Plus, Overwatch in particular limits the amount of people you can play with drastically when you reach a certain rank. If my friends were to hypothetically jump up the ranking system into the top 1% of players, I would only be able to play with one of them at a time as Overwatch caps the group size to 2 when queuing in Grandmaster and above.

So why not? Let’s follow a proven formula and create a system that’s open to everyone. The best part of playing ranked is the magic synergy you create with your team to better your opponents and win the game. Overwatch isn’t Call of Duty, it isn’t quake or any other game where you can perform independently and stomp your opponents. And although these games do have some aspects of teamplay in higher levels of play, the emphasis on coordination and organized play in Overwatch particularly is fundamental to the integrity of it’s gameplay.

The basic commands involved when interacting with the system.

The system involves 3 major components - A collection of discord clients that represent the “players”, an SQL database to store player data and the bot that processes commands and match outcomes form players within the system.

The major elephant in the room is data accuracy and how we can be sure that match outcomes are being processed correctly. Overwatch doesn’t have any publicly exposed api’s so relying on game data wasn’t a viable solution. I considered some alternative methods to pull data from the client and found other developers using techniques like pixel scaping and client-modding but these would’ve set back development months, and for a quick experiment this seemed like a poor use of my time.

The solution I decided on relied entirely on the trust of the player majority - processing important context based decisions via a voting system, of which a certain ratio of votes would be needed for that particular suggestion to be passed. These could be different per action and could be adjusted based on team/match sizes. For instance a forfeit vote would need a vote from 100% of team members, whether that’s 1 or 6, using context based ratios was an effective solution.

switch (type)
{
      case VoteType.EndMatch:
      {
            this.MaxVotes = match.GetPlayers().Count;
            this.RequiredVotes = (int)Math.Ceiling(this.MaxVotes * 0.66);
            this.Title = "Match Vote";
            break;
        }

        case VoteType.Forfeit:
        {
              this.MaxVotes = match.GetPlayers().Count / 2;
              this.RequiredVotes = (int)Math.Ceiling(this.MaxVotes * 0.5);
              this.Title = "Match Forfeit";
              break;
        }
}

Two examples from the Vote constructor

Here’s an example in action:

The match is found and it’s time to Pick a Map.

Players are incentivised to vote to conclude the match and are stuck within the game-state if a conclusion cannot be met. I never addressed the possibility of this conundrum not being enough to reliably process matches, but I suppose the entire system was a workaround, so best case-scenario the data would be server authoritative and controlled from within the client.

At the beginning of this post I mentioned my inspiration for this project and the basis from which many of my systems where designed. Overwatch is a killer example of a ranked system done right, bringing a competitive ladder that splits players into groupings based on their skill rating and pitches similarly ranked players up against each other to determine the best players.

This system gives a unique opportunity for matchmaking as a player’s data is tracked alongside their skill rating - this means we can construct two separate assessments of skill and compare them to more accurately determine the rating won/lost at the end of a game.

My implementation of simpler rendition:

double playerWeighting = player.Rating / average;
double playerRating = 0;

if (favors == SkillFavors.TeamA)
{
         playerRating = ratingBase - (ratingBase * multiplier);
         playerRating /= playerWeighting;
}
else if (favors == SkillFavors.TeamB)
{
         playerRating = ratingBase + (ratingBase * multiplier);
         playerRating /= playerWeighting; 
}

Although I don’t have anywhere near the quantity of data needed to construct an MMR (Match-Making-Rating) value for players in my system, I derived a method of calculating team/match biases, which allocated players based on rating and win percentage - this proved to split teams fairly accurately and made for some great games!

Previous
Previous

CAB .1: Infrastructure

Next
Next

Generics and the power of Factory Patterns