=====Code Formatting Conventions=====
===Common Sense===
----
Just use it, it may be better to break the convention rules in some cases.
===Indentation===
----
Tabs, at four columns. Always indent within braces.
Remember to change your text editor/IDE configuration, so it automatically uses tabs instead of spaces.
===Braces===
----
Braces in your code should look like the following example:
for (int i = 0; i < t; i++) {
[...]
}
if (j < k) {
[...]
} else {
[...]
}
class Dummy {
[...]
};
===Whitespaces===
----
In no case there should be two whitespaces together. If you want align some code use tabs instead, that are easier to maintain. Pay attention to spaces or tabs at the ending of a line, remove them.
==Conventional operators surrounded by a space character==
a = (b + c) * d;
==C++ reserved words separated from opening parentheses by a white space==
while (true) {
==Commas followed by a white space==
SomeFunction(a, b, c);
int d, e;
==Semicolons followed by a space character, if there is more on a line==
for (int i = 0; i < 10; i++) {
DoSomething(e); DoSomething(f); // This is probably bad style anyway
==When declaring class inheritance and in a ? construct, colons should be surrounded by white space==
class Foo : public Bar {
var1 ? var2 : var3;
==Array delete operator has no whitespace before []==
delete[] foo;
==STD library and <>==
No whitespaces before or after <, and whitespaces only after >.
std::vector array;
std::vector > array_of_arrays;
==Operator overloading==
Operator keyword is not separated from the name, except for type conversion operators where it is required.
struct Foo {
void operator()() {
// ...
}
operator bool() {
return true;
}
};
==Pointers and casts==
No whitespace after a cast; and in a pointer, we write a whitespace after it but not before it. Consider "*" to be part of the type.
const char* ptr = (const char*)foobar;
==References==
Unlike pointers, use a whitespace before the "&" but not after it. Consider the & operator to affect the variable, not the type.
int i = 0;
int &ref = i;
void func(const int &foo) {
====Switch / Case constructs====
----
switch(command_window->GetIndex()) {
case 0: // New Game
CommandNewGame();
break;
case 1: // Load Game
CommandContinue();
break;
case 2: // Exit Game
CommandShutdown();
}
====Naming====
----
==Constants==
All upper case, with underscores as name separators, but no leading/trailing underscores:
THIS_IS_A_CONSTANT
''As a exception'', for headers use the following format:
#ifndef _WINDOW_COMMAND_H_
#define _WINDOW_COMMAND_H_
==Type names==
We use RPG Maker XP/VX RGSS and scripts as our API base. Normally classes should be named in UpperCamelCase, like EventCommand, but there are some exceptions when trying to mantain the names RPG Maker XP/VX use, like RPG or Scene_Title. Scripts or "Engine" classes use a word prefix with a underscore indicating what they are for: Game_, Sprite_, Spriteset_, Window_ and Scene_.
class RPG::MoveRoute {
class Game_CommonEvent {
class Window_MenuStatus : public Window_Selectable {
class Scene_Battle : public Scene {
==Functions==
Functions should be UpperCamelCase.
void ThisIsAFunction() {
Property methods should start with Get or Set:
class Foo {
public:
int GetThatInt() { return that_int; }
void SetThatInt(int new_int) { that_int = new_int; }
private:
int that_int;
}
==Variables==
Variables should be lower case with underscores as word separators.
int this_is_a_variable;
====Headers includes====
----
Use the following format:
#include "header1.h"
#include "header2.h"
And when possible use the following headers order:
* System headers (e.g. windows.h)
* C headers (e.g. math.h)
* C++ headers (e.g. string)
* system.h
* Current class/namespace header (e.g. game_map.h for game_map.cpp)
* Tools headers (e.g. output.h)
* Backend/Multimedia headers (e.g. graphics.h)
* Engine headers (e.g. game_character.h)
* liblcf headers (e.g. lmu_reader.h)
For each headers group alphabetically sort the includes.
====Comments====
----
Use // preferably. Use /*Multiline comments*/ when disabling multiline code.
==License File Header==
Remember to copy (from any other existing file) the license header to all new created files.
==Documentation==
Use Doxygen like documentation, with the following format for functions:
/**
* Description of MyFunction.
* A more detailed description here.
* @param var1 : this is a description for var1
* @param var2 : this is a description for var2
* @return here goes a description for return value
*/
virtual int MyFunction(double var1, std::string var2);
With the exception of getters and setters:
/** @return description of variable */
int GetVariable();
/** @param variable : description of variable */
void SetVariable(int variable);
And for variables:
/** Description of example_variable. */
std::string example_variable;
Remember to document only declarations and not implementations, i.e. in headers. An exception could be .cpp static functions or variables, if documenting is really necessary.
==Code descriptions==
We prefer a global function description with Doxygen headers rather than inside the function descriptions. Only when code is really hard to follow, or there is something hardcoded then add some comments explaining the situation. Do not add redundant comments, like actions that should be already understand easily.
==Special comments==
// TODO: what is left to do
// FIXME: what code and in what circumstances it does not work, and if possible why it does not work well