151 lines
8.4 KiB
Bash
Executable File
151 lines
8.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# golden 基线换代辅助(呈现类改动批专用;含棋盘与菜单全屏两种基线路径)。
|
||
# 权限口径(Q6):呈现类改动批内 agent 自行换代+提交说明**强制写明触发原因**;数值/逻辑批禁碰。
|
||
# 前置条件(Q5/S3):素材必须齐盘(本脚本逐项守卫,缺位即拒跑退出 1=基线禁锚回退态;
|
||
# 缺位时先拷主区素材+导入边车再跑)。
|
||
# 模式:
|
||
# --menu:shot_probe 启动态菜单整屏帧 → game/tests/golden/menu_boot.png。
|
||
# --screens:shot_probe 十六图(七屏+营地五窗+四浮层)全量采集 → 按基线名 cp 入库
|
||
# (camp_screen/settings_screen/battle_screen/career_screen/status_panel/camp_forge/
|
||
# camp_chest/camp_tree/camp_codex/camp_notebook/battle_end/curio_pick/legend/debug_overlay
|
||
# ——golden 补锚批 2026-11-08)。候选图仍须用户逐张审核确认后才算冻结(审核关卡)。
|
||
# --lmap:level_map_shot_probe 关卡视口两 Shot(入口停点+Boss 列锚定——2026-11-05 用户裁
|
||
# 两 Shot 面)→ game/tests/golden/lmap_entry.png + lmap_boss.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)"
|
||
. "$REPO/tools/gate_platform.sh" # 跨平台件(平台探测/路径形式/带超时执行)
|
||
GAME=""
|
||
MODE="board"
|
||
for a in "$@"; do
|
||
case "$a" in
|
||
--menu) MODE="menu" ;;
|
||
--lmap) MODE="lmap" ;;
|
||
--screens) MODE="screens" ;;
|
||
*) if [ -z "$GAME" ]; then GAME="$a"; fi ;;
|
||
esac
|
||
done
|
||
GAME="${GAME:-$REPO/game}"
|
||
GAME_WIN="$(gate_game_path "$GAME")" # Godot --path 接受形式(Windows 混合斜杠,其他平台原样)
|
||
GOLDEN="$REPO/game/tests/golden" # 单基线跨平台落点(2026-11-08 用户裁,无平台子目录)
|
||
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
|
||
gate_run_timeout 420 "$TMP/run.log" "$G" --path "$GAME_WIN" --quit-after 3000 res://probe/shot_probe.tscn -- "$TMP/shots"
|
||
st=$?
|
||
grep -E "\[shot_probe\]" "$TMP/run.log" | tail -3
|
||
# 判定锚工件而非退出码:macOS 窗口化下 --quit-after 与探针 quit(0) 竞速,quit-after 先到帧限
|
||
# 时 Godot 以 124 离场(run21 实证 12s 完活 PASS 后 124)——工件齐全即按完成判定,124 非真红。
|
||
if [ ! -s "$TMP/shots/shot_menu.png" ] || ! grep -q "问题=0" "$TMP/run.log"; then
|
||
echo "[golden_refresh] FAIL — 菜单截图缺失或 shot_probe 自检红(st=$st,见上)"
|
||
exit 1
|
||
fi
|
||
mkdir -p "$GOLDEN"
|
||
cp "$TMP/shots/shot_menu.png" "$GOLDEN/menu_boot.png" || exit 1
|
||
echo "[golden_refresh] 完成 — 菜单全屏基线已代入 game/tests/golden/menu_boot.png(提交说明须写明触发原因)"
|
||
exit 0
|
||
fi
|
||
|
||
if [ "$MODE" = "screens" ]; then
|
||
# 七屏+九态候选基线采集(golden 补锚批 2026-11-08):跑完整 shot_probe(十六图+meta),
|
||
# 全部按基线名 cp 入库——候选图仍须用户逐张审核确认后才算冻结(审核关卡=README「基线冻结与审核」)。
|
||
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
|
||
gate_run_timeout 420 "$TMP/run.log" "$G" --path "$GAME_WIN" --quit-after 3000 res://probe/shot_probe.tscn -- "$TMP/shots"
|
||
st=$?
|
||
grep -E "\[shot_probe\]" "$TMP/run.log" | tail -3
|
||
if ! grep -q "问题=0" "$TMP/run.log"; then
|
||
echo "[golden_refresh] FAIL — shot_probe 自检红(st=$st,见上)"
|
||
exit 1
|
||
fi
|
||
mkdir -p "$GOLDEN"
|
||
for m in "shot_camp.png camp_screen.png" "shot_settings.png settings_screen.png" \
|
||
"shot_battle.png battle_screen.png" "shot_career.png career_screen.png" \
|
||
"shot_status.png status_panel.png" "shot_camp_forge.png camp_forge.png" \
|
||
"shot_camp_chest.png camp_chest.png" "shot_camp_tree.png camp_tree.png" \
|
||
"shot_camp_codex.png camp_codex.png" "shot_camp_notebook.png camp_notebook.png" \
|
||
"shot_battle_end.png battle_end.png" "shot_curio_pick.png curio_pick.png" \
|
||
"shot_legend.png legend.png" "shot_debug.png debug_overlay.png"; do
|
||
set -- $m
|
||
[ -s "$TMP/shots/$1" ] || { echo "[golden_refresh] FAIL — 候选缺失: $1"; exit 1; }
|
||
cp "$TMP/shots/$1" "$GOLDEN/$2" || exit 1
|
||
done
|
||
echo "[golden_refresh] 完成 — 14 张屏态/浮层候选基线已代入 game/tests/golden/(呈报用户逐张审核后随批提交)"
|
||
exit 0
|
||
fi
|
||
|
||
if [ "$MODE" = "lmap" ]; then
|
||
# 关卡视口两 Shot 面(卷轴视口批·2026-11-05 用户裁:只对拍关卡最开始与关卡 Boss 节点,
|
||
# 中间过程不对拍)——入口停点 + 末列 Boss 列锚定,两基线各存平台子目录。
|
||
for a in assets/fonts/ui_font_fusion_pixel_zh_hans.ttf \
|
||
assets/art/ui/button_stone.png \
|
||
assets/art/ui/node_battle.png assets/art/ui/node_reward.png \
|
||
assets/art/ui/node_rest.png assets/art/ui/node_boss.png \
|
||
assets/art/ui/node_shop.png; do
|
||
if [ ! -f "$GAME/$a" ]; then
|
||
echo "[golden_refresh] 拒跑 — 关卡屏素材缺位: ${a}(S3 停机点口径:基线禁锚字形回退态,先补素材+导入边车)"
|
||
exit 1
|
||
fi
|
||
done
|
||
gate_run_timeout 420 "$TMP/run.log" "$G" --path "$GAME_WIN" --quit-after 3000 res://probe/level_map_shot_probe.tscn -- "$TMP/shots"
|
||
st=$?
|
||
grep -E "\[level_map_shot_probe\]" "$TMP/run.log" | tail -3
|
||
# 判定锚工件(同 menu——quit-after 与 quit(0) 竞速的 124 非真红):PASS 签名 + 双图非零。
|
||
if ! grep -q "PASS — 两 Shot 落盘" "$TMP/run.log" || [ ! -s "$TMP/shots/lmap_entry.png" ] || [ ! -s "$TMP/shots/lmap_boss.png" ]; then
|
||
echo "[golden_refresh] FAIL — 关卡视口截图缺失或探针自检红(st=$st,见上)"
|
||
exit 1
|
||
fi
|
||
mkdir -p "$GOLDEN"
|
||
cp "$TMP/shots/lmap_entry.png" "$GOLDEN/lmap_entry.png" || exit 1
|
||
cp "$TMP/shots/lmap_boss.png" "$GOLDEN/lmap_boss.png" || exit 1
|
||
echo "[golden_refresh] 完成 — 关卡视口两 Shot 基线已代入 game/tests/golden/(提交说明须写明触发原因)"
|
||
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
|
||
|
||
gate_run_timeout 360 "$TMP/run.log" "$G" --path "$GAME_WIN" --quit-after 3000 res://probe/board_shot_probe.tscn -- "$TMP/shots"
|
||
st=$?
|
||
grep -E "\[board_shot\]" "$TMP/run.log" | tail -6
|
||
# 判定锚工件(同上——quit-after 与 quit(0) 竞速的 124 非真红):meta 在 + PASS 签名在 = 完成。
|
||
if [ ! -s "$TMP/shots/board_meta.json" ] || ! grep -q "PASS — 三关双帧取证" "$TMP/run.log"; then
|
||
echo "[golden_refresh] FAIL — board meta 缺失或探针自检红(st=$st,见上)"
|
||
exit 1
|
||
fi
|
||
python3 tools/golden_board_crop.py "$TMP/shots/board_meta.json" "$TMP/shots" "$TMP/crop" || exit 1
|
||
mkdir -p "$GOLDEN"
|
||
for b in board_L1_dungeon.png board_L2_underdark.png board_L3_deep_underdark.png; do
|
||
cp "$TMP/crop/$b" "$GOLDEN/$b" || exit 1
|
||
done
|
||
echo "[golden_refresh] 完成 — 三张基线已换代入 game/tests/golden/(提交说明须写明触发原因)"
|