From 08a0d88bd42c265e96eb04e537e0cffbf649bfe7 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 30 Sep 2026 15:59:03 +0800 Subject: [PATCH] =?UTF-8?q?iter9-T9+T10:=20=E5=8D=A1=E2=91=AE=20=E5=88=86?= =?UTF-8?q?=E8=BE=A8=E7=8E=87=E6=A1=88=E7=94=B2=E8=90=BD=E7=A0=81+?= =?UTF-8?q?=E5=8D=A1=E2=91=B0b=20C=20=E6=A1=A3=E9=BB=84=E9=87=91=E5=9B=BE?= =?UTF-8?q?=E5=9F=BA=E5=87=86=E2=80=94=E2=80=94stretch=20aspect=20expand?= =?UTF-8?q?=E2=86=92**keep**=EF=BC=881920=20=E6=A1=A3=3D=E7=AD=89=E6=AF=94?= =?UTF-8?q?=201.35=C3=97+=E5=B7=A6=E5=8F=B3=E9=BB=91=E8=BE=B9=20~96px?= =?UTF-8?q?=E3=80=9416:10=20=E8=AE=BE=E8=AE=A1=E5=9C=A8=2016:9=20=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E9=9D=9E=E5=AD=97=E9=9D=A2=201.5=C3=97?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=91=88=E6=8A=A5=E8=90=BD=E7=A0=81=E6=B3=A8?= =?UTF-8?q?=E8=AE=B0=E5=A6=82=E5=AE=9E=E4=BF=AE=E6=AD=A3=E3=80=95=EF=BC=9B?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=B8=83=E5=B1=80=201920/1280=20=E9=80=90?= =?UTF-8?q?=E9=94=AE=E4=B8=80=E8=87=B4=E5=AE=9E=E6=B5=8B=207=20=E9=94=AE?= =?UTF-8?q?=EF=BC=89+HUD=E6=A1=86=E6=9E=B6=E4=B8=A4=E6=A1=A3=E6=9D=A1?= =?UTF-8?q?=E6=AC=BE=E4=BF=AE=E8=AE=A2=EF=BC=881280=20=E5=9F=BA=E5=87=86?= =?UTF-8?q?=E6=A1=A3=E5=AE=9A=E5=80=BC=E5=8F=A3=E5=BE=84+1920=20=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E7=AD=89=E6=AF=94=EF=BC=89+=C2=A78.2=20=E6=A1=88?= =?UTF-8?q?=E7=94=B2=E6=B3=A8=E8=AE=B0+06=20=E5=88=86=E8=BE=A8=E7=8E=87?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE=E6=94=B6=E5=8F=A3+=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=E5=8D=87=E6=A1=A3=E6=9D=A1=E7=9B=AE=E6=A1=88=E4=B9=99=E8=A3=81?= =?UTF-8?q?=E5=86=B3=E8=90=BD=E6=96=87+=E7=BE=8E=E6=9C=AF=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E8=A7=84=E6=A0=BC=E4=B8=A4=E9=A1=B9=E6=9D=A1=E7=9B=AE?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=EF=BC=88=E8=A3=81=E5=86=B3=E4=B8=80=E7=94=B2?= =?UTF-8?q?/=E4=BA=8C=E8=BF=BD=E8=AE=A4=EF=BC=89+tools/golden=5Fcompare.py?= =?UTF-8?q?=EF=BC=88=E5=AE=B9=E5=B7=AE=E5=8F=A3=E5=BE=84=EF=BC=9A=E7=81=B0?= =?UTF-8?q?=E5=BA=A6=E5=B7=AE>16=20=E5=8D=A0=E6=AF=94=20=E2=89=A42%?= =?UTF-8?q?=EF=BC=8C=E5=9B=9B=E5=B1=8F=E9=BB=84=E9=87=91=E5=9B=BE=20artwor?= =?UTF-8?q?k/qa-golden-20260930=20=E5=BB=BA=E5=9F=BA=E5=87=86=E8=87=AA?= =?UTF-8?q?=E6=AF=94=200.00%=20PASS=E2=80=94=E2=80=94=E5=8D=87=E6=A1=A3?= =?UTF-8?q?=E6=89=B9=E6=8D=A2=E4=BB=A3=E9=A1=BB=E6=98=BE=E5=BC=8F=E9=87=8D?= =?UTF-8?q?=E5=88=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/art/art-bible.md | 2 +- design/gdd/06-待办清单.md | 18 +----- design/gdd/systems/表现与支撑/HUD框架.md | 2 +- design/qa/m3-iter9-t8-rulings-2026-09-30.md | 2 + game/project.godot | 2 +- tools/golden_compare.py | 65 +++++++++++++++++++++ 6 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 tools/golden_compare.py diff --git a/design/art/art-bible.md b/design/art/art-bible.md index d80be353..731dd077 100644 --- a/design/art/art-bible.md +++ b/design/art/art-bible.md @@ -428,7 +428,7 @@ - **缩放纪律(硬规则,2026-09-30 v3.1 起按资产两类分级——2026-09-26 用户裁「更改规则,不做个案豁免」)**: - **甲类·文本与语义件**(数字、图标、旗、砖面 tile、格面纹样):维持严格整数倍缩放硬规则——可读性与语义精确性优先,**禁非整数缩放不变**。 - **乙类·角色与单位精灵**(有机形体、非文字):允许运行时非整数倍缩放(NEAREST 过滤不变),容忍轻度像素宽窄不均;判据 = 实机目检,可感不适即回整数档。乙类今后免逐案豁免(豁免蔓延断根)。 - - 1920×1080 对 1280×800 非整倍(1.5×),两档适配策略(1920 档独立 2× 基准 vs 全局 1.5×)**待裁决**——登记 06-待办清单(表现与支撑/HUD框架节),整屏样张闸(§1.4)出对照随格边长终值一并拍;该待决项与本分级同构,裁决时按甲/乙类口径一并裁。 + - **1920×1080 档策略(2026-09-30 三裁决案甲落定——三案呈报见 design/qa/m3-iter9-t8-rulings-2026-09-30.md)**:全局等比(stretch=canvas_items+aspect **keep**)——16:10 设计在 16:9 窗口=等比 1.35×+左右黑边各 ~96px,构图与 1280×800 基准档完全一致(逻辑布局 1920/1280 逐键一致实测);甲类 1.35 非整数缩放例外注记:轻度宽窄不均系本档位接受代价(像素游戏 shipped 常态),实机目检可感不适→回乙案(1920 独立 2× 基准)重议;乙类同前款。 - **画布基准(2026-09-23 用户暂定值)**: - **主角人设原图 = 48×72**(1× 基准,暂定;与站姿降采样可读性验证一致); - **主角战斗状态图(含 B 区站桩侧向)= 48×72**(同上暂定;v1.9 待决注记「主角立绘档空缺」由此收口); diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index e269c93e..73a73d06 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -349,21 +349,7 @@ **归属**:表现层升级批(HUD框架 修订随批) -**状态**:编入 M-3 迭代 9 卡⑮(2026-09-30 用户扩编,台账 288)——落码与 HUD框架 条款修订同卡(档位已定案,随视觉落码批执行) - -#### 美术资产规格两项待样张批裁决(1920 档缩放策略 / 帧数规格) - -**现状**:art-bible §8 已成文(2026-09-23)但留两项缺口,用户指令「保留缺口,样张批时提醒」。 - -① **1920×1080 档缩放策略**:1920 对 1280 非整倍(1.5×),「像素绝对均匀(1920 档独立 2× 基准)」与「两档视野一致(全局 1.5×)」不可兼得,待样张批出对照随格边长终值一并拍。 - -② **帧数规格**:待机/准备/受击/碎裂候选档(4/6/2/4–6)看数字定不了,样张批出动画关键帧后看效果定。 - -画布基准已获用户暂定值(主角原图与战斗状态图 48×72、棋盘小人 32×32 二头身,见 [art-bible](../art/art-bible.md) §8.2)。 - -**归属**:[art-bible](../art/art-bible.md) §8 · P0 样张批(格子样张/战斗一屏样张)同窗裁决 - -**状态**:随 M-3 迭代 9 卡⑤整屏样张闸呈(2026-09-30 编入承诺,台账 288——样张批开工时先呈本条提醒再动工;资产升档同闸呈,裁升档转加卡) +**状态**:**已裁决案甲并落码(2026-09-30 迭代 9 三裁决+卡⑮ T9)**——1920 档=全局等比(stretch canvas_items+aspect **keep**)——16:10 设计在 16:9 窗口=等比 1.35×+左右黑边各 ~96px(非字面 1.5×,纵横比差;呈报单落码注记),逻辑布局 1920/1280 实测逐键一致;HUD框架「两档定值 36/45px」条款改为「1280 基准档定值+1920 档全局 1.5×」;§8.2 甲类 1920 档 1.5× 例外注记随批(实机目检可感不适→回乙案重议) #### 呈现层测试分级与 UI 驱动夹具周期化(2026-09-26 登记) @@ -437,7 +423,7 @@ NodeOverlay 现行实态为模态覆盖层:恢复点全量服务(回复读 **归属**:[art-bible](../art/art-bible.md) §8.2 · 资产管线批 -**状态**:随 M-3 迭代 9 卡⑤整屏样张闸呈(2026-09-30 编入承诺,台账 288——方向已立,代拍板已追认;升档与否与终值随闸裁决,裁升档→主角三态+八敌种重产转迭代 9 加卡;提灯点亮解禁候选同闸重议) +**状态**:**已裁决案乙(2026-09-30 迭代 9 三裁决,用户「按推荐来」)**——本迭代不升档,先收 Alpha 真人读数再定(B 区舞台落影已改善存在感;T10 黄金图基准本迭代内建成不被作废);升档批=M-4 候选位,届时提灯点亮解禁候选一并重议;A4 尺寸基线冻结(立绘 46×48/小人源 32×32)维持有效 ### 数据配置 diff --git a/design/gdd/systems/表现与支撑/HUD框架.md b/design/gdd/systems/表现与支撑/HUD框架.md index 36be5adb..89496281 100644 --- a/design/gdd/systems/表现与支撑/HUD框架.md +++ b/design/gdd/systems/表现与支撑/HUD框架.md @@ -64,7 +64,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 分区尺寸与组件落位的像素级裁决归 [battle.md](../../ux/battle.md);三区结构与双舞台常驻是结构冻结项,修订走文档修订而非调参。节点链进度不在战斗屏呈现——它由关卡画面(选路覆盖层常驻形态)的节点态承载,见[关卡节点地图](../冒险循环/关卡节点地图.md)。 -**结论**:棋盘格边长取两档定值——12×12 的板用 36px、10×10 的板用 45px([battle.md](../../ux/battle.md) 拍板值);下式不推导这两档,只在装板时校验"定值塞得进扫雷图区",违例立即报错中止。 +**结论**:棋盘格边长取两档定值——12×12 的板用 36px、10×10 的板用 45px([battle.md](../../ux/battle.md) 拍板值);下式不推导这两档,只在装板时校验"定值塞得进扫雷图区",违例立即报错中止。**分辨率档位(2026-09-30 迭代 9 三裁决案甲修订)**:两档=1280×800 基准档(本表全部定值的口径)+1920×1080 档=**全局等比**(stretch canvas_items+aspect keep——16:10 设计在 16:9 窗口为等比 1.35×+左右黑边各 ~96px);本节与各屏定值一律按 1280 基准档书写,1920 档由引擎等比承载、零重排。 ``` 可行性校验(装板期断言): diff --git a/design/qa/m3-iter9-t8-rulings-2026-09-30.md b/design/qa/m3-iter9-t8-rulings-2026-09-30.md index 39312f22..9e5ef034 100644 --- a/design/qa/m3-iter9-t8-rulings-2026-09-30.md +++ b/design/qa/m3-iter9-t8-rulings-2026-09-30.md @@ -1,5 +1,7 @@ # 迭代 9 卡⑤ 随闸三裁决呈报单(2026-09-30) +> **【过闸记录 2026-09-30】用户表态「没有问题,都按你推荐的来」=三裁决全落+9A 目检过闸+k1-k9 随闸追认**:裁决一=**甲**(全局等比,T9 落码——**落码注记**:1280×800 为 16:10、1920×1080 为 16:9,等比实现=stretch keep 等比 1.35×+左右黑边各 ~96px〔非字面 1.5×,纵横比差使然〕;逻辑布局 1920/1280 逐键一致实测过)/裁决二=**追认关账**(帧数样张 v2 已冻,06 半条关闭)/裁决三=**乙**(Alpha 后再议,升档批留 M-4 候选);draw calls 缺口处置=**案 a**(瓦片纹理合流优化批立项,9B 承接)。 + > 呈报人=迭代 9 执行会话;裁决权=用户。三案全部列全(含已淘汰+依据),每案附数据/代价/联动。**T9 分辨率落码与 T10 黄金图基准卡在裁决一/三上**——裁决前两卡挂起(其余卡不阻塞)。 > 实测材料:`artwork/qa-screens-20260930/`(1280×800 四屏+shot_meta.json)/ `artwork/qa-screens-1920-20260930/`(1920×1080 四屏)。 diff --git a/game/project.godot b/game/project.godot index a355141e..063460b2 100644 --- a/game/project.godot +++ b/game/project.godot @@ -24,7 +24,7 @@ RngService="*res://core/rng_service.gd" window/size/viewport_width=1280 window/size/viewport_height=800 window/stretch/mode="canvas_items" -window/stretch/aspect="expand" +window/stretch/aspect="keep" ; 1920 档案甲(迭代 9 三裁决)——16:10 设计在 16:9 窗口=等比 1.35×+左右黑边各 96px,构图与基准档一致 [gui] diff --git a/tools/golden_compare.py b/tools/golden_compare.py new file mode 100644 index 00000000..817d6ec8 --- /dev/null +++ b/tools/golden_compare.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +r"""golden_compare.py — C 档黄金图对比(迭代 9 卡⑰b 2026-09-30;呈现层测试分级·周期重闸件)。 + +用法: python tools/golden_compare.py <黄金图目录> <新截图目录> [屏清单...] +默认屏清单 = shot_menu.png shot_camp.png shot_level.png shot_battle.png。 + +判据(容差口径,v1 冻结): + ① 四屏存在且尺寸一致(与黄金图逐屏比对); + ② 逐像素灰度差 >16 的像素占比 ≤2%(抗锯齿/微噪声容差带——结构级变化必超带); + ③ changed 占比 >2% 即 FAIL(视觉回归信号——逐屏列差异热区提示)。 +基准冻结=2026-09-30(v3.5 视觉落码+营地终稿+分辨率案甲后);资产升档批换代时显式重制基准。 +退出码: 0 = 全过 / 1 = 有失败。 +""" +import sys +from pathlib import Path + +from PIL import Image, ImageChops + +TOLERANCE = 16 # 灰度差容差(单通道) +FAIL_RATIO = 0.02 # changed 占比失败线 + + +def compare(base: Path, curr: Path, name: str, failures: list) -> None: + pb, pc = base / name, curr / name + if not pb.exists(): + failures.append("%s: 黄金图缺失(基准未建)" % name) + return + if not pc.exists(): + failures.append("%s: 新截图缺失" % name) + return + a = Image.open(pb).convert("L") + b = Image.open(pc).convert("L") + if a.size != b.size: + failures.append("%s: 尺寸 %s != 基准 %s" % (name, b.size, a.size)) + return + diff = ImageChops.difference(a, b) + hist = diff.histogram() + total = a.size[0] * a.size[1] + changed = sum(hist[TOLERANCE + 1:]) / total + print("[golden] %s — changed=%.2f%%(容差 ≤%.0f 差/≤%.0f%%)%s" % ( + name, changed * 100, TOLERANCE, FAIL_RATIO * 100, "OK" if changed <= FAIL_RATIO else "FAIL")) + if changed > FAIL_RATIO: + failures.append("%s: changed %.2f%% > %.0f%%(视觉回归——核对热区后重制或修复)" % (name, changed * 100, FAIL_RATIO * 100)) + + +def main() -> int: + if len(sys.argv) < 3: + print("用法: python tools/golden_compare.py <黄金图目录> <新截图目录> [屏清单...]") + return 1 + base, curr = Path(sys.argv[1]), Path(sys.argv[2]) + shots = sys.argv[3:] or ["shot_menu.png", "shot_camp.png", "shot_level.png", "shot_battle.png"] + failures = [] + for name in shots: + compare(base, curr, name, failures) + if failures: + print("[golden] FAIL——") + for f in failures: + print(" - %s" % f) + return 1 + print("[golden] PASS(%d 屏黄金图对比全过)" % len(shots)) + return 0 + + +if __name__ == "__main__": + sys.exit(main())