Oh no, the AI are taking over! What shall we do? Don’t worry, it’s not the end of the world just yet! You can always retake control by joining the game again!
Wait, what? That’s right, when you leave siege mode, mid battle, the AI will valiantly take control of your MAV and march it into battle for you. But what happens if you get your connection back? You can just hop right back in and retake control of your MAV, right in the terrible situation the AI walked you into 😉
So, yay, new feature!
This was actually quite a big deal, so I am spent the good majority on this sole feature. This started as a simple fix to the current issue you experience in multiplayer games, where if someone quits and rejoins, the server is basically ruined and needs to be restarted. What was happening is a ‘ghost instance’ of the player data was being left on the server, much like a memory leak, and it would cause all kinds of havoc when the game actually tried to address the ghost player, like when checking for win conditions. This right here was actually a fairly easy fix, as I keep the player around, but just mark them as disconnected and if the reconnect, put them back into their reserved spot. This all gets pruned after the round is over, so you don’t have to worry about hanging on to tons of ghost players from round to round.
Only this didn’t really work for siege mode. In arena mode, leaving and rejoining would wipe your round stats and spawn you fresh. No big deal, right? This becomes a huge deal in the more competitive mode of siege games. For starters, a team being down a player is at a serious disadvantage. Also, if the player can join back in [and actually be on the same team now] in a full heath MAV, with all parts replaced, there is a huge avenue for cheating. So, lets see just how robust the AI is and put them in your place!
So, that is exactly what I did! For once, I was incredibly happy with the modularity of my AI design. Having the AI be adaptable enough to literally pilot any player creation turned out to be a non-factor, as the AI decision making is data driven by all the parts on the MAV. All I had to do was turn the AI on and it already had all the information it needed to be an effective pilot!
Next, was taking control back. This was a bit more complicated. MAV uses dedicated servers, which are also authoritative. This means that nothing that happens on any other computer playing the game actually matters, only what happens on the server. In this instance, we are taking an object [the AI controlled MAV] that is fully under the control of the server and passing some of that control back to the client. To do this, I had to implement a kind of synced handshake / pass off system of messages to ensure it all went smoothly.
But, this new persistence of data revealed another problem. There was nothing that was tracking the actual game state of MAVs. There was nothing telling you how much ammo you had left, how much health was on any individual parts, or even what parts had been blown off! This is even more complicated by the fact that half the MAV could be missing on the server, but you show a full MAV on your screen and so you are left wondering why you new guns [that don’t actually exist] aren’t doing any damage.
The first thing I tried was the easy on. Just save the current state of the MAV on the server and send it down to the client. Easy, right? Well, turns out, that is a horrible idea. You see, when you are doing networking you need a way to reference the same object in every single connected instance. In Unity, these are called networkID’s. If you want the cockpit on the server to say it got hit, it sends a message addressed to it’s networkID to all the clients. The client can then use that ID to find the same cockpit and have it process the message. It’s like a mailing address or IP address for individual components in the game. Now, how you create these and give them to objects is VERY important. I use a deterministic spawning system, meaning that given the same inputs, I am guaranteed the same output every time, in every system. Using this, I can send a client a MAV and a list of IDS and know that every single time that MAV will have the same IDs on the same parts, on every computer. Pretty neat, right! But, we want to send partial MAV data. Now, the IDs don’t match. Now when we start sending messages, they will get processed by the wrong part! in the simplest case, we get an error and nothing happens. In the strangest case, a machine gun starts firing like a shotgun, but shooting cannon shells and howitzer damage numbers. Things can get…. weird.
So, I needed to create a way to store the difference in a MAV from it’s current state to its original state. Using this, I could spawn in a brand new MAV, ensuring the IDs all matched up, then send in the difference state and have it remove parts and set the health and ammo counts of everything. This also required some super special handshaking over the network to ensure the difference file wasn’t sent before the actual MAV was spawned. The end result: You can see how bad or good the AI was doing for you while you were away 😉
At this point I feel I am far enough along that I can start doing some private multiplayer testing with some of the current players. These will be small data gathering sessions to hunt bugs that I could have missed [like race condition issues] and would be during set times. If you are interested, please send me an email to MAV@bombdogstudios.com with the subject of Multiplayer beta testing and I will pick a handful of players to start this will.
That is all for this week [besides the large amounts of secret stuff I also did ;)] ! Next week I will be fixing a few issues the stats system and how it handles multiplayer games, as well as addressing any issues that come up from the beta testing! See you then!
[Side note: I will not be attending Sunday Funday this weekend due to the Easter holiday.]