bubbles bubbles bubbles
cornerhomegamesabouthelpcontactcorner corner
logo

Koonsolo Blog

logo

deWiTTERS Tao of Coding

(This article was translated to Serbo-Croatian by Jovana Milutinovich)

This guide describes the coding style that I developed over the years. My style isn’t very widespread. As a matter of fact, I don’t know anyone who comes even close to the weird way I program. But I like it and want to share it with you anyway (you lucky bastard!). I use it for all kinds of programming languages: C, C++, Java, C#, Python,… .

If you just want a quick overview of the style, scroll to the bottom of this page and see how some source code was rewritten to my deWiTTERS Style, this should give you an quick idea of how nice it all looks.

Why a Coding Style?

Every programmer uses some sort of style, some good, some terrible. A coding style can give code a uniform look. It can make algorithms more clear or more complex. There are 2 main reasons for a certain coding style:

  1. Develop clean and readable code, so when someone else has to dig through it, he can pick it up rather quickly. And more important when you get back to some old code you have written a year ago, you don’t start thinking “I can’t remember being that wasted…”.
  2. When working in team, it’s best that everybody uses the same style so the code has a uniform look.

Since I develop most of my code on my own, I don’t have to consider the second reason. And since I am very stuburn, I am not going to take over someone elses style. That’s why my style is completely optimized to produce clean and readable code.

The Basic Rules

I tried to capture the most important aspects of coding style in the following rules.

  1. All should be as understandable as possible.
  2. All should be as readable as possible, except when it would conflict with the previous rule.
  3. All should be as simple as possible, except when it would conflict with the previous rules.

The best way to look at these rules is make everything as simple as possible, unless understandability or readability suffer. Or to quote Albert Einstein:

Make everything as simple as possible, but not simpler.

As a programmer you must always try to respect the above rules, even if you don’t follow my style of coding.

Writing understandable and readable code became possible with the birth of modern programming languages. The days when programming was entirely done in assembly are long past us. Therefore my style tries to be as closely to our natural language as possible. You can almost say my code reads like a book. This is probably also the reason why my code is badly documented. I hardly document at all! I even consider documenting as “bad” (and not in the cool sense of the word). Only when I do something weird I add a comment to explain why. In my humble opinion, comments should never say what your code does, let your code say what it does.

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Martin Fowler

Identifiers

Let’s start with the most important topic of coding style: identifiers. All identifiers and the rest of your code and comments should be written in English. It is not unusual that software projects shift from one person to another, from one company to another one, located at the opposite side of the world. So since you never know where your code is going to be next, write all in English.

Variables

Variable names should be all lowercase with the words separated by underscores. It resembles our natural writing the most and therefore it is the most readable. The underscores just replace the spaces in our normal way of writing. A variable called “RedPushButton” cannot be read as easely and as fast as “red_push_button”, thrust me.

If you want the variables to be understandable, you must give them obvious names. It is clear that variables all represent some kind of “object” or “value”, so name them accordingly. Please don’t waste your time with jkuidsPrefixing vndskaVariables ncqWith ksldjfTheir nmdsadType because it just isn’t understandable or clean. If you have a variable “age” it’s clear that it’s an int or unsigned short. If it is “filename”, well then it must be a string. Easy! Sometimes for some variables it is more understandable if you include the type in it, for example for gui buttons like “play_button” or “cancel_button”.

There are some pre- and postfixes that can increase the readability of your variables. Here follows a list of the most common ones:

is_, has_
Use these for all boolean values so there can be no mistake about their type. It also fits nicely in if statements.
the_
Start all global variables with “the_”, which makes it very clear that there is only one.
_count
Use _count to represent the number of elements. Don’t use plural like “bullets” instead of “bullet_count”, as plural will represent arrays.

Arrays or other variables that represent lists must be written in plural, like enemies, walls and weapons. However, you don’t have to do this for all array types since some arrays don’t really represent a list of items. Some examples of these are “char filename[64]” or “byte buffer[128]“.

Const or Final

Consts or finals must always be written in UPPERCASE, with the words separated by underscores to make them readable, like MAX_CHILDREN, X_PADDING or PI. This use is widespread and should be used to avoid any confusion with normal variables.

You can use MAX and MIN in your constant names to represent value limits.

Types

Types define the classification of variables. It is a rather abstract term, so we cannot use the English language as a reference on how to write them. But we should definitely make an obvious distinction between them and other identifiers. So for types, I use UpperCamelCase. For every class, struct, enum and other things you can put in front of your variable declarations, use UpperCamelCase.

