From c28d01ccb0e6ca500eab086ee9b81ef2918fb5cb Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 03:09:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E7=A8=8B(ci=E8=BF=9C=E7=AB=AF?= =?UTF-8?q?=E5=8C=96=C2=B7=E9=98=B6=E6=AE=B5=E4=B8=89):=20golden=E5=9F=BA?= =?UTF-8?q?=E7=BA=BF=E6=8C=89=E5=B9=B3=E5=8F=B0=E5=90=84=E5=AD=98=E2=80=94?= =?UTF-8?q?=E2=80=94=E5=9B=9B=E5=BC=A0=E7=8E=B0=E8=A1=8C=E5=9F=BA=E7=BA=BF?= =?UTF-8?q?(=E6=A3=8B=E7=9B=98=E4=B8=89=E5=9B=BE+menu=5Fboot)=E8=BF=81?= =?UTF-8?q?=E5=85=A5windows/=E5=AD=90=E7=9B=AE=E5=BD=95,=20mac/=E5=BE=85Ma?= =?UTF-8?q?c=E7=AB=AF=E9=87=8D=E5=88=B6=E5=90=8E=E5=85=A5=E5=BA=93;=20gold?= =?UTF-8?q?en=5Fcompare.py=E6=8C=89sys.platform=E8=87=AA=E5=8A=A8=E6=8B=BC?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=AD=90=E7=9B=AE=E5=BD=95(=E7=BC=BA?= =?UTF-8?q?=E6=9C=AC=E5=B9=B3=E5=8F=B0=E5=9F=BA=E7=BA=BF=3Dfail-closed?= =?UTF-8?q?=E6=98=BE=E5=BC=8F=E7=BA=A2=E5=B9=B6=E7=BB=99=E9=87=8D=E5=88=B6?= =?UTF-8?q?=E6=8C=87=E5=BC=95,=20=E7=A6=81=E9=9D=99=E9=BB=98=E7=BB=BF);=20?= =?UTF-8?q?render=5Fgate=E5=9F=BA=E7=BA=BF=E6=96=AD=E8=A8=80=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E4=B8=8Egolden=5Fbaseline=5Frefresh=E5=86=99=E5=85=A5?= =?UTF-8?q?=E8=90=BD=E7=82=B9=E5=85=A8=E6=94=B9=E5=B9=B3=E5=8F=B0=E5=AD=90?= =?UTF-8?q?=E7=9B=AE=E5=BD=95;=20gate=5Fplatform.sh=E6=96=B0=E5=A2=9Egate?= =?UTF-8?q?=5Fplatform=5Fid;=20=E4=BE=9D=E6=8D=AE=3D=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=A3=81=E8=B7=A8=E5=B9=B3=E5=8F=B0=E9=80=90=E5=83=8F=E7=B4=A0?= =?UTF-8?q?=E5=BF=85=E5=A4=B1=E9=85=8D(=E5=AD=97=E5=BD=A2/=E6=8A=97?= =?UTF-8?q?=E9=94=AF=E9=BD=BF=E6=9C=BA=E5=88=B6=E5=B7=AE=E5=BC=82),=20?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=86=85=E9=83=A8=E4=B8=A5=E6=A0=BC=E5=BA=A6?= =?UTF-8?q?=E4=B8=8D=E9=99=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/tests/golden/README.md | 9 +++++++-- .../golden/{ => windows}/board_L1_dungeon.png | Bin .../golden/{ => windows}/board_L2_underdark.png | Bin .../{ => windows}/board_L3_deep_underdark.png | Bin game/tests/golden/{ => windows}/menu_boot.png | Bin tools/gate_platform.sh | 10 ++++++++++ tools/golden_baseline_refresh.sh | 13 +++++++------ tools/golden_compare.py | 13 +++++++++++++ tools/render_gate.sh | 9 +++++---- 9 files changed, 42 insertions(+), 12 deletions(-) rename game/tests/golden/{ => windows}/board_L1_dungeon.png (100%) rename game/tests/golden/{ => windows}/board_L2_underdark.png (100%) rename game/tests/golden/{ => windows}/board_L3_deep_underdark.png (100%) rename game/tests/golden/{ => windows}/menu_boot.png (100%) diff --git a/game/tests/golden/README.md b/game/tests/golden/README.md index 05913c31..51cb1287 100644 --- a/game/tests/golden/README.md +++ b/game/tests/golden/README.md @@ -1,7 +1,12 @@ # 视觉 golden 基线(渲染闸的比对基准) -五张基线:棋盘三图(`board_L1_dungeon` / `board_L2_underdark` / `board_L3_deep_underdark`, -裁剪区 900×760)+ 启动态菜单(`menu_boot`,全屏)+ 关卡画面(`level_map`,全屏)。 +基线**按平台各存**(2026-11-03 用户裁:跨显卡/字形渲染机制差异使跨平台逐像素必失配—— +`windows/` 与 `mac/` 子目录各持一套,平台内部照常严格比对,跨平台不互比; +平台选择实现单点 = `tools/gate_platform.sh` 的 `gate_platform_id`,比较器 `tools/golden_compare.py` +自动拼平台子目录)。本目录现持:`windows/`(棋盘三图 `board_L1_dungeon` / `board_L2_underdark` / +`board_L3_deep_underdark`,裁剪区 900×760 + 启动态菜单 `menu_boot`,全屏)、 +`level_map`(关卡画面全屏,历史基线留根——现行闸件未对拍它)、 +`palette_baseline/`(色板基线,纯文件内容比对与平台无关)。 比对判据与工具见 `tools/golden_compare.py` (逐像素灰度差 >16 的像素占比 ≤2%)。 diff --git a/game/tests/golden/board_L1_dungeon.png b/game/tests/golden/windows/board_L1_dungeon.png similarity index 100% rename from game/tests/golden/board_L1_dungeon.png rename to game/tests/golden/windows/board_L1_dungeon.png diff --git a/game/tests/golden/board_L2_underdark.png b/game/tests/golden/windows/board_L2_underdark.png similarity index 100% rename from game/tests/golden/board_L2_underdark.png rename to game/tests/golden/windows/board_L2_underdark.png diff --git a/game/tests/golden/board_L3_deep_underdark.png b/game/tests/golden/windows/board_L3_deep_underdark.png similarity index 100% rename from game/tests/golden/board_L3_deep_underdark.png rename to game/tests/golden/windows/board_L3_deep_underdark.png diff --git a/game/tests/golden/menu_boot.png b/game/tests/golden/windows/menu_boot.png similarity index 100% rename from game/tests/golden/menu_boot.png rename to game/tests/golden/windows/menu_boot.png diff --git a/tools/gate_platform.sh b/tools/gate_platform.sh index cf5828d1..77385dd2 100644 --- a/tools/gate_platform.sh +++ b/tools/gate_platform.sh @@ -84,3 +84,13 @@ gate_godot_count_all() { else ps -axo comm= 2>/dev/null | grep -ci 'godot' || true fi } + +# golden 基线平台子目录名——渲染基线按平台各存一份(Windows 显卡字形/抗锯齿与 macOS CoreText +# 差异使跨平台逐像素比对必失配,2026-11-03 用户裁:按平台各存基线,平台内部照常严格比对)。 +gate_platform_id() { + case "$(uname -s 2>/dev/null)" in + MINGW*|MSYS*|CYGWIN*|Windows_NT) echo "windows" ;; + Darwin) echo "mac" ;; + *) echo "linux" ;; + esac +} diff --git a/tools/golden_baseline_refresh.sh b/tools/golden_baseline_refresh.sh index 6bcac2b7..4753a2b7 100755 --- a/tools/golden_baseline_refresh.sh +++ b/tools/golden_baseline_refresh.sh @@ -26,6 +26,7 @@ for a in "$@"; do done GAME="${GAME:-$REPO/game}" GAME_WIN="$(gate_game_path "$GAME")" # Godot --path 接受形式(Windows 混合斜杠,其他平台原样) +PLAT="$(gate_platform_id)" # 基线落点=本平台子目录(game/tests/golden//) TMP="$(mktemp -d /tmp/goldenrefresh_XXXXXX)" trap 'rm -rf "$TMP"' EXIT @@ -44,9 +45,9 @@ if [ "$MODE" = "menu" ]; 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(提交说明须写明触发原因)" + 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 @@ -70,8 +71,8 @@ if [ "$st" -ne 0 ] || [ ! -s "$TMP/shots/board_meta.json" ]; then 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" +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/$b" || exit 1 + cp "$TMP/crop/$b" "$REPO/game/tests/golden/$PLAT/$b" || exit 1 done -echo "[golden_refresh] 完成 — 三张基线已换代入 game/tests/golden/(提交说明须写明触发原因)" +echo "[golden_refresh] 完成 — 三张基线已换代入 game/tests/golden/$PLAT/(提交说明须写明触发原因)" diff --git a/tools/golden_compare.py b/tools/golden_compare.py index c98701df..c87decc8 100644 --- a/tools/golden_compare.py +++ b/tools/golden_compare.py @@ -19,6 +19,14 @@ from PIL import Image, ImageChops TOLERANCE = 16 # 灰度差容差(单通道) FAIL_RATIO = 0.02 # changed 占比失败线 +# 基线平台子目录:<黄金图根目录>/——渲染基线按平台各存(gate_platform_id 同口径), +# 平台内部照常逐像素严格比对;跨平台不互比(字形/抗锯齿机制差异,2026-11-03 用户裁)。 +_PLAT = {"win32": "windows", "darwin": "mac"}.get(sys.platform, "linux") + + +def plat_missing(base: Path) -> bool: + return not (base / _PLAT).is_dir() + def compare(base: Path, curr: Path, name: str, failures: list) -> None: pb, pc = base / name, curr / name @@ -48,6 +56,11 @@ def main() -> int: print("用法: python tools/golden_compare.py <黄金图目录> <新截图目录> [屏清单...]") return 1 base, curr = Path(sys.argv[1]), Path(sys.argv[2]) + base = base / _PLAT + if not base.is_dir(): + print("[golden] FAIL — 本平台(%s)基线目录未建:%s" % (_PLAT, base)) + print(" 处置:在该平台跑 tools/golden_baseline_refresh.sh 重制基线并提交(基线换代权限 Q6)") + return 1 shots = sys.argv[3:] or ["shot_menu.png", "shot_camp.png", "shot_level.png", "shot_battle.png"] failures = [] for name in shots: diff --git a/tools/render_gate.sh b/tools/render_gate.sh index ee2722f5..bd89674d 100755 --- a/tools/render_gate.sh +++ b/tools/render_gate.sh @@ -34,6 +34,7 @@ REPO="$(cd "$(dirname "$0")/.." && pwd)" . "$REPO/tools/gate_platform.sh" # 跨平台件(平台探测/路径形式/带超时执行/孤儿清杀) GAME="${1:-$REPO/game}" GAME_WIN="$(gate_game_path "$GAME")" # Godot --path 接受形式(Windows 混合斜杠,其他平台原样) +GOLDEN="$REPO/game/tests/golden/$(gate_platform_id)" # 本平台基线目录(按平台各存,比较器同口径) TMP="$(mktemp -d /tmp/rendergate_XXXXXX)" trap 'rm -rf "$TMP"' EXIT _rc=0 @@ -122,8 +123,8 @@ for b in board_L1_dungeon.png board_L2_underdark.png board_L3_deep_underdark.png done echo "======== 棋盘 golden 逐像素(T2——裁剪→对比,容差 provisional) ========" -if [ ! -d "$REPO/game/tests/golden" ]; then - echo "[render_gate] FAIL — game/tests/golden/ 基线目录缺失(基线在库=验收断言②)"; _rc=1 +if [ ! -d "$GOLDEN" ]; then + echo "[render_gate] FAIL — 本平台($(gate_platform_id))基线目录缺失:$GOLDEN(基线按平台各存、在库=验收断言②)"; _rc=1 elif [ ! -s "$BD/board_meta.json" ]; then echo "[render_gate] SKIP — board_meta.json 缺失(取证段已红),golden 对比不判" else @@ -154,8 +155,8 @@ else fi echo "======== 菜单 golden 逐像素(迭代 28 T4——启动态全屏基线)========" -if [ ! -s "$REPO/game/tests/golden/menu_boot.png" ]; then - echo "[render_gate] FAIL — game/tests/golden/menu_boot.png 基线缺失(菜单 golden 未建——tools/golden_baseline_refresh.sh --menu)"; _rc=1 +if [ ! -s "$GOLDEN/menu_boot.png" ]; then + echo "[render_gate] FAIL — $GOLDEN/menu_boot.png 基线缺失(菜单 golden 未建——本平台跑 tools/golden_baseline_refresh.sh --menu)"; _rc=1 elif [ ! -s "$SHOT/shot_menu.png" ]; then echo "[render_gate] SKIP — shot_menu.png 缺失(shot_probe 段已红),菜单 golden 不判" elif [ ! -f "$GAME/assets/fonts/ui_font_fusion_pixel_zh_hans.ttf" ] || [ ! -f "$GAME/assets/art/ui/button_stone.png" ]; then