#!/usr/bin/env bash # golden 基线换代辅助(呈现类改动批专用;含棋盘与菜单全屏两种基线路径)。 # 权限口径(Q6):呈现类改动批内 agent 自行换代+提交说明**强制写明触发原因**;数值/逻辑批禁碰。 # 前置条件(Q5/S3):素材必须齐盘(本脚本逐项守卫,缺位即拒跑退出 1=基线禁锚回退态; # 缺位时先拷主区素材+导入边车再跑)。 # 模式: # --menu:shot_probe 启动态菜单整屏帧 → game/tests/golden/menu_boot.png。 # 全屏基线可行性前置已验证:菜单连续帧差 0.0000%/max_diff=0(光柱为 # 程序生成静态贴片、零动画着色器,全屏基线不抖动);采集确定性=探针隔离档(无断点+出厂 # 设置 1280×800),与 render_gate 的 shot_menu 对比段同源同帧。 # 缺省(棋盘):board_shot_probe 抓 L1-L3 整屏帧+board_meta.json → golden_board_crop.py # 按 meta 取样坐标裁棋盘区(禁硬编码像素)→ 覆盖 game/tests/golden/ 三张基线。 # 过程截图落 mktemp 临时区即弃(Q2),只有基线产物入库。 # 用法: tools/golden_baseline_refresh.sh [game目录] [--menu] 触发原因写进当批提交说明(强制)。 set -u G="${GODOT_BIN:-/d/code/godot/Godot_v4.7.2-stable_win64_console.exe}" REPO="$(cd "$(dirname "$0")/.." && pwd)" GAME="" MODE="board" for a in "$@"; do case "$a" in --menu) MODE="menu" ;; *) if [ -z "$GAME" ]; then GAME="$a"; fi ;; esac done GAME="${GAME:-$REPO/game}" GAME_WIN="$(cygpath -m "$GAME")" TMP="$(mktemp -d /tmp/goldenrefresh_XXXXXX)" trap 'rm -rf "$TMP"' EXIT if [ "$MODE" = "menu" ]; then for a in assets/fonts/ui_font_fusion_pixel_zh_hans.ttf \ assets/art/ui/button_stone.png; do if [ ! -f "$GAME/$a" ]; then echo "[golden_refresh] 拒跑 — 菜单素材缺位: $a(S3 停机点口径:基线禁锚回退态,先补素材+导入边车)" exit 1 fi done timeout 240 "$G" --path "$GAME_WIN" res://probe/shot_probe.tscn -- "$TMP/shots" >"$TMP/run.log" 2>&1 st=$? grep -E "\[shot_probe\]" "$TMP/run.log" | tail -3 if [ "$st" -ne 0 ] || [ ! -s "$TMP/shots/shot_menu.png" ]; then echo "[golden_refresh] FAIL — shot_probe 退出码=$st(菜单截图缺失/探针自检红,见上)" exit 1 fi mkdir -p "$REPO/game/tests/golden" cp "$TMP/shots/shot_menu.png" "$REPO/game/tests/golden/menu_boot.png" || exit 1 echo "[golden_refresh] 完成 — 菜单全屏基线已代入 game/tests/golden/menu_boot.png(提交说明须写明触发原因)" exit 0 fi for a in assets/fonts/ui_font_fusion_pixel_zh_hans.ttf \ assets/art/board/seal_mark.png \ assets/art/character/character_hero_idle.png \ assets/art/board/terrain_wall_n_dungeon.png assets/art/board/terrain_floor_dungeon_1.png \ assets/art/board/terrain_wall_n_underdark.png assets/art/board/terrain_floor_underdark_1.png \ assets/art/board/terrain_wall_n_deep_underdark.png assets/art/board/terrain_floor_deep_underdark_1.png; do if [ ! -f "$GAME/$a" ]; then echo "[golden_refresh] 拒跑 — 素材缺位: $a(S3 停机点口径:基线禁锚字形回退态,先补素材+导入边车)" exit 1 fi done timeout 180 "$G" --path "$GAME_WIN" res://probe/board_shot_probe.tscn -- "$TMP/shots" >"$TMP/run.log" 2>&1 st=$? grep -E "\[board_shot\]" "$TMP/run.log" | tail -6 if [ "$st" -ne 0 ] || [ ! -s "$TMP/shots/board_meta.json" ]; then echo "[golden_refresh] FAIL — board_shot_probe 退出码=$st(meta/截图缺失见上)" exit 1 fi python tools/golden_board_crop.py "$TMP/shots/board_meta.json" "$TMP/shots" "$TMP/crop" || exit 1 mkdir -p "$REPO/game/tests/golden" for b in board_L1_dungeon.png board_L2_underdark.png board_L3_deep_underdark.png; do cp "$TMP/crop/$b" "$REPO/game/tests/golden/$b" || exit 1 done echo "[golden_refresh] 完成 — 三张基线已换代入 game/tests/golden/(提交说明须写明触发原因)"