Since something interesting is going on at work, I thought I'd share. Well, interesting and something I can discuss publicly, which is a rare combo.
The last couple of days have been spent in an intense bug hunting frenzy. Earlier this week, I was working on a small demo for an upcoming milestone, when a couple of memory bugs cropped up. What started out as a memory leak became a nasty chase through a convoluted inheritance hierarchy, dozens of misapplied templates, and some truly backwards code design.
Ironically, just at the end of last week, I'd signed off on that code as more or less usable, which is why I was doing a demo in the first place - I had vouched for the technology as solid enough to be showing off, albeit in a rudimentary form.
Apoch's n++th Law of Software Development:
You cannot truly judge the quality of a block of code until you must locate a bug in it.
The longer you use a piece of code without having to hunt down a bug in it, the closer you can come to saying the code works correctly. However, this approach is asymptotic - you will never get there.
Fixing the Bugs
After a few hours of analysis, I determined that salvaging the code was out of the question. It would take less time and effort to rearchitect it and then copy/paste the functionality back in.
So that's what I've been doing lately. There's a huge chunk of work finished and ready for a version control commit, but a few major elements are still missing. As of right now there's actually less functionality working than when I set out to build the demo, so... bummer, I guess. That's the way things go.
Postmortem: Dissecting the Insects
So how did this situation come about in the first place? It's a simple and sadly common problem.
About a year ago, we had a newcomer to the team, who was interested in working on the engine and doing some game logic stuff. This particular technology was already written in another scripting language for an old engine, and needed to be ported to C++ for future use. The demand was minimal, so he was under no time pressure, and it seemed like a good project for a beginner.
As it turns out, the entire thing suffered badly as a result. He made a valiant effort, to be fair, but the result just wasn't up to par. The original programmer of the technology did some work to make it a bit better, but by and large it was a low-priority item, and thus languished in disrepair for months.
Worse still, the new guy disappeared after a few weeks, and nobody seems to know what happened - or, if they do, they're keeping quiet. It's unfortunate from a production point of view that a lot of time and code was wasted, but it's worse that a potential team member who had been trained (partially) on our workflow pipeline has been lost.
The Newbie Problem
This introduces a difficult question. Let's say we have a team of programmers, all of whom have an average skill level of X. Then a new guy joins up, with a skill level of Y, where Y is significantly lower than X.
It seems at first glance that no matter what J. Random Newbie does, the team suffers as a result. If he works on critical technology, chances are it will fail because it isn't up to the team's standards. If he works on something low priority, chances are it will crop up as a hidden cost when the item becomes high priority at some point in the future - and these surprises can bite you hard.
My personal opinion is that the only way to really do this is to let Mr. Newbie observe for a while, almost like a pair programming arrangement. Assign him to rotate between existing coders, and have them explain what they do, how and why they make their decisions, and so on.
It may seem like an annoyance and a drag on the veterans, but in my estimation, it will pay off immensely, for three reasons. First, the veteran's work is subjected to scrutiny - both his own and J. Random's - which is likely to increase its quality. Secondly, chances are the veteran would have to give up some time to slow his pace down and meet Mr. Newbie on his own level anyways; for example, if Newbie does Random Module Z, Veteran will have to integrate with Z at some point, and likely discover all kinds of things that need to be fixed or improved.
The third point, though, is the one I feel is most important: mentoring newbies in this manner creates veterans much faster than the old "sink or swim" method. It reduces turnover. It decreases stress, because everyone expects the training to be going on - it's all too easy for veterans to just expect the new guys to be up to speed, and get frustrated when that is not the case. Last, but definitely not least, it raises the overall quality of your code.
I'm not really in a position to institute this kind of policy at Egosoft, nor do we currently really have anyone who could realistically be put into a apprentice-type position; but next time the situation arises, I'm definitely going to be putting forward an argument for it.
I've worked almost solid since 6:30 this morning until now (about 1:30 AM), minus a couple of hours for meals and a brief nap. It's starting to take its toll on my motivation, but not my mental energy. That's a really good sign.
This is the first really strenuous push I've made at work in a very long time. It's refreshing to be back at a point where I can sprint when I need to. Time will tell if I end up crashing and burning afterwards, but so far none of the signs of a typical manic buildup/crash are manifesting. Of course, that might just be because I'm on so many drugs that all the symptoms are utterly masked.
In any case, it looks like I'm finally coming out of the long tunnel of bipolar disorder and starting to regain some semblance of normal functional life. Just don't judge my state of dysfunction by looking at my apartment - it's a wreck.
1 - Yes, Krystals. We don't get the Holy White Castle here in Atlanta, and although Krystal is a very distant - nigh-on-blasphemous - second place, it suffices to satisfy the occasional urgent crave. This is especially true during crunch time.