Name your types in such a way that you can use the same name for generic variables, for example:

HelpWindow help_window;
FileHeader file_header;
Weapon weapons[ MAX_WEAPONS ];

Program Flow

if, else if, else

There are a few ways to write if statements. Let’s start with the braces. There are 3 mayor ways to place your braces:

    if(condition)

    if (condition)

    if( condition )

I have never seen an English text where braces are placed like the first example, so why should we code like that? The words are just not properly separated. The second example puts the braces with the condition instead of the if statement, while the braces are actually part of the if statement and not the condition, so the last example is the best. The last one also has the advantage that one has a better overview over the braces structure.

    if (!((age > 12) && (age < 18)))

    if( !((age > 12) && (age < 18)) )

Personally I would write this code differently, but it’s just to show you an example.

Now what to do with the curled braces? Don’t use them! Unfortunately C, C++, Java or C# don’t allow this, only Python does. So we can’t just drop them, but what we can do is place our braces so it looks like a Python program, simple and clean:

    if( condition ) {
        statements;
    }
    else if( condition ) {
        statements;
    }
    else {
        statements;
    }

When conditions get too long, you’ll have to split the line. Try to split it up before an operator and where conditions are leastly related. Align the next line with the previous one and use indentation to reveal the nested structure. Don’t put the curled brace right behind the condition, but in this case put it on the next line to make the subblock clear.

    if( (current_mayor_version < MIN_MAYOR_VERSION)
        || (current_mayor_version == MIN_MAYOR_VERSION
            && current_minor_version < MIN_MINOR_VERSION) )
    {
        update();
    }

When there is only one statement after the if condition, you can skip the curled braces, but make sure you put the statement on the next line, unless it is a return or a break.

    if( bullet_count == 0 )
        reload();

    if( a < 0 ) return;

while

While loops are written the same as if structures. I use 4 spaces for every indentation.

    while( condition ) {
        statements;
    }

For do-while loops, put the while at the same line as the closing bracket. This way there is no confusion if it is a while at the end or the beginning of a subblock.

    do {
        statements;
    } while( condition )

for

for-loops’ one and only purpose in life is iteration. It’s what they do! for-loops can always be replaced with while-loops, but please don’t do that. When you iterate over some elements, try using ‘for’, and if it really doesn’t work out, use a ‘while’. The ‘for’ structure is pretty straight forward:

    for( int i = 0; i < MAX_ELEMENTS; i++ ) {
        statements;
    }

Use i, j, k, l, m for iterating over numbers and ‘it’ for iterating over objects.

switch

Switch statements have a similar structure to if and while structures. The only thing you have to consider is the extra indentation. Also leave an extra space right behind the break.

    switch( variable ) {
        case 0:
            statements;
            break;

        case 1:
            statements;
            break;

        default:
            break;
    }

Functions

Functions do things, and their name should make this clear. Therefore, always include a verb in it, no exceptions! Use the same naming as with variables, this means all lowercase words separated by underscores. This allows you to make nice little sentences in your code that everyone can understand.

Also make sure the function does what the name says it does, no more, no less. So if you have a function called “load_resources”, make sure it only loads resources and doesn’t do any other init stuff. Sometimes you get tempted by quickly initializing things in the load_resources because you already call it from a higher level, but this will only get you into trouble later. My deWiTTERS Style uses very few comments, so a function should definitely do what it’s name says it does. And when a function returns something, make sure it is clear from it’s name what it returns.

Some functions come in “yin and yang” pairs, and you should be consistent with your naming. Some examples are get/set, add/remove, insert/delete, create/destroy, start/stop, increment/decrement, new/old, begin/end, first/last, up/down, next/prev, open/close, load/save, show/hide, enable/disable, resume/suspend, etc.

Here follows a simple function call. Use a space right after the opening brace and right before the closing brace, just as with if structures. Also leaver a space right after the comma, like done in the English language.

    do_something( with, these, parameters );

When function calls get too long, you’ll have to split it up in several lines. Align the next lines with the previous so the structure gets obvious, and break after the comma.

    HWND hwnd = CreateWindow( "MyWin32App", "Cool application",
                              WS_OVERLAPPEDWINDOW,
                              my_x_pos, my_y_pos,
                              my_width, my_height
                              NULL, NULL, hInstance, NULL );

Definition

Here follows an example of a function definition:

    bool do_something_today( with, these, parameters ) {
        get_up();
        go_to( work, car );
        work();
        go_to( home, car );
        sleep();

        return true;
    }

Make sure your functions don’t get too long. Or to quote Linus:

