HomeNewsFeaturesLicensingDownloadsScreenshotsFAQRoadmap Contact Us
Search:
3 Online

Community

Discussion Topics Recent Postings User Contributions General Articles Example Documentation Credits

Licensed Developer

Programmer's Manual Artists Manual Tutorials and Articles

Programming: Game Code

Game Code Overview Server Side Game Code Client Side Game Code

Programming: System

Alphabetical Function List Renderer File System Collision & Ray Casting Low Level Audio Game Audio The Console Console Variable List Multiplayer Localisation Maths Library Memory Manager Model File Formats Texture Formats

Art: Overviews

Specifications Shaders Particle Systems Lens Flares Cipher console Cipher file types Tutorials Reference

Art: Tools

Shader Designer Particle Designer 3dsmax tools Model Conversion Font Generator

Cipher Engine
Game Development Search Engine
GameDev.net
You are not signed in - [sign in] [register]

Why does everything have to be so complicated?

Have you ever noticed that most things are far more complicated than they need to be? Programmers are often some of the worst offenders at making things more complicated than they need to be (or maybe it is just effects me more when they do it). They seem to have powerful ways of making tasks harder to do, longer to do or more error prone to do. Why? Who knows, but here are some clear signs that it is happening to you.

"We could do a system"

Do I ever panic when I hear that phase. This is the first step in making a simple task into a more complex one. It does this by trying to provide solutions to problems that do not exist in the first place. If you work in C++, classes with the word "Manager" in them are also a sure fire way of spotting trouble.

The System Builder will tell you "Think of the benefits, for only 5 times the work, it will also work in this other situation I just made up". You may try to reason with them that the other situation is not one that we need a solution for at this point in time, but they just tell you how much time you will save in the future when it does happen.

Experience has shown me that it saves no time at all. When the future finally gets around to happening and a new situation crops up, it is invariably not the same as the one the System Builder planned for. Even if it is almost identical, that code will need a load of maintenance to get it working as it should. In the meantime, we have to deal with a complicated solution to our simple problem. All that extra complexity comes at a cost. First, and most obviously, it takes longer to create, so our product is delayed a little. The costs just keep on coming though. Testing is harder now, as we have a more complex code base, with more code paths to test. When bugs are found in the new system, they take longer to track down and are harder to fix because there are more places where things could have gone wrong. The programmers that have to call this new system often suffer as well. The new system may need to be more abstract or have more entry points in order to support its new features, making it harder and fiddlier to use.

I strongly believe in building software that is as simple as it could possibly be. Don't write code that you don't need. Sure, think about how your code will be used in the future and try and design a solution that will take you into the future, but only actually implement the parts of it that you need today. After all, you may get away with never having to add the other stuff. If you do have to add additional features, you will be adding them when you know exactly what they need to do, instead of having to guess now. Cipher (the game engine that I am responsible for building and maintaining) takes this to heart, and as a result it takes only 15 seconds to compile (I kid you not). It compares well to the previous project I worked on, which took about 1 hour to compile. Cipher is also very easy to maintain and extend and is very very fast. I generally don't have any active bugs in the bug database, and when I do, they are usually very easy to find and fix (which is why I am normally able to keep the database so empty).

Bad architects result in bad buildings

The other problem of course is that most programmers aren't very good. I was going to say that most programmers aren't very good at designing high level APIs, but I decided that the shorter version was simpler and more accurate. Designing high level APIs is hard and it is something that most programmers have to do quite often. A badly designed API can make life very complicated for a lot of people.

A good API needs to satisfy a couple of criteria as far as I am concerned.

  1. It has to be simple to use and understand.
  2. It has to make it very hard for the programmer to use incorrectly.

When I started at Bullfrog (before Electronic Arts took it over) I took over the development of the library that was used by all of Bullfrog's games and asked to make it work with the recently released Windows 95 as well. This library had been extended and extended again, and was up to version 6 when I got it. By this point there were about 50 functions for manipulating files (opening files, reading data from files etc). Most of the functions were obviously pretty redundant; some existed for compatibility with old games and some just provided default arguments to other functions. If you wanted to open a file and read some data from it, it took a fair bit of effort to figure out how. This API clearly broke my first rule and I spent more time than I should have spent trying to port this lot to Windows 95. Getting it all to behave the same as the DOS version was not always obvious or easy, as there were so many subtle side effects in a lot of the functions. In the end I tossed a load of it out and things started to get a lot simpler to work with after that. In Cipher, there are only 4 functions for accessing files.

If you are looking for a classic example of an API that breaks rule 2, you need look no further than Microsoft's DirectX API (A set of interfaces for building games for Windows and the Xbox). Every function in the API can fail for more reasons than you can shake a stick at. You have to be careful not to use some functions if other functions return certain values. It is easy to create hundreds of memory and resource leaks if your not too clear what you are doing. Basically, it is a minefield. To be fair to it, the last couple of releases have really tackled these problems and the latest release (8.1 at the time of writing) is greatly improved and far more pleasant to work with.

Advanced Compiler Features

Fear exciting new features in your favourite programming language. They generally just make things harder to understand without offering any real benefit in return. My current least favourite feature of C++ is templates. Sure, they let you do some amazing things that just were not possible without them, but for the most part they are just pure evil, designed to make code unreadable by human beings (and to be honest, most C++ compilers as well).

On one of the mailing lists I subscribe to, other developers are frequently trying to out-complicate each other. An ideal post will contain an example that will do something useful sounding (but not actually useful), but no one on the list will be able to work out how it does it. Debugging this kind of stuff must be hell on earth. I wouldn't know though, as I will avoid using them until someone can show me something useful that is easy to work with. To date, stl is the only template based piece of code that remotely borders on acceptable; though debugging this is still a nightmare and using it kills you build times.

Real Programmers just use 1's and 0's

People do like to compete. It may start with "My dad's bigger than yours", progress to "My car is redder and has a higher specular exponent than yours" and end up as "Only a genius like me is capable of understanding the complexities of this computer program". This kind of macho "showing off" produces a lot of very complicated solutions to simple problems. If other programmers look at your code and say "Is that it? I could have done that!", then you must be doing something right in my opinion. The reality is that they probably couldn't have done it. They would have made it far too complicated.

User Contributed Comments

mohaps 31st July, 2003 17:45
The F Word
====================

corollary to the case 1:

I hate the F word... Frameworks I mean... every time i have been handed some code which is "a generic extensible frameowrk" , I have had to spend nights and weekends just trying to debug a particular issue or else (shiver) trying to extend the "F"ramework.. :(

my rule of thumb..get at least three implementations going as stand alone executables...before you even think about the "f" word...


mmelo 9th August, 2003 01:06
Hey!

I don't know who was the original poster of this article, but I guess we probably bumped into each other at some point! I worked for EA UK dev from 95 to 97, and even moved down to Guildford for a while - so we might have met at some stage!

(Great article, BTW)

Miguel




Register and Sign In to discuss this article