Progress continues implementing Multiplayer in Super Skidmarks 2015.
Actually, Skidmarks is going to use two multiplayer codes.
The first one uses a peer-to-peer architecture on the local network. I already had some robust code for peer discovery and packet exchange on the local subnet using the unreliable UDP protocol from another project. It didn't take long to adapt it to cars racing around a Skidmarks track and before long I had a variety of iPads, iPhones and Android devices all driving AI cars and saturating the local wi-fi.
The second multiplayer code uses a client-server architecture for playing Skidmarks over the open internet. This one took a little longer to develop, at least partly because the client is written in C++ against a server written in python. It's currently using the reliable TCP protocol while I squeeze out the bugs and work on the control protocol (start race, determining winners, joining a match-in-progress, horn noises etc), but the plan is for the actual position data to be shared over UDP to provide the best experience over bursty 3G mobile networks.
The original Super Skidmarks, back in 1995, ran over a 1200 baud modem connection. A 1200 baud modem transmits 120 characters per second, or equivalently, 2 bytes per frame on an NTSC amiga. Using some bit stuffing techniques we managed to encode each of the 4 player's inputs using just 4 bits each, and even found spare bandwidth for an interactive chat line.
We also exploited the timing of the incoming bytes to recover a timing signal, so that both computers would run in lockstep.
Fast forward to the present day, and even the slowest 3G mobile connection runs at 200 Kbps – about 200 times faster than those old modems. A back of the envelope calculation suggests we can have up to 50 player cars on screen at the same time.
Bandwidth is only half the story. There is also latency. Back in 1995 we'd buffer up the player inputs and play then back 2 frames (40 milliseconds) later. This gave enough time for the modem to transmit your input across town and also be ready to pair it with the incoming input from the other player across town. Back here in the internet age, our development server is physically located in California, while I'm testing from here in New Zealand. Using the ping tool, I measure a minimum of 160 milliseconds for the information to round trip across the pacific ocean. It could be considerably more bursty (higher) on a 3G connection with poor reception.
There's no good solutions here :
* Introduce 160 millisecond delay between your inputs and when they appear on screen.
* Use client prediction to draw remote vehicles 160 milliseconds ahead of their current position.
* Disallow players with slow/unreliable pings from participating in multiplayer.
* Blanket the globe with fast high availability servers.
I suspect the answer will be some combination of all of the above – for example, an 80 millisecond delay plus an 80 millisecond lookahead. (I'm certainly open to suggestions!!!)
Here's where I get to innovate a bit more as an Indie. Remember I'm using two multiplayer codes? The idea is to gang them together. I'll use the peer-to-peer multiplayer code to combine all the skidmarks players on the local network. This means that all the players on your local subnet will be synchronized together at the millisecond scale. Then use the client-server code to synchronize all the local subnet information with the internet players. As soon as *any* device on the local subnet receives a packet from the server, it will rapidly spread that new information to all the nearby devices.
Then, if a skidmarks player wants the best experience playing on the internet, they can open a port in their firewall so that their skidmarks peer will operate as a 'supernode' on the peer-to-peer network, providing a low-ping race for everyone connecting from their local ISP.
At least, that's the plan. Wish me luck :D