by Leon Rosenshein

Inheriting Code

One of the things we've all had to do is learn how to work with an established system. Whether it's your first internship, switching teams, going to a new company, or just helping someone use something you've built, you have to orient yourself. So what do you do?

The first thing to do is ask questions. If you're lucky, there are folks around who can give you an overview, tell you where the problems are, and give you some history on why things are the way they are. If so, take advantage of that opportunity. 

Think of it like moving to a new city. You've got a specific destination and someone told you to check out a cool place while you're there, but that's it. The first thing you need is to get the utilities turned on, then you need a broad map to get you into the right areas. Then you start exploring and adding detail to the map. At first the details are only in a couple of places, maybe close to home and your job. The rest of the map has some general labels like industrial, residential, and downtown. Over time though, partly out of need, and partly out of curiosity, you start to fill in those blank spots. Eventually you end up with a pretty good internal map of the city, with a lot of detail for areas you spend most of your time in. And then, when you're the "expert" you share your map with friends and family.

Codebases are the same thing. Around here getting the utilities set up is called on-boarding. Getting your tools set up and getting access to what you'll need. Depending on how far you're coming from (new intern vs. another project on your current team) you'll need to do more or less on-boarding. You'll need a goal. A bug fix or a small feature. Maybe you need to add some validation to some input. You find (or build) a rough architecture diagram so you can figure out where the input is read. You look around the neighborhood and see how folks have done similar things in the past. You follow the data around in the debugger and start to understand some of the other blocks in that diagram.

When I joined the Combat Flight Sim team my first job was to figure out why the AI would sometimes just dive for the deck in the middle of a dogfight. Before I could fix it I needed to build my map of how things worked. There was already a tool that we could use to monitor the state of the simulation in real-time, but it was inherited from the main FlightSim team and focused on the flight models and graphics engine. So my first task turned into making better tools to understand the system. I started out simple by plumbing the AI's current target into the monitor, which taught me about how the AI stored its state, how data flowed through the system and how the display system worked. With that rough map I was able to dive deeper into the AI itself, figure out what state was important, and where it came from. Once I had that understanding I could look into the problem I was there to fix.

Which brings us to the last part of learning a new system, sharing what you learned. Very often when learning a new system you'll come up with new tools or enhancements to existing ones. Building those tools is a really good way to understand those systems, and sharing them helps you and the team along the way.

For those that care, it turned out that the AI was paying attention to energy management, like all good fighter pilots do. The problem was that instead of comparing its energy to the highest threat or some weighted average of multiple threats, it was comparing to the total energy of those threats. Of course, in that case it came up comparatively very low on energy and would trade altitude for airspeed in an attempt to even the score. I switched the comparison to a weighted average and solved the problem.