extends Node ## What the player keeps between sessions: the level reached (saved on every win, and ## dropping by one for every Params.LOSE_HOURS away), best stars per level, and settings. const PATH := "user://progress.cfg" ## Level the next game scene starts at. var current_level := 0 var _config := ConfigFile.new() func _ready() -> void: _config.load(PATH) ## Records a win that leads to [param level]. The saved level only goes up (replaying an ## old level never lowers it), but any win restarts the decay clock. func save_level(level: int) -> void: _config.set_value("progress", "level", maxi(level, saved_level())) _config.set_value("progress", "time", Time.get_unix_time_from_system()) _config.save(PATH) ## The level the player continues from (after any decay applied by [method load_level]). func saved_level() -> int: return _config.get_value("progress", "level", 0) ## Best stars earned on [param level], 0 if never won. func stars(level: int) -> int: return _config.get_value("stars", str(level), 0) ## Highest level the player has won, -1 if none. func highest_won() -> int: var highest := -1 if _config.has_section("stars"): for key in _config.get_section_keys("stars"): highest = maxi(highest, int(key)) return highest ## Applies any decay since the last save and returns [level, hours until the next decay]. func load_level() -> Array: var level: int = _config.get_value("progress", "level", 0) var last: float = _config.get_value("progress", "time", 0.0) var now := Time.get_unix_time_from_system() var period := 3600.0 * Params.LOSE_HOURS var remaining := period + last - now while remaining < 0.0 and level > 0: last += period level -= 1 remaining = period + last - now _config.set_value("progress", "level", level) _config.set_value("progress", "time", last) _config.save(PATH) return [level, remaining / 3600.0] ## Keeps the best star count (1 to 3) for a level; returns true if it is a new best. func save_stars(level: int, stars: int) -> bool: var key := str(level) if stars <= _config.get_value("stars", key, 0): return false _config.set_value("stars", key, stars) _config.save(PATH) return true func total_stars() -> int: var total := 0 if _config.has_section("stars"): for key in _config.get_section_keys("stars"): total += int(_config.get_value("stars", key)) return total func save_best_score(score: int) -> bool: if score <= best_score(): return false _config.set_value("progress", "best_score", score) _config.save(PATH) return true func best_score() -> int: return _config.get_value("progress", "best_score", 0) func music_on() -> bool: return _config.get_value("settings", "music", true) func set_music_on(on: bool) -> void: _config.set_value("settings", "music", on) _config.save(PATH)