2 GDScript behaviour I don't understand

Godot Version

4.2

Question

First, setter function.
If you know setter, you know that you have to add “value = new_value” in the function, or the property won’t be modify.
HOWEVER, if you modify the property’s sub-property directly, it WILL modify the property, and the setter still gets called, which…leads to confusion.
I actually posted this as an issue yesterday, nobody said anything, but I’m still confused as hell.
I want to get this question out of my head.

Second, custom resource.
I just tried to duplicate a custom resource, and somehow it doesn’t duplicate the value at all.
Ask around gave me the solution: add @export in front of every property. THEN Godot will duplicate then.
Now. I might be ignorant to assume all @export do is expose property to the editor and store stuff in a scene file, but why would Godot assume if I don’t export a variable, I wouldn’t want to duplicate it??
I mean it’s right there, all the stored property printable, accessible, but will be ignore if I duplicate the whole thing??
Should I report this as a bug, or am I missing something? At least there’s no mention of this behaviour in doc about @export.

For your first question, if you replace your print with this you will see that the value is already set by the time the setter is called:

print("Set function called. Current: %s, new: %s" % [vec_2, new_vec])

Will print:

Set function called. Current: (2, 0), new: (2, 0)
(2, 0)
Set function called. Current: (2, 2), new: (2, 2)
(2, 2)

In other languages setter won’t be even called if you just modify members of the instance directly. Here though, the setter is called but the value is already set. I guess it is called just for the sake of notifying you that the value actually changed.


For your second question it’s by design. You control what is serializable in the resource by exporting fields. Everything else is ignored.

I just now notice that doc already mention duplicate only works on @export var. I still don’t get the use case, but I guess that’s it then.
The first one though, I still think it should at least be in the doc. Setter not being called when modified members would be inconvenient, but would at least be more consistent IMO.