extends Node signal config_changed(key: String, value: Variant) var _settings: Dictionary = {} func _ready() -> void: _load_config() func get_setting(key: String, default_value: Variant = null) -> Variant: return _settings.get(key, default_value) func set_setting(key: String, value: Variant) -> void: if _settings.has(key) and _settings[key] != value: _settings[key] = value _save_user_config() config_changed.emit(key, value) ## Parse a "r, g, b" string from config into a Color with alpha 1.0. func get_color(key: String, default_color: Color = Color.WHITE) -> Color: var raw: Variant = _settings.get(key) if raw == null or typeof(raw) != TYPE_STRING: return default_color var parts: PackedStringArray = (raw as String).split(",", false) if parts.size() < 3: return default_color var r: float = parts[0].strip_edges().to_float() var g: float = parts[1].strip_edges().to_float() var b: float = parts[2].strip_edges().to_float() return Color(r, g, b, 1.0) func _load_config() -> void: # Load defaults, then overlay user config. var defaults := _read_json_file("res://config/default.json") var user := _read_json_file("res://config/config.json") _settings.clear() if defaults != null and defaults is Dictionary: _merge_dict(_settings, defaults as Dictionary) if user != null and user is Dictionary: _merge_dict(_settings, user as Dictionary) static func _read_json_file(path: String) -> Variant: var file := FileAccess.open(path, FileAccess.READ) if file == null: return null var content: String = file.get_as_text() var parsed: Variant = JSON.parse_string(content) return parsed static func _merge_dict(dst: Dictionary, src: Dictionary) -> void: for key in src: dst[key] = src[key] func _save_user_config() -> void: # Only persists settings that differ from defaults. var defaults := _read_json_file("res://config/default.json") if not (defaults is Dictionary): return var diff: Dictionary = {} for key in _settings: if not defaults.has(key) or defaults[key] != _settings[key]: diff[key] = _settings[key] var path: String = "res://config/config.json" var json_str: String = JSON.stringify(diff, "\t") var file := FileAccess.open(path, FileAccess.WRITE) if file != null: file.store_string(json_str)