If a resource is used as a key in a dictionary, it will be replaced by null when saving with ResourceSaver

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dizzar

I created two resources, ResA and ResB:
ResA.gd:

extends Resource
class_name ResA

export var data : String
export var data2 : int

ResB.gd:

extends Resource
class_name ResB

export var data : Dictionary = {}

Then, I created a new ResB instance and saved it like this:

func _ready():
	var buggy = ResB.new()
	
	var res = ResA.new()
	res.data = "A1"
	res.data2 = 1
	
	buggy.data[res] = [1, 2, 3]
	
	res = ResA.new()
	res.data = "A2"
	res.data2 = 2
	
	buggy.data[0] = res
	
	ResourceSaver.save("res://data.tres", buggy)

Then, when looking at the saved resource, I found that the resource that was used as a key in the dictionary was replaced with a null, while the resource that was used as a value in the same dictionary was saved. Why does this happen?
The workaround I found is to add another array to the ResB that will hold all your resources that were used as keys. In that case it will be saved properly.

Also, this is output to console when trying to save:

ERROR: Resource was not pre cached for the resource section, bug?
   At: scene/resources/resource_format_text.cpp:1373

The debugger Is actually asking you if that’s a bug?
Lol

Does it work if you save the resource in a resource in a lesser fancy way?
Like a simple buggy.data=res? (instead of involving dictionaries)

Andrea | 2021-08-26 10:30

It works, only time I noticed a resource is replaced by null is when it is used as a key in a Dictionary that is a part of another resource, and isn’t stored in other variables in the same parent resource.

Dizzar | 2021-08-26 12:41

Could be that the resource used in the dictionary is actually just an index to the real resource, but I’m not sure…

Andrea | 2021-08-27 17:40

:bust_in_silhouette: Reply From: Dizzar

So, with the release of Godot 4 alpha 1, while the bug is still present, I found a workaround for you, theoretical person who ran into this problem.

Simply use .res file instead of .tres, and the problem will go away. The downside is that now your file is binary and not human readable. Oh well.