Godot version : Godot_v4.4.1-stable_linux.x86_64
Context:
I am trying to make a gdextension implementation of behaviour trees. So I use classes, inheritance, and virtual functions.
Problem:
My classes inheriting from other classes with virtual functions are not detected by the GDScript editor. However, their base classes are registered correctly. Sometimes the output console is empty, sometimes I get these errors :
ERROR: Extension runtime class 'GdrBtNodeNative' cannot descend from 'GdrBaseBtNode' which isn't also a runtime class.
ERROR: Extension runtime class 'GdrBehaviourSelector' cannot descend from 'GdrBaseNativeBehaviour' which isn't also a runtime class.
I cannot find any documentation on the subject and the extension won’t compile if I try to register the base classes as anything other than abstract
Code example:
Here are the important parts of some minimalistic code that reproduces the error. It compiles, and the GDScript editor knows BaseClass but not ChildClass:
test.hh
# ifndef TEST_H
# define TEST_H
# include <godot_cpp/core/binder_common.hpp>
# include <godot_cpp/core/class_db.hpp>
# include <godot_cpp/classes/object.hpp>
using namespace godot;
namespace custom
{
class BaseClass : public Object
{
GDCLASS(BaseClass, Object);
public :
static void _bind_methods();
void RealMethod();
virtual void VirtualMethod() = 0;
};
class ChildClass : public BaseClass
{
GDCLASS(ChildClass, BaseClass)
public :
static void _bind_methods();
void AnotherRealMethod();
void VirtualMethod() override;
};
}
# endif // TEST_H
register_classes.cpp
using namespace godot;
using namespace custom;
void initialize_module(ModuleInitializationLevel p_level)
{
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
{
return;
}
GDREGISTER_ABSTRACT_CLASS(BaseClass);
GDREGISTER_RUNTIME_CLASS(ChildClass);
}
void uninitialize_module(ModuleInitializationLevel p_level)
{
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
{
return;
}
}
extern "C" {
// Initialization.
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization)
{
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
init_obj.register_initializer(initialize_module);
init_obj.register_terminator(uninitialize_module);
init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
return init_obj.init();
}
}