Authors:

Targeted audience:

Required reading:

Required knowledge:

Explains:

Indentation

All sources have been written using two-space indentation and with inserting spaces instead tabs. Hold on to that if you want, but you don't really have to unless you work in Croteam. This one is optional for all except Croteam programmers.

Symbol Naming

Functions and variables and types are named with CapitalFirstLettersOfEachWord.
Class type names are prefixed with a capital 'C'. If there is a risk of a possible name-clash, 'CT' (short for Croteam) is used instead of 'C'.
Preprocessor macros are ALLCAPITALS.
Relaxed Hungarian convention is used for variables. Variables do have prefixed type, but more than one type can have same prefix, if they are not used in same scope. E.g 'f' can be a prefix for both floats and doubles. If both floats and doubles are used in the same context, then sometimes 'd' is used for doubles to make distinction.
Member variables or classes are prefixed with abbreviation of the class type and an underscore (gffi_fnFileName). Exception to this are the entity classes, where the prefix is always 'm_' for simplicity.

Exception throwing

Only (char *) typed exceptions are thrown by all the code. Note that this is not the same as (const char *) and this one includes the immediate string constants in code. Usually a function throws an error report string which can be an immediate string constant, or formated using ThrowF_t() function.
The fact that a function may throw such an exception, or call some other function which does so is denoted by appending the '_t' suffix to the function name (e.g CTStream::Read_t() ).
This enables a programmer to manually check that no unhandled exceptions will occur. So much for that, until the method of using 'throw' keyword in function declaration becomes supported by compilers.
Most of the functions throwing exceptions are loading, saving or network connection functions.

Member Access Privileges

Most member variables and functions are declared public. But they are usually separated into two different blocks in the class declaration using 'implementation:' and 'interface:' comments. You should respect those comments and not use the implementation parts of the class.
This was done to remove the neccessity for a large number of 'friend' declarations and to enable access to some of the implementation parts from assembler functions.
In some places, you may find some private or protected declarations. Those were used to prevent the programmer from accessing some functions/variables by mistake.

Translation and Localization Support

All string constants in the code that must be relayed through TRANS() preprocessor macro that will generate binary tags for automatic translation support.

Example:
Bad: CPrintF("Successfully loaded\n");
Good: CPrintF(TRANS("Successfully loaded\n"));

Filename Dependencies in the Executable Code

The Engine takes care that every file name (CTFileName) that you save in a binary or text file has a tag that can be found by the Depend utility. This tag is DFNM for binary data files, TFNM for text files. In executable binaries, the tag is EFNM. But the compiler cannot know which of the string constants are filenames. To add the tag, you must relay all the file names in code through either CTFILENAME() or DECLARE_CTFILENAME() macro.
Use CTFILENAME() for immediate constants, or DECLARE_CTFILENAME() to declare a filename and assign a value to it.
To prevent a programmer from inadvertently forgetting to do so, it is impossible to initialize a CTFileName variable directly with a (char *) constant or variable. This was disabled by declaring all functions for construction from (char *) as private. If you encounter a compiler error stating that you cannot convert from (char *) to CTFileName, you will know that you must use CTFILENAME() macro, or cast through CTString.

Example (with dependency):
Bad: strm.Open_t("file.dat");
Good: strm.Open_t(CTFILENAME("file.dat"));

Usually, you will want to have the filenames to be dependencies. If you don't (perhaps for temporary files, log files etc.), you must cast it through CTString.

Example (without dependency):
Bad: strm.Open_t("file.log");
Good: strm.Open_t(CTString("file.log"));