The maximum length of a function is inversely proportional to the complexity and indentation level of that function. So, if you have a conceptually simple function that is just one long (but simple) case-statement, where you have to do lots of small things for a lot of different cases, it’s ok to have a longer function. However, if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about, you should adhere to the maximum limits all the more closely. Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it’s performance-critical, and it will probably do a better job of it that you would have done).

Classes

For the naming of classes I use the same UpperCamelCase as for types. Don’t bother putting a ‘C’ as a prefix for every class, it’s just a waste of bytes and time.

As for everything, give classes clear and obvious names. So if a class is a child of class “Window”, name it “MainWindow”.

When creating a new class, remember that everything starts from data structures.

Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.

Fred Brooks

Inheritance

“Is a” relationship should be modeled by inheritance, “has a” should be modeled by containment. Make sure you don’t overuse inheritance, it is a great technique, but only when applied properly.

Members

You should definitely make a distinction between members and normal variables. If you don’t do this, you’ll regret it later on. Some possibilities to name them are m_Member or fMember. I prefer to use my_member for non static members and our_member for statics. This way you get nice sentences in you method bodies like

    if( my_help_button.is_pressed() ) {
        our_screen_manager.go_to( HELP_SCREEN );
    }

For the rest everything that applies to variable naming also applies to members. There is one problem that I was unable to fix as of yet, and that is with boolean members. Remember that boolean values must always have “is” or “has” in them. When combining this with “my_” you get crazy stuff like “my_is_old” and “my_has_children”. I haven’t found the perfect solution for this yet, so if you have any suggestions, please leave a comment below this post!

You shouldn’t declare members of a class as public. Sometimes it seems quicker to implement, and therefore better, but oh boy are you wrong (as I was many times before). You should pass through public methods to get to the members of a class.

Methods

Everything that applies to functions also applies to methods, so always include a verb in the name. Make sure you don’t include the name of the class in your method names.

Code Structure

Align similar lines to give your code a better overview, like:

    int object_verts[6][3] = {
        {-100,  0, 100}, {100, 0,  100}, { 100, 0, -100},
        {-100, 11, 100}, (100, 0, -100}, {-100, 0, -100}
    };

    RECT rect;
    rect.left   = x;
    rect.top    = y;
    rect.right  = rect.left  + width;
    rect.bottom = rect.right + height;

Never put multiple statements on the same line unless you have a good reason for it. One or those reason could be that simular lines can be put right after each other for clarity, like:

    if( x & 0xff00 ) { exp -= 16; x >>= 16; }
    if( x & 0x00f0 ) { exp -=  4; x >>=  4; }
    if( x & 0x000c ) { exp -=  2; x >>=  2; }

Related variables of the same type can be declared in a common statement. This makes the code more compact and provides a nicer overview. But never declare unrelated variables in the same statement!

    int x, y;
    int length;

Namespaces, packages

Namespaces or packages should be written in lower case, without any underscores. Use a namespace for every module or layer you write so that the different layers become clear in the code.

Design

When I start a project I don’t do that much upfront design. I just have a global structure in my mind and start coding. Code evolves, whether you like it or not, so give it the chance to evolve.

Evolving code means reworking bad code, and after some programming your code will turn bad. I use following rules to keep a good structure in the code.

  1. When a functions gets too big, divide the problem in some smaller helper functions.
  2. If a class contains too many members and methods, split a part of the class up in a helper class and include the helper class in your main class (don’t use inheritance for this!). Make sure your helper class doesn’t reference or use the main class for anything.
  3. When a module contains too many classes, divide it up into more modules where the higer level module make use of the lower level module.
  4. When you are done implementing a feature or fixing a bug, read over the entire files you have changed to make sure everything is in the most perfect state.

Some projects may become big, very big. A way to cope with this increasing complexity is splitting your project up into different layers. In practice, layers are implemented as namespaces. Lower layers are used by the higher layers. So every layer provides functionality to the above, and the topmost provides functionality to the user.

Files

Files should be named after the class they contain. Don’t put more than one class in a file, so you know where to look when you search a specific class. The directory structure should represent the namespaces.

.h file structure

