Technical Documentation

Programming Guidelines

Last Updated: October 28, 20242.4 min read

Clang Format

We use Clang Format to format our source files to be consistent. Always use format on save functionality as mentioned in Getting Started | Internal Documentation (clickup.com)

Enums

Prefer enum class everywhere, there should not be any usage of โ€˜enumโ€™.
Use the ENUM_FLAG_OPERATORS macro to define common operators for an enum class.

Avoid Boolean members and function arguments

Boolean code bloat can make it very confusing to read function calls when they over time end up looking like foo(true, false, true); so we avoid them wherever possible. Instead, prefer using enum classes and our EnumFlags class so that the same example can instead look like foo(Flags::Show | Flags::EnableInput | Flags::DisableInteraction);

No prefixes

We avoid prefixes such as โ€˜Cโ€™, โ€˜Sโ€™, โ€˜Aโ€™ etc in front of class names. Exceptions are made for templates (can be prefixed by โ€˜Tโ€™) and pointers (can be prefixed by โ€˜pโ€™).

Namespaces

Always put code into relevant namespaces when possible, and avoid bloating the root engine namespace.

Naming

Avoid overly shortened named classes and functions, always ensure that the purpose of the class is conveyed in the name.

Const Safety

Use const whenever a variable is not modified, this ensures that programmers can easily scan through code and see what is being changed.

Express intent

Use variable naming and explicit type definitions to express the concise intent of the code. Auto is allowed, but only if itโ€™s clear what the type is.

Pointers & References

Prefer references wherever possible. If a function null-tests a pointer before every usage, then it should have been a reference to begin with. We have a coding contract where any reference is assumed to have already been null-checked.
Avoid pointers in containers, instead use ReferenceWrapper to indicate that the contents can never be null.

Forward Declare Everything

Forward declarations should be used for everything that is possible. if the definition is not needed, it should not be included in a header file.

One implementation for file

Do not mix multiple class definitions into one file. Instead, prefer having one file for each source.

No unrelated code

Unrelated code should never be present in a project or plug-in. Instead, move common code to the Common project or a relevant plug-in dependency. This ensures that we never duplicate functionality.

Unit Testing

Write unit tests for core classes in the Common project. See for more information. Never use mocking, in cases where mocking is necessary prefer .

Prefer explicit unit types

We prefer wrapping units into specific types combined with user-defined literals, such as:
  • Math::Radiusf & Math::Lengthf (_meters, _centimeters and more)
  • Math::Anglef (_degrees and _radians)
  • Math::Color (_color, _colorf)
  • Math::Mass (_kilograms, _tons and more)

Include Common headers at the bottom

Add headers from the Common project at the bottom of all includes. This ensures that every header includes what it needs.