Variable values are not written to the save file

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By JerryHayat

I began to study conservation and ran into a problem. The code saves only what was originally set and ignores subsequent changes to the variable. I did it using different examples.

    extends Control
   

var FPSview = false
var lang = 1
var Volume = 1
const SAVE_PATH = "res://config.cfg"
var _config_file = ConfigFile.new()


var _settings = {
	"test" : {
		"fps" : FPSview 
	},
	"lang" : {
		"langset" : lang
		}
	}

func save_settings():
	for section in _settings.keys():
		for key in _settings[section].keys():
			_config_file.set_value(section, key, _settings[section][key])
	_config_file.save(SAVE_PATH)

func load_settings():
	var values = []
	for section in _settings.keys():
		for key in _settings[section].keys():
			var val = _settings[section][key]
			values.append(_config_file.get_value(section, key, val))
	
	return values

func del_settings():
	var dir = Directory.new()
	dir.remove("res://config.cfg")


func get_config(section, key):
	return _settings[section][key]

func set_settings(section, key, value):
	 _settings[section][key] = value

func _ready():
	load_settings()
	save_settings()



func _on_Save_pressed():
	del_settings()
	yield(get_tree().create_timer(1.0), "timeout")
	save_settings()

func _on_fpsOn_pressed():
	FPSview = true

I thought it was worth deleting the file before the new save, but that didn’t work.

:bust_in_silhouette: Reply From: Zylann

save_settings() looks correct, it saves the current values stored in _settings.

However load_settings won’t work if settings were never saved beforehand. It doesn’t check if a file exists, and doesn’t load one either. Indeed, it only reads values from _config_file (wether it has data in it or not) and returns them as an array, which you don’t even use.

Then in _ready, you call load_settings() first (which does nothing then), and save_settings(), which saves the current settings at that time, which are most likely the default ones because _settings hasn’t been updated at all by load_settings().

Now if you change FPSview = true, you change the variable, but not the value stored in _settings, which is something else. Indeed, when you declared the contents of _settings earlier, GDScript copies the values into the dictionary, because primitive types (float, int, Vector2, Vector3) are always handled by value. If you want that value to change, you need to change the contents of _settings, not another variable.

Finally, when saving you delete the file, wait a second and save it. That works, but deleting and waiting aren’t necessary. You can just call save_settings().


Now, to fix all this:

To modify _settings directly, do this:

func _on_fpsOn_pressed():
    # No need to use extra variables
    _settings.test.fps = true

To load them correctly:

func load_settings():
	var err = _config_file.load(SAVE_PATH)
	if err != OK:
		# Likely no settings were saved yet
		return err
    for section in _settings.keys():
        for key in _settings[section].keys():
            var val = _settings[section][key]
            _settings[section][key] = _config_file.get_value(section, key, val)
    return OK

Oh, that helped, thanks! The values ​​are saved, but I could not load the value for the variable from the file.

JerryHayat | 2020-02-29 15:54