Skip to content

Code style guideline

Vincent Mahnke edited this page May 7, 2023 · 1 revision

Knowledge requirements

This document is best read with a basic understanding of...

Overview

This document outlines our approach to code style for this repository.
It is highly encouraged to address violations if you stumble across them, while working on the codebase, even if your PR is unrelated or code was originally written by another team-member.

If you have suggestions or concerns regarding these rules, feel free to open up a new or participate in already existing discussions.

Terminology

PascalCase

Writing variable or method names, starting with an uppercase letter, and starting every subsequent word with an uppercase letter, without any -.
For example: DoTheThing()

camelCase

Writing variable or method names, starting with an lowercase letter, and starting every subsequent word with an uppercase letter, without any -.
For example: doTheThing()

Variables

  • All variables must be written in camelCase
  • Start all member variables with _ to distinguish them from local variables
  • Keep member variables private, and use properties to access them in code. If the variable needs to be changed in the editor, use [SerializeField] in front of it
  • All properties should be in PascalCase
  • All variables should be declared on their own line

Methods

  • All methods must be written in PascalCase

  • A method's functionality should be deducible from its name

  • Curly braces for method bodies start on the next line, on the same indentation level as the method declarations:

    private bool DoTheThing(int newThing)
    {
      return true;
    }
  • Provide a summary for each method you write, which includes:

    • A small description of your method
    • A small description of each parameter
      • A small description of the return value
    [SerializeField] private int m_veryCoolThing = 3;
    
    /// <summary>
    /// A function that performs some useless int magic
    /// </summary>
    /// <param name="newThing">The int to do magic with</param>
    /// <returns>Whether the magic was successful</returns>
    private bool DoTheThing(int newThing)
    {
        int calculatedThing = newThing * m_veryCoolThing;
        return calculatedThing > m_veryCoolThing;
    }
  • Static members should be accessed without qualifying the class name explicitly. (MSDN on Style rule IDE0002)

    class Foo
    {
        static void M1() { }
        static void M2()
        {
            // IDE0002: 'C.M1' can be simplified to 'M1'
            C.M1();
    
            // Fixed code
            M1();
        }
    }
  • Methods should first assert data is in an expected format and either return or create appropriate log messages.
    This enhances legibility and also forces developers to explicitly handle erroneous cases, reducing unexpected behavior down the line.
    Change...

    if (!_inkStory.canContinue)
    {
        List<Choice> choiceList = _inkStory.currentChoices;
    
        if (choiceList.Count > 0)
        {
            _isAtChoice = true;
        }
    }

    ...to...

    if (_inkStory.canContinue)
    {
        return;
    }
    List<Choice> choiceList = _inkStory.currentChoices;
    
    if (choiceList.Count <= 0)
    {
        Debug.Log("No choices present, continue with linear story progression");
        return;
    }
    _isAtChoice = true;

Attributes

  • A line should only ever be used for one attribute
    [Header("My Header")]
    [Range(0, 100)]
    [SerializeField]
    private int myInt;
  • Is is encouraged to keep member properties private and use [SerializeField] to expose them to the Unity Inspector
  • Use a [Header(“HeaderName”)] to group variables together in the editor if necessary
  • Use [Tooltip(“Content)] only when not being redundant and adding non-inferable information
  • Use the [Range(0, 2000)] tag to limit the range of number variables in the editor and allow easy editing

Testing

  • When updating existing functionality, preferably de-couple custom logic from Unity-specific functionality unless strictly required
  • When adding new functionality, adding a test scene to the Demo assembly to be able to play with the new feature with one click is highly encouraged
  • It is encouraged to create automated tests alongside any changes or newly created functionality

General guidelines

  • Use scriptable objects to create data structures which can be created by designers in editor