Tuesday, 19 January 2010

Designing things very carefully.

The Complex System:

We all know that software architecture is important in large projects. We've all envisioned systems to help us maintain larger and larger complex problems with less user or developer input. Scripting systems, shader building tools, data-driven editors, and many other cool things that would take a long time to write properly, but when they're done they're a great benefit to everyone that uses them.

Except half finished, they're worse than useless.

I work in games, and games are highly complex systems of interactions. Games would take forever to write if they were written correctly with all the great and clever architecture they should have, so producers push for a minimum feature set, veto the clever architecture and demand a simpler approach to the solution.

Later on in the project, usually about half way through to maybe three quarters, the project starts to slow down due to growing complexity and difficulty separating sections of code from each other. When production asks why it is, often the coders will say that it's because the way it's written is wrong, it needed more abstraction or better architecture, or just more time spent on the design stage, and less time on just getting features in.

The bad programmers say "oh, noes, we should have designed it betterer from the beginning. We told you that we should have written all the code that was only marginally likely to be necessary, but would have been fun to write and figure out."

However, the good coders would note that only small proportion of the code that they would have written, is now necessary. They will be note the time saved by writing code that does the job rather than over-architected super-code that could do anything, and breath a sigh of relief that all they have to do is one month of overtime getting the final features in place, rather than a year of overtime getting the "correct way to do it" code working at all.

In fact, when I've been on over-engineered projects, the one thing that has come to bite us more than anything else has been the inability to refactor the code because it is too complex or too clever for a single human to understand.

Complexity When Necessary:

There's a big difference between sloppy coding and coding to requirements, but it seems that the longer I spend in software engineering, the more I find people thinking that they are the same thing. I realise that a lot of people architect away because they think reuse is good and encapsulation and data hiding this that and the other, but we don't actually reuse a lot of our code because it's usually game specific, genre specific, platform specific. The stuff that isn't, is usually our "we brewed our own because we didn't trust 3rd party software", or just generally us reinventing the wheel for small sections of module specific code. If you're lucky, you'll get a series of games that just need new art, that's real code reuse, never need to actually do more than change some constants and recompile for a new game. If you think you can write reusable code, they why haven't you released it as a library (whether for sale, or for free)?

Tell me that it's really important to write a fully data driven engine to power your next game, and I'll remind you that your consoles and PCs already have a powerful and fast, data-driven, flexible, ready-for-anything fully-supported easily-debuggable and profilable, and generally very well documented system. The system is C/C++. Why don't you write some game in it?


wererogue said...

Then again, at every games company I've worked at except Broadsword (I realise that's a small, exclusive set) I've seen excellent examples of how designing an extensible, non-game-specific engine can save massive amounts of time when it comes to actually cranking out a game. So there's that.

fabs(); said...

But at every games company you've worked at (other than Broadsword), you've only seen examples of how a large company designs a game engine capable of carrying the expected complexity of the games they're developing, not some blue-sky technology parade engine. And even then, I'm sure you'll be able to point out a few elements of even those engines that are "done, but not strictly seful"

wererogue said...

Actually, generally what happens is that the technology that applies to every game (renderers, memory allocators etc.) gets polished and becomes a product, maybe even part of an "engine" (which may or may not contain scene editors, memory debuggers and other generic tools,) while the bits that change a lot (asset pipeline, character control) don't. You still save a lot of time on a new project, by not rewriting the bits that almost always have the same requirements.