C or C++ header files show the interface of the implementation. This is crucial knowledge when designing the layout of a .h file. In a class, first define the “public” interface that can be used by other classes, then define all “protected” methods and members. This way the most important information for people using the class is shown first. I don’t use private methods or members so all members are grouped at the bottom of the class declaration. This way you have a quick overview of the contents of the class at the bottom. Group the methods together by their meaning.

    /*
     * license header
     */

    #ifndef NAMESPACE_FILENAME_H
    #define NAMESPACE_FILENAME_H

    #include <std>

    #include "others.h"

    namespace dewitters {

        class SomeClass : public Parent {
            public:
                Constructor();
                ~Destructor();

                void public_methods();

            protected:
                void protected_methods();

                int     my_fist_member;
                double  my_second_member;

                const static int MAX_WIDTH;
        };

        extern SomeClass the_some_class;
    }

    #endif

.java .cs file structure

.java or .cs files don’t provide an interface to the class, they just contain the implementation. Since data structures are more important than algorithms, define your members before your methods. This way when you browse through the code, you have a quick impression of the class through its data members. Simular methods should be grouped together.

Here follows a sketchy overview of a .java or .cs file:

    /*
     * license header
     */
    package com.dewitters.example;

    import standard.modules.*;

    import custom.modules.*;

    class SomeClass extends Parent {
        public final int MAX_WIDTH = 100;

        protected int     my_first_member;
        protected double  my_second_member;

        Constructor() {
        }

        Methods() {
        }
    }

Jokes

Some people like to put little jokes in their code, while others hate this kind of funny stuff. In my opinion you can use them as long as the joke doesn’t interfere with the readability of the code or execution of the program.

deWiTTERS Style vs. others

Here I will present you with some live action code. I stole some code from others and rewrote it to my style. Decide for yourself if my style is better or not. In my opinion you can read faster through my code since it is shorter, and all identifiers are carefully named.

If you think you have seen code that can beat the crap out of my style, leave a comment below this post, and I will write it in the most extraordinary ‘deWiTTERS’ style, and post it here.

Indian Hill C Style

/*
 *	skyblue()
 *
 *	Determine if the sky is blue.
 */

int			/* TRUE or FALSE */
skyblue()

{
	extern int hour;

	if (hour < MORNING || hour > EVENING)
		return(FALSE);	/* black */
	else
		return(TRUE);	/* blue */
}

/*
 *	tail(nodep)
 *
 *	Find the last element in the linked list
 *	pointed to by nodep and return a pointer to it.
 */

NODE *			/* pointer to tail of list */
tail(nodep)

NODE *nodep;		/* pointer to head of list */

{
	register NODE *np;	/* current pointer advances to NULL */
	register NODE *lp;	/* last pointer follows np */

	np = lp = nodep;
	while ((np = np->next) != NULL)
		lp = np;
	return(lp);
}

Rewritten to deWiTTERS Style:

bool sky_is_blue() {
    return the_current_hour >= MORNING && the_current_hour <= EVENING;
}

Node* get_tail( Node* head ) {
    Node* tail;
    tail = NULL;

    Node* it;
    for( it = head; it != NULL; it = it->next ) {
        tail = it;
    }

    return tail;
}

“Commenting Code” from Ryan Campbell

/*
 * Summary:     Determine order of attacks, and process each battle
 * Parameters:  Creature object representing attacker
 *              | Creature object representing defender
 * Return:      Boolean indicating successful fight
 * Author:      Ryan Campbell
 */
function beginBattle(attacker, defender) {
    var isAlive;    // Boolean inidicating life or death after attack
    var teamCount;  // Loop counter

    // Check for pre-emptive strike
    if(defender.agility > attacker.agility) {
        isAlive = defender.attack(attacker);
    }

    // Continue original attack if still alive
    if(isAlive) {
        isAlive = attacker.attack(defender);
    }

    // See if any of the defenders teammates wish to counter attack
    for(teamCount = 0; teamCount < defender.team.length; i++) {
        var teammate = defender.team[teamCount];
        if(teammate.counterAttack = 1) {
            isAlive = teammate.attack(attacker);
        }
    }

    // TODO: Process the logic that handles attacker or defender deaths

    return true;
} // End beginBattle

Rewritten to deWiTTERS Style:

function handle_battle( attacker, defender ) {
    if( defender.agility > attacker.agility ) {
        defender.attack( attacker );
    }

    if( attacker.is_alive() ) {
        attacker.attack( defender );
    }

    var i;
    for( i = 0; i < defender.get_team().length; i++ ) {
        var teammate = defender.get_team()[ i ];
        if( teammate.has_counterattack() ) {
            teammate.attack( attacker );
        }
    }

    // TODO: Process the logic that handles attacker or defender deaths
}

Koen Witters

