After a week of cleaning up last week's mess, networked multiplayer is starting to get into shape.
I've even added amazing features like "adding a new player" or "finishing a level without crashing the game".
And just for fun, you can edit levels with friends in a multiplayer game too!
Local Player Hot Join
Supporting local players joining an in-progress networked multiplayer game1 was tricky.
Firstly, the rollback-based networked-multiplayer library I'm using2 doesn't allow adding players once the game session has started.
To fix it, I lie to the networking library: I tell it there is always only one local player on each connected computer, and if there are actually 2 or more local players, then I pack all the local player inputs together and send 'em as if they're from one player (then unpack 'em on the receiving end).
Secondly, local players can be added via a menu option, which is a problem when the entire networking approach is based on sending player inputs. I can't go adding a separate player input for every single menu option which may or may not be selected! 3
Instead I allow each computer to send one of N predefined "game commands" along with the local player inputs it collected, and "add player character" is one of those game commands; I can send that command both when a level is started and when a new local player wants to join midway-through.
It worked great when I tested it in a 1-computer game, but with 3 computers connected, it had, err, shall we say, a few kinks to work out:
Reloading levels was even stranger; here's a case with only 2 computers connected:
How could reloading a level double the amount of controlled player characters?
It turned out each connected computer was sending an "add player character" command for every player character in the game - rather than just for their own characters. Oops.
But after some days of furiously unwinding various poor assumptions, I got it working:
Finishing or reloading levels also works, but I ran out of time to record that4 so you'll have to take my word for it!
Multiplayer Level Editing
I have a basic level editor built into the game, in addition to the support for LDTK-built levels.
I am still undecided whether this game is going to have hand-crafted or procedurally-generated (or hybrid) levels, but I do use the level editor quite a bit to debug problems, and I wanted that to work in multiplayer too.
So now it does!
I send the edit inputs to other connected computers just like regular (run/jump/etc) inputs and it all pretty much just works. 5
The Multiplayer Iceberg
The core of the game is now working in multiplayer.
But the remaining work is like an iceberg: most of the work is hidden below the surface, and I don't know I need to do it until I run into it!
Here are todos that I do know of:
- Test performance on slower computers and with bad network connections, to see how much I need to improve the game simulation's performance.
- Figure out how to make the game compile into a playable web build again.
- Communicate network connection issues to players, so everyone knows that it's "Wifi Is All I Need" John's fault when a game freezes.
- Add some sort of matchmaking UI or server browser. 6
- Support remote players (re-)joining an in-progress game. (probably quite tricky!)
- About 20 other smaller tasks that defy categorization.
It's a lot of work! I still don't even know if it's all going to work out! We shall see.
PS. If you're here looking for a playable online demo and are terribly disappointed to not find one, there is a demo in the Sprayable Fluids update from two weeks ago.
For example, Tim and Jane are playing on two separate computers running two separate game clients connected to each other; Mary then picks up a controller attached to Tim's computer and wants to join in as the 2nd local player on Tim's computer.
The library I'm using is GGRS.
Although, performance is currently much worse when someone is using Edit mode because the highly-continuous-and-often-changing cursor position is used as-is, which causes a lot of rollbacks & resimulations because I haven't quantized it like I should yet.
Right now you need to specify the game to join as command line parameters when you launch the game, and you can't "leave" a game session except by quitting the game entirely. This is totally fine for my quick testing but obviously players will need at least a "Connect to IP Address" dialog box, and preferably a list of open lobbies or in-progress matches to choose from (and, eventually, Steam matchmaking integration).
Well, I guess I could just add more and more state to the "input data" that game clients send to each other. But, the smaller your input data is, the better, as the inputs are transmitted using the (intentionally) unreliable-by-design UDP network protocol, and larger UDP packets are more likely to be dropped as they travel over the internet (which then hurts performance).
Actually making the recording is quick, but splicing the videos together with various bits of explanatory text embedded takes a bit of time. I really need to figure out how to automate that nicely.