Error constructing a GDScriptInstance

Godot Version

4.2.2 Stable

Question

Full Error:

E 0:00:00:0305 deck_entry.gd:81 @ load_from_file(): Error constructing a GDScriptInstance.
<C++ Error> Method/function failed. Returning: nullptr
<C++ Source> modules/gdscript/gdscript.cpp:188 @ _create_instance()
deck_entry.gd:81 @ load_from_file()
deck_entry_display.gd:18 @ _ready()


Here is the additional context:

Saving and loading methods for this class:

func save_to_file(folder_path: String) -> Error:
	# Construct the full file path
	var file_path := folder_path + "/" + card.id_string + ".tres"

	# Save the resource to a file
	var error := ResourceSaver.save(self, file_path)
	if error != OK:
		print("Error saving DeckEntry: ", error)
	
	return error


static func load_from_file(file_path: String) -> DeckEntry:
	# Load the resource from the file
	var resource : Resource = ResourceLoader.load(file_path)
	print(file_path)
	if resource is DeckEntry:
		return resource as DeckEntry
	else:
		print("Error loading DeckEntry from file: ", file_path)
		return null

Here is the code I ran to produce the error from another class:

var d := DeckEntry.new(preload("res://resources/cards/test_card.tres"))
	d.save_to_file("res://resources/decks/bbb/deck_entries/main/")
	deck_entry = DeckEntry.load_from_file("res://resources/decks/bbb/deck_entries/main/test_card.tres")

Notes:

  • The resource does exist under the name at the file path
  • I have deleted and created new resources but the same error occurs
  • The resource does reference the correct script
  • The resource is in fact of type DeckEntry in the inspector
  • However when checking the type of the resource when loading it from code I can see that it is of type resource but not DeckEntry for some reason.
  • Casting it to DeckEntry immediately also did not help

image

Any help is appreciated. I have sadly no clue what is going on and this is really blocking any progress.

Fixed following the steps here:

Godot will try to call your _init method while loading the Resource. But it can’t because it has a non-optional parameter (Godot has no means to figure out what to pass).

Thus, a possible solution is to make it optional:

func _init(_some_title: String = ""):
    title = _some_title

Alternatively, you could remove it entirely.

You could also take control of how the Resource is loaded by implementing a ResourceFormatLoader which you register with ResourceLoader.add_resource_format_loader.

Alternatively - in particular if you need to be able to load the Resource from the editor - you could be interested in implementing EditorImportPlugin which you register from an EditorPlugin using EditorPlugin.add_import_plugin.

Then your implementation can use your _init correctly.

As an alternative to adding parameters to _init you can add static methods to build your type※:

static func with_title(_some_title:String) -> MyDataStructure:
    var result = MyDataStructure.new()
    result.title = _some_title
    return result

※: Doing this in Godot 3.x would have required a helper class, because Godot would not resolve the name of the class while parsing the class.

That might also improve readability of your code. For example, anybody unfamiliar with your code, and without looking up the definition, could guess that argument is a title:

var instance := MyDataStructure.with_title("BLAH")

By the way: Godot does not support named arguments.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.