If you enjoy making games like I do, then subscribe to this blog and/or follow me on twitter or facebook! Don't forget that we offer the best tool for making RPG's! And while we're at it, why not try out our super innovative indie game 'Mystic Mine' :).


  1. Koen Witters
    July 24th, 2009 at 09:28 | #1

    I receive lots of suggestions by email for the problem when using boolean variables as members, below is a selection of that feedback:

    How about relaxing your rule that Booleans must start with is_ or has_ and change it to say that Booleans must start with or contain “is” or “has”.

    They you can have “my_age_is_old” and “my_family_has_children”.

    I always use the prefix i_am or i_have as they have the same structure as is_ and has_ except they are in the first person context and shows ownership like my_ does. You may have already thought of this, but it seems to work, at least for me.

    I am wondering if instead of using “my” for the boolean member you use “it”, like you do in for loops for object specification.

    Instead of:

    my_is_old, my_has_children

    You would have:

    it_is_old, it_has_children

    I would assume that since “it” is being used in the variable name and isn’t by itself that “it” would be recognized as a class member instead of as part of a for loop. Other pronouns would possibly work as well, but they often are gender specific and may not work in the context of the class:

    he_is_old, she_has_children

    Have you considered doing this?
    “i_am_old” or “i_have_children”
    “we_are_old” or “we_have_children”

    I thing the answer is simple: Use no prefixes and always refer to them using this pointer. Like this (pun intended):

    if( ! this->isReadable )
    rewrite();

    Since you are using is_ and has_ in conjunction with my_ and our_, had you given thought to just applying proper english? Instead of my_is_old and my_has_children, would it be particularly bad to say i_am_old and i_have_children, or for statics, we_are_old and we_have_children?

    I can see the upsides and downsides to this – upside being increased readability and possibly clarity, and it seems that it wouldn’t require any extra thought as we already process language that way. The biggest downside would be the increased variability, but since you are already using my_/our_ and is_/has_ for different situations…

    What do u think about using this:
    is_my_old and has_my_children

    How about using “I_am” instead on “is_” and I_have” instead of “has_” for boolean members?

    Hence: “I_am_old” instead of “my_is_old”
    and “I_have_children” instead of “my_has_children”.

    My personal favorite is also the one which was suggested the most: i_am_…, i_have_… and we_are_…, we_have_…

  2. Jay
    August 21st, 2009 at 01:22 | #2

    Hi.

    Thank you so much for this article.
    On the boolean thing, I think that if you borrow the ’self’ from Python you won’t get the ‘crazy’ words.

    if( self_is_sleeping )
    wakeUp()

  3. Wes
    December 28th, 2009 at 22:35 | #3

    Great article. My coding style already looks a lot like yours, but you have given me some great ideas. I think I’m going to start using my_ and our_ instead of m_ (for member) and s_ (for shared), for one thing. I also eschew lame verbose comments, but one thing I’ve come to really appreciate is comments that explain a high-level approach.

  4. February 10th, 2011 at 16:25 | #4

    Hi Koen!

    Your article was the first to make me realize that coding styles aren’t just a convention. I found a research article which actually discusses camel casing vs underscores and blogged about it.

    http://whathecode.wordpress.com/2011/02/10/camelcase-vs-underscores-scientific-showdown/

    Although the conclusion of the paper seems to favor camel casing, I think they based it on the wrong statistical data. Apparently it IS proven that it reads slower, and that seems to be the most important aspect to me!

    Hope it interests you! P.s.: There’s a poll, so it’d be interesting to see some results. :)

  5. CodeMaker
    January 4th, 2012 at 08:00 | #5

    Use a postfix for your fix… my_name_condition, or my_name_state

    thus…

    if (my_name_condition != TRUE) { … }

  6. CodeMaker
    January 4th, 2012 at 08:02 | #6

    @CodeMaker
    obviously if(!my_name_condition) would be better!!!

  7. March 17th, 2012 at 01:53 | #7

    Your coding style will bring me some great improvements. I’ve got good clean code but you have eliminated many lines of unnecessary comments.

  8. Michael
    February 15th, 2013 at 08:48 | #8

    I have to say I prefer to always use blocks for if, for, while, etc. (like this…)
    if (is_valid == true) {
    do_one_thing();
    }
    even though I could omit the braces, too often I found I added an extra line to log that condition (or added an extra code line for some reason. If the braces weren’t there initially and I was in a hurry I could forget to add them in when I added the extra line and end up with
    if (is_valid == true)
    log_this();
    do_one_thing();
    it looks right but isn’t because of the missing braces and now you’ve got trouble. :-(

  1. February 10th, 2011 at 09:19 | #1

Copyright ©2006-2007 Koonsolo - All rights reserved.