Networking (3)


Additional Thoughts on Skill Ratings

I suspect I’d get significant value from writing about systems earlier in their development because breaking a system down in words often leads to new insights. Over the past week I’ve been thinking about my recent post on how online skill ranking works in INVERSUS Deluxe. If you haven’t read it or aren’t deeply familiar with skill rating systems, you might want to click that link or the rest of this won’t make much sense.

One of the primary hurdles that I had integrating Glicko-2 (and that most games have from my understanding) was applying the rating periods. INVERSUS forces a rating period to pass with each completed match and then also runs a separate step forcing inactive rating periods to be evaluated for players that have been away from the game for a while. This has two downsides:

  • Depending on the frequency you play matches you will evaluate more or less rating periods than others.
  • Rating periods never get to evaluate more than one match at a time (which would be preferred by Glicko). That said, I haven’t run through the math to know how much that actually matters.

I now believe that you should be able to get the best of both worlds and let rating periods get a fixed time (e.g. a week) but still give players instant feedback after each match. The idea is to change the interface to process less than one rating period and take input representing the intermediate computations from any prior call. It would then update the intermediate state to be used by a future call and output what the players rating, deviation, and volatility would be as of right now (partially through the rating period). Internal to the system, it would continue to append match results to the intermediate state and reevaluate the current rating period from scratch with the additional supplied information. The resulting logic  would be something like:

  1. If the additional time step has advanced to a new rating period, commit the prior rating period’s variance estimate into a new rating, deviation and volatility.
  2. Apply any necessary inactive rating periods if the time step is greater than one rating period.
  3. Apply the new match results to the tracked intermediate values necessary for computing the current rating period’s variance estimate. Note that we shouldn’t actually need to track the full match history for this rating period, but just need to update the accumulated values.
  4. Output the player’s displayable rating and deviation by evaluating the current intermediate values for the partial rating period state. Note that these values are actually logically recomputed across the entire current rating period until step 1 commits them and starts a new rating period on a future call.

I’m pretty sure that would both work and not be too complicated implement. Maybe someday, I’ll go back and try it out, but for now I just want to put the idea out there for others!




The Online Skill Ranking of INVERSUS Deluxe

Online skill ranking was one of the big features added to the Deluxe edition of INVERSUS and building it was uncharted territory on my part. It required a bunch of learning and is one of the systems players ask about the most so I’d like to share some behind the scenes details regarding how it works.

Rank Points and Skill Rating

From the player’s perspective, they earn and lose Rank Points (RP) while playing online. I wanted the Rank Points system to achieve two goals:

  • By inspecting a player’s RP, you can tell how challenging they are. Players with a higher RP are expected to defeat players with a lower RP.
  • You are awarded and deducted RP in a manner that matches your expectations. If you win, your RP should increase. If you lose your RP should decrease.

While those goals might not sound like anything special, they can actually conflict because computing a statistically accurate skill rating (the first goal) can produce results which are both confusing and do not match player expectations (the second goal).

  • There might be wild fluctuations as the system is first learning how you perform.
  • There might be counterintuitive ups and downs such as an increase in skill after an expected due the system’s confidence level in your skill increasing more than its penalty for the match.
  • You might not actually gain any skill after a win if you were expected to win.

To mitigate these issues, the actual skill rating of the player is decoupled from the player-facing representation of Rank Points. Before getting into how the Rank Points are calculated, let’s dig into the actual skill rating system they are built upon.




Rollback Networking in INVERSUS

INVERSUS is a fast-paced shared-screen multiplayer game for up to four players. It is the type of game that would traditionally be local-multiplayer, and for a long time I thought latency issues would make it a poor candidate for online. Late in development, I committed to adding online support with the mindset that a “playable but inferior” experience would be better than nothing, but I ended up with something hard to differentiate from its local counterpart! While the subject of networking can cover everything from matchmaking, to choosing a map, and finally playing the game, I’m only going to be discussing the gameplay portion. I want to break down how I made the split-second actions of INVERSUS into a polished online experience.

Overview

INVERSUS uses a peer-to-peer rollback system. Before getting into the implementation details, let’s review how rollback networking functions at a high-level.

Rollback networking an evolution of synchronous networking systems where every player would send input commands to every other player. In these systems, a deterministic game simulation would advance one frame every time it had received commands from each peer. This architecture had numerous benefits, but one huge caveat that drove action games away from it: input latency. In order to allow time for receiving remote player input, the local input wouldn’t be injected into the simulation for a number of frames equal to the transfer speed.

synchronousinput

Rollback fixes the latency issue by processing local inputs immediately while predicting the remote inputs. When the actual remote inputs arrive over the network, it checks if anything was mispredicted. If a misprediction was found, time will be rewound to the mispredicted frame and then simulated back to the present using the corrected input values and further predicted values. This rollback and correction process all happens in the span of a single frame such that user only sees a slight pop in the results.rollbackinput

As network latency increases, visual pops in motion will increase, but they will only be in relation to direct effects of remote player input. For example, the launching of a projectile might skip the first couple frames, but once the projectile is in flight it can be reacted to exactly as if it were in a local multiplayer game.

Rollback networking is designed to create a near zero latency experience for the local user and fair conflict resolution because every participant’s inputs are respected. When you move, you move right away. If you press a button on a specific frame to counter an attack, you will counter the attack. This architecture also creates a minimal overlap in which game and network code need to consider one another. When adding features to the game, there is almost zero concern about networking. Everything just works and that’s a rather freeing experience for the engineer.

The main downsides of rollback are that it does not easily support joining in-progress matches, and it does not scale to large player counts. It also doesn’t support a variable frame rate simulation, but I’ll discuss how it can still support variable frame rate rendering later.

Rollback is perfect for fast, twitchy, frame-accurate games that require responsive input and have short gameplay rounds. It is the standard approach for modern fighting games and should be the standard approach for any quick round-based game with direct player interaction.