-
Notifications
You must be signed in to change notification settings - Fork 31
Project Code Conventions
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.
- Encode as UTF-8.
- Use tabs for indentation.
- Use LF for end-of-line sequences.
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 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.
| Type | Convention | Example | |
|---|---|---|---|
| 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
|
| 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> |
|
| 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 |
| 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 |
|
| 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 |
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
#includedirectives at the top of the file. -
Always place code within an
OpenVicnamespace. -
Never use
using namespacein any file that'll be included somewhere, you may useusing namespace OpenVic;andusing namespace godot;inside cpp source files. -
Avoid the use of the
autokeyword except where it is impossible to avoid. This ensures our codebase is readable without a dedicated IDE. -
Prefer
inline staticmember 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 upclang-format. -
Use
#pragma oncefor 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, orcatch, 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
constwherever a one-time assigned immutable variable is intended, including parameters. Avoidconstas class members unless they arestatic. -
Prefer
constexprtoconstwhere possible. -
Order type related specifiers like so:
<type> const* const,<type> const&,<type>&,<type>&& -
Prefer rvalue reference (
Type&&) parameters toType const¶meters and const reference (Type const&) parameters to reference (Type&) parameters. -
Order specifiers like so:
externinlinestaticmutableconstexprconstvolatile
-
Prefer
classtostructdeclarations 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
privatefirst,protectedsecond, andpubliclast. 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
constif they do not mutate the object instance. -
Prefer marking member functions as
staticif they do not relate to or access the object instance, exceptions may be made if it makes code easier to read. -
Prefer
enum classtoenumexcept for any enums bound to Godot. -
Always use
usingtype alias declarations, never usetypedefdeclarations. -
Avoid C-style casts (e.g.
(int)float_value), always preferstatic_castfirst,reinterpret_castsecond, andconst_castlast. See our guide on RTTI fordynamic_cast. -
If
clang-formatseparates 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-formatas: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;
See the GDScript Style Guide in the Godot Engine's Documentation.