(Warning: while writing this post I thought of new things and reconsidered my opinion multiple times, forcing me to change what I'd written. Hopefully it makes some kind of sense.)
I just realized that conceptually there are
three possible states for a custom property:
-There's the
default value: the value a property is set to if not specifically initialized for a particular object.
-There's the
initial value: the value of the property for a particular object set in the editor.
-There's the
current value: whatever the value has been set to at runtime for a particular object, with SetProperty().
I'm not 100% clear on which ones you are saying don't get stored as part of the save game.
So, I need to either do what I planned to do, and at least make modified values distinctive to be saved by introducing explicit "unmodified/modified" states to them.
Or I would need to keep any property value in memory and on disk, significantly increasing memory requirements, even if the game does not need that (that means most of the games).
Well, we don't know that most properties will never be changed; that depends entirely on how people use them. I can certainly believe that for most objects the custom property is just left to its default value, but I would think that in many cases where the custom property is actually set, it will be updated at runtime.
How do regular properties behave here, BTW? E.g. something like GUI.Y – if it's set in the editor and not modified in code, where will it appear if the value has been changed between the saved game and the current game version? What if it
has been modified in code? The question is fundamentally tricky, I think: there is no one behavior that will always be "right".
Personally I therefore think the priority here is to make the behavior consistent (or, rather, systematic) across regular properties, regular variables/fields, readonly "constants", #define constants, Global Variables, and custom properties. To me, the most logical distinction is that only values that can't be updated in the script should be automatically set to what they're defined as in the latest game version. (Readonly "constants" should technically then update to the new values, but if that's hard to do, I feel that the difference in terminology provides an acceptable loophole.)
For properties, I think as a dev I would prefer to have a distinction between initialized and uninitialized ones: For objects where the property has not been initialized (either set in the editor or with SetProperty()), any change to the default value will apply to them. This makes sense because the default is a constant.
With the new SetProperty() API, I don't think the property values of specific objects can be considered constants any more. So I think they should always use whatever value they were set to, either in the editor or with SetProperty(). If this takes a bit more storage, well, that's the natural consequence of introducing more variables into the game, isn't it?
If you want to be able to keep the behavior where they take on new values from the game version, instead of this modified/unmodified distinction, how about a distinction between constant and variable properties? Constants can't be changed with SetProperty(), but will take on the value set in the new game version, while variables will retain whatever value they've been set to, whether or not they've been "modified" in the code. (The same distinction could be extended to Global Variables as well.)