godotengine / godotengine/godot
_init doesn't override a value in inherited scene with @export flag
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
Reproducible in v4.3.stable (77dcf97d8) : _init of inherited scene doesn't override a `@export` variable from the base class.
### System information
Godot v4.3.stable (77dcf97d8) - Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1070 (NVIDIA; 32.0.15.6094) - AMD Ryzen 7 2700 Eight-Core Processor (16 Threads)
### Issue description
The class which inherits from another and tries to update `@export` variable of a parent class can't do it.
I've created two classes. One inherits from another (for e.g. Animal & Dog). Animal has an `@export` variable (e.g. `@export` animal_name: String). Dog has _init function included which tries to update Animal's animal_name. Once I try to preload and then instantiate Dog class somewhere in my project the code from _init inside Dog class executes, but animal_name doesn't update like it should.
Once we delete `@export` flag everything works fine - in this case _init of the class that inherits updates base class variable.
Example in project:
Animal Scene script:
```
class_name Animal extends Node2D
@export var animal_name: String # Once we delete @export everything seems to work fine
@onready var animal_name_label = $AnimalNameLabel # Label in the node tree
func _init() -> void:
print("Animal _init Happens")
animal_name = "Animal"
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
animal_name_label.text = animal_name
print(animal_name)
```
Dog Scene (it inherits from Animal) script:
```
class_name Dog extends Animal
func _init() -> void:
print("Dog _init Happens")
animal_name = "Dog" # If animal_name is @export variable then it doesn't work, otherwise animal_name gets updated
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
super._ready()
pass # Replace with function body.
```
Main scene to which I try to add my Dog scene:
```
extends Node2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var scene = preload("res://Dog.tscn")
var instantiated_scene = scene.instantiate()
add_child(instantiated_scene)
```
Effect:

### Steps to reproduce
1. Create new scene
2. Attach script to created scene, give it a custom class_name and add any variable with `@export` flag
3. Create new inherited scene using Godot Editor (right click on the previously created scene -> New Inherited Scene)
4. Save Inherited Scene with custom name
5. Attach new script to newly created scene
6. Make the second scene extend the first one (e.g. class_name Dog extends Animal)
7. Add _init inside second scene and try to update previously created variable from the base scene
8. Once we will try to programatically add our base scene to the node tree - preload(scene) - and then instantiate it, the value from our base class won't be updated, yet the code from _init in second class (class that inherits) will be executed
### Minimal reproduction project (MRP)
[example_project.zip](https://github.com/user-attachments/files/17446819/example_project.zip)
Contributor guide
Research direction
Start with the attached example_project.zip and reproduce the issue by inspecting the Animal and Dog scripts and the preload/instantiate sequence in the main scene. Compare initialization with and without the @export flag, then verify that the inherited scene's _init assignment persists when Dog is instantiated and added to the scene tree.
Written by the indexing model from the issue text.
Assessment
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100