I’ve always made time for reading postmortems about sales. They were useful when I first considered going indie and are still useful today with over two years of selling INVERSUS behind me. Whenever peers ask how the game did (or is still doing), I find it hard to frame the answer. INVERSUS is not an obvious runaway success nor is it a failure. It sort of “does well enough” given how my solo studio, Hypersect, is run. Hopefully sharing some specifics of how it has sold will in turn help you evaluate past and future decisions.
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:
- 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.
- Apply any necessary inactive rating periods if the time step is greater than one rating period.
- 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.
- 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!
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.
The official INVERSUS Discord server (found at discord.gg/inversus) has grown to house an active community of both veteran and new players. Creating the community was my first introduction to Discord and I quickly came to see the advantages of having a bot to help automate common questions and needs. I first searched for an existing bot to integrate with the INVERSUS server, but nothing was very focused on being build around the community for a competitive game. I wanted features such as players positing invitations to their private lobby by typing !invite or having the bot automatically let everything know when a new high score was reached on the leaderboards. Thus, once I got the time to learn a bit about node.js and the Discord API, I went ahead and build my own bot, named Hyperbot, that I could add to over time.
Putting Hyperbot on your Discord server
If you are in a similar position and want a reference bot to start from or just want to boot up Hyperbot as is, you can find the latest code and documentation on the full feature set on GitHub at https://github.com/hypersect/hyperbot
This post will be a bit different than my normal technical posts. Rather than covering a successful finished system, this will be a glimpse into the process of (hopefully) getting to that point in the future.
With INVERSUS finally out on all platforms, I can clean up some of the engine’s rough edges, and one of the bigger pain points has been the font pipeline. When it comes to refactoring workflows and engine architecture, I think it’s important to find tractable small steps you can take on the path towards your desired goal. I have a fuzzy picture of how I’d like things to be, and I make small improvements while at the same time getting a better focus on the destination.
In my experience, the complexity of properly rendering text is an underappreciated problem by engineers that have never worked on it. It seems so simple! There are really only three steps:
- Choose the next glyph to draw
- Choose where to draw the glyph
- Draw the glyph
So which of those steps is the hard one? Unfortunately, if you want to render crisp text in multiple languages across the world, all of them are the hard one.
When discussing the visual style of INVERSUS, there has always been an amusing contrast between the random YouTube comment saying that “this could run on an Atari” and the periodic questions asking how I’m actually managing to draw what is happening on screen. We’re going to take a detailed walk through how INVERSUS Deluxe composes a frame, but for fun let’s start off by looking at an actual demake of INVERSUS for Atari that Ed Fries was toying around with (believe it or not, just finding a way to render the obstructions on the map was non-trivial).
More news means it’s time for a new edition of the INVERSUS Newsletter!
Let’s get straight to it. INVERSUS Deluxe is launching on Nintendo Switch™ on September 28th and Xbox One on October 4th!
As you may recall, all of the current players on PlayStation 4 and Steam will be getting access to INVERSUS Deluxe as a free downloadable expansion. But when? The plan is to publish the Steam update alongside the Nintendo Switch launch on the 28th. The PS4 patch doesn’t have an exact date yet, but it will be in early November. I’ll be sure to send out a reminder once I have it locked in.
Feel free to share the news on twitter and anywhere else people pay attention to!
Have you checked out the official INVERSUS Discord server yet? It’s a great place to meet others for setting up matches or just getting tips to improve your game. It’s also now the central location for setting up community tournaments!
Starting this Friday we will be running a double elimination tournament for Steam players. Click here to sign up and enter the bracket! We are managing the tournament through a service called Challonge that automatically emails you and your opponent when you have a match available. After you sync up and play, you can log in, enter your results and then the tournament will progress. Head over to the #tournaments channel on Discord to meet your competitors, ask any questions or just follow along!
It’s time for another edition of the INVERSUS Newsletter!
INVERSUS just got a whole lot bigger and it’s headed to Nintendo Switch™ this fall!
Last time we talked, I was working away on the 1.5 update. Then I started adding more content. Then I decided to add some more new features. I certainly wasn’t done adding more unlocks. And then I went and gave the whole thing a big visual upgrade. Looking back at the current game and what I had been building, I realized that it had become this giant beast of an update and just bumping the version number wasn’t enough. This needed a name!
INVERSUS Deluxe is still going to be a free update for all existing players and it will be the version of the game launching on Xbox One and Nintendo Switch (more on the below!). Click play to check out the trailer!
Let’s talk details:
- 12 new versus maps and 4 new arcade maps create a total of 50 unique maps for players to enjoy.
- Test your skills in the new single-player versus mode by facing off against AI Bots that scale in difficulty from beginner to world-class player.
- The addition of ranked online multiplayer rewards skill in both 1v1 and 2v2 games.
- New real-time soft shadows and high definition materials add a depth and richness to the screen.
- With the new split-shot ammo, players can fork bullets and shoot around corners.
- Equipping new unlockable motion trails allow players to show off personality in the arena.
Ever since the Nintendo Switch was announced, I’ve had people telling me how perfect INVERSUS would be on it. Today, I’m happy to officially announce that INVERSUS Deluxe is launching on Nintendo Switch and to officially confirm that it fits like a glove. The game controls great on everything from a single Joy-Con to a Pro Controller.
I was pleasantly surprised to find how well the game works for a portable console. Playing a round in arcade mode or challenging the AI in versus mode both hit that sweet spot for filling some time while you are out and about. On top of that, the game looks fantastic running at 1080p 60fps undocked.
The online experience works great on Nintendo Switch as well with full support for public matchmaking and private games with people on your friend list. I can’t wait to start competing for the top spot in the new ranked online multiplayer!
Demo Demo Demo
PAX West is coming up at the end of the month in Seattle. I’ll be there showing the game so come find me! I might even get some shirts printed up (if I can magically find the time to make that happen).
I also want to say thanks to everyone that’s come by at all the shows I’ve been at recently! INVERSUS made it’s way back to EVO this year and also got to make it’s first appearance at San Diego Comic-Con thanks to the Behemoth! It’s a privilege to get to meet all the players out there and it’s well worth getting sick almost every time despite how much hand sanitizer I try to use 🙂
For the full newsletter, click here!
INVERSUS is headed to Xbox One with more maps, more power-ups and more ways to play!
The next update for INVERSUS is launching later this year on Xbox One, PS4 and PC! You heard that right. INVERSUS is finally headed to Xbox!!!
The 1.5 edition is also going to be the biggest content update the game has ever seen!
- Compete on 12 new maps in Versus mode!
- Master 3 new levels in Arcade mode!
- Collect new split-shot ammo that can fork into multiple bullets!
- Sharpen your skills against the community’s most requested feature: AI controlled bots in Versus mode!
Click play on the announcement trailer to see in motion:
If you have tickets for PAX East next month, you can be one of the first people to try out INVERSUS 1.5! I’ll be there demoing the game on an actual Xbox One and look forward to testing all the new maps with everyone.
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.
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.
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.
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.