Skip to content
Benedek Vartok edited this page Nov 19, 2014 · 31 revisions

nodeGame Developer Guide

DISCLAIMER

Be advised that the steps described in the following sections are a work in progress and may not work at the moment.

Installation

The README describes a simple way to get the program running, but for development it might be more useful to work with the more recent Git-version and let npm only install the dependencies:

  1. git clone [email protected]:nodeGame/nodegame.git
  2. cd nodegame
  3. npm install

That way, you will also get Git's version-control files in the root nodegame/ directory and the submodules, such as nodegame/node_modules/nodegame-client/.

Compiling the Code

If you make changes in the code, you will have to run some build scripts to update the files necessary for running nodeGame:

  1. Do your changes in the module or your choice.
  2. In that module: node bin/make.js build
  3. Go to the server module (nodegame/node_modules/nodegame-server) and do: node bin/make.js build-client

After these steps, the program should be good to go.

Writing Code

The source code of nodeGame follows the following conventions.

Whitespace

  • Indenting uses four spaces, tabs are never used.
  • Lines do not have any trailing whitespace.
  • Source files have one newline at the end.
  • In control flow statements, the opening parenthesis follows a space (see examples in Braces).
  • There is no space between a function name and the opening parenthesis of its parameters.

Braces

  • Opening braces are on the same line as their corresponding control flow statements.
  • Closing braces are on their own line.
  • When a control flow statement is broken into multiple lines, it is followed by an empty line.
  • Braces may only be left out if the single statement it would contain is on the same line as the leading control flow statement (see bottom of example).

Examples:

function control(a, b) {  // No space after 'control'.
    if (a >= b) {
        console.log('Greater or equal');
    }
    else if (a < b) {  // Note brace arrangement around 'else'.
        console.log('Less');
    }
    else {
        console.log('NaN');
    }

    while (veryLongCondition1 &&
           veryLongCondition2) {  // Empty line following.

        doThing(function(e) {   // No space after 'function'.
            console.log(e);
        });
    }
}

if (x < 0) x = 0;  // OK

if (x === 5) {
  x = 8;  // OK
}

if (x > 9)
    x = 9;  // NOT OK!

Logic

  • Strict in-/equality !==/=== is used instead of !=/== wherever possible.
  • All "for-in" loops check hasOwnProperty on each iteration.
  • Variable shadowing should be avoided.

Examples:

function printProps(obj) {
    var i;

    for (i in obj) {
        if (obj.hasOwnProperty(i)) {  // Important.
            console.log(i, obj[i] === null ? 'N/A' : obj[i]);
        }
    }

    function() {
        var obj;  // Shadowing NOT OK!
    }();
}

Naming

  • Variable names use camelCase.
  • Constant names use UNDERSCORED_UPPER_CASE.
  • Class names use PascalCase.
  • Names should be descriptive.

Miscellaneous

  • Lines are at most 80 characters long.
  • Strings use single quotes by default, double quotes if more convenient.
  • All variables are declared at the top of their scope and are assigned to separately.
  • Messages in new exceptions start with the class name suffixed with a dot (if inside a class), followed by the function name and a colon. The description starts with a lower-case letter and ends with a period.
  • Comments are generally on lines of their own, before the code they concern, starting with a capital letter and ending with a punctuation symbol, usually a period.

Examples:

function sumArray(array) {
    var i, sum;  // All declarations on top, no assignments.

    // Check input.
    if (!array || 'number' !== typeof array.length) {
        throw new TypeError('sumArray: array.length must be number.');
    }

    // Sum up elements.
    sum = 0;
    for (i = 0; i < array.length; ++i) {
        sum += array[i];
    }

    console.log("Sum of 'array': " + sum + '.');
    return sum;
}

MyClass.prototype.fail = function() {
    throw new Error('MyClass.fail: always throws.');
}

Writing Documentation

nodeGame uses docker to generate its documentation. In addition to the above practices used in the code, the following rules apply for doc comments.

Sections

Docker pages use a hierarchy of sections, with different levels denoted by #, ##, ### etc. A nodeGame source file has the following structure:

# ClassName [filename without extension]
## ClassName constructor
### ClassName.field
### ...
## ClassName methods
### ClassName.method
### ...

For example:

# Circle
## Circle constructor
### Circle.posX
### Circle.posY
### Circle.radius
## Circle methods
### Circle.setPosition
### Circle.getArea
### Circle.draw

In special cases, more sections can be added.

Documentation comments

After the section definition, the rest of the doc comment describes the documented field or method.

  • The first line is a short summary, beginning with a capital letter and ending without a period, surrounded by empty lines. For methods, this should start with a verb in third person.
  • Next, an optional longer description follows. The sentences in the descriptions end in a punctuation symbol.

Field example:

/**
 * ### Circle.radius
 *
 * Radius of the circle
 *
 * The radius is half the diameter.
 */
this.radius = radius;

For methods:

  • Parameter descriptions start with a capital letter, the last sentence has no period.
  • Descriptions of optional parameters begin with "Optional.".

Method example:

/**
 * ### Circle.setPosition
 *
 * Sets the circle's position
 *
 * @param {number} x The new x position
 * @param {number} y The new y position
 * @param {boolean} rel Optional. Whether to add to the old position.
 *   Default: FALSE
 */
Circle.prototype.setPosition = function(x, y, rel) { ... }
Clone this wiki locally