Skip to content

Project Code Conventions

George L. Albany edited this page Mar 28, 2026 · 52 revisions

Note

If anything in this specific repository is found to be breaking these conventions, and the issue has not been previously reported to our issue tracker, submit a new issue describing where and how the convention is being broken.

File Requirements

  • Encode as UTF-8.
  • Use tabs for indentation.
  • Use LF for end-of-line sequences.

Name Conventions

The guideline for names should be the shortest possible to describe the object's purpose, intent, or content without being ambiguous or being confused for something else.

Acronyms

Acronyms in PascalCase should be uppercase like PNG.
Acronyms in snake_case should be lowercase like png.
Acronyms in CAPITAL_SNAKE_CASE should be uppercase like PNG.
Acronyms in camelCase should be lowercase like png as the first word, and uppercase otherwise like PNG.

Case Convention

Type Convention Example

Files

File Suffix
C++ Header .hpp Named after the primary class/struct/enum for the header, else PascalCase describing its purpose. ArgumentParser.hpp, Bind.hpp
C++ Source .cpp Named after its related header, else PascalCase describing its purpose. ArgumentParser.cpp
Godot Scene .tscn PascalCase describing the scene's purpose. GameMenu.tscn
GDScript Source .gd Named after its related scene, else PascalCase describing the class' purpose. GameMenu.gd, MonitorDisplaySelector.gd
GDShader .gdshader snake_case describing the shader's purpose. unit_colours.gdshader
Godot Resource .tres snake_case describing the resource's content/purpose. options_menu.tres
Godot Asset .png, .ogg, .mp3, .csv, .txt snake_case describing the asset's content/purpose. loading_screen.png, click.ogg

C++ Concepts

Notes
Namespace snake_case describing the namespace's content. Prefer one word names. namespace OpenVic::detail
Class PascalCase describing the class' purpose. class ArgumentParser
Struct PascalCase describing the struct's purpose. struct TopBar
Enum Name PascalCase describing the enum's purpose. enum BudgetType
Enum Value CAPITAL_SNAKE_CASE describing the enum's value, prefixed with the enum's type. enum BudgetType { BUDGET_TYPE_EXPENSES };
Function/Method snake_case describing the function's purpose. Variant::Type get_type() const
Private Function/Method Includes functions not bound for Godot. snake_case describing the function's purpose, prefixed with an underscore (_). Variant _get_empty_value_for(Variant::Type p_type)
Macro CAPITAL_SNAKE_CASE describing the macro's purpose, prefixed with OV_. OV_BIND_METHOD
Constant snake_case describing the constant's purpose. String value_placeholder;
Variable snake_case describing the variable's purpose. float max_height;
Template Typename Either T or PascalCase describing the typename's purpose, suffixed with a T template<typename ToT, typename FromT>

GDScript Concepts

Notes
Class Name PascalCase describing the class_name's purpose. class_name GameDebug
Class PascalCase describing the class' purpose. class BuildingSlot
Enum Name PascalCase describing the enum's purpose. enum BudgetType
Enum Value CAPITAL_SNAKE_CASE describing the enum's value. enum Screen { PRODUCTION }
Function/Method snake_case describing the function's purpose. func start_loading_screen(thread_safe_function)
Private Function/Method These functions are not meant for general access. snake_case describing the function's purpose, prefixed with an underscore (_). func _setup_compatibility_mode_paths()
Constant CAPITAL_SNAKE_CASE describing the constant's purpose. const PRODUCED_GOOD_COUNT
Private Constant These constants are not meant for general access, only applies to class constants. CAPITAL_SNAKE_CASE describing the constant's purpose, prefixed with an underscore (_). const _INSTANCE_COUNT
Variable snake_case describing the variable's purpose. var source_path : String
Private Variable These variables are not meant for general access, only applies to member variables. snake_case describing the variable's purpose, prefixed with an underscore (_). var _map_view : MapView

GDShader Concepts

