fix(@projects/@magic-civilization): 🐛 fix auto-play tier misclassification

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-04-18 19:03:42 -07:00
parent 0dae7341fc
commit 937845f061

View file

@ -1232,8 +1232,12 @@ func _manage_production(city: Variant) -> void:
best_wonder = wid
if not best_wonder.is_empty():
built = best_wonder
var unit_ids: Array[String] = ["warrior", "founder", "worker"]
if built in unit_ids:
# Use DataLoader.get_unit to classify built item as unit vs building —
# previously a hardcoded list `["warrior", "founder", "worker"]` silently
# mis-queued tier-2+ melee units (p0-39) as buildings → add_to_queue
# rejected them and tier progression never manifested.
var unit_entry: Dictionary = DataLoader.get_unit(built)
if not unit_entry.is_empty():
city.add_to_queue("unit", built)
else:
city.add_to_queue("building", built)
@ -1437,14 +1441,20 @@ func _next_building(city: Variant, player: Variant, city_count: int, has_founder
func _best_melee_for_player(player: RefCounted, city: Variant) -> String:
# Highest-tier buildable melee unit per p0-39 rules:
# Strongest buildable melee unit per p0-39 rules:
# - unit_type == "military" AND not in the ranged-specialist set
# - tech_required satisfied (player.has_tech) if set
# - requires_resource satisfied (BuildableHelper) if set
# - race_required matches player.race_id if set
# Returns "warrior" when no higher-tier candidate qualifies.
# Strength proxy is `cost` (costlier unit = stronger = later game) since
# dwarf unit JSONs (public/resources/units/*.json) don't carry an explicit
# `tier` field — cost ordering matches the tech-chain ordering empirically
# (warrior=40 < spearman=56 < iron_vanguard=90 < berserker=100 <
## graven=145 < bulwark=165 < ironwarden=190 < mithril_vanguard=280).
# Falls back to `tier` when present; callers with explicit tiers get ranked
# that way for forward-compatibility.
var best_id: String = "warrior"
var best_tier: int = 1
var best_rank: int = 0
var ranged_keywords: Array[String] = [
"archer", "ranger", "arbalest", "crossbow", "flying", "catapult", "ballista",
]
@ -1462,9 +1472,6 @@ func _best_melee_for_player(player: RefCounted, city: Variant) -> String:
break
if is_ranged:
continue
var tier: int = int(u.get("tier", 1))
if tier <= best_tier:
continue
var tech_req: String = str(u.get("tech_required", ""))
if not tech_req.is_empty() and tech_req != "<null>" and not player.has_tech(tech_req):
continue
@ -1477,10 +1484,17 @@ func _best_melee_for_player(player: RefCounted, city: Variant) -> String:
if not res_req.is_empty() and res_req != "<null>":
if not BuildableHelperScript.player_owns_resource(player, res_req):
continue
# Also require the engine agrees this city can build it.
if not city.can_build(uid, player):
continue
best_tier = tier
# Rank by explicit tier when present, otherwise by cost (dwarf units
# don't carry tier). `tier * 1000 + cost` keeps explicit tiers from
# colliding with cost-ranked peers in the same tier bucket.
var tier_hint: int = int(u.get("tier", 0))
var cost: int = int(u.get("cost", 0))
var rank: int = tier_hint * 1000 + cost
if rank <= best_rank:
continue
best_rank = rank
best_id = uid
return best_id