hey guys, I had an issue with resources and wanted to know if there’s a fix for it or if i messed up anything in my code that’s causing this issue. So i was coding a dialogue system using resource files. i basically had 3 resource layers one on top of the other. the issue for me was that when i filled the container tres file’s dict variable with key/value pairs and then tried to save it, it just would not save. only the non dict variable’s would save. Also when i use the inspector on the container and try to fill the node dict and the choice dict, none of it would save. only the container tres’s non dict variables would save. is this a bug? or am i doing something wrong.
[resource]
script = ExtResource(“2_6piuy”)
conversation_id = “test_1”
starting_node = “1”
nodes = Dictionary[String, ExtResource(“1_bdlmo”)]({
“”: null
})
metadata/_custom_type_script = “uid://c3cp8odvddpta”
this is the raw text from the file if it helps.
extends Resource
class_name DialogueContainer
@export var conversation_id: String
@export var starting_node: String
@export var nodes: Dictionary[String, DialogueNode] = {}
@export var is_repeatable: bool
extends Resource
class_name DialogueNode
@export var node_id: String
@export var speaker: String
@export var dialogue_text: String
@export var ref_visual: String
@export var ref_ui: String
@export var choice_list: Dictionary[String, DialogueChoice]
@export var next_dialogue_id: String
extends Resource
class_name DialogueChoice
@export var choice_id: String
@export var choice_text: String
@export var choice_effects: Dictionary = {}
# choice_effects shape {"stat_name": {"delta": float}} + more after modifiers addition
@export var next_dialogue_id: String
@export var requirements: Dictionary = {}
#requirements shape: { "stat_name": {"value": float, "operand": String} }
What you try to too looks perfectly alright, but from my experience with explicit types – even tho they are great to have – in Godot it can pay often out to try without them.
I would try without explicit types on the dictionaries and if that helps you could also try to use Variants instead of your custom Resource types as a little compromise.
So try I would try it like this first, if you haven’t yet:
@export var nodes: Dictionary = {}
@export var choice_list: Dictionary = {}
@export var choice_effects: Dictionary = {}
@export var requirements: Dictionary = {}
Do you assign the dictionaries in code or through the Godot editor (i.e. inspector)? For debugging purposes I would try the to do it in code here first, in order to see if that works, because in code you can be sure what you assign is of the correct type.
Another way you could try to debug it is to exchange the Dictionaries for Arrays and see if everything works with those instead.
After adding a new DialogueNode keyVlaue for example, and then filling it it, make sure you add an empty DialogueNode key/value, before saving. Otherwise it will not see the last entry.
See screen shot. You must add an empty Key/Value otherwise DN3 will not be saved.
Is it a bug though?
When should it save? If you save the new entry as soon as you create the new entry then all that you change in the value doesn’t get saved (ex Speaker, dialogue text, etc)
Should it have a dedicated Save button as well as an Add Key/Value Pair button?
I don’t think this is a bug situation but I agree it is a quirk.
For the record, this very situation had me scratching my head as to what was going wrong the first time I ran into it.
hey thank you for your response. i tried it without explicit types and it didn;t work, the second comment solved it tho. it was more so related to how godot inspector saves the values in inspector for dictionaries. also i use the inspector for debugging resource files but you’re right i could try to do it in code first. i’ll implement that from now on,
omg thats so ridiculous. i honestly almost gave up on resources all together. ty for finding this out. it works like a charm. i get why its saved this way but it would’ve been nice if godot had this documented. anyways ty
It’s unexpected behavior in the inspector because normally any change one makes should be saved immediately when the scene is saved. In this case you need to add an extra empty property to save correctly.
I have gotten bitten several times by forgetting to hit the Add button after editing a new entry. But I’ve been assuming the reason you have to hit that button is because the entry you just edited is still an in-progress entry that has not been added to the dictionary yet. Not that you are adding a blank entry to the table at the end.
I do wish it were more obvious that the last entry isn’t in the dictionary/array yet.
It isn’t so straight forward.
One of the items editable in the inspector is the key.
If the key is saved immediately then it would allow editing an existing key and that you cannot even do via code.
(Also the first attempt to save a key would be a NULL key and although NULL is a legitimate key in GDScript dictionaries, if you are exporting typed dictionaries such as my_dict[String, int] what happens?)
If you begin saving the key as letters are typed then you open the interface up to duplicated keys.
test
test2
If you save on leaving the input box and the user has typed an existing key you end up in exactly the same situation this post is about; Godot will have no choice but to not save that entry. (This is what happens currently when you try to add a duplicate key).
In my opinion this system is quirky but does not constitute a bug.
I could, however, see this a feature request to change the way dictionaries are exported. The only real alternative imo is a dedicated save entry button.
Edit:I didn’t see this at first for the reply here:
saved immediately when the scene is saved
I would say this is closer to expected behaviour but it still leaves the problem of how to handle invalid keys (and values) on save.
Do you stop the scene save? Do you flag an error? Do you silently fail like the problem presented in this thread does?