Godot version:
2cde466ebdb6237b6f72ef78614dc05f2ffb551b
OS/device including version:
Windows 10 64bit
Issue description:
From what I can tell subclasses do not inherit the _init function when they are extended
extends Node
class test:
func _init(t = 0):
print(t)
class test2 extends test:
var nothing = 0
func _ready():
test.new(100)
test2.new(4)
this code prints 100 and then throws an error of Invalid call to function 'new' in 'GDScript'. Expected 0 arguments. at line 12 test2.new(4)
Steps to reproduce:
You can either run the reproduction project, or paste the code above and run it.
Minimal reproduction project:
subclass_bug.zip
You didn't declared the _init(arg) for your class test2.
You may try this
class test2 extends test:
var nothing = 0
func _init(t = 0).(t):
pass
Maybe needs to be better documented?
Writing an additional signature doesn't make any sense if I'm not actually going to do something inside that new definition. It's just more code I have to write to do exactly what I want it to do.
Yeah actually I agree this shouldn't be needed.
@akien-mga Is this something you don't see being possible before 3.0?
@Geequlim I appreciate the knowledge of the possible workaround at the moment.
Yes it's too late for 3.0.
I have another example of this for reference:
extends KinematicBody2D
var state = B.new(self)
class A:
var player = "test"
func _init(p_player = "test2"):
player = p_player
call("randomfunc")
class B extends A:
func _init(p_player = "test3"):
._init(p_player)
func randomfunc():
print("Hello: ", player)
Prints:
Hello: test2
Hello: [KinematicBody2D:1120]
First the base class's _init() callback fires, but it completely ignores any inputted parameter and runs with whatever the default value is. I think this is another part of the bug that should still use the provided value.
Then the derived class's callback fires, but because we instanced the derived version (my guess), it actually does plug in the parameter we passed. I then manually called the base class's constructor callback a second time via the "parent call" syntax (notated by the preceding '.' in the method call).
My initial issue might be related to this
https://github.com/godotengine/godot/blob/master/modules/gdscript/gdscript_compiler.cpp#L1611
0 is hardcoded for the number of arguments for the default _init function, I'm not sure what the right fix is though.
@willnationsdev I imagine what's happening for your case is you probably need to write it like:
func _init(p_player="test3").(p_player):
pass
otherwise it's going to call like this: I think
A._init() -> B._init("test3") -> B.Super._init("test3")
Edit:
The reason I think the suggestion above works is because you're trying to change the default value. If you weren't, you'd be doing the same thing I'm trying to do in the original issue.
NOTE:
I personally think the _init().() syntax is a bit annoying, and the _init method should probably just require ._init() (super) to be called inside it. but that's a different topic.
I tried to fix this for 3.1 but it wasn't as easy as I thought at first. Will try to review this soon.
For 4.0 we might try to change the syntax for calling the parent constructor (among other things). It's a big compatibility breakage but I think it's for the best.
Most helpful comment
You didn't declared the
_init(arg)for your classtest2.You may try this