When I am programming something that requires a module or a sub-system of any kind, my first impulse is to always write it myself; sometimes, even rewriting things I had already written before. While there’s a danger in doing too much of this and avoiding well-established solutions to common problems – the syndrome of Not Invented Here is a thing – I have always justified this decision by rationalizing that I have a better understanding of tools I build from scratch than some mysterious library with unknown side-effects, and that it is more fun to do it myself anyway. Obviously, this is not a solution that should be used all the time, as sometimes the time spent building complex systems (say, a rigid body physics system) can easily outweigh the benefits, but it’s one I find myself doing time and time again, and feeling guilty doing so.
In reading Game Engine Architecture by Jason Gregory, however, I ran into the best rational defense of the practice I’ve seen so far. When talking about building custom container classes for certain data structures, the author gives the following reasons why game developers normally choose to do so:
- Total control. You control the data structure’s memory requirements, the algorithms used, when and how memory is allocated, etc.
- Opportunities for optimization. You can optimize your data structures and algorithms to take advantage of hardware features specific to the console(s) you are targeting; or fine-tune them for a particular application within your engine.
- Customizability. You can provide custom algorithms not prevalent in third-party libraries like STL (for example, searching for the n most relevant elements in a container, instead of just the single most-relevant).
- Elimination of external dependencies. Since you built the software yourself, you are not beholden to any other company or team to maintain it. If problems arise, they can be debugged and fixed immediately, rather than waiting until the next release of the library (which might not be until after you have shipped your game!)
I could not have said it better, and have to confess I felt a bit vindicated when reading it. It’s very often that I have to dig into a certain class to either add a missing feature, or to tweak something in an otherwise unorthodox way to provide some much-needed performance boost for a particular edge case. For good reasons, generalized solutions tend to go against that; and while tweakable, open-source solutions exist, nothing beats knowing the behaviors of a particular system inside and out because you built it.
Joel Spolsky talks a little bit about the subject in much a much better manner than what I’d be able to conjure, and comes up with an advice for software teams (as a short tenet, in true Joel Spolsky fashion):
If it’s a core business function — do it yourself, no matter what.
There’s an advantage in using stuff that has been tested by a big group of people, of course. I probably need to get better at using other people’s stuff. In the meantime, though, I’ll happily continue reinventing when I can. It’s more fun this way.