Godot Version
4.4-beta1
Question
I’m trying to write a GDExtension with a virtual class that I can use as a base for other GDScript classes to extend from.
So far I have a C++ class:
class TerrainGenerator : public Node {
GDCLASS(TerrainGenerator, Node)
private:
int seed;
protected:
static void _bind_methods() {
ClassDB::bind_static_method("TerrainGenerator", D_METHOD("create", "seed"), &TerrainGenerator::create);
GDVIRTUAL_BIND(_generate_chunk, "chunk")
ClassDB::bind_method(D_METHOD("generate_chunk", "chunk"), &TerrainGenerator::generate_chunk);
ClassDB::bind_method(D_METHOD("get_seed"), &TerrainGenerator::get_seed);
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &TerrainGenerator::set_seed);
}
public:
static auto create(const int seed = 0) -> TerrainGenerator* {
auto* inst = memnew(TerrainGenerator);
[...]
return inst;
}
GDVIRTUAL1(_generate_chunk, Chunk*)
virtual auto generate_chunk(Chunk* chunk) -> void {
assert(GDVIRTUAL_CALL(_generate_chunk, chunk) && "generate_chunk not implemented in target class");
}
auto get_seed() const -> int { return seed; }
auto set_seed(const int seed) -> void { this->seed = seed; }
};
which I registered with GDREGISTER_VIRTUAL_CLASS
and then created a simple .gd script with a class that extends it:
class_name SimpleNoiseGenerator
extends TerrainGenerator
var noise: FastNoiseLite
func _generate_chunk(chunk: Chunk) -> void:
[...] (omitted for brevity)
This parses fine, but when I try to instantiate the SimpleNoiseGenerator
class through the base class’s .create()
method, I get an error message on runtime:
var generator: SimpleNoiseGenerator = SimpleNoiseGenerator.create(0)
Invalid call. Nonexistent function 'create' in base 'GDScript'.
For more context:
- the .create() pattern works on other (C++) classes of mine that don’t have any inheritance
- the Godot script editor suggests SimpleNoiseGenerator.create(seed: int) as a valid method and I can even view its signature
- I’m using this .create() pattern because AFAIK there is (currently) no way to have a custom constructor with parameters exposed from a GDExtension to the GDScript side