Inconsistent Saving Resources in Editor

Godot Version

Godot 4.6

Question

I’m making a graph-based tool for a game using the engine’s GraphEdit. I’m using the Graph Edit and its nodes as a view, which should save the graph’s data as a custom resource.

I’ve noticed some unusual behavior when trying to save my graphs as a custom resource. There are several distinct issues and I don’t know what’s causing them.

The simplified data structure is this: GraphData is a custom resource representing a graph. It holds an array of NodeData, another custom resource.

The save code goes as follows:

func save_current_graph() -> void:
    var path = "res://addons/graph_attack/test/graph.tres"
    var resource: GraphData = current_graph.to_data()

    ResourceSaver.save(resource, path)

The to_data function reads:

func to_data -> GraphData:
  var data := GraphData.new()

  for node_key: String in _current_nodes.keys():
      data.nodes.append(_current_nodes[node_key].to_data())

  data.root_node = root_node.to_data()

The first issue is that this doesn’t overwrite the resource in disk. The engine prints 0 as error code, i.e no error.

I tried to fix it by adding this line before saving:

resource.take_over_path(path)

This lets the editor overwrite the file, however the saved resource’s values never get updated. The file created is new, but if the first save had a node named “FOO” and I changed it later to “BAR”, the file in disk would say “FOO”, even erasing it and saving it again.

I checked for problems by printing the resource created, and the data is fine at the moment of printing. The file in disk isn’t, it’s all over the place. The only thing that is correctly updated is the array’s size.

The only way I’ve gotten this to kinda work is by changing the save path to a new path every time, i.e:

var save_path = path + str(counter) + ".tres"
counter += 1

I’d be glad if anyone has encountered this issues. Most plugins are able to save resources just fine, it seems.

1 Like

I don’t know why you chose .tres, but I personally like this method:

save

var save_path = "res://game_data.save"
func save_game():
	var file = FileAccess.open(save_path, FileAccess.WRITE)
	var data = {
		"Attaak" : 100,
		"Deffend" : 100
	}
	file.store_var(data)

load

func load_game():
    var file = FileAccess.open(save_path, FileAccess.READ)
    var data = file.get_var()
    return data

P.s. I’m not good at graphs, but I hope this method works for you.

It sounds like you have nested custom resources. Give this a read – How to properly save nested resources edited with custom editors? · godotengine/godot-proposals · Discussion #7168 · GitHub

Also maybe this Saving Nested Custom Resources applies

1 Like