Hello Champions of Battlerite!
My name is Daniel “Prog” Fahlström and I am one of the programmers (Editor’s Note: aka “One of the lead devs”) here at Stunlock Studios. I’ve been working here since January 2013. Some of you might know me from the Bloodline Champions days as I was an active community member and moderator back then. During the development of Battlerite, I’ve been working in multiple areas such as the gameplay backend, UI and localization.
In this blog I will briefly explain how the Champion movement works in Battlerite (without being too technical) and what requirements and challenges we’ve had with the solution we use.
Requirements and Challenges
All movement in Battlerite has to feel responsive, as you are in direct control of the character. Visual delays to inputs has to be avoided for full immersion and to keep the gameplay fluid and on point. This is something we think we have achieved with our current solution. The movement in Battlerite feels very responsive and will do so regardless of what your latency might be.
As Battlerite is a competitive game, we put a lot of effort into making sure players are unable to cheat. Due to this, the server is the authority of the actions the player performs, meaning all the actions (Movement, Ability Cast, Projectile Collisions etc.) are fully controlled by the server.
The solution therefore requires the server to verify all the actions sent from a local client (i.e the Battlerite game running on your computer). The server then makes sure the actions are valid, and will only send valid positions to all the other clients.
A challenge that is unavoidable when making an online game is of course latency. It is a common rage-factor in multiple games, especially those relying on responsive inputs and reactions.
Latency causes all actions from a local client to be delayed for all other clients, unless it is predicted or simulated. Since latency cannot be avoided, a phrase that is used among us is “You don’t remove the latency, you just decide where to hide it”.
In a perfect world all players would have less than 50ms latency to our servers, but as that is not the case, a requirement we have is that the solution should work with up to 150ms latency.
Here is a visual example how the responsiveness would look with and without our solution with a high latency. The green line represents which direction the input is pressed on the client. Obviously the delayed visual feedback of the input makes the game a lot more sluggish for the player.
Since the movement in Battlerite is based on WASD movement, similar to how it works with most FPS games, we took inspiration from the very solid solutions used in Quake and any of Valve’s Source games. We’ve adapted their solutions to better work for Battlerite, but the core of the solution remains the same.
A big difference between the above mentioned FPS games and Battlerite is that Battlerite uses slower projectiles instead of instant line shots. This means that whenever latency causes visually invalid spell collisions (you getting hit when it looks like a projectile misses) it is much more noticeable. The fact that Battlerite is a game with a top-down camera view further enhances this.
If you’re interested in reading more about the solutions we’ve been inspired by, I’ve listed some articles at the bottom of this blog.
So how does it work?
The simplest way of explaining how the movement system works is to think of it like this; The client simulates its movement visually, and sends all simulated movement commands to the server. This means the client is constantly visually showing the position it believes is the current position for the player. Since the client and the server run the same calculations, a mismatch rarely occurs. If it does, the client will modify the simulation so it matches the expected position on the server.
Here is another visual representation with and without our solution when running with very high latency. This time with some circles showing the position for the client and server. The red circle represents what position the player has on the server. The green circle represents the position on the local client, with the green line representing client’s input direction.
The green circle is always ahead when we’re simulating the movement commands on the client, instantly responding to the input. The server position however is delayed due to the latency.
Now, this solution (or any other solution) is not completely perfect since latency will always still be a factor. And also, as mentioned earlier, collision errors will be a lot easier to spot in a top-down perspective with projectiles.
Here is an example of a visual error at a very high latency. The red circle that is shown is the position of Shifu when a collision is detected. Even though it looks wrong on the client, it is the correct result on the server.
This is something we know players occasionally refer to as “invalid hitboxes”, but in actual fact, a lot of the times it is an issue with the latency to the server.
To conclude, issues like these are unavoidable. We want to allow the client to simulate the movement, yet still let the server have authority over the positions. We are aware this is something that has been frustrating for Battlerite players, and we’re constantly looking at different ways of solving these issues in order to strive for the best experience possible for all players.
Thanks for reading!
Here is some of the articles we’ve used as a inspiration for the network model we use for different areas of the gameplay in Battlerite.