diff --git a/src/game/engine/scenes/tests/auto_play.gd b/src/game/engine/scenes/tests/auto_play.gd index 8096c40f..b9b36503 100644 --- a/src/game/engine/scenes/tests/auto_play.gd +++ b/src/game/engine/scenes/tests/auto_play.gd @@ -635,6 +635,20 @@ func _play_turn() -> void: c.city_name, c.population, food_surplus, food_stored, float(cy.get("production", 0)), c.owned_tiles.size(), c.buildings.size(), ]) + # Tile yield detail (every 50 turns) + if _turn_count % 50 == 0: + for tp: Vector2i in c.owned_tiles: + var tl: Resource = game_map.get_tile(tp) + if tl == null: + continue + var ty: Dictionary = tl.get_yields(player.index) + var worked: bool = tp in c.get_worked_tiles() + print(" tile(%d,%d) %s f=%d p=%d g=%d %s" % [ + tp.x, tp.y, tl.biome_id, + int(ty.get("food", 0)), int(ty.get("production", 0)), + int(ty.get("trade", 0)), + "[WORKED]" if worked else "", + ]) # 0. Pick research if idle if player.researching.is_empty(): @@ -891,6 +905,9 @@ func _next_building(city: Variant, player: Variant, city_count: int, has_settler # Then walls for defense if not city.has_building("walls"): return "walls" + # Marketplace for gold income — without this, warriors get disbanded from bankruptcy + if not city.has_building("marketplace"): + return "marketplace" # Count military units var military: int = 0 for u: Variant in player.units: diff --git a/src/game/engine/src/modules/management/turn_processor.gd b/src/game/engine/src/modules/management/turn_processor.gd index 6d1c679e..b39275c4 100644 --- a/src/game/engine/src/modules/management/turn_processor.gd +++ b/src/game/engine/src/modules/management/turn_processor.gd @@ -224,6 +224,9 @@ func _process_growth(player: RefCounted) -> void: # Player continue var tile_json: String = BuildableHelperScript.build_tile_yields_json(c, game_map) var prev_pop: int = c.population + # Small cities prioritize food growth; pop 4+ uses balanced Default focus + if c.population < 4 and c.has_method("set_focus"): + c.set_focus("food") c.process_growth(tile_json) if c.population != prev_pop: # Re-assign citizens to tiles after growth or starvation @@ -420,6 +423,11 @@ func _process_culture(player: RefCounted, game_map: RefCounted) -> void: var candidates_json: String = _build_border_candidates_json(c, game_map, player) var claimed: Vector2i = c.expand_borders(candidates_json) if claimed != Vector2i(-1, -1): + # Re-run citizen assignment so the new tile can be worked immediately + var fresh_tile_json: String = BuildableHelperScript.build_tile_yields_json( + c, game_map + ) + c.auto_assign_citizens(fresh_tile_json) var tile: Resource = game_map.get_tile(claimed) if tile != null: tile.owner = player.index diff --git a/src/simulator/crates/mc-city/src/city.rs b/src/simulator/crates/mc-city/src/city.rs index cac4a059..b4b3f370 100644 --- a/src/simulator/crates/mc-city/src/city.rs +++ b/src/simulator/crates/mc-city/src/city.rs @@ -323,7 +323,7 @@ impl City { // means first border expansion in ~5 turns. yields.food += 3.0; yields.production += 2.0; - yields.gold += 1.0; + yields.gold += 3.0; yields.science += 1.0; yields.culture += 2.0; @@ -706,10 +706,10 @@ mod tests { fn yields_include_city_center_baseline() { let city = City::found("Ironhold", (5, 5), true, 1); let yields = city.get_yields(&[]); - // City center: 3 food, 2 production, 1 gold, 1 science, 2 culture - assert_eq!(yields.food, 3.0); + // City center: 4 food, 2 production, 3 gold, 1 science, 2 culture + assert_eq!(yields.food, 4.0); assert_eq!(yields.production, 2.0); - assert_eq!(yields.gold, 1.0); + assert_eq!(yields.gold, 3.0); assert_eq!(yields.science, 1.0); assert_eq!(yields.culture, 2.0); } @@ -722,7 +722,7 @@ mod tests { city.worked_tiles = vec![(5, 5), (6, 5)]; let ty = sample_tile_yields(); let yields = city.get_yields(&ty); - // Center baseline: 3f + 2p + 1g + 1s + // Center baseline: 4f + 2p + 3g + 1s // Center tile yield: 2f + 1p + 0g // (6,5) tile: 3f + 0p + 1g assert_eq!(yields.food, 3.0 + 2.0 + 3.0);