C# style guide

    This page contains a coding style guide, which is followed by developers of and contributors to Godot itself. As such, it is mainly intended for those who want to contribute to the project, but since the conventions and guidelines mentioned in this article are those most widely adopted by the users of the language, we encourage you to do the same, especially if you do not have such a guide yet.

    Note

    This article is by no means an exhaustive guide on how to follow the standard coding conventions or best practices. If you feel unsure of an aspect which is not covered here, please refer to more comprehensive documentation, such as C# Coding Conventions or .

    Godot currently uses C# version 7.0 in its engine and example source code. So, before we move to a newer version, care must be taken to avoid mixing language features only available in C# 7.1 or later.

    For detailed information on C# features in different versions, please see .

    Formatting

    • Use line feed (LF) characters to break lines, not CRLF or CR.

    • Use one line feed character at the end of each file, except for csproj files.

    • Use UTF-8 encoding without a byte order mark.

    • Use 4 spaces instead of tabs for indentation (which is referred to as “soft tabs”).

    • Consider breaking a line into several if it’s longer than 100 characters.

    For a general indentation rule, follow the “Allman Style” which recommends placing the brace associated with a control statement on the next line, indented to the same level:

    However, you may choose to omit line breaks inside brackets:

    • For simple property accessors.

    • For simple object, array, or collection initializers.

    • For abstract auto property, indexer, or event declarations.

    1. public interface MyInterface
    2. {
    3. int MyProperty { get; set; }
    4. }
    5. public class MyClass : ParentClass
    6. {
    7. public int Value
    8. {
    9. get { return 0; }
    10. set
    11. {
    12. ArrayValue = new [] {value};
    13. }
    14. }
    15. }

    Insert a blank line:

    • After a list of using statements.

    • Between method, properties, and inner type declarations.

    • At the end of each file.

    Avoid inserting a blank line:

    • After {, the opening brace.

    • After a comment block or a single-line comment.

    • Adjacent to another blank line.

    1. using System;
    2. using Godot;
    3. // Blank line after `using` list.
    4. public class MyClass
    5. { // No blank line after `{`.
    6. public enum MyEnum
    7. {
    8. Value,
    9. AnotherValue // No blank line before `}`.
    10. }
    11. // Blank line around inner types.
    12. public const int SomeConstant = 1;
    13. public const int AnotherConstant = 2;
    14. private Vector3 _x; // Related constants or fields can be
    15. private Vector3 _y; // grouped together.
    16. private float _width;
    17. private float _height;
    18. public int MyProperty { get; set; }
    19. // Blank line around properties.
    20. public void MyMethod()
    21. {
    22. // Some comment.
    23. AnotherMethod(); // No blank line after a comment.
    24. }
    25. // Blank line around methods.
    26. public void AnotherMethod()
    27. {
    28. }
    29. }

    Insert a space:

    • Around a binary and tertiary operator.

    • Between an opening parenthesis and if, for, foreach, catch, while, lock or using keywords.

    • Before and within a single line accessor block.

    • Between accessors in a single line accessor block.

    • After a comma which is not at the end of a line.

    • After a colon in a single line case statement.

    • Around a colon in a type declaration.

    • Around a lambda arrow.

    • After a single-line comment symbol (//), and before it if used at the end of a line.

    Do not use a space:

    • After type cast parentheses.

    • Within single line initializer braces.

    Use PascalCase for all namespaces, type names and member level identifiers (i.e. methods, properties, constants, events), except for private fields:

    1. namespace ExampleProject
    2. {
    3. public class PlayerCharacter
    4. {
    5. public const float DefaultSpeed = 10f;
    6. public float CurrentSpeed { get; set; }
    7. protected int HitPoints;
    8. {
    9. }
    10. }
    11. }

    Use camelCase for all other identifiers (i.e. local variables, method arguments), and use an underscore (_) as a prefix for private fields (but not for methods or properties, as explained above):

    1. private Vector3 _aimingAt; // Use a `_` prefix for private fields.
    2. private void Attack(float attackStrength)
    3. {
    4. Enemy targetFound = FindTarget(_aimingAt);
    5. targetFound?.Hit(attackStrength);
    6. }

    There’s an exception with acronyms which consist of two letters, like UI, which should be written in uppercase letters where PascalCase would be expected, and in lowercase letters otherwise.

    Note that id is not an acronym, so it should be treated as a normal identifier:

    It is generally discouraged to use a type name as a prefix of an identifier, like string strText or float fPower, for example. An exception is made, however, for interfaces, which should, in fact, have an uppercase letter I prefixed to their names, like IInventoryHolder or IDamageable.

    Lastly, consider choosing descriptive names and do not try to shorten them too much if it affects readability.

    For instance, if you want to write code to find a nearby enemy and hit it with a weapon, prefer:

    1. FindNearbyEnemy()?.Damage(weaponDamage);

    Rather than:

    1. FindNode()?.Change(wpnDmg);

    Member variables

    Don’t declare member variables if they are only used locally in a method, as it makes the code more difficult to follow. Instead, declare them as local variables in the method’s body.

    Declare local variables as close as possible to their first use. This makes it easier to follow the code, without having to scroll too much to find where the variable was declared.

    Implicitly typed local variables

    Consider using implicitly typing (var) for declaration of a local variable, but do so only when the type is evident from the right side of the assignment: