diff --git a/src/game/engine/src/modules/ai/simple_heuristic_ai.gd b/src/game/engine/src/modules/ai/simple_heuristic_ai.gd index 19e0a718..d29915dd 100644 --- a/src/game/engine/src/modules/ai/simple_heuristic_ai.gd +++ b/src/game/engine/src/modules/ai/simple_heuristic_ai.gd @@ -519,11 +519,25 @@ static func _decide_production( # T100. After T80 the standard Priority 4 target takes over. var early_mil_floor: int = 4 if GameState.turn_number <= 80 else 0 if military_count < maxi(1, early_mil_floor): - var emergency_unit: String = _pick_buildable_military_unit_id( - city, player + # Capital walls interject: once the capital has at least 1 defender + # and is >20 turns old, pause military top-up to slot walls in. Walls + # were being starved indefinitely by the mil-floor above; a T40-50 + # wall hardens the capital before the opponent's full army arrives. + var capital_age: int = ( + GameState.turn_number - int(city.turn_founded) ) - if not emergency_unit.is_empty(): - return _prod_unit(city_index, emergency_unit) + var capital_needs_walls: bool = ( + city_count == 1 and city_index == 0 + and military_count >= 1 and capital_age > 20 + and not city.has_building("walls") + and city.can_build("walls", player) + ) + if not capital_needs_walls: + var emergency_unit: String = _pick_buildable_military_unit_id( + city, player + ) + if not emergency_unit.is_empty(): + return _prod_unit(city_index, emergency_unit) # Priority 1: Build walls if city has none (defense first) if not city.has_building("walls") and city.can_build("walls", player): @@ -547,12 +561,11 @@ static func _decide_production( return _prod_unit(city_index, "founder") # Priority 4: Military — maintain 2 warriors per city, scaling up to - # match enemy's FULL army when they're closing on us so we don't lose - # on parity once reserves arrive. - var enemy_mil: int = enemy_total if threatened else 0 + # match enemy's FULL army at all times (not only when imminent) so we + # don't get jumped when a distant stack closes the gap in 3-4 turns. var mil_target: int = maxi(4, city_count * 2) - if enemy_mil > 0: - mil_target = maxi(mil_target, enemy_mil + 1) + if enemy_total >= mil_target: + mil_target = enemy_total + 1 var want_military: bool = military_count < mil_target if want_military: var unit_id: String = _pick_buildable_military_unit_id(city, player)