Doolwind's Game Coding Standard

For some time now I’ve been asked by a few people to write up my thoughts on a coding standard. To me, coding standards are like source control, until you use them you don’t realise just how awesome they are. Coding standards are a requirement for large software teams, however even if you are working alone I’d recommend adopting at least a simple coding standard.Keeping code consistent and readable is helpful when reading other people’s code as well as when reading your own code weeks or months are it was written. In effect a coding standard is trading development time for maintainability time. I’ve found that the ratio of dev time to maintenance time grows from 1:1 on a small project to something approaching 1:∞ on larger projects.
I’d like to formally thank Greg for showing me the light on a lot of these points. I’ve spoken previously about pair programming and just generally mixing the experience level of developers to help the younger ones. I think that these kinds of relationships are invaluable for making great programmer as it’s something that you just can’t pick up from textbooks or coding by yourself.
As always, please add your thoughts and complaints. I think that just talking about these issues is a good step in growing as a software developer, even if everyone doesn’t always agree.
General Tips
1. Be consistent
This is the golden rule with coding standards in any language. Every other rule below is pointless unless there is consistency. If you completely disagree with all of my points below that’s fine, so long as you set out a standard, and everyone conforms to it. The only thing worse than a bad coding standard is not having one or having one that isn’t followed by everyone.
This can be an issue for some programmers as their ego’s get in the way however it’s vitally important that everyone follows the standard otherwise it will quickly turn into bedlam. This consistency should ideally cross both the programmer boundary and the project boundary. It will be much harder to have consistency between projects, however if this can be achieved, any programmer within the company can switch projects freely (even if only to assist briefly). This also increases efficiency on new projects when programmers who haven’t worked together already have this coding standard in common.
2. Get everyone involved
To get the best “buy-in” and to reduce friction amongst the team, it’s important to get everyone involved in the discussions. I’d recommend writing up the standard once “complete” and passing it around as the first draft. Giving people plenty of time to comment also gives leaders more ammunition when enforcing the standard. If people can voice their thoughts on the subject they are more likely to follow the standard in the future.
There is always going to be the inevitable ideological disputes where programmers won’t be able to come to a conclusion. There are really two options here:
i. Military style: The highest ranked programmer makes a decision, and everyone follows suit. This may be the only way to solve the most ideological debates but has the side effect of lowering morale.
ii. Politician style: Both sides put their case forward and the entire team (or key members) vote on which to choose.
Specific Tips
3. Curly braces – on the next line
if (condition)
{
}
This is pretty much the standard I’m seeing everyone use these days. There are some strange lecturers and Java programmers that keep the brace on the same line, but otherwise most people seem to have unofficially agreed to this. This has the added advantage of allowing the condition to be commented out quickly (using //)
Negative: It takes up less space having it on the same line.
Response: It makes code far more readable, and white space is free and should be used.
4. Always put curly braces in
The main reason for this is that it reduces errors in code such as a macro hiding the fact its multiple statements. The secondary reason is for maintainability. If the single statement becomes multiple statements it takes longer to update, and can lead to errors if people miss adding the braces.
Negative: It saves time to leave braces out.
Response: Saving time at the expense of readability is bad. If all conditions/loops have braces then the source will be far more consistent.
Negative: It takes up less space without braces and more code can fit on the screen.
Response: Fitting more code on screen is not as important as having error free, maintainable code. As desktop resolutions increase this argument holds even less weight.
5. Prefix members and arguments
class MyClass
{
int m_myInt;
};
void MyFunction( int a_myParam )
{
}
Firstly, adding these prefixes is NOT Hungarian notation. Rather than describing the type of a variable adding these prefixes gives context about what the variable is. This context is the key reason for adding prefixes. Prefixes make it easier to build a map in your mind of what the code is doing as you can quickly tell what variables are arguments/parameters, which are members and which are simply local variables. You can also add g_ to globals, however I’d be advocating the use of globals then J.
If m_ and a_ are too verbose then the alternative is simply appending m and a.
void MyFunction( int aMyParam )
{
}
Personally, I prefer the full prefix (m_) as it makes the code more readable, and it follows the convention of the first character of the variable name being lower case.
Negative: With modern IDE’s you can mouse over variables to get extra information
Response: Mousing over is slower than simply perusing code. The information given is usually just the type which doesn’t give context, it only gives further information.
Negative: It takes too long
Response: Again, readability is more important than saving a few seconds on typing
Negative: Underscore is hard to type
Response: Once you’ve been using it for a while it becomes quite natural. Also with tools like visual assist the underscore can automatically be added in for you.
6. Put modifiers (* and &) next to variable type rather than variable name
MyClass* myVariable;
This point actually goes against what I am seeing most people using in their coding standards at the moment. It also goes against what I was taught at university (whether that’s bad or not I don’t know). Before you dismiss it though, I recommend you actually sit and think about the alternatives and why you would use them. The modifier (pointers or reference) is modifying the type of the variable and therefore it should be placed next to the type itself. The negative to this is one I gave when first taught this, however after thinking about it I realised the error of my ways.
Negative: The modifier should go next to the variable name as it is misleading if you declare multiple variables per line. In the example below, the first variable is a pointer and the second is not, this is misleading.
MyClass* myPointerVariable, myNonPointerVariable;
Response: Declaring multiple variables on one line is really the exception to the rule. Should you be making a decision about based on the exception or the rule? If there are any modifiers like this, don’t declare them on the same line. The worst issue here is a bit of extra typing and more screen real-estate being used up, neither of which should be an issue. Having the pointer next to the variable name makes it harder to reader when skimming over code, particularly if there are a number of spaces (or tabs) between the type and name.
7. Create const on functions and function arguments where appropriate
Const correctness for variables is a bit like cleaning your teeth. It’s annoying to do, but everyone agrees that you should do it. There are three main benefits:
i. More descriptive code. A quick look at a function tells you whether it changes the state of an object, and whether it changes the state of any variables passed in.
ii. Faster code. Giving the compiler more information about constness allows it to optimize your code.
iii. Less errors. If a function or argument is const then anyone changing the function will get compile time errors if they do something the function was never intended to do.
8. Conditions/Loops should have a space after them
if (myVar)
{
}
This is the most readable way of writing conditional and loop statements I’ve seen. I personally recommend this usage, however the main reason for this point is to get you thinking about how it should be done. If you disagree, that’s fine, just make sure you remember point #1 and decide how you want your code to look and keep it consistent.
9. Camel case variables, capitalize classes and functions and full capitalize constants
I’ll finish up with an easy one. Most people agree with this standard but I thought I’d list it anyone. The best way to show this is with examples:
Variable:
int myVariableName; // camel case
Class and functions:
class MyClassName {} ; // camel case with capital first
void MyFunctionName();
Constants:
const int MY_CONSTANT_NAME = 5;
Feed
Subscribe By Email
Twitter
I was always a big proponent of 4 (Always put curly braces in), but I was also a proponent of late-return. for example, compare the following. I personally believe that the latter is much clearer (and even that it’s clearer without the extra braces:
bool CheckStuff(int a_withThis, string a_andThat)
{
if (NULL != a_andThat)
{
if (0 != a_withThis)
{
DoStuff(a_withThis, a_andThat);
return true;
}
}
return false;
}
bool CheckStuff(int a_withThis, string a_andThat)
{
if (NULL == a_andThat)
return false;
if (0 == a_withThis)
return false;
DoStuff(a_withThis, a_andThat);
return true;
}
All that said, it’s of course not the point. the point is to have some form of consistency in order to make all programmers feel at home, and hence more productive on a project.
I guess my problems with standards in general are that often the standard standardises the wrong things at the expense of quality, maintainability or old-skool creativity. Just because the standard is to have coversheets on our TPS reports doesn’t necessarily mean that it makes the team more productive. Striking a good balance is fundamental.
Great article, Alistair! I agree with most of this, however I have some comments:
Like Drew, I find his second example easier to read and I’m more used to doing it that way.
I also have a comment about always placing extra braces: If I need extra braces because I’m adding more statements, I’ll add them. If I remove a bunch of code and just have one statement, I’ll remove the braces.
Obviously that doesn’t follow the braces everywhere idea, but for some reason I find it more readable. I don’t think I’ve ever had a problem because I added a single brace and not the ending brace, but that could be because Visual Assist inserts the ending brace anyway.
Point 5 you kinda contradict yourself. First of all you say “Mousing over is slower than perusing code” as though speed is an issue when discovering information, yet in the next negative/positive you say “readability is more important than saving a few seconds typing”. So which is more important, speed or readability?
I actually use mousing over or just clicking on the variable when I need to discover a variable’s type as Visual Assist helps out yet again showing the declaration in the same window, instead of having to find out where it’s declared. Of course this is rarely used so I would hardly call it a slow down as most of my time is spent coding something, not perusing code. Obviously it depends on your current task in the team at the time. This is another angle for using the mouse/clicking though, than the ones you raised.
Cliff
Ahh coding standards, always a point of contention amongst programmers. ^_^ I largely agree with what you’ve outlined though. Coming from a Java developer background (which tends to adopt curly braces on the same line) and having started using C# in Visual studio (which puts curly braces on a new line), I have to agree that having a new line for brackets is very much more readable. When discussing this with Greg at some point, he explained that it also enhances your ability to bracket match when seeing where a block starts and ends which is very handy I’ve found and speeds up development.
With point 4, regarding always having braces, and in response to the comments already about it, I’d like to say that there seems to be a point missed with always blocking a statement, even with only one line. The problem is that a new developer, or even an old one who is coming back to it, will not always pick up that there is no curly brace, especially if they personally prefer to add them for one line statements. This means they end up coding after the open statement (eg. if (condition) ) on the assumption their code is in a block and won’t realise until compile time (or errors start appearing in the error checker).
The problem with coding standards is that we learn them too late. By the time kids get to university or the workplace, most have made their own coding standard that is terrible. And with the prolification of terribly-formatted code snippets across the internet, it’s hard to know where to turn for good help. And suddenly, “I’ll do it my way and you can do it your way – as long as the code works.” And then you have a bad programmer that you have to fire just because they won’t put curly braces in the right spot.
Thank goodness that Doolwind’s Game Coding Journal can help us through these murky waters with a welcome and refreshing clarity.
Most of these are good points, though 6 & 8 are getting into the ‘just shutup and let me code’ category. I have my personal preference for these, as does everyone, and generally these preferences all differ.
I honestly don’t think these affect the speed with which a programmer reads code. For the record, I disagree with 6 but agree with 8.
what i find annoying is when you are working with a large 3rd party code base such as unreal or something that has terrible (in my opinion) coding standard and you are kind of obligated to follow at least some of their standards. I’m not sure, what do other people do in with this?
For the record I use the same standards as Doolwind, except no a_ for function arguments. I personally find that a bit too anal for me.
Also I think where comments are place is important too, but that’s another kettle of fish.
cowlibob-
Great point about using 3rd party code. I would make a judgment call based on the surface area between your code and the engine. If you are simply making calls to an API or similar then I’d keep my own standard however if the code is quite a mix (as I believe is the case with Unreal) then it’d be best to look at adopting their standard to keep things consistent.
Cliff-
“Point 5 you kinda contradict yourself. First of all you say “Mousing over is slower than perusing code” as though speed is an issue when discovering information, yet in the next negative/positive you say “readability is more important than saving a few seconds typing”. So which is more important, speed or readability?”
Readability is more important in both cases. In point 5 I believe prefixes make for both more readable and therefore it’s faster to read it
.
The main reason for the mouse over comment was that a number of people have used that as a counter to Hungarian notation (which they are correct about) and to prefixing members and arguments (which I believe they are incorrect about).
I agree with James that 6 & 8 are a waste of time in a standard. As long as everything is named correctly, an auto-formatter can take care of spaces (and even braces if need be).
We recently had a huge discussion thread at work where people were arguing over point 6. (I fall in the “I don’t care – the code looks the same either way” camp. My brain has a limited register set and don’t want to waste registers by keeping little rules like this in working memory.)
I love it. I’ve been coding C++ for a little more then a year now, at this lovely university in the Netherlands in Breda, and haven’t really picked a standard yet myself, because I’m usually working with others that have picked one out for me (I’m pretty flexible in that way at this point). I’m trying to become a game developer and going to work on my own (basic) game engine this week for future (school) projects, so this can really come in handy.
Modern IDE’s have auto reformatting options so that no matter how ugly you write your code it can automatically be cleaned up to the defined standard.
Literally, LOL.