DEVLOG #11 Networking Part 1 - Who’s Got The Crate?

Hello! I’m one of the engineers on Begone Beast and this is the first in a series of posts about Networking and Multiplayer systems, which is where I spend a lot of my time and energy.  


One of the goals in multiplayer game development is making sure that the world each player sees is as consistent as possible for things that matter.  For this blog post, we wanted to share a simple yet amusing challenge that we needed to solve for our Throwables: if two players pick up an item at the same time, who gets to throw it at that large horde of hands?!

What’s a Throwable?

A Throwable is a game object like a crate or an oil drum that a player can pick up and fling at a bunch of enemies. We also have Deployables like barricades and turrets that players can use for strategy and crowd control.  And both of these are types of Pickupables in terms of game object hierarchy, but throwable is more fun to say so that’s what I’m going to use.

Let’s say there’s a crate in the level that two players want to pick up.  The first challenge is making sure the crate exists up in the same place in both players’ worlds, which Unity mostly handles for us.  When a player picks up a crate, it’s given to that player and removed from the world for everyone else.

But what happens when those two players try to pick up the same crate, at the same time?  This happens more often than you might think!  In the chaos of a battle, players are grabbing anything and everything they can, but because this information has to travel over the internet there is always a small  window of uncertainty.   

Who’s Got the Crate?

In Begone Beast one of the players acts as the Host for the parts of the game that need a single source of truth.  The host is responsible for spawning network objects, executing abilities, running monster behaviors and, as it happens, deciding who picked up a throwable crate.

In the case of simultaneous pickup, a straightforward approach to deciding who actually grabbed the crate is just to have both players send a request to the host, then the host decides the winner (simply by whose request arrived first) and notifies both players of the outcome.

This works but can make the UX feel sluggish because the winning player can’t actually perform any pickup actions until they hear back from the host.  That round trip communication takes time and is entirely dependent on the internet’s speed and mood.

They Can’t Both Be Right, Right?

An alternative approach, and the one we use for Begone Beast, is for each player to assume they have successfully picked up the object.  This way we can start playing pickup animations and the UX feels snappy and responsive.  But it does create another interesting situation: what happens to the player who didn’t really pick up the crate?  After all, the host still has to choose a winner.

In Begone Beast, both players will optimistically start their pickup animation while sending the pickup request to the host.  When the response comes back, the “losing” player will have to stop any pickup animation in progress and cancel any effects (including proxy crates… but that’s a story for another day). Keep in mind this is all happening in just a few frames, but those frames really matter to make sure actions feel responsive.

It’s tricky to get right and can create a brief moment where you can start picking up a crate that another player got to first. But one of our guiding principles is to make your actions feel as responsive as possible. In this case the winning player already has the crate and the feedback was instantaneous, so we felt it was worth it.

Thanks for joining me on this trip around the internet!  As always, deep breath and … 







Next
Next

DEVLOG #10 THE EFFECT CHAIN