Notes
Struct PascalCase describing the struct's purpose. struct CornerArgs
Function snake_case describing the function's purpose. vec3 get_map_colour(vec2 uv)
Macro CAPITAL_SNAKE_CASE describing the macro's purpose. #define SAMPLE(N)
Constant Minimal CAPITAL_SNAKE_CASE describing the constant's purpose. const uint BILLBOARD_COUNT
Variable snake_case describing the variable's purpose. uint scaled_index

Terms

Type Description Example
PascalCase First letter of each word is uppercase with no underscore between the words. HelloWorld
snake_case Only lowercase characters, each word is separated by an underscore _. hello_world
CAPITAL_SNAKE_CASE Only uppercase characters, each word is separated by an underscore _. HELLO_WORLD
camelCase First letter of each word is uppercase except for the first word with no underscore between the words. helloWorld

C++ Style Guide

Note

This style guide refers to general style mandates which are not enforced by clang-format v22.1.1. If clang-format can be used to enforce the style instead, the mandate will be removed from here. Always run pre-commit to validate style checks.

  • Always remove trailing whitespace.
  • Prefer to keep header #include directives at the top of the file.
  • Always place code within an OpenVic namespace.
  • Never use using namespace in any file that'll be included somewhere, you may use using namespace OpenVic; and using namespace godot; inside cpp source files.
  • Avoid the use of the auto keyword except where it is impossible to avoid. This ensures our codebase is readable without a dedicated IDE.
  • Prefer inline static member functions to lambdas, unless the function is a one liner like [](int a, int b) ‑> bool { return a > b; } lambda functions can make reading code more difficult and tends to trip up clang-format.
  • Use #pragma once for C++ headers.
  • Do not use Runtime Type Information features, it is generally disabled in our codebases. It has negative performance and binary size impacts and trends towards bad habits.
  • Do not use Exceptions, try, or catch, they are disabled in our codebases. It has negative performance and binary size impacts. Prefer error codes, Godot's error handling, or OpenVic error handling.
  • You may declare multiple variables at once. Do not declare multiple pointer variables at once.
  • Where possible, keep initialization with the variable's declaration.
  • Where possible, keep initialization with the variable's declaration.
  • Use const wherever a one-time assigned immutable variable is intended, including parameters. Avoid const as class members unless they are static.
  • Prefer constexpr to const where possible.
  • Order type related specifiers like so: <type> const* const, <type> const&, <type>&, <type>&&
  • Prefer rvalue reference (Type&&) parameters to Type const& parameters and const reference (Type const&) parameters to reference (Type&) parameters.
  • Order specifiers like so:
    1. extern
    2. inline
    3. static
    4. mutable
    5. constexpr
    6. const
    7. volatile
  • Prefer class to struct declarations except when the type is small and contains only public variables, exceptions may exist for small helper member functions.
  • Prefer to order access specifiers with private first, protected second, and public last. Minimize the amount of access specifiers as much as possible by grouping members together.
  • Group members together by a common purpose, use, or category. Use a newline to seperate member groups.
  • Prefer marking member functions as const if they do not mutate the object instance.
  • Prefer marking member functions as static if they do not relate to or access the object instance, exceptions may be made if it makes code easier to read.
  • Prefer enum class to enum except for any enums bound to Godot.
  • Always use using type alias declarations, never use typedef declarations.
  • Avoid C-style casts (e.g. (int)float_value), always prefer static_cast first, reinterpret_cast second, and const_cast last. See our guide on RTTI for dynamic_cast.
  • If clang-format separates the return type of the function from its name, use comments to split the parameters onto a newline. For example:

    std::pair<LongTypeName, AnotherLongTypeName> a_long_long_long_long_long_function_name(LongTypeName a, LongTypeName b) const;

    May get formatted by clang-format as:

    std::pair<LongTypeName, AnotherLongTypeName>
    a_long_long_long_long_long_function_name(LongTypeName a, LongTypeName b) const;

    Prefer:

    std::pair<LongTypeName, AnotherLongTypeName> a_long_long_long_long_long_function_name( //
        LongTypeName a, LongTypeName b
    ) const;

GDScript Style Guide

See the GDScript Style Guide in the Godot Engine's Documentation.

Clone this wiki locally