# C# Code Style Guide For Game Creator

{% hint style="danger" %}
The documentation has moved to: <https://mitschmr-studios.io/documentation/codestyle/codestyle.html>

This version will no longer be updated and maintained.&#x20;
{% endhint %}

## Introduction

Seeing how many programming languages there are and how many companies use their own coding conventions, it is favorable for the developers to have a certain standard they can refer to. The same goes for the Unity assetstore, where a developer of an asset has written code that may be or may not be readable. This code style guide is designed to give you an overview of how code may be structured within the Game Creator eco system. It is based on these two coding style guides:&#x20;

* [sourceformat.com - C# Code Style Guide](http://www.sourceformat.com/pdf/cs-coding-standard-bellware.pdf)
* [microsoft.com - C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)

The target Unity version for this code style guide is Unity 2020.3 LTS with support for the C# 8 language features. \
**Reference:** <https://docs.unity3d.com/2020.3/Documentation/Manual/CSharpCompiler.html>

## Organization

### Source Files

* One class per file (except classes in a class)
* The class name must match the file name (e.g. class name is `Test` then the file name is `Test.cs`)

### Ordering

The structure of a script is as follows:&#x20;

* `using` statements
* `namespace` statements
* `Class` and `Interface` declarations

## Layout

* Indentation is four spaces long (equals one tab)
* Only one statement per line
* Only one declaration per line
* If continuation lines are not indented automatically, indent them one tab stop (four spaces)
* Add at least one blank line between method definitions and property definitions

#### Wrapping lines

When an expression does not fit on a single line, follow these breaking rules:&#x20;

* Break after an operator
* Break after a comma
* Indent once after a break (see 4th point in [Layout](#layout))

### Comments

* Place the comment on a separate line, not at the end of a line of code
* Begin comment text with an uppercase letter
* End comment text with a period
* Insert one space between the comment delimiter (//) and the comment text, as shown in the following example:

```csharp
// The following declaration creates a query. It does not run
// the query.
```

## Language

### Declaration security

| Declaration | Notes                                            |
| ----------- | ------------------------------------------------ |
| Fields      | First `protected`, then `public`, then `private` |
| Properties  | First `protected`, then `public`, then `private` |
| Methods     | First `protected`, then `public`, then `private` |

In order to not need to change a script of a module of Game Creator, the fields etc. have the `protected` security flag as default, so they can be accessed and changed by scripts that derive of the other.&#x20;

### Method declaration

Methods are generally written with the `virtual` keyword, so they can be overridden by other scripts.&#x20;

```csharp
// Script 1.
public virtual float GetFloat() => floatValue;

// Script 2.
public override float GetFloat() => floatValue2;
```

### Naming

| Identifier Type     | Naming Rules                                                                                                                                                     | Examples                                                                                                                                                                                                              |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Namespaces          | A noun in Pascal case. When the word consists of two or less characters, it is written in capital case. Avoid acronyms and abbreviations when possible.          | <p><code>GameCreator.Core;</code></p><p><code>UnityEngine.UI;</code></p>                                                                                                                                              |
| Classes             | A noun written in Pascal case, avoid acronyms and abbreviations when possible.                                                                                   | <p><code>class ActionHit;</code></p><p><code>class ConditionX;</code>             </p>                                                                                                                                |
| Interfaces          | A word in Pascal case, starting with the letter "I".                                                                                                             | `interface IAction;`                                                                                                                                                                                                  |
| Methods             | Active verb/noun forms written in Pascal case.                                                                                                                   | <p><code>GetLetter();</code></p><p><code>UpdateHierarchy();</code></p>                                                                                                                                                |
| Instance Fields     | Meaningful names written in camel case. Underscores should not be used for private or protected variables.                                                       | <p><code>protected string name;</code></p><p><code>public int age;</code></p>                                                                                                                                         |
| Enum Types / Values | Words written in Pascal case. Do not use the `Enum` suffix on Enum type names. When more than two values, it is recommended to write each value on its own line. | <p><code>enum State {On, Off};</code></p><p><code>enum World</code></p><p><code>{</code></p><p>    <code>Curved,</code><br>    <code>Round,</code><br>    <code>AroundTheCorner</code>      </p><p><code>}</code></p> |
| Events              | Written in Pascal case.                                                                                                                                          | `EventActivation onActivate;`                                                                                                                                                                                         |
| Attributes          | Custom attributes are in Pascal case and have the suffix "Attribute".                                                                                            | `SingleSkillAttribute;`                                                                                                                                                                                               |
| Properties          | Properties are written in Pascal case. They should directly reflect the underlying attribute (field).                                                            | <p><code>public string Name;</code></p><p><code>public int Age;</code></p>                                                                                                                                            |
| Local Variables     | These are written in camel case. Avoid using acronyms and abbreviations.                                                                                         | <p><code>int age = 6;</code></p><p><code>Order order = new Order();</code></p>                                                                                                                                        |
| Constants           | Constants are written in Pascal Case, but may also be written in all uppercase.                                                                                  | <p><code>const int NumDaysInWeek = 4;</code></p><p><code>const int NUM\_DAYS\_IN\_WEEK = 4</code></p>                                                                                                                 |

### Strings

[String interpolation](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated) should be used to concatenate string:

```csharp
string displayName = $"{nameList[n].LastName}, {nameList[n].FirstName}";
```

### Local Variables

* [Implicit typing](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables) for local variables may be used when the type of the variable is obvious from the right side of the assignment or when the precise type is not important

```csharp
var var1 = "This is clearly a string.";
var var2 = 27;
```

* [var](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var) should not be used when the type is not apparent from the right side of the assignment

```csharp
int var3 = Convert.ToInt32(Console.ReadLine());
int var4 = ExampleClass.ResultSoFar();
```

* Do not rely on the variable name to specify the type of the variable, it might not be correct

### Arrays

Use the concise syntax when you initialize arrays on the declaration line:

```csharp
// Preferred syntax. Note that you cannot use var here instead of string[].
string[] vowels1 = { "a", "e", "i", "o", "u" };

// If you use explicit instantiation, you can use var.
var vowels2 = new string[] { "a", "e", "i", "o", "u" };

// If you specify an array size, you must initialize the elements one at a time.
var vowels3 = new string[5];
vowels3[0] = "a";
vowels3[1] = "e";
```

### Conditional logical operators

Use [&&](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#conditional-logical-and-operator-) as well as [||](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#conditional-logical-or-operator-) for comparisons in order to avoid exceptions and increased performance due to skipped unnecessary comparisons.&#x20;

### Null propagation

Unity overrides the null comparison operator for Unity objects and therefore the C# null propagation feature is incompatible.

```csharp
public GameObject test = null;

// Set in the inspector.
public Transform test2;

private void Update()
{
    // Should not be done.
    test?.transform = test2;
    
    // Correct comparison.
    if (test != null)
    {
        test.transform = test2;
    }
    
    // Shortened version is also possible.
    if (test != null) test.transform = test2;
}
```
