diff --git a/src/game/engine/src/modules/victory/victory_manager.gd b/src/game/engine/src/modules/victory/victory_manager.gd index de495017..d0be34ed 100644 --- a/src/game/engine/src/modules/victory/victory_manager.gd +++ b/src/game/engine/src/modules/victory/victory_manager.gd @@ -14,14 +14,29 @@ const UnitScript: GDScript = preload("res://engine/src/entities/unit.gd") const CityScript: GDScript = preload("res://engine/src/entities/city.gd") ## Minimum turn before any victory check fires. +## Number of opening turns during which victory is suppressed. Early wins on +## degenerate maps (one player eliminated before the game has had time to +## develop) are not interesting and skew metrics — give every game at least +## this much runway before a winner can be declared. const VICTORY_GRACE_TURNS: int = 10 -## Turn limit after which score fallback fires. Mirrors TurnProcessor.max_turns. -const MAX_TURNS: int = 500 +## Fallback turn limit if GameState.game_settings.turn_limit is missing. +## Real limit is read from game_settings["turn_limit"] at check time so the +## score fallback fires in sync with whichever limit the game actually runs +## against (batches set 300, real games may set 150 or 500). +const MAX_TURNS_FALLBACK: int = 500 var _game_over: bool = false +## Resolved max-turn limit for this run. Reads GameState.game_settings first +## so the score fallback fires at the same turn the game itself ends on, not +## a hardcoded constant that gets out of sync. +func _resolved_max_turns() -> int: + var settings: Dictionary = GameState.game_settings if GameState.game_settings != null else {} + return int(settings.get("turn_limit", MAX_TURNS_FALLBACK)) + + ## Check all victory conditions. Emits EventBus.victory_achieved once. func check_all(_game_map: RefCounted) -> void: if _game_over: @@ -36,7 +51,7 @@ func check_all(_game_map: RefCounted) -> void: return # Score fallback: at max turns, award the highest-scoring player. - if GameState.turn_number >= MAX_TURNS: + if GameState.turn_number >= _resolved_max_turns(): var score_winner: int = _check_score_winner(_game_map) if score_winner >= 0: _game_over = true