# VERTICAL SLICE - NOT FOR PRODUCTION # Date: 2026-09-29(最小设置面:音量入口+减动效开关——设置与本地化.md P1) # 系统级设置独立存储(设置与本地化.md:一安装一份、删游戏才消失, # 不进存档与生涯数据两分)。三件最小面:音量(master bus)/全屏/减动效。 # 生效侧分工:入口与持久化归本类;音量对声音的生效口径归 音频.md(master bus 单点); # 减动效对动画的分档兑现归 battle.md §Transitions(UiKit.motion_scale 既有承载,结算逐行 # 兑现=信息载体只降速不跳过)。 # 探针隔离:path 可注入(冒烟/探针禁碰真实 user://settings.cfg——同存档隔离纪律)。 class_name SettingsStore extends RefCounted const DEFAULT_PATH := "user://settings.cfg" var path: String = DEFAULT_PATH var volume_linear := 1.0 # master bus 线性 0-1(0=静音) var fullscreen := false var reduced_motion := false func _init(path_override: String = "") -> void: if path_override != "": path = path_override func load_settings() -> void: var cf := ConfigFile.new() if cf.load(path) != OK: return # 缺文件 = 出厂默认(合法态——非损坏不兜底) volume_linear = clampf(float(cf.get_value("audio", "volume_linear", 1.0)), 0.0, 1.0) fullscreen = bool(cf.get_value("display", "fullscreen", false)) reduced_motion = bool(cf.get_value("motion", "reduced", false)) func save_settings() -> bool: var cf := ConfigFile.new() cf.set_value("audio", "volume_linear", volume_linear) cf.set_value("display", "fullscreen", fullscreen) cf.set_value("motion", "reduced", reduced_motion) return cf.save(path) == OK # 应用到引擎态(启动恢复与实时调节同一口——headless 下窗口面跳过) func apply() -> void: var master := AudioServer.get_bus_index("Master") AudioServer.set_bus_mute(master, volume_linear <= 0.001) AudioServer.set_bus_volume_db(master, linear_to_db(maxf(volume_linear, 0.001))) UiKit.motion_scale = 0.5 if reduced_motion else 1.0 if DisplayServer.get_name() != "headless": DisplayServer.window_set_mode( DisplayServer.WINDOW_MODE_FULLSCREEN if fullscreen else DisplayServer.WINDOW_MODE_WINDOWED)