extends RefCounted ## Finite mana reserve; timing and production rates belong to the caller. ## Every advance supplies totals for ONE interval, not a per-minute rate. ## Generation first covers demand, then unused mana enters storage up to capacity. ## No Runtime wiring or default balance values are implied by this component. const VERSION := 1 const LIMIT := 1000000000 var _capacity := -1 var _amount := -1 var _minute := -1 var _last_flow: Dictionary = {} func initialize(amount: Variant, capacity: Variant, minute: Variant) -> Dictionary: if _minute >= 0: return _failure(&"ALREADY_INITIALIZED") if not _integer(amount) or not _integer(capacity) or not _integer(minute) or amount > capacity: return _failure(&"INVALID_INITIAL_STATE") _capacity = capacity _amount = amount _minute = minute return {&"ok": true} func get_amount() -> int: return _amount func is_depleted() -> bool: return _minute >= 0 and _amount == 0 func advance_to(minute: Variant, generation: Variant, demand: Variant) -> Dictionary: if _minute < 0: return _failure(&"NOT_INITIALIZED") if not _integer(minute) or not _integer(generation) or not _integer(demand) or minute < _minute: return _failure(&"INVALID_FLOW") if minute == _minute: if not _last_flow.is_empty() and generation == _last_flow[&"generation"] and demand == _last_flow[&"demand"]: return {&"ok": true, &"replayed": true, &"flow": _last_flow.duplicate(true)} return _failure(&"REPLAY_MISMATCH") var flow := _plan(_amount, _capacity, generation, demand, _minute, minute) _amount = flow[&"after"] _minute = minute _last_flow = flow return {&"ok": true, &"replayed": false, &"flow": flow.duplicate(true)} func create_snapshot() -> Dictionary: return {&"version": VERSION, &"capacity": _capacity, &"amount": _amount, &"minute": _minute, &"last_flow": _last_flow.duplicate(true)} func restore_snapshot(source: Dictionary) -> bool: if not _keys(source, ["version", "capacity", "amount", "minute", "last_flow"]) \ or typeof(source["version"]) != TYPE_INT or source["version"] != VERSION \ or not _integer(source["capacity"]) or not _integer(source["amount"]) \ or not _integer(source["minute"]) or source["amount"] > source["capacity"] \ or not source["last_flow"] is Dictionary: return false var flow: Dictionary = source["last_flow"] if not flow.is_empty(): if not _keys(flow, ["from_minute", "to_minute", "before", "generation", "demand", "consumed", "shortage", "overflow", "after"]): return false for key: Variant in flow: # Overflow may include an entire reserve plus this interval's supply. if typeof(flow[key]) != TYPE_INT or flow[key] < 0 or flow[key] > LIMIT * 2: return false if not _integer(flow["generation"]) or not _integer(flow["demand"]) \ or not _integer(flow["from_minute"]) or flow["from_minute"] >= flow["to_minute"] \ or flow["to_minute"] != source["minute"] or flow["before"] > source["capacity"]: return false var expected := _plan(flow["before"], source["capacity"], flow["generation"], flow["demand"], flow["from_minute"], flow["to_minute"]) if expected != flow or flow["after"] != source["amount"]: return false # Commit only after validation; invalid loads leave the existing reserve intact. _capacity = source["capacity"] _amount = source["amount"] _minute = source["minute"] _last_flow = flow.duplicate(true) return true static func _plan(before: int, capacity: int, generation: int, demand: int, start: int, end: int) -> Dictionary: var available := before + generation var consumed := mini(available, demand) var remaining := available - consumed return {&"from_minute": start, &"to_minute": end, &"before": before, &"generation": generation, &"demand": demand, &"consumed": consumed, &"shortage": demand - consumed, &"overflow": maxi(remaining - capacity, 0), &"after": mini(remaining, capacity)} static func _integer(value: Variant) -> bool: return typeof(value) == TYPE_INT and value >= 0 and value <= LIMIT static func _keys(source: Dictionary, expected: Array) -> bool: if source.size() != expected.size(): return false for key: Variant in source: if typeof(key) not in [TYPE_STRING, TYPE_STRING_NAME] or String(key) not in expected: return false return true static func _failure(code: StringName) -> Dictionary: return {&"ok": false, &"code": code}