fix(@projects/@magic-civilization): 🐛 add ai promotion debug logging
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
690039cdf3
commit
587a10bca0
3 changed files with 55 additions and 6 deletions
|
|
@ -469,9 +469,17 @@ case "${MODE}" in
|
|||
# 2026-04-18. Opt-in via env override; gpu-walltime flips
|
||||
# per-iteration as its explicit comparison.
|
||||
GPU_ENV="AI_GPU_ROLLOUT=${AI_GPU_ROLLOUT:-false}"
|
||||
echo "[$(date +%H:%M:%S)] smoke batch: ${SEEDS} seeds T${TURNS} PARALLEL=${PARALLEL} ${GPU_ENV}"
|
||||
# p2-44b: forward MC_AI_* diagnostic envs so instrumentation prints surface in game.log
|
||||
MC_AI_ENV=""
|
||||
for var in MC_AI_PROMOTION_DEBUG; do
|
||||
val="${!var:-}"
|
||||
if [[ -n "${val}" ]]; then
|
||||
MC_AI_ENV="${MC_AI_ENV} ${var}=${val}"
|
||||
fi
|
||||
done
|
||||
echo "[$(date +%H:%M:%S)] smoke batch: ${SEEDS} seeds T${TURNS} PARALLEL=${PARALLEL} ${GPU_ENV}${MC_AI_ENV}"
|
||||
ssh "${APRICOT}" "set -euo pipefail; cd '${SCRATCH_ABS}' && \
|
||||
AI_USE_MCTS=true ${GPU_ENV} PARALLEL=${PARALLEL} \
|
||||
AI_USE_MCTS=true ${GPU_ENV}${MC_AI_ENV} PARALLEL=${PARALLEL} \
|
||||
bash tools/autoplay-batch.sh ${SEEDS} ${TURNS} ${RESULTS_ABS}/smoke 2>&1 | tail -30"
|
||||
;;
|
||||
clan)
|
||||
|
|
|
|||
|
|
@ -47,14 +47,24 @@ static func dispatch_action(
|
|||
## the audio chime, throne-room counter, and chronicle log all fire on the
|
||||
## same path the human picker uses.
|
||||
static func dispatch_promotion_picked(fields: Dictionary, index_maps: Dictionary) -> bool:
|
||||
var unit: RefCounted = resolve_unit(int(fields.get("unit_id", -1)), index_maps)
|
||||
if unit == null or not unit.is_alive():
|
||||
return false
|
||||
var debug: bool = OS.get_environment("MC_AI_PROMOTION_DEBUG") != ""
|
||||
var uid: int = int(fields.get("unit_id", -1))
|
||||
var promo_id: String = String(fields.get("promotion_id", ""))
|
||||
if debug:
|
||||
print("[promo-debug] dispatch_promotion_picked entry uid=", uid, " promo=", promo_id)
|
||||
var unit: RefCounted = resolve_unit(uid, index_maps)
|
||||
if unit == null or not unit.is_alive():
|
||||
if debug:
|
||||
print("[promo-debug] dispatch_promotion_picked ABORT unit_null_or_dead uid=", uid)
|
||||
return false
|
||||
if promo_id.is_empty():
|
||||
if debug:
|
||||
print("[promo-debug] dispatch_promotion_picked ABORT empty_promo_id uid=", uid)
|
||||
return false
|
||||
unit.promote(promo_id)
|
||||
EventBus.unit_promoted.emit(unit, promo_id)
|
||||
if debug:
|
||||
print("[promo-debug] dispatch_promotion_picked SUCCESS uid=", uid, " promo=", promo_id, " new_vlvl=", unit.veteran_level)
|
||||
return true
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,15 @@ static func build_tactical_state(focal: RefCounted) -> Dictionary:
|
|||
if p == null:
|
||||
continue
|
||||
players.append(player_to_dict(p))
|
||||
if OS.get_environment("MC_AI_PROMOTION_DEBUG") != "":
|
||||
var total_with_choices: int = 0
|
||||
var total_units: int = 0
|
||||
for pdict: Dictionary in players:
|
||||
for udict: Dictionary in pdict.get("units", []):
|
||||
total_units += 1
|
||||
if not (udict.get("pending_promotion_choices", []) as Array).is_empty():
|
||||
total_with_choices += 1
|
||||
print("[promo-debug] build_tactical_state turn=", int(GameState.turn_number), " focal=", int(focal.index), " total_units=", total_units, " units_with_choices=", total_with_choices)
|
||||
return {
|
||||
"current_player": int(focal.index),
|
||||
"turn": int(GameState.turn_number),
|
||||
|
|
@ -412,27 +421,45 @@ static func _load_clan_entry(clan_id: String) -> Dictionary:
|
|||
## 4. The promotion's prerequisite (if any) must already be owned.
|
||||
## 5. The promotion's level entry must equal the unit's next veteran level.
|
||||
static func _eligible_promotion_ids(unit: RefCounted) -> Array:
|
||||
var debug: bool = OS.get_environment("MC_AI_PROMOTION_DEBUG") != ""
|
||||
var out: Array = []
|
||||
if unit == null or not unit.has_method("can_promote") or not unit.can_promote():
|
||||
if unit == null or not unit.has_method("can_promote"):
|
||||
if debug:
|
||||
print("[promo-debug] eligible: unit=null or no can_promote")
|
||||
return out
|
||||
var can: bool = unit.can_promote()
|
||||
var uid: int = int(unit.get("id")) if "id" in unit else -1
|
||||
if not can:
|
||||
if debug:
|
||||
print("[promo-debug] eligible unit=", uid, " kind=", unit.unit_id, " xp=", unit.xp, " vlvl=", unit.veteran_level, " can_promote=false")
|
||||
return out
|
||||
var trees: Dictionary = DataLoader.get_promotion_trees()
|
||||
if trees.is_empty():
|
||||
if debug:
|
||||
print("[promo-debug] eligible unit=", uid, " ABORT trees_empty")
|
||||
return out
|
||||
var owned: Array = Array(unit.promo_ids)
|
||||
var next_level: int = int(unit.veteran_level) + 1
|
||||
var unit_data: Dictionary = unit.get_data()
|
||||
var unit_flags: Array = unit_data.get("flags", [])
|
||||
var unit_combat_type: String = String(unit_data.get("unit_type", "melee"))
|
||||
var rejected_trees: Array = []
|
||||
var matched_trees: Array = []
|
||||
var no_level_match: Array = []
|
||||
for tree_key: String in trees:
|
||||
var tree: Dictionary = trees[tree_key] as Dictionary
|
||||
if tree == null:
|
||||
continue
|
||||
if not _tree_applies_to(tree, unit_combat_type, unit_flags):
|
||||
rejected_trees.append(tree_key)
|
||||
continue
|
||||
matched_trees.append(tree_key)
|
||||
var levels: Array = tree.get("levels", [])
|
||||
var any_level_match: bool = false
|
||||
for level_entry: Dictionary in levels:
|
||||
if int(level_entry.get("level", 0)) != next_level:
|
||||
continue
|
||||
any_level_match = true
|
||||
for choice: Dictionary in level_entry.get("choices", []):
|
||||
var pid: String = String(choice.get("id", ""))
|
||||
if pid.is_empty() or owned.has(pid):
|
||||
|
|
@ -441,6 +468,10 @@ static func _eligible_promotion_ids(unit: RefCounted) -> Array:
|
|||
if not prereq.is_empty() and prereq != "<null>" and not owned.has(prereq):
|
||||
continue
|
||||
out.append(pid)
|
||||
if not any_level_match:
|
||||
no_level_match.append(tree_key)
|
||||
if debug:
|
||||
print("[promo-debug] eligible unit=", uid, " kind=", unit.unit_id, " xp=", unit.xp, " vlvl=", unit.veteran_level, " ctype=", unit_combat_type, " flags=", unit_flags, " next_lvl=", next_level, " matched=", matched_trees, " rejected=", rejected_trees, " no_lvl=", no_level_match, " out=", out)
|
||||
return out
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue