posted on March 10, 2016
I’m Garrett, a Senior Programmer here at OWI. You guys probably know me as RoyAwesome on the forums and Reddit. I’ve been working on Squad for almost a year now, implementing a variety of features you guys play with every day, like the Deployable system, the Gamemode system, AAS gamemode, flags, scoring and so on. One of my main tasks for the last several months has been implementing one of our headlining features: Vehicles.
I started working on Vehicles in September 2015. At this point we had done two proof-of-concept prototypes, both in Blueprint (Unreal Engines scripting system). I quickly discovered that both prototypes had some fatal flaws, which prompted my decision to simply start from scratch with our vehicle implementation. This proved to be the correct decision, as it allowed us to create a very robust system that can create some really unique vehicles.
However, before I could write a single line of code, I needed to know what exactly did we want to do with vehicles. What kind of actions could you take? What happens if a vehicle gets shot by a rifle? A rocket? A tank shell? What do we want passengers to be able to do? Gunners? Drivers? I had a lot of questions I needed answers to, so I turned to our awesome designers Z-Trooper and SgtRoss to help brainstorm up some ideas for what they wanted Vehicles to look like in their final form. That simple question set off a massive round of design discussions, ending up with a huge design document with all kinds of cool ideas and features to add. With a design in hand, I had work to do.
Starting with an empty code file, I had to decide where to start. The previous prototypes had focused on the Physics and movement portion of Vehicles, and since I was starting from scratch, I figured I’d start with the part that neither of those prototypes ever tackled& Getting into the vehicle and how seats work. How seats work and what you can do in them was a major focus of the design, so I figured I’d start there but implement a simplified version for now. As an added bonus, this also meant that we could leverage this code for Emplaced Weapons, as getting in and out of the weapon was something we needed to do to make them work.
The initial implementation of Seats and interacting with them went by pretty quick, and by the end of September I had a working prototype of a static Vehicle that could have any number of seats. I encountered a serious issue testing it though& the game crashed every time I would get into the Vehicle. After some quick investigation, I discovered that parts of our code assumed that PlayerController (what you are) always controlled a Soldier (your person in the game). Oh simple, I thought, Ill just fix those assumptions. Yeah, It wasnt that simple.
Configuring the Seats for a Technical
To understand the problem a bit more, Unreal Engine has a few important objects. Players are represented by the PlayerController. The PlayerControllers job is to handle all input from players, as well as track their state across the game. They dont exist in the world, but they can Possess objects called Pawns, which are objects in the world that can be controlled. From the beginning of development until now, we have only had one type of Pawn: The Soldier. Because of that, some very core systems such as weapons and damage only really worked when a PlayerController was controlling a Soldier. If the PlayerController was controlling something else (lets say, a Vehicle), those systems just broke.
How you actually get into a vehicle
Breaking these assumptions and fixing them took me quite a bit of time, from October into most of November. Some of them were easy to fix, such as instances where our code would cast a Pawn into a Soldier and not check if the cast failed, but some of them were not. I figured, around the start of October, we could get these issues fixed and released Emplaced Weapons in November. However, I discovered that our Weapons assumed that our PlayerController controlled a soldier in a big way. Progress on fixing Weapons was very slow. Weapons needed to be inside of an Inventory, which was part of the Soldier. I had to split that off into a component (horribly breaking it in the process). October slipped into November, and I was still changing things like instances where the weapon was playing Soldier Animations on any Pawn that was controlled (which obviously didn’t work with vehicles).
Setting up a 50cals Inventory
Luckily, while I was busy fixing these issues Kory, another programmer, finished up his tasks and started working on Vehicles with me. At this point we had blown vehicles for the November patch, but we were still trying to get them out for Early Access. I asked Kory to look into getting physics working with the vehicles, getting the M1151 Enhanced Armament Carrier drivable. At this point, I had fixed all the simple soldier-only assumptions so driving the vehicle was possible. We figured we could at least have transport vehicles. Kory set to work integrating the UE4 vehicle system into the multiplayer Vehicle system I had built.
By Thanksgiving, Kory and I were driving M1151s around our test map. However, after turning on fake lag we started to notice some odd behavior, with the M1151s and Technicals rubber banding and desyncing when driven. We needed to do some more investigation, but with Alpha 3 right around the corner it would have to wait.
Around this exact same time, I finally fixed the last few issues with weapons, and successfully fired an Emplaced .50 cal. However, due to how buggy the Alpha 3 release was looking in testing, like Kory, I tabled working on Vehicles to focus on Alpha 3 and making the Early Access release awesome. I did add a method of spawning vehicles in any map so that post-EA we could spawn vehicles on full servers and see how they performed.
After the Early Access release, we did a number of tests, spawning M1151s and Technicals on full servers and seeing how they performed. The results were not promising. The issues we saw with desyncing and rubber banding were much worse in full servers. I took a short break from firefighting post-release bugs to investigate, and I discovered that the default vehicle code didn’t really have netcode or lag correction. Vehicles were warping around because the drivers inputs were sent to every client and the server, but only the servers position was Correct. Due to the nature of physics engines, every client had small but compounding errors in positions and velocity, causing every client to see vehicles in different positions. When the server sent the Correct positions, the vehicle was teleported to the proper position, giving a very ugly warping and rubber banding effect.
The netcode for Vehicles had to be redone.
In Part 2, I’ll talk about the process of rewriting the Netcode for Vehicles, putting the last few pieces together for vehicles, and talk a bit about how to mod them. For now, I hope you enjoyed this look into the development process of Vehicles. If you have any questions, you can follow me on Twitter, @RoyAwesome.