How do I pass in arguments to parent script when extending a script?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Jamoxploder

I have a base item class which stores universal item information.
The intention is to extend this class for different item types.

extends Node

class_name Item, "res://Scripts/Item.gd"

var id
var item_name
var type

func _ready():
	pass
	
func _init(var _id, var _item_name, var _type):
	id = _id
	item_name = _item_name
	type = _type

and I’m trying to extend this class to create a Health Item class:

extends "res://Scripts/Item.gd"

class_name Health, "res://Scripts/Health.gd"

var hp
var heal_time

func _ready():
	pass
	
func _init(var _hp, var _heal_time, var _id, var _item_name, var _type):
	id = _id
	item_name = _item_name
	type = _type
	hp = _hp
	heal_time = _heal_time

This is how I would assume inheritance to work.
Is there some variation of a super keyword that I’m not aware of. Extending scripts is never made clear in the documentation (unless I missed something).
Can someone tell me what I’m doing wrong or what concept/s I don’t understand.
Is there a better way to achieve the same result?

:bust_in_silhouette: Reply From: Zylann

You can call base class functions by writing a . in front of the call, like this:

.some_function(id, item_name, type)

However, something very odd but important that Godot is doing, is that it calls _init automatically and in some special way (this also happens with special functions like _ready, _process and _input). So if you were to write this:

class A:
    func _init():
	    print("A constructor")

class B extends A:
    func _init():
	    print("B constructor")

It will print:

A constructor
B constructor

Notice how we didnt call the base class’s _init(). So basically, you don’t have to call the base function.
Instead, you do this:

func _init(a, b, c).(a, b):
    ....

Notice the extra .(a, b), this is how you call the base constructor with custom arguments.

Note 1:
You wrote var for each argument, but you don’t have to, they are optional.

Note 2:
For these _init to be called, I assume you are creating those objects from script, using Health.new() for example. On the other hand, I see you extend Node, but do you need this to be in the scene tree? (it won’t be if you don’t add them as child of another node).
If you don’t, you can simply remove extends Node and _ready(), as you don’t seem to use them here.

Excellent answer, thanks!

Found the reference in the docs :
3.2 docs → GDScript Basics → Class Constructor.

GDScript basics — Godot Engine (3.2) documentation in English

This makes my week so much simpler.

gamepad_coder | 2020-10-11 00:37