godotjs/javascript

How to extend from Scene

Opened this issue · 2 comments

Card.tscn

[gd_scene load_steps=2 format=2]

[ext_resource path="res://Card.jsx" type="Script" id=1]

[node name="Card" type="Node2D"]
script = ExtResource( 1 )

Card.jsx

export default class Card extends godot.Node2D {
  _ready() {
    console.log('Card _ready')
  }
}

FarmerCard.tscn

[gd_scene load_steps=2 format=2]

[ext_resource path="res://Card.tscn" type="PackedScene" id=1]
[ext_resource path="res://FarmerCard.jsx" type="Script" id=2]

[node name="FarmerCard" instance=ExtResource( 1 )]
script = ExtResource( 2 )

FarmerCard.jsx

import Card from './Card'

export default class FarmerCard extends Card {
  _ready() {
    super._ready()
    console.log('FarmerCard _ready')
  }
}

run FarmerCard.tscn scene, console output(missing "FarmerCard _ready" log):

Card _ready

error by exit the program:

Object leaks:
       ADDRESS REFS SHRF          PROTO      CLASS PROPS
0x7fa149587bd0    1   0* 0x7fa148dbd410 GodotOrigin { __class__: 1"ECMAScript", __ptr__: 1"0x49587B00", __ctx__: 1"0x469A94E0", __id__: 1382 }
Assertion failed: (list_empty(&rt->gc_obj_list)), function JS_FreeRuntime, file quickjs.c, line 1978.

Card.gd

extends Node2D

func _ready():
  print('Card _ready')

FarmerCard.gd

extends "res://Card.gd"

func _ready():
  print('FarmerCard _ready')

use gdscript run FarmerCard.tscn scene, console output:

Card _ready
FarmerCard _ready

You are right this isn't working at the moment.

I tested it and found out that the functions of FarmerCard.jsx aren't called when the node is inherited.

It only works if the FarmerCard.tscn extends from godot.Node (I use TS here which includes the Card.jsx code in the other file):

image

prints:
image


This leads us to a workaround and a question/bug.

Bug
If it's possible with gdscrip it should be possible in JS/TS. The question is how and who can solve it ^.^

Workaround - Separate Nodes and code

If you have Card.tscn you can add other Child Nodes and use it as a pure UI Node without any scripts attached.
Inside FarmerCard.tscn you add your FarmerCard.jsx which extends the Card.jsx and both _ready functions should be called.

With this approach, we add some complexity, because you need to add scripts to children inside Card.jsx by code with set_script. On the other hand, you would separate your "UI" and "Code" which is a common pattern, I guess :P