godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.34k stars 20.01k forks source link

ProjectSettings.SaveCustom doesn't write default values #83494

Open Joshimuz opened 10 months ago

Joshimuz commented 10 months ago

Godot version

4.2.beta1.mono

System information

Godot v4.2.beta1.mono - Windows 10.0.19045 - Vulkan (Mobile) - dedicated NVIDIA GeForce RTX 3070 (NVIDIA; 31.0.15.3758) - AMD Ryzen 9 3900X 12-Core Processor (24 Threads)

Issue description

If when using ProjectSettings.SaveCustom() to write a value to a setting that is a default Godot Engine value, the line that would contain that setting and it's value is omitted from the file, even if the project.godot file has that setting at not a default value.

For example, the "display/window/size/mode" setting has a value of 0 by default in Godot. If you attempt to set this value to 0 with ProjectSettings.SetSetting("display/window/size/mode", 0); and then use either ProjectSettings.Save() or ProjectSettings.SaveCustom() it won't be committed to the file and instead skipped, which makes sense to save on file size and all that.

The problem arises, if you change the value from the default 0 in project.godot (using ProjectSettings.Save()) to say: 1, then try to set it back to the default value of 0 in override.cfg (using ProjectSettings.SaveCustom("override.cfg")), that setting's line and associated value is then omitted from the file, thus not overwritten from the project.godot file setting, and therefore is not changed.

Steps to reproduce

In Project Settings in the editor, change a setting to a non-default value, for example: Display/Window/Size/Mode to "Minimized" ("display/window/size/mode = 1").

In a C# script, use ProjectSettings.SetSetting() to change the value back to the editor's default, for example: ProjectSettings.SetSetting("display/window/size/mode", 0); Then use ProjectSettings.SaveCustom() to attempt to save the value to a override.cfg file, for example: ProjectSettings.SaveCustom("override.cfg");

Run the script, and open "override.cfg" and see that the line window/size/mode=0 is missing from the [display] section and the program will start minimized, even after repeated restarts.

You can set "display/window/size/mode" to anything other than 0 and it will successfully override the project.godot setting, you can also manually add the line window/size/mode=0 in the [display] section and it will work as intended and override the setting and the program will start in windowed mode.

Minimal reproduction project

N/A

KoBeWi commented 10 months ago

This is somewhat consistent with how Resources are normally saved, although ProjectSettings use custom saving and explicitly skip defaults: https://github.com/godotengine/godot/blob/fd33c7b32f54e9ac3d346be718618575338cd7ef/core/config/project_settings.cpp#L1032-L1034 Since it's a simple ConfigFile, you can manually write one without using ProjectSettings API.

Not sure how this should be solved. save_custom() is used internally by other methods, so this behavior (i.e. saving defaults) should be optional. Either when writing override.cfg or as a separate argument. Although I assume you'd expect that only defaults that are changed in the base project settings are written? Because not skipping defaults means that the override file will contain every single setting. Probably too much hassle to support this.

AThousandShips commented 10 months ago

Also what happens if you change the setting in project.godot from default to not, how should override.cfg react to that? If we handle this by having the result of project.godot + override.cfg be equal to what your settings are

TwinTailDigital commented 2 months ago

I believe this is still an issue in 4.3beta1 as I am trying to use ProjectSettings.save_custom() and my settings that have been changed with ProjectSettings.set_setting() don't seem to work.

TwinTailDigital commented 2 months ago

Also what happens if you change the setting in project.godot from default to not, how should override.cfg react to that? If we handle this by having the result of project.godot + override.cfg be equal to what your settings are

This is what is the issue. The game is looking at project.godot and completely ignoring override.cfg. When I removed the setting in project.godot it started loading from override.cfg