One of the best ways of learning how to write code is by reading other people’s code. Imitating what other people do, especially if it’s done well, is a very solid way to gain proficiency in any skill rather quickly. This holds true for a variety of skills such as carpentry, cooking, and for artistic skills such as writing, painting and also programming. We build on what others have done before us. That way, we don’t have to make the same mistakes over and over again: we benefit from the historic wisdom of the masses as it were.
Unlike with other skills, writing code can be done in any number of ways. Not only are there countless of ways to solve any given problem, there are also numerous possible implementations of any of those solutions. This raises the question: “what separates a good implementation from a bad one?”
About eight years ago, I got my first job as a software engineer on a game development team. I was about as green as I could be, and between not being very strong mathematically and not having any prior education in development, I was set for a challenge, to say the least. Fortunately, the gaming industry was chock-full of concepts such as behavior trees and fancy algorithms, which all made very little sense to me at the time.
Being the fresh, adamant programmer, I looked up the Wikipedia page for behavior trees, and started hacking together an implementation. I honestly couldn’t tell what a behavior tree looked like for the life of me, and I wasn’t very proficient in the language either. A lot of hacking later, the result sort of resembled a behavior tree, but it performed very poorly and it upset quite a few people. Something along the lines of “does this guy even know what he’s doing?”. Well, not really. But it’s not like I could tell them.
Ultimately, we did need a framework for expressing behavior trees. One of my colleagues decided to pick up the slack. Within a few days he wrote a far better implementation that I could ever come up with. What struck me most about it was its simplicity. While my implementation was a royal mess, his consisted of only a handful of types, and none of its methods were particularly complex.