Style Guide - KSU-CS-Software-Engineering/VetMedSim GitHub Wiki
This page contains the list of all conventions that should be used while creating code for the VetMedSim project. Please note that any violation of those principles will most likely result in rejection of the pull request. We understand that this approach might seem harsh, but we find it worth the effort.
In case you want to refer to any of those rules (mostly in pull requests), please use the format:
Rule: <name_of_rule_section> <name_of_rule>
We would like our code to be thoroughly and clearly commented. However, comments can easily overrun the code base. Therefore we have established standards, which should help maintain the code documented while minimizing the space comments actually take.
All those structures should be commented according to C# documentation standards with their summary starting with a verb.
/// <summary>
/// Represents one item in player's inventory
/// </summary>
public class Item
{
...
}
Functions uphold all the rules specified in the previous section, but following additional rules apply:
- param lines should be sorted in the order they are required by the function
- returns should start with a noun (definitely should NOT contain a word Returns)
Also, all functions that implement or override behavior should NOT have documentation provided, because the documentation should be located near the function declaration and providing it again would break the DRY principle (and potentially introduce actualization anomalies).
All the properties and fields should be commented using the summary comment.
The use of in-block comments is strictly prohibited. If you feel like the code in block needs explanation, first think if it really cannot be simplified. If this is the simplest way to write that piece of code, create a new function and move that code in there instead of using in the block comment.
The only exception for this rule is the use of a comment inside an empty block of code, which states, that the mentioned block has been left blank on purpose.
public Item()
{
// intentionally left blank
}
This section might seem trivial to you, but it is vital to have all the developers on the same page, otherwise the codebase starts to get rusty pretty fast and commit difs will grow dramatically.
The opening and closing curly brackets should always be on their own separate line (even in case of one line blocks and loops).
if( condition )
{
...
}
else
{
...
}
To improve readability of the code, all content inside parentheses (function parameters and arguments, loops, if statements, ...) should be separated from its encolsing parenthesis by one space.
On the other hand, the function call (or control declaration) should NOT be separated from the following parenthesis by a space.
public int Clamp( int value, int lowerBound, int upperBound )
{
...
}
...
if( condition )
{
...
FunctionCall( argument, otherArgument );
...
}
...
foreach( var item in items )
{
...
}
Each level of nesting should have its own level of indentation, which is one higher than the previous one. The first level of indentation starts at the very left side of the screen and every two levels differ by exactly one tab.
The line right before return statement should be empty unless the block the return statement is contained in does not contain anything else.
...
SomeFunctionCall();
return true;
}
...
{
return false;
}
To add a little bit more intuition and allow faster orientation, we have agreed on a few naming conventions:
- baseline: camel case notation
- properties: start with an uppercase letter
- fields: start with an underscore ("_") followed by a lowercase letter
- interfaces: start with a capital "I" followed by its name starting with a capital letter
To be able to quickly navigate even really chunky files, it is reasonable to enforce the same structure across all files.
The using statements should be located on the very first lines of the file. Also, they should be sorted alphabetically and there should be no unused statements.
Regions are a great way of separating the file into sections. Therefore we have agreed to use regions and sort them in the following order:
- Constants
- Fields
- Properties
- Constructors
- Overrides
- Functions
- <Interfaces> (called by their name in the order they are specified in the class definition)
If some of those regions should be empty, they should be omitted.
There are a few more additional rules that do not fit into any of previous categories, so they were put in here.
Even though Unity does not create namespaces by default, we decided to use them (so please do).
To save some indentation during a lot of nesting, please use early return strategy demonstrated in the following example:
DO:
if( !condition )
{
return;
}
RestOfFunction();
DON'T:
if( condition )
{
RestOfFunction();
}