Welcome to the final part in A Premortem: Lessons Learned So Far. If you haven’t read part 1 or part 2, you might want to do that now.
I’m reaching the bottom of my list of lessons, so there’s not going to be much of a theme in today’s collection; instead, it’s going to be the odds-and-ends that I wanted to talk about, but couldn’t fit into the two earlier articles. Without further ado, let’s get started.
NIH syndrome, or not invented here syndrome is the fear of using something which you – or your social or corporate circles – did not create. This is a very common disorder amongst programmers, and at the start of Hegemony, Rob and I were both afflicted.
As an example, I’ve written a lot of library code for Hegemony. If you’re not sure what I mean by “library code”, I’m mostly talking about back-end stuff which isn’t directly related to game development, but which is still necessary to get things done. This is normally things you don’t think about when you think about game programming, like parsing XML, or converting a number into a textual form.
While I was working on this library code, I wrote a lot of little data structures, smart pointers, callback wrappers; all sorts of programmy things. Lots of this work was inspired by what’s available in Boost, a collection of C++ libraries written by – among others – members of the C++ standard committee.
So why did I write my own code when Boost had already provided a perfectly good solution? Well, most of these libraries were relatively simple – or at least they started out that way – so it seemed like it would be easier to just write my own version than to explain why it was necessary to add an extra dependency.
Inevitably, over time these libraries required more features, more bug fixes, and more documentation, until I realized that I had spent quite a bit of time on them. Eventually I gave in and added Boost as a dependency, and it turns out my fear of explaining myself was unfounded. Nowadays we use Boost so often that I wish I had done it earlier. I’m so impressed with it, that I would suggest any programmer install Boost and begin using it as freely as they use the standard C++ libraries.
Of course, you need to be a little careful before you decide to use third-party software instead of creating your own. For instance, we created our own XML parser (if you’re not sure what XML is, right-click on this page and select ‘View Source’ – webpages are written in a form of XML) and to our parser we’ve added support for Fast Infoset, a much more efficient alternative to XML that remains completely compatible with XML. This is a form of binary XML which is a somewhat controversial topic amongst programmers, but for us it’s really cool because it means we get high performance, but we can still convert our files into human-readable form when we need to.
Adding this sort of feature to an existing XML library would have been difficult, so in this instance, rolling our own solution was a win. The lesson here is not to be shy about third-party code, but to remember that it’s not panacea.
Another form of NIH we suffered from was an initial resistance to collaboration. When we started Hegemony, we planned to do everything ourselves, but after some prodding, the guys over at Shinnyo Interactive Audio convinced us to hire them to do our sound (watch our foley field trip here). Later, Dana DiAnda of Cannibal Island Studios convinced us to hire him to write and record the score for our interactive music system, which you can get a taste of in our PAX trailer.
It took us a while to agree to work with these guys. We were hesitant because we had worked with people outside the company before, and we got burned. There was also a sort of pride we felt by saying that everything in the game was made by us.
In the end, though, we’re glad they pushed us, because their work is outstanding, and it adds a lot to the experience in Hegemony. Hopefully we’ll get a chance to work with them again in the future. We’ll still be careful about who we work with, but now that we’ve seen what collaboration is like when it works well, we’ll be much less worried about doing it again in the future.
Don’t Talk About Release Dates
As Shiguru Miyamoto wisely said, “A delayed game is eventually good, a bad game is bad forever.” We’ve learned to plan for the fact that we might have to delay our games, so it’s not a good idea to tell anybody our launch date predictions, because if we’re wrong (and if you pay any attention to launch dates, you’ll know that developers are often wrong) it can be rather embarrassing.
I’d like to talk some more about this, but if I do that then it proves that I haven’t actually learned my lesson. Instead, I’m going to distract you with a picture of a squirrel. Look over there!
So you’re a independent video game developer, and you’d like to try something innovative, but you’re strapped for cash? Congratulations, you’ve just discovered the status quo of indie development. But not to fret! There’s government programs around to help people like you.
You should do some research on the initiatives your government has to offer. Here in Ontario, Canada there’s a number of different funds and tax credits you can apply for if you’re a small company working on something artistic or technical. They haven’t all been helpful, but a couple of them have been indispensable.
Researching this stuff and going through the application processes is boring work, but it helps pay the bills, so don’t skimp on this step.
ROI stands for return on investment. In economics this is a term used to discuss profit calculations, but in software development it’s used to compare the amount of effort it takes to add a new feature against the amount of benefit that the feature actually offers. In bigger companies than ours, PHBs will actually try to estimate how many man-months it will take to implement a feature and compare that to their estimate of how many more sales the new feature will bring in.
If it sounds like I’m talking about this process disparagingly, it’s because some companies take it too far. This is the sort of mind set that causes a company to release the same sports game year after year with nothing but new rosters and a new celebrity on the cover-art.
But the concept of ROI isn’t entirely without merit. Let me give you an example: the code we have for our controls used to be atrocious. This is a natural part of programming and was no fault of our own; you start out with a good design, but nobody’s precognitive, so over time you add new requirements to the design and it starts to get quite messy.
In our case, we ended up with a number of problems; the way the controls interacted with different parts of the GUI wasn’t well-defined, simple things like double-clicks were awkward to implement, it was impossible to allow a player to change their controls, we couldn’t support joypads, and we couldn’t change the behaviour of our controls without shotgun surgery. There were only two solutions:
a) Leave it as it was and work around the warts, or
b) Clean up the code (a process called ‘refactoring’), rewriting the parts that were irredeemable.
A purist would tell you that (b) is the only option, while many schedule-oriented managers would prefer (a), citing “if it ain’t broke, don’t fix it.” Let’s try to take a pragmatic look at the problem.
What it all boils down to is whether you want to save time now, or save more time at some point in the future. If you take ugly code and try to work around it, you’ll probably get results faster, but you’re going to make your framework more difficult to use, more difficult to add features to, more susceptible to bugs, and more difficult to debug; all of which add more time to development further down the line. If you refactor the code, you’ll end up saving time in the long-run, but the point where those savings pay for themselves may be a very long time in the future. Sometimes it’s more important to focus on what will save you time today.
Well, I was fresh out of college and still living in an ivory tower, so I chose to refactor the code. I expected the process to take a few weeks. At this point I should have been suspicious, because as Evan Weaver, one of my college professors, had once said, “Programmers think they can do anything in three weeks.”
The process took me months.
Mind you, I’m pretty happy with the end result; I added all the features I had hoped for, it’s much easier to modify the code, and in the process of refactoring I also got a chance to clean up our GUI code, which had also been languishing. But it took me a long time, with little visible benefit. I think it will eventually pay for itself in the time we’ll save, but I don’t think we’ve seen that point yet. In fact, I don’t think we’ll see it until some time during our next project.
In retrospect, some of that refactoring certainly had to be done. But refactoring to support joypads or configurable controls is something that could have waited, and we probably could have lived with some of the warts, at least for a while.
That’s it for our three-part series on the lessons we’ve learned so far. Like I said at the start of the series, none of this has been proven correct yet, and we won’t know if I’m really right about any of these things until after Hegemony releases. It will certainly be interesting to take a look back on these articles after we write a real postmortem to see how far off the mark I am.