feat(@projects/@magic-civilization): ✨ auto-pick research for idle ai players
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
f9100f9e29
commit
9fcdbb6c95
1 changed files with 68 additions and 1 deletions
|
|
@ -139,8 +139,19 @@ func _process_research(player: RefCounted) -> void: # Player
|
|||
## to Rust `GdTechWeb::process_research` (warcouncil p1-39 port,
|
||||
## 2026-04-27). GDScript only assembles input JSON + applies
|
||||
## completion side-effects (tech_researched signal, resource reveals).
|
||||
##
|
||||
## Auto-pick fallback: when a player has no current research target
|
||||
## (just completed one, or never picked one — the latter case is the
|
||||
## bug we hit on huge-map 5-clan runs where AI players P1-P4 stalled
|
||||
## at techs=1 forever because nothing ever called `_pick_research`
|
||||
## for them; auto_play.gd only picks for its impersonated current
|
||||
## player slot). Re-pick from the bridge using the same scorer the
|
||||
## headless autoplay uses, so AI players progress through eras
|
||||
## naturally instead of sitting idle.
|
||||
if player.researching.is_empty():
|
||||
return
|
||||
_auto_pick_research(player)
|
||||
if player.researching.is_empty():
|
||||
return
|
||||
|
||||
# Per-yield difficulty multiplier (composed by GameState).
|
||||
# p1-29 cycle 4: research-yield catch-up boost. When this player is at least
|
||||
|
|
@ -202,6 +213,62 @@ func _process_research(player: RefCounted) -> void: # Player
|
|||
_check_resource_reveals(completed_tech, player.index)
|
||||
|
||||
|
||||
func _auto_pick_research(player: RefCounted) -> void:
|
||||
## Pick a research target for `player` via the Rust bridge scorer.
|
||||
##
|
||||
## Mirrors the candidate-list construction from
|
||||
## `auto_play.gd::_pick_research`. Runs for every player on every turn
|
||||
## that finds `researching` empty — so AI players P1..P4 (which
|
||||
## auto_play does NOT impersonate via `_play_turn`) actually advance
|
||||
## through eras. Without this, only the auto_play-impersonated slot
|
||||
## ever picked a tech and the rest sat at techs=1 forever (huge-map
|
||||
## batch `20260516_212826`).
|
||||
var ctrl: RefCounted = GameState.get_ai_controller()
|
||||
if ctrl == null:
|
||||
return
|
||||
var candidates: Array = []
|
||||
for tech: Dictionary in DataLoader.get_all_techs():
|
||||
var tid: String = str(tech.get("id", ""))
|
||||
if tid.is_empty() or player.has_tech(tid):
|
||||
continue
|
||||
var met: bool = true
|
||||
for req: Variant in tech.get("requires", []):
|
||||
if not player.has_tech(str(req)):
|
||||
met = false
|
||||
break
|
||||
if not met:
|
||||
continue
|
||||
var unlocks: Dictionary = tech.get("unlocks", {})
|
||||
var unlock_buildings: Array = []
|
||||
for bid: Variant in unlocks.get("buildings", []):
|
||||
unlock_buildings.append(str(bid))
|
||||
var unlock_units: Array = []
|
||||
for uid: Variant in unlocks.get("units", []):
|
||||
unlock_units.append(str(uid))
|
||||
candidates.append({
|
||||
"id": tid,
|
||||
"pillar": str(tech.get("pillar", "")),
|
||||
"cost": maxi(int(tech.get("cost", 1)), 1),
|
||||
"tier": int(tech.get("tier", 0)),
|
||||
"unlocks_buildings": unlock_buildings,
|
||||
"unlocks_units": unlock_units,
|
||||
})
|
||||
if candidates.is_empty():
|
||||
return
|
||||
var clan_id: String = str(player.get("clan_id") if player.get("clan_id") != null else "")
|
||||
var axes: Dictionary = {}
|
||||
if not clan_id.is_empty():
|
||||
var personality: Dictionary = DataLoader.get_ai_personality(clan_id)
|
||||
if personality != null and not personality.is_empty():
|
||||
axes = personality.get("strategic_axes", {})
|
||||
var best_id: String = ctrl.pick_research(
|
||||
JSON.stringify(candidates), JSON.stringify(axes)
|
||||
)
|
||||
if not best_id.is_empty():
|
||||
player.researching = best_id
|
||||
player.research_progress = 0
|
||||
|
||||
|
||||
func _check_resource_reveals(completed_tech: String, player_index: int) -> void:
|
||||
TurnProcessorHelpersScript._check_resource_reveals(completed_tech, player_index)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue