Loading embedded resources

Godot Version

4.6.2

Loading embedded resources

I have a class of resource that often has certain other resources attached. In order to reduce file clutter, I saved them as embedded on the parent resource.

However, now Godot is failing to load the embeded resource. Specifically, they attempt to load the embedded resource directly, using it’s unique path ([parent resource path]::Resource_5olpp for example), but is failing to do so.

Is it possible to access embedded resources this way or do I have to save what are currently embedded resources as separate files?

Thank you for your time

What’s the error message?

E 0:00:01:576 story_info.gd:200 @ load_all(): Resource file not found: res://Story Scenes/Dialogs/Marcus/Options/Games.tres::Resource_5olpp (expected type: unknown)

It’s a dialog option that grants a clue upon being selected, and the error is happening when attempting to load an onoing game. When the clue is first added to the global list of clues in the Story_info object in runtime, it works fine

And what’s the code you’re using to load it?

The error message above was acheived using a simple load using the resource path as determined by resource_path. Using a resource loader the same error message as above is found, and the following is added to it:

E 0:00:01:726 story_info.gd:200 @ load_all(): Error loading resource: 'res://Story Scenes/Dialogs/Marcus/Options/Games.tres::Resource_5olpp'.

Perhaps someone else can help you without seeing your code, but I cannot.

Double check that the id is correct.

In general, if you need to load a sub resource, it’s better to save it in its own file because Godot might re-generate ids on some occassions.

Sorry, but it’s just that I asically alrady told you what the code does, but it contains other things that don’t seem particularly relevant here, but could worsen understanding significantly, such as creating dictionaries and lists during the process of saving

The process was also working before I changed the resources into being embedded (and still doesn’t in the ones I didn’t), hence why I laser focused on that aspect

As in if I am simply using the wrong kind of load, or if the solution is to save them as separate files

Seems the id indeed changed. Will reverse the change and save them as separate resources. Thank you for the clarification

Double checked and actually they did not change, and remained res://Story Scenes/Dialogs/Marcus/Options/Games.tres::Resource_5olpp. But if there is the chance they could spontaneously change, and since this is clearly the problem + two experienced devs could not easly point out a possible solution, it seems more than reasonable to simply save as separate resources regardless

I just got tired of playing 21 questions. I can think of a number of things it could be, but I decided I just don’t have time for, “Did you try this?”

You seem to think that you know better than I do what I need to diagnose your problem, so here we are…

You get what you put into a question, and you have put very little effort into this one.

Glad you found your solution on your own, but why waste our time if you were going to just do this from the beginning?

I’m sorry if I came off as rude. That was not my intention. I have learned that it’s generally better to ask a question, even if it seems stupid or obvious, and tried to apply it here. I really was looking for a possible simple solution that might exist, and had little genuine hope one could be found, especially when it seemed to not be obvious to you right away

Here is the full code (unrelated bits removed) in case you are still interested. Of note is that none of the manual error messages coded by me triggered, rather the excecutable stopped and Godot itself returned the error messages above

Like I mentioned, other resources have been loaded successfully by this method , and manually cheking the resulting files show the correct path

func save() -> void:
	var clue_info :Dictionary[String, Array] = {
		"clues": get_paths(clues_found)
	}
	save_dictionary(save_paths["clue_info"], clue_info)

##Saves the dictionary dic in the specified position[br]
##path should be a 'user://' path
func save_dictionary(path :String, dic :Dictionary) -> void:
	var save_file = FileAccess.open(path, FileAccess.WRITE)
	if save_file:
		save_file.store_line(JSON.stringify(dic))
	else:
		pass

func get_paths(arr :Array) -> Array[String]:
	var ret_arr :Array[String] = []
	for res in arr:
		ret_arr.append(res.resource_path)
	return ret_arr

 ##Loads all information from memory
func load_all() -> void:
	var json = JSON.new()

	info = load_dictionary(save_paths["clue_info"], json)
	if info != {}:
		clues_found.clear()
		for path in info["clues"]:
			clues_found.append(ResourceLoader.load(path))
	else:
		print("Error loading ", save_paths["clue_info"], ". Error: ", json.get_error_message())

	#Current scene is loaded last in case it needs to access the previously loaded info
	info = load_dictionary(save_paths["current_scene"], json)
	if info != {}: 
		assert(info.has("PackedScene"), "Failed to load current_scene")
		current_scene = load(info["PackedScene"]).instantiate()
		current_scene.load_saved_info(info)
		get_tree().root.add_child(current_scene)
	else:
		print("Error loading ", save_paths["current_scene"], ". Error: ", json.get_error_message())

##Returns the parsed dictionary, or an empty dictionary if it didn't work
func load_dictionary(path :String, json :JSON = JSON.new()) -> Dictionary:

	var json_string = FileAccess.open(path, FileAccess.READ).get_line()
	var parse_result = json.parse(json_string)
	if not parse_result == OK:
		return {}

	if json.data is Dictionary:
		return json.data
	else:
		return {}`

Keeping spaces and uppercase letters in directory names is a really bad habit.