Mike Acton posed a challenge a while back to show your ignorance. Fittingly, I don’t know much about professional game development. I know, I know, what the schnitzel am I doing writing for AltDevBlogADay?
I like reading source code, especially games. I’ve written a game or two myself, and just a couple of days ago, I went back to game I wrote in 2003 to see how I used to do things back then (and to be honest, it was actually overall pretty ok quality, which is rare when you go back that far to read your own code). Reading your own code is about as exciting as reading your own novel though, it can be nostalgic, but I seriously doubt it’ll be very exciting. Somehow it’s always Colonel Mustard with a candle stick in the study…
Finding good reading material isn’t as difficult as it might sound. Several game studios have opted to open up their source code after the game has more or less reached its end-of-life, one of the more prominent examples would be iD-softwares Quake titles. I actually still have the Quake 2 source code on my hard drive and I’ve learned so much from it with regards to so many different aspects of game development. Conveniently, Wikipedia has a list of game titles which have either been opened up, or are open source to begin with. Pick one and start reading!
Don’t get me wrong, I love technical articles about deferred shading and color correction as well, but you’ll rarely find the nuts and bolts aspects of game programming there. There are exceptions of course, two notable being Glenn Fiedler’s excellent networking series, and if you haven’t already you should read them. But I digress.
But how do you read code? It’s not like reading a story, where there’s a beginning and an end, in fact the first thing you see when opening a file might very well be some obscure spline reticulation function. How’s that for in medias res? I’d say there are typically two ways to go about reading code, you either start at some entry point (like main) and follow an execution path of your choice up and down stack, or you find a function doing something interesting (like through a full text keyword search) and you work from there, trying to figure out who’s calling it in what situations. As much as I’d love to have a suitable E-book format for source code, and that I could pop it into my Kindle and read on my way to work, I don’t think that’s going to happen. So what do we have?
VIm – VI Improved
My weapon of choice is usually for both editing and reading. Except when working in Java, a language which is inherently impossible to deal with without a suitable IDE, or your fingers will go numb trying to navigate the source tree.
VIm offers a few tricks on its own which might be useful ‘*’ and ‘#’ search forward and backwards respectively for the word under the cursor. This is completely language unaware, it’s merely searching words, and will also catch
To read through larger projects effectively though, simply searching up and down a file will not do you much good. This is where a tags file comes in handy. A tags file is simply a text file, indexing all identifier declarations in your source code, such as structs and classes, functions, and defines. There are two dominant formats for tags files, ctags and etags, where former is traditionally the VI format, and the latter the Emacs format.
To create your tags file, you need ctags, which luckily is usually readily available in your favorite distribution, and it usually translates to the exuberant ctags package. You run the ctags command with something like this
ctags -nR --extra=+q
The -R is asking it do traverse your source tree recursively, and -n selects line numbers rather than regular expression search. Using regular expressions (i.e. omitting -n) will make it more robust when used during active development, as the editor will search (rather than simply jump to a line number) for the line ctags discovered allowing the line numbers to change.
The extra-parameter with the q-flag tells ctags to put a note in the tags file with the fully qualified name, which you can use to either search directly (using the ‘:tag’-command in VIm) or when showing multiple results, you’ll be able to tell them apart.
When you have a tags file in VIm’s current directory, it’ll load it automatically and you can place the cursor over any tag and jump to the definition using the intuitive (hrrm…) key sequence Ctrl-]. This will push down one on the tag stack and jump to the location described by the tags file. To pop elements off the stack, use the obvious opposite key sequence Ctrl-t.
What I haven’t been able to do yet (although, it’s also due to lack of trying) is searching for references to a certain function, i.e. a call hierarchy. Feel free to give me a pointer in the comments.
When dealing with Java, I usually go with Vrapper, hands down the coolest Eclipse plugin.
Eclipse offers an extensive tool set for navigating code, like class hierarchy visualization (default F4), call hierarchies (Ctrl-Alt-H), highlighting the symbol under the cursor (Alt-Shift-O), among others. The neat thing here is that everything is completely language aware, and it will only highlight (as an example) that very symbol, and not any that might be using the same name. Although this is rarely a problem, with simple highlighting (most people try to differentiate their variable names) it does come in handy when looking at call graphs, or trying to find a specific method implementation (how many ‘update’ methods do you have?).
Eclipse was developed with a clear Java target audience, and the C/C++ plugins (known in Eclipse as CDT) have often been considered rudimentary at best. I haven’t used it myself much, but from what I have seen, CDT has really become a viable option for C++.
Eclipse also has the option to jump back to previous locations using browser-style back and forward buttons, but for some reason I thought they felt a bit awkward and indeterministic, so I barely use them.
I believe Doxygen is one of the more common automatic documentation generators handling C and C++ out there (it handles other languages as well, of course), but it’s also pretty useful as a code reading tool. Doxygen provides all the standard syntax highlighting and cross referencing you’d expect, as well as some simple called-from information, although when I used it, that along with class hierarchy visualization, seemed to have some difficulty with template classes. Doxygen, like Javadoc, generates HTML pages which can be viewed with a standard web browser. This has the added benefit that anything you have in your web browser (like plugins for note taking, or whatever) will be available when browsing the code. Back and forward buttons also work intuitively, it’s after all just web pages.
Doxygen also provides a great overview of all the name spaces and classes in your project, and the alphabetical class list was really useful to me at the time. I was working on a three million LOC project, so there were a lot of classes. Of course, if there are Doxygen comments in the code, they’ll be presented in an elegant fashion as well.
One note though, you might want to enable extraction of private and static stuff as well as source browser and generation of references, per default Doxygen only generates documentation for the public things, which makes sense if you’re actually generating documentation.
I haven’t really used Source Navigator. I got a tip from a colleague when we were looking for alternatives as Doxygen was having trouble with our code base (which turned out to be a problem with Doxygen when dealing with exceptionally large files). First you create an index of your entire tree, which can then be used for browsing the code; syntax highlighting, call hierarchies and cross references are of course available here as well. The deal breaker for us here was that you couldn’t share the same index file, at least not at the same time.
That’s all for this post, I hope you enjoyed it. I’d really like to know how others work with code reading. I assume a lot of you use Visual Studio, which I don’t have, and I haven’t used it regularly for almost a decade. Or maybe someone has a perfect mobile app? So please, help me out, how do you read code?
Note: Cross posted on my own blog, excu.se