Instantiate loosing values

Godot Version

4.1

Question

So, to keep it short:

i have a control node (scene) with a script on it:

extends Control

@export var title:String
@export var pages:Array
## Max 4 Choices[br]
## Choice: Array [choice text, packedscene]
@export var choices_available:Array

Its a “choose your own adventure” book. A chapter has an array of pages and a choices array of arrays.
For testing purposes, i made a ready function that prints out the values and instantiated directly into the scene.
If I load a different chapter, the 2nd loaded chapter looses everything after @export pages (i made extra export values after where i defined chapter name and the packedscene)


test_01, pages, option text, target scene
test_02,pages, option text empty, target scene null

Tried different approaches but it always looses those values, but keeps/loads the first 2 perfectly and individually. i broke up the array of arrays into seperate values. loaded them directly into the scene. I even kicked the inheritence, that both are inherited from my default chapter thing.

Is this a Bug or am I missing something?

Edit: So it was because 1st PackedScene was referencing a 2nd PackedScene which referenced back to the 1st PackedScene. It throughs an error because of the loop and loses every value after this and sets it to the default, which is null

Can you post the code that loads the nodes?

1 Like

Can you show us the print code? You’re outputting PackedScene resources, which are the actual scenes, and not strings or arrays.
Also, is the test_01,pages etc part of the print output? I can’t tell if that’s forum messing up the formatting or if that’s supposed to be something else.

Nitpick: “Loose” means something isn’t tight, “lose” means it’s lost.

1 Like
extends Control

@export var choices: Array

#here is the first chapter where it starts
@export var chapter: PackedScene

@onready var title = $"Title Area/VBoxContainer/Label"

@onready var chapter_pages = $TextBtn/HBoxContainer/Pages

func _ready():
     set_up_page(chapter)

#here is the func to get all the values from the instance and put them on other nodes to display
func set_up_page(new_chapter):
     var chapter_to_load = new_chapter.instantiate()
     title = chapter_to_load.title
     chapter_pages = chapter_to_load.pages

#buttons send a int to this function to select the loaded choices, which is a list of packed Scenes
func change_chapter(choice:int):
     #id 1 is the packed scene in the array, id 0 is the text that is on the 
     #button
     set_up_page(chapter_to_load.choices_available[choice][1])

#Note: trying to recreate the code i had at the start

First time load works, when i turn the page and trigger set_up_page through the change_chapter, the choices_available are empty but the title and the chapter_pages are loaded normal.

With that I tried to make clear that test_01 loads normal and test_02 still has the name “test_02” and the array of pages (PackedScene xxx) and then lost the complete array of choices_available.

which should be something like this:

[
[back to test 1, PackedScene(chapter test_01)],
]

lol the Nitpick.

Eventually I tried to write both chapters as export in the main scene and load them both in ready function into the scene and add them as child. with that the ready func of the chapters get triggered and tell me whats loaded (img above) and the 2nd chapter always loses the choices available on it.

Both chapters are inherited scenes of an empty chapter scene, where i setup the export values.
which i eventually broke for testing

I’m not an expert but my first guess would be double checking to make sure the packed scenes are preloaded before instantiating.

It also looks like the set_up_page alters the title and chapter pages, but does nothing to the choice or chapter variables.

Can you post the scene or scene tree from the left side of the editor?

can i preload right before i instantiate or just when the scene starts? Because that would mean preloading potentially 100 chapters, which i’d rather not.

what i do with loaded instances is not important. My problem is instantiate loses values.

Like i said, i put it outside of those functions and just loaded them in right at the start of loading the scene with the same method and 2nd page has lost values.

I’m gonna test in a new project.

If you are assigning PackedScenes to your choices_available then you are essentially preloading the other scenes, this may cause a cyclical dependency which is resolved by silently nulling the value. You should instead use file paths and load before instantiating

# I'd use two aligned arrays for text and scenes instead of array of arrays
@export var choices_text: Array[String]
@export_file("*.tscn") var choices_available: Array[String]

func change_chapter(choice: int) -> void:
    var new_chapter: Control = load(chapter_to_load.choices_available[choice])
    set_up_page(new_chapter)
1 Like

Ah, thank you. I’ll give it a try

By the way, preload is only done when the script is first parsed. If you do it later, it’s just load.

1 Like

Thank you again, works perfectly.

I was wondering why Godot screamed at me after i restarted the project.
And thanks for the:

Array[String]

didn’t know i could define what kind of array it is.