Files
gplan-2/tools/golden_baseline_refresh.sh

113 lines
6.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# golden 基线换代辅助(呈现类改动批专用;含棋盘与菜单全屏两种基线路径)。
# 权限口径(Q6):呈现类改动批内 agent 自行换代+提交说明**强制写明触发原因**;数值/逻辑批禁碰。
# 前置条件(Q5/S3):素材必须齐盘(本脚本逐项守卫,缺位即拒跑退出 1=基线禁锚回退态;
# 缺位时先拷主区素材+导入边车再跑)。
# 模式:
# --menu:shot_probe 启动态菜单整屏帧 → game/tests/golden/menu_boot.png。
# --lmap:level_map_shot_probe 关卡视口两 Shot(入口停点+Boss 列锚定——2026-11-05 用户裁
# 两 Shot 面)→ game/tests/golden/<plat>/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" ;;
*) if [ -z "$GAME" ]; then GAME="$a"; fi ;;
esac
done
GAME="${GAME:-$REPO/game}"
GAME_WIN="$(gate_game_path "$GAME")" # Godot --path 接受形式(Windows 混合斜杠,其他平台原样)
PLAT="$(gate_platform_id)" # 基线落点=本平台子目录(game/tests/golden/<windows|mac|linux>/)
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 "$REPO/game/tests/golden/$PLAT"
cp "$TMP/shots/shot_menu.png" "$REPO/game/tests/golden/$PLAT/menu_boot.png" || exit 1
echo "[golden_refresh] 完成 — 菜单全屏基线已代入 game/tests/golden/$PLAT/menu_boot.png(提交说明须写明触发原因)"
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 "$REPO/game/tests/golden/$PLAT"
cp "$TMP/shots/lmap_entry.png" "$REPO/game/tests/golden/$PLAT/lmap_entry.png" || exit 1
cp "$TMP/shots/lmap_boss.png" "$REPO/game/tests/golden/$PLAT/lmap_boss.png" || exit 1
echo "[golden_refresh] 完成 — 关卡视口两 Shot 基线已代入 game/tests/golden/$PLAT/(提交说明须写明触发原因)"
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 "$REPO/game/tests/golden/$PLAT"
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/$PLAT/$b" || exit 1
done
echo "[golden_refresh] 完成 — 三张基线已换代入 game/tests/golden/$PLAT/(提交说明须写明触发原因)"