picture by ramotion
1. Lack of Comments
“Real programmers don’t write comments. If it was hard to write, it should be hard to read and harder still to modify.” is NOT an acceptable philosophy, especially if you’re working on a team with other engineers or programmers. Write comments in your code, lots of them, explain what you’re doing, what you’re expecting to happen, especially in parts of the code that may be tricky or difficult to follow.
2. Lack of Whitespace
Making your code as dense as possible doesn’t make it run faster, it just makes it unreadable and unmaintainable for the poor guy who has to clean up your mess once you’ve been fired.
Bad:
for(int i=0;i<IsEnabled()&&(CRenderer::Get().GetLight(i)->GetFlags()&0xFF00FFFF)&&!gLightsDisabled&&whatever...) CRenderer::Get().GetLight(i)->SetProperty( etc.... )
Although the above isn’t real code, it’s based on code I’ve had the (dis)pleasure of working with.
3. Operator Precedence
You may be some amazingly “l33t” programmer (or most likely, just think you are), but not everyone who follows you is going to be. Not everyone has the C++ standard for operator precedence memorized, so make it easy on your fellow programmers and put in a few extra parenthesis. Who knows, it might even prevent you from making a few mistakes as well.
4. Poor Variable/Function Names
This continues in the vein of making things easier for yourself, your colleagues, and anybody who ends up maintaining your code later. Short, non-descriptive, or just downright silly names aren’t acceptable in production code because they don’t allow anybody to, at a glance, understand your code. They don’t make it easier for someone who’s seeing the code for the first time to figure what it’s doing.
int foo;
struct {
int a, b, c;
static void fn( void* );
} _d = { foo1, boo, floop };
async::Spawn( &_d );
This is based loosely on actual production code I’ve had to work with. I probably wasted a week more than necessary on the task, since I spent so much time deciphering this hack’s steaming pile of “code”.
5. NMH Syndrome – (Not Made Here Syndrome).
Something game developers suffer from particularly badly is the belief that, since they didn’t write it, it couldn’t possibly be useful. Unless you have a very good reason to (ie. learning purposes), just use the standard libraries. These libraries have been fire-tested by god knows how many thousands of programmers around the world for years, whereas your personal container library is probably teeming with bugs.
I worked with a programmer once who insisted on replaced std::vector with his own vector implementation, which internally was a singly-linked list. You can imagine that using the [] operator wasn’t exactly O(1). Not to mention the horrible memory fragmentation, etc…
6. Premature Optimization
This issue is hotly contested among programmers, with many ardent followers in both the for and against camps. I’m part of the “against” camp, in that I don’t believe in putting a huge amount of effort into optimizations until later in the project. The mistake newbies make often is over-optimizing chunks of code that are never, or rarely, called and will never show up in a profiler.
Here’s an example of a programmer who strongly believes in optimizations throughout the project (http://www.gamasutra.com/view/feature/6426/sponsored_feature_programming_.php?page=3), but as you can see from the article he’s made some fundamental mistakes when he went to optimize. A proper approach to optimization would take an entire series of articles to write, but we can spot his first mistake here: “I fired up the profiler and … there it was! A big hot spot. I optimized it,…..” Your first job as an optimizer is to understand the highest levels of the program, the overall flow, where data is going, how often functions are called, etc… It’s a newbie mistake to fire up the profiler and simply try to stamp out the hotspots. The fastest code is code that isn’t called, so start with algorithmic analysis at the highest levels of your code.
7. Graceful Failure
This doesn’t need much explanation, your code should be resistant to failure, and even better, provide you with information about errors which do occur. Crashing out is not an acceptable method of detecting errors.
8. Excessive Macros
Macro’s suck, period. Arguments to macro’s aren’t type checked, while inline functions are. Arguments to macro’s can be evaluated multiple times, whereas they’re only evaluated once for inline functions. You can step into an inline function (in debug mode), whereas you can’t with a macro. Yes, they have a few good uses, but overall they’re abused far too often. Use inline functions, unless you really really, absolutely must use a macro.
9. Copy/Paste Bugs
If you’re going to copy-paste a chunk of code, might as well move them both to a common function. Why, you might ask? Simple, first off, it’s cleaner. Secondly, you make it a lot easier to fix any bugs that crop up. Recently, I was hunting for a bug that was causing some visual artifacts. Eventually, I traced it down to a piece of code in a shader that had been copy pasted from another shader. The original shader had been fixed, but none of the others had been. If the original programmer had simply moved the code to a common function (which is exactly what I did), this extra bug wouldn’t have existed.
10. Poor Time Estimates
One of the most important skills for new programmers, learn to estimate your time properly. When I first started, a senior developer once told me “Take whatever time you think it’ll take you, and multiply by 2-3.” which has served me fairly well. Don’t be a hero, buffer your time to take into account last minute errors, miscalculations, position of the moon, etc… By Sam.
Other reading : Top 10 Tips For Getting In The Game Industry As A Programmer


