Sunday, July 16, 2006

Reusable Code

I think we should all be quicker to criticise our own code.
I've been working on a lot of core code recently, lots of helper functions and multi-project libraries, during which I have aquired a stronger nose for reuse than I previously had, I can smell possible hinderances to modularity a mile off, and can also spot a flourishng bud of future usability currently hidden beneath a swamp of tight coupling.
I know why I've gained this talent: necessity. I work in a relatively small gdev company, and with our current influx of contracts, it's become imperative that we reuse a lot of the code between projects. Normally, we'd tech design a game quite thoroughly and only then start the coding from a baseline of the helper functions already provided by our inhouse engine. Recently, we copied a project, and bent it to match new design requirements and art content. No thought went into the design, we just copied it. That felt wrong.

These games we are working on are all multi-platform, so all in all, I'm currently in charge of 8 different publishable products (on 3 different platforms, with 4 different gameplay codebases), an editor, 2 research and development projects, and all the people (not just the coders) who are working on them. Ok, so I currently command the largest team in our office. It makes sense that we have, overall, the most work to do, but sometimes it feels like there is just too much to do. As a saviour to my own sanity, in stepped my pragmatic gland and I went code weaving (my term for very high level refactoring). We've suddenly increased from each game including one library (the engine), to an average of three libraries (standard helpers, and another semi-specific library on top of the existing engine). We have moved from source safe (ugh) to subversion for our content and source control (which makes my life easier, as I can stop what i'm doing and help out easier due to the amazing branching capabilities). We started ripping up the games we had running, breaking them into component pieces, rebuilding the pieces as reusable libraries, and reinjecting them back into the games. This approach has given us the ability to drop in whole wodges of tested game code (one sony approved TRC compliant module of code is worth ten in the presub) and not worry about backlashes and being dragged kicking and screaming back to months old code that has just shown up a bug that you can't remember how you fixed it for product "3c"... but its imperative that it is fixed for "5b"


So, looking back on how we originally approached this recent spate of tasks, I'd say we were hasty in getting the first one done - which might have been why it took so long to do ;)
We should have built up libraries of reusable code (like the ones we are building now from the remnants of the first two games), and the bugs would have been easier to clear out as they would not have happened twice (bugs fixes from the first game accidentally did not get applied to the second).
So, with my new eye for modularity, reusability, and possibility, I see less and less work for us code guys on the horizon, and more and more work for our artists and designers, which to me means we're finally doing something right. Shouldn't we all be writing tools, algorithms, and architectural code?
We should not, at this stage, still be developing options menus, memory card handling routines, controller handlers and state machines. We should be developing tools for our designers and artists so that have more autonomy.

We optimised our build times from 5 minutes down to 30 seconds recently (a combination of pch and #include "*.cpp" module compile files), so why are we not optimising the turn around for our artists and designers? They need quick feedback too.