godot-modules-code-conventions/README.md
2025-06-23 18:37:54 +00:00

1.7 KiB

Godot module style guide and conventions

Headers

// always use #define-based header guards,
// the name has to match the filename
#ifndef MY_CLASS_H
#define MY_CLASS_H

// PascalCase for all types
class MyClass : public Object {
    GDCLASS(MyClass, Object);
    // functions are always snake_cased
    static void _bind_methods();
    void on_some_signal(); // signal listeners are private unless otherwise called
public:
    void do_things();
    void set_my_var(int value); // set first
    int get_my_var() const; // get second, and const except when it can't be
private:
    int myvar{1}; // variables are snake_case, and always initialized in headers unless impossible
                  // (e.g, const vars that get initialized in constructors)
    String const sig_some_signal{"some_signal"}; // store signal names in a variable to make them easier to keep track of
};
#endif // !MY_CLASS_H // end #if/#ifdef/#ifndef directives with a repeat of the condition

Implementations

#include "my_class.h"
// the matching header always goes on top, other header includes come after in alphabetical order
#include "macros.h"
void MyClass::_bind_methods() {
    BIND_PROPERTY(Variant::INT, my_var); // use macros.h simplified binding tools when possible
}

void MyClass::do_things() {
    set_my_var(10); // this-> is not required for class methods
    cast_to<Object>(this); // nor for static class methods.
    // use self_type when referring to the type of 'this'
    this->connect(this->sig_some_signal, callable_mp(this, &self_type::on_some_signal));
}

void MyClass::set_my_var(int value) {
    // for all uses of member variables, use this->
    this->my_var = value;
}

int MyClass::get_my_var() const {
    return this->my_var;
}