merge(波2 目录收尾): game/smoke/ 目录退役——探针件迁 game/probe/、测量/诊断/驱动件迁 game/sim/、smoke_all.gd 删除落 master;全仓引用改指+熵增闸 RETIRED 收编+Project Layout 换代;全量域闸验收通过零新增红(回执 commit=16c6f136 与分支尖对齐)

This commit is contained in:
DKChan committed 2026-10-24 02:17:38 +08:00
commit 40c14dc2c6
110 files changed
+139 -7305

No files matched your search

+4 -4
View File
@@ -17,9 +17,9 @@
## 运行与验证(工作目录 = 含 project.godot 的切片目录)
- **交付前验收 = 跑 `tools/run_all_gates.sh`,按本批改动域选档(`--code` 只跑代码域/`--docs` 只跑文档域/不带参数=两域全量),所选域全绿才合回 master**——它是全部验证闸的唯一入口与唯一清单,**域划分也只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单。一次改动同批混触 `game/` 与文档面时跑全量档。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推出该验哪个域再校验回执(六况拦截细则见 process-conventions §3.9)
- 单件直跑(调试期最窄确认用,**不构成验收**):冒烟测试 `python tools/run_smoke.py`(`game/tests/smoke_boot.tscn` 极小启动场景)· 系统测试 `python tools/run_system_test.py`(过渡期宿主 `game/smoke/smoke_all.gd`)· 场景探针 `…console.exe --headless --path . res://smoke/ui_probe.tscn` · 单元与集成 `… --script res://tests/run_all.gd`
- 调参批量:`--script res://smoke/adventure_monte_carlo.gd`(全冒险期望)· `res://smoke/reward_expectation.gd`(奖励期望);通关率/难度类测量一律走全冒险
- 数值验证:`python tools/balance_verifier.py`(采集端 `res://smoke/verifier_batch.gd`,报告与原始数据落 `sim-data/`)
- 单件直跑(调试期最窄确认用,**不构成验收**):冒烟测试 `python tools/run_smoke.py`(`game/tests/smoke_boot.tscn` 极小启动场景)· 系统测试 `python tools/run_system_test.py`(宿主 `game/tests/system_test.gd`)· 场景探针 `…console.exe --headless --path . res://probe/ui_probe.tscn` · 单元与集成 `… --script res://tests/run_all.gd`
- 调参批量:`--script res://sim/adventure_monte_carlo.gd`(全冒险期望)· `res://sim/reward_expectation.gd`(奖励期望);通关率/难度类测量一律走全冒险
- 数值验证:`python tools/balance_verifier.py`(采集端 `res://sim/verifier_batch.gd`,报告与原始数据落 `sim-data/`)
- 熵增闸(新类别 = 同批修订 Project Layout + 白名单):`python tools/repo_structure_audit.py`
## Project Layout
@@ -30,7 +30,7 @@
- `design/content-archive/` — 退役内容留底(活文档,2026-10-20 用户裁新立:内容已退役、留底供日后重新过准入;落内文件头部写明所属线)
- `design/research/` **已退役(2026-10-21 用户裁)**——`design/` 全目录只放持久化设计文档与规范,调研/提案/评估/历史验收一律落 `reports/`(熵增闸退役路径清单已收该目录,再现即判红);`design/qa/` 已退役,验证截图不进 `design/`(判据见 doc-conventions §11)
- `artwork/` — 在途图像素材唯一工作区(文档归文档/在途图归一处/终稿归游戏);整目录不入 git(.gitignore 强制),收口归档 `archive/`
- `game/assets/art/` — 已验收终稿(入包被游戏加载);`game/` — 游戏工程本体(代码 + smoke/ 冒烟 + tests/ 单元集成)
- `game/assets/art/` — 已验收终稿(入包被游戏加载);`game/probe/` — 场景探针的场景与宿主+探针共用面(probe_gate/render_gate 在闸+人工取证探针);`game/sim/` — 测量/诊断/模拟驱动件(autoplay 策略、MC 批量、数值验证采集端);`game/` — 游戏工程本体(代码 + tests/ 冒烟/单元/集成/系统测试面)
- `sim-data/` — 机器读数据产物;数据件不入 git(入库例外 = README+analyze.py+growth_model.py);MC 锚与读数常驻留盘,无数值调整禁重跑
- `tools/` — python 工具脚本;`archive/` — 批次完结归档 zip(gitignored)
- `reports/` — 过程件容器:**需求卡片**(写卡段产出,实现批的输入合同)+迭代批产出物(实现报告/代拍板追认单/GDD 反哺点清单)+设计讨论段过程稿(提案/审计/需求澄清/评估);**实现批唯一可写目录**,中间文档唯一容器(`design/research/` 已退役),不是事实源(细则见 `reports/README.md`)
@@ -186,7 +186,7 @@
| 模块 | 载体 | 独占职责 | 对外暴露 | 判定口径 |
|---|---|---|---|---|
| **run_smoke**(冒烟测试运行器) | `tools/run_smoke.py` | 冒烟测试总入口与判定权:headless 以项目运行目标拉起 `res://tests/smoke_boot.tscn`(极小启动场景——autoload 在位、配置表全载、主屏实例化,零逻辑判定)+ 三闸判定 | 进程退出码(0=PASS / 1=FAIL) | 三闸齐备、判定无洞:①退出码 = 0;②摘要行「[smoke] 摘要:N 项检查,0 项失败」在案且失败数为 0;③输出扫 `SCRIPT ERROR` / `Parse Error` 标记行。外部 wall-clock 超时在位(超时 = FAIL) |
| **run_system_test**(系统测试运行器) | `tools/run_system_test.py` | 系统测试总入口:headless 跑真实玩法路径断言面(过渡期宿主=`res://smoke/smoke_all.gd`,断言迁移批后=`res://tests/system_test.gd`)+ 三闸判定(口径同 run_smoke,摘要行兼容两种宿主格式) | 进程退出码(0=PASS / 1=FAIL) | 三闸齐备(同 run_smoke:退出码/摘要失败数/脚本错误扫描;wall-clock 超时在位) |
| **run_system_test**(系统测试运行器) | `tools/run_system_test.py` | 系统测试总入口:headless 跑真实玩法路径断言面(宿主=`res://tests/system_test.gd`)+ 三闸判定(口径同 run_smoke,摘要行兼容两种宿主格式) | 进程退出码(0=PASS / 1=FAIL) | 三闸齐备(同 run_smoke:退出码/摘要失败数/脚本错误扫描;wall-clock 超时在位) |
| **run_all**(单元与集成测试) | `game/tests/run_all.gd` | 40 套统一入口(39 单元+1 集成,2026-10-22 实数):套件 manifest 逐条「套件 → 期望退出码」,致命类 expect=1 独立子进程实跑;`negative` 字段标负面套件(仅豁免错误扫描一闸) | 逐套件结果 + 汇总退出码(任一套件失败 quit(1)) | 套件级退出码协议在位;三硬闸齐备(入口内扫子套件输出 + 编排层扫 `unit.log`;`Kit.finish` 零断言返回专用码 2)。子进程输出须经系统命令解释器重定向落盘再读——`OS.execute` 的输出管道在本机恒空 |
| **probe_gate**(场景探针) | `tools/probe_gate.sh` | headless 场景探针段编排:默认段 ui_input_probe / ui_struct_probe / layout_probe / ui_contrast_probe / **screen_flow_probe**(屏壳切换),`--click` 加跑 ui_click_probe,`--full` 加跑 ui_probe / ui_tune_probe / t17_defer_probe / fx_probe;孤儿 Godot 预清 + 批末残留清点(必须 0) | 段级 FAIL 输出 + 汇总退出码 | 每段 timeout 守卫在位(挂死 124/137 = FAIL,不静默);判定统一走 `verdict` 函数——退出码为唯一权威判据,PASS 串降级为附加判据,逐段跑 `tools/error_scan.py` |
| **render_gate**(视觉 golden) | `tools/render_gate.sh` | 窗口化渲染闸:①shot_probe 七屏截图 → shot_checker A-D 语义断言;②fx_shot_probe / board_shot_probe 取证(超时/零字节/文件缺失任一 = FAIL);③棋盘 golden 逐像素容差比对(差 ≤16 / changed ≤2%,provisional)+ 菜单 golden;④批末孤儿残留清零 | 段级 FAIL 输出 + 汇总退出码 | 查退出码在位(每段 timeout 守卫 + 退出码/取证文件双检);**SCRIPT ERROR 扫描缺失**;断言数下限不适用(判定主体 = golden 容差与取证文件存在性,非断言计数) |
@@ -238,8 +238,8 @@
| 冒烟测试 | 这版活着吗(零逻辑判定) | `game/tests/smoke_boot.tscn/.gd` | `run_smoke.py`(闸 00) |
| 单元测试 | 最单元的逻辑代码对不对 | `game/tests/unit/` | `run_all.gd`(闸 02) |
| 集成测试 | 跨系统闭环对不对 | `game/tests/integration/` | 同上(同一入口同一协议) |
| 系统测试 | 真实玩法路径断言面 | 过渡期 `game/smoke/smoke_all.gd`(迁移后 `game/tests/system_test.gd`) | `run_system_test.py`(闸 01) |
| UI 探针+渲染 golden | 场景切换与观感 | `game/smoke/*.tscn` 探针 | `probe_gate.sh`(闸 03/04)、`render_gate.sh`(闸 05) |
| 系统测试 | 真实玩法路径断言面 | `game/tests/system_test.gd` | `run_system_test.py`(闸 01) |
| UI 探针+渲染 golden | 场景切换与观感 | `game/probe/*.tscn` 探针 | `probe_gate.sh`(闸 03/04)、`render_gate.sh`(闸 05) |
**判定原则**:验收不能只是「跑一遍没崩」。三硬闸(退出码/脚本错误扫描/断言数下限)是判定的底线,
缺一即判定有洞;「日志里写着 PASS」不作判据。另有两类静默失效必须机制性防范——规则扫描面为空
@@ -312,7 +312,7 @@ CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无
→ 关卡末:通关结算(钥石/GP/专长 level_clear 渠道——现行语义归 冒险结构 GDD;原 clear_inventory 随库存轴下线退役 2026-09-15)
```
**启动后置条件**(2026-10-17 用户裁入册——迭代 28 以冒烟 V2a–V2f 共 11 条断言把「启动完成后玩家该看到什么」成文;执行判据事实源在 `game/smoke/smoke_all.gd`):
**启动后置条件**(2026-10-17 用户裁入册——迭代 28 以冒烟 V2a–V2f 共 11 条断言把「启动完成后玩家该看到什么」成文;执行判据事实源在 `game/tests/system_test.gd`):
1. ConfigDB 就绪且表已载(`is_ready` + hero 表在座)。
2. 系统设置已落引擎态——Master 音量 mute/volume_db = settings_store 现值;减动效开关 = `UiKit.motion_scale`。
+1 -1
View File
@@ -64,7 +64,7 @@
4. **lambda 捕获循环变量按创建时值**——循环内先落地局部变量再捕获,或用 `bind`。
5. **重命名脚本必须同步 `.uid` 文件**;新增 `class_name` 后必须跑一次编辑器扫描刷新全局类缓存,否则 `--headless --script` 模式解析失败。
6. **`print` 格式占位符与实参类型必须匹配**(`%d` 配 String = 静默输出字面量)。
7. **语言纪律已机器化为 S9 类型闸**——`tools/audit_type_hints.py`,执行载体=静态扫描域 S9(`game/tests/static_scan.sh`),退出码 0=归零。扫描面=产品码(`game/core`+`game/data`+`game/presentation`;smoke/tests 豁免——测量面容器直构是既有惯例)。三规则:R1 无类型容器(显式非参数化 `Dictionary`/`Array` 注解)/R2 有值返回缺返回类型(纯副作用缺 `-> void` 属写法面不入闸)/R3 参数缺类型(`_init` 豁免——构造注入面形态自由)。
7. **语言纪律已机器化为 S9 类型闸**——`tools/audit_type_hints.py`,执行载体=静态扫描域 S9(`game/tests/static_scan.sh`),退出码 0=归零。扫描面=产品码(`game/core`+`game/data`+`game/presentation`;probe/sim/tests 不在扫描面——测量面容器直构是既有惯例)。三规则:R1 无类型容器(显式非参数化 `Dictionary`/`Array` 注解)/R2 有值返回缺返回类型(纯副作用缺 `-> void` 属写法面不入闸)/R3 参数缺类型(`_init` 豁免——构造注入面形态自由)。
8. **`:= {}` 推断形态不算债**——`var x := {}` 类赋值推断属类型推断合法面,不入 R1 扫描;只有显式写的非参数化容器注解才算无类型容器。
9. **行级白名单通道 `# type-hint: ignore`**——豁免该行不入 S9;豁免理由必须随行注明(现行例:`board_generator` 四函数的 db 参鸭子型——typed 参拒冒烟夹具 `_BoardRowStub` 注入)。
10. **`# rng-seed-exempt` 标记豁免通道**——S1/S2 随机函数扫描对该行豁免;限定用途=非玩法 RNG 消费面的引擎熵(现行例:组合根种子编辑框空态取 `randi()`——建种子不进玩法封闭流)。
+3 -3
View File
@@ -1,6 +1,6 @@
# 测试规范(Dungeon Sweeper)
> 约束范围:`game/smoke/`、`game/tests/` 与一切场景探针的编写与验收。
> 约束范围:`game/probe/ 与 game/sim/`、`game/tests/` 与一切场景探针的编写与验收。
> 分工:测试**执行许可**(什么时候允许跑测试)归 AGENTS.md「硬性红线·测试执行两入口铁规」;**跑什么闸、什么顺序**归 `tools/run_all_gates.sh`(脚本即清单,本文与 AGENTS.md 均不另列);本文管测试怎么写、怎么算合格。
**写任何测试前必须通读本文。**
@@ -33,7 +33,7 @@
需求卡片 §8「改动—验收对照表」每一条都要落成可执行的验证;本文定统一写法,卡里定每批的具体内容(测什么/注入哪里)。写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期。
1. **执行载体五选一,逐条声明**:单元测试(`tests/run_all`)/冒烟断言(`smoke_all.gd` 对应场景段)/场景探针(`smoke/` 下 `*_probe`)/MC 同种子逐项比对/人工核对(仅限无法自动化的纪律类需求点,如命名锁定、数值占位)。行为类条目以自动化载体为主。
1. **执行载体五选一,逐条声明**:单元测试(`tests/run_all`)/系统测试断言(`tests/system_test.gd`)/场景探针(`probe/` 下 `*_probe`)/MC 同种子逐项比对/人工核对(仅限无法自动化的纪律类需求点,如命名锁定、数值占位)。行为类条目以自动化载体为主。
2. **粒度与对应关系**:每条清单条目至少一个自动断言,且断言必须从该条目的真实入口进入;多条条目可合用一个测试函数,但撤销对应改动时每条都要能单独变红。断言失败消息末尾带编号尾缀〔卡短名 Vn〕(如〔秘宝批 V3〕)——断言与卡片清单可互相 grep 查找。
3. **断言词汇按验证对象五选一**:
@@ -78,7 +78,7 @@
- 负面套件(测试目标就是产生错误输出)仅可豁免第 2 闸,且须在 manifest 显式标记,其余两闸照判。
- 子进程输出须经系统命令解释器重定向落盘再读——`OS.execute` 的输出管道在本机恒空。
**新写测试件全类型标注**——新写的测试件(冒烟断言/探针/单测)参数、返回值、容器一律带类型标注,与 S9 对产品码的要求同型;存量不强制清扫,被批次触碰时顺带换代。暂不机器闸(S9 扫描面=产品码,smoke/tests 豁免是测量面直构惯例的既有裁量)。
**新写测试件全类型标注**——新写的测试件(冒烟断言/探针/单测)参数、返回值、容器一律带类型标注,与 S9 对产品码的要求同型;存量不强制清扫,被批次触碰时顺带换代。暂不机器闸(S9 扫描面=产品码,probe/sim/tests 不在扫描面是测量面直构惯例的既有裁量)。
## 8. 判定可靠性优先于覆盖率(迭代 29 核心命题)
@@ -92,7 +92,7 @@
生命周期:进程启动后流待命(未注入主种子就取数,致命中止,禁止默认种子兜底)→ 冒险开始注入主种子并开日志会话 → 冒险中按事件取号(全局计数器只增不重置)→ 冒险结束流保留供复盘。续玩与复盘的快照 = 主种子加全局取数计数器,由[存档序列化](存档序列化.md)消费;快照切出须发生在没有在用取号实例的时刻。要新增随机用途(含战斗内随机),走扩签通道:改代码加用途标签并通过评审——词表封闭是刻意的设卡。
举证:派生公式与实现规约见 `game/core/rng_service.gd`(盐与派生常量为代码事实),黄金向量断言见 `game/smoke/smoke_all.gd`;本文不转载。
举证:派生公式与实现规约见 `game/core/rng_service.gd`(盐与派生常量为代码事实),黄金向量断言见 `game/tests/unit/data_config/rng_stream_boot_test.gd`;本文不转载。
### fail-fast 校验:宁可启动失败,不带病运行
+1 -1
View File
@@ -126,7 +126,7 @@
1. **历史文本**:git 提交说明、裁决记录中引用用户原话的句子——保留原用词,不按 A 表追改。
2. **对照性文本**:「退役词对照」表本身、「原 ××」式更名记载、禁令引举句——旧词在这些位置是内容本身,不是残留。
3. **玩家可见专名与机制词**:按「对外命名纪律」节与各系统文档现行用语使用(标中/踩雷等机制词在文档内部照常用)。
4. **被检查的禁字不算使用**:守卫代码里作为检查对象的禁字字面量——`game/smoke/smoke_all.gd` 的 `contains("旗")` 检查项、`game/tests/unit/presentation/ui_font_asset_test.gd` 的字形集负探针、`game/data/tables/feats.tres` 头注的「desc 禁『雷/旗』字面」、`tools/doc_term_audit.py` 的退役词表定义行——不属换代范围:被检查的字不是对该字的使用,改写等于自毁守卫。术语清扫的复扫口径按 **game/ 全部文件类型、不排除任何扩展名**执行(迭代 31 卡① 实测:金币/插旗/雷格/惩罚格/`flag` 均 0 命中,残留仅为上述保留面)。
4. **被检查的禁字不算使用**:守卫代码里作为检查对象的禁字字面量——`game/tests/unit/core/adventure_feats_test.gd` 的 `contains("旗")` 检查项、`game/tests/unit/presentation/ui_font_asset_test.gd` 的字形集负探针、`game/data/tables/feats.tres` 头注的「desc 禁『雷/旗』字面」、`tools/doc_term_audit.py` 的退役词表定义行——不属换代范围:被检查的字不是对该字的使用,改写等于自毁守卫。术语清扫的复扫口径按 **game/ 全部文件类型、不排除任何扩展名**执行(迭代 31 卡① 实测:金币/插旗/雷格/惩罚格/`flag` 均 0 命中,残留仅为上述保留面)。
存量口径:A 表生效前已入库的正文不做强制清扫;文件后续被批次触碰时,顺带按 A 表换代。
+7 -7
View File
@@ -5,7 +5,7 @@
> // "数值提升→通关期望改善"的 Roguelike 元进度验证——基线属性应该难到打不过、天赋数值提升把
> // 通关期望拉回可玩带,且这条曲线能用数值调整板 + 批量模拟**测量出来**
> // (通关攻击期望 / 败北血量数学期望);v1 的单战斗循环问题(逐行归因 P2 / Core headless 可跑)
> // 已于 2026-09-10 验证并保持回归(smoke_all 前 46 项)。
> // 已于 2026-09-10 验证并保持回归(初版断言面 46 项,后并迁系统测试宿主,沿革查 git log)。
> // Date: 2026-09-10(v1)· 2026-09-11(v2 关卡扩展)· 引擎 Godot 4.7.2 · 本目录仅作设计验证参考,禁止 import 进生产代码
## 运行
@@ -18,27 +18,27 @@
headless 冒烟(752 项断言〔计数随批增长,现值以最新批末闸读数为准〕,含关卡线性推进/满配通关/裸装败北/回放确定性;2026-10-02 性能报告实测 60.55 秒,报告在 `性能实测报告(已退役,git 历史可查)`):
```
Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/smoke_all.gd
Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://probe/smoke_all.gd
```
场景级 UI 探针(项目运行模式实例化 main.tscn 驱动第一关,断言棋盘真实渲染——D1 教训"呈现层零测试承载"的原型兑现):
```
Godot_v4.7.2-stable_win64_console.exe --headless --path . res://smoke/ui_probe.tscn
Godot_v4.7.2-stable_win64_console.exe --headless --path . res://probe/ui_probe.tscn
```
调试浮窗场景探针(缺陷⑤回归载体沿袭——2026-10-04 迭代 14.5 随批改接浮窗形态:打开可见性〔浮于菜单之上,开始层不隐藏〕/滑条联动/应用写表/重置/批量模拟全链路):
```
Godot_v4.7.2-stable_win64_console.exe --headless --path . res://smoke/ui_tune_probe.tscn
Godot_v4.7.2-stable_win64_console.exe --headless --path . res://probe/ui_tune_probe.tscn
```
其余八场景探针(ui_click_probe 行为链 / ui_input_probe 输入合成 / ui_struct_probe 全屏结构 / ui_contrast_probe 对比度 / ui_probe·ui_tune_probe 调参面板 / t17_defer_probe 结算演播延迟链回归 / shot_probe·fx_probe·fx_shot_probe·board_shot_probe 画面与特效采样;全部由 `tools/probe_gate.sh` 与 `tools/render_gate.sh` 调度,闸清单见 `tools/run_all_gates.sh`)+ 板图校准工具 `smoke/calibrate_boards.gd`(board_calibration.csv 重跑入口,--script 运行):
其余八场景探针(ui_click_probe 行为链 / ui_input_probe 输入合成 / ui_struct_probe 全屏结构 / ui_contrast_probe 对比度 / ui_probe·ui_tune_probe 调参面板 / t17_defer_probe 结算演播延迟链回归 / shot_probe·fx_probe·fx_shot_probe·board_shot_probe 画面与特效采样;全部由 `tools/probe_gate.sh` 与 `tools/render_gate.sh` 调度,闸清单见 `tools/run_all_gates.sh`)+ 板图校准工具 `sim/calibrate_boards.gd`(board_calibration.csv 重跑入口,--script 运行):
全冒险期望扫描(零加成三关连探批量——通关率/止步分布/败退节点;调参期难度读数一律走全冒险口径):
```
Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/adventure_monte_carlo.gd -- [N] [seed0]
Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://sim/adventure_monte_carlo.gd -- [N] [seed0]
```
(原关卡期望扫描 level_monte_carlo.gd 走单关直入口口径——满血零上下文进关与真实冒险脱节,随口径退役删除,2026-09-23 用户拍板。)
@@ -47,7 +47,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/a
**日志合规(2026-09-12 用户要求)**:任何模拟运行与真人试玩均落全量 JSONL(user://logs/)——逐操作(op/cell/accepted/round)、逐结算明细行、轮次状态快照、battle_end、level_end。模拟(verifier/adventure_monte_carlo / 调试浮窗批量模拟)一文件多局,run 行携带种子/档位切分局次。
**试玩画像口径(2026-09-19 用户拍板固化——全项目试玩/扫描/面板模拟一律只用以下两档,随机策略口径退役)**:`policy="normal"` = **普通画像·基础定式**(单数字满足规则——满足即标/满足即开,无处可推盲挖边界格、不刷新;教学后正常玩家的下限近似);`policy="perfect"` = **完美画像**(single+subset 全推理零盲挖/卡死刷新——技能上界仪)。实现单一出口 = `smoke/auto_player.gd`(novice_action / perfect_action)经 `smoke/level_autoplay.gd`,调试浮窗批量模拟与各扫描工具自动同口径;战斗层冒烟夹具与调试转储的 `choose_dig` 直调是机制测试夹具、不承载画像语义。分级依据与新旧读数(乱点 0%/5% → 基础定式 65%/90%)见 auto_player.gd 普通策略档节与台账 77。
**试玩画像口径(2026-09-19 用户拍板固化——全项目试玩/扫描/面板模拟一律只用以下两档,随机策略口径退役)**:`policy="normal"` = **普通画像·基础定式**(单数字满足规则——满足即标/满足即开,无处可推盲挖边界格、不刷新;教学后正常玩家的下限近似);`policy="perfect"` = **完美画像**(single+subset 全推理零盲挖/卡死刷新——技能上界仪)。实现单一出口 = `sim/auto_player.gd`(novice_action / perfect_action)经 `sim/level_autoplay.gd`,调试浮窗批量模拟与各扫描工具自动同口径;战斗层冒烟夹具与调试转储的 `choose_dig` 直调是机制测试夹具、不承载画像语义。分级依据与新旧读数(乱点 0%/5% → 基础定式 65%/90%)见 auto_player.gd 普通策略档节与台账 77。
单关诊断工具(level_debug.gd)随单关直入口口径退役(2026-09-23)——败退归因走 balance_verifier 冒险段(层/节点/敌人人读归因)。
战斗级工具(v1 遗产):`dump_battle.gd`(结算流水)/ `monte_carlo.gd`(战斗期望)/ `experiment_density.gd`(密度调参)。
+1 -1
View File
@@ -24,7 +24,7 @@ func _init(db_ref, panel_ref, base_hp: int, driver = null) -> void:
func _autoplay():
if _driver != null:
return _driver
return load("res://smoke/level_autoplay.gd") # 与 headless 扫描同口径的自动策略(P3 兜底路径)
return load("res://sim/level_autoplay.gd") # 与 headless 扫描同口径的自动策略(P3 兜底路径)
func run(n: int) -> void:
@@ -1,7 +1,7 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# 棋盘渲染帧取证探针(目视验证面:机检≠看得清)。
# 必须**窗口化**运行(headless 无渲染面):
# Godot_console.exe --path . res://smoke/board_shot_probe.tscn -- <输出目录>
# Godot_console.exe --path . res://probe/board_shot_probe.tscn -- <输出目录>
# 流程:L1/L2/L3 各起一板(真实 LevelRunner+settle_batch 驱动 ~18 步 novice——自然揭示数字/封印),
# BoardView 真渲染,frame_post_draw 同步后抓视口 PNG。零存档触碰(无 save_manager 引用)。
# 护栏:headless fail-fast(shot_probe 同款);空纹理取证 fail——取证段失败=闸红,
@@ -14,7 +14,7 @@
# 前置 UiKit.motion_scale=0.5 冻结接触带呼吸相位(静态带色),两帧差异唯一定位在类型微光。
extends Node
const AutoPlayer := preload("res://smoke/auto_player.gd")
const AutoPlayer := preload("res://sim/auto_player.gd")
const ActionEconomy := preload("res://core/action_economy.gd")
var _meta := {} # 棋盘视图实测几何(全局 rect——tools/golden_board_crop.py 取样坐标源)
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/board_shot_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/board_shot_probe.gd" id="1"]
[node name="BoardShotProbe" type="Node"]
script = ExtResource("1")
@@ -3,7 +3,7 @@
# ①死亡碎裂(standee mark_dead → 碎块计数)②意图三档动画(damage/buff/debuff/charge 摇定不炸+徽标可见)
# ③胜利纹章+失败掸灰+封印光收回(battle_end open_victory/open_defeat → fx_probe 计数)
# ④结算轮光带(settlement_fx play_round_sweep → 子节点落位)。
# 运行:Godot_console.exe --headless --path . res://smoke/fx_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/fx_probe.tscn
extends Node
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/fx_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/fx_probe.gd" id="1"]
[node name="FxProbe" type="Node"]
script = ExtResource("1")
@@ -1,12 +1,12 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# 演出渲染证据探针(真实渲染设备抓战斗演出瞬间帧)。
# 必须**窗口化**运行(真渲染设备——headless 无渲染面):Godot_console.exe --path . res://smoke/fx_shot_probe.tscn -- <输出目录>
# 必须**窗口化**运行(真渲染设备——headless 无渲染面):Godot_console.exe --path . res://probe/fx_shot_probe.tscn -- <输出目录>
# 流程 = shot_probe 同款隔离面(存档/设置/元进度换注隔离档,禁碰真实档)+ 真实按钮路径开冒险进首战;
# 自动玩家挖格驱动行结算,在 行到达/弹道飞行/结算排播 三时刻抓帧——演出链「逻辑在(fx_probe PASS)×
# 渲染在(本探针 PNG)」双证的第二半边。PNG 落输出目录(artwork/qa-fx-*/,素材纪律不入 git)。
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
# ── 演出采样窗口口径(headless/窗口化帧率不定,帧时刻以墙钟近似锚定;改窗口 = 改抓帧
# 时刻观测面,非断言语义。窗口值与字面量同值——仅提为具名常量。) ──
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/fx_shot_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/fx_shot_probe.gd" id="1"]
[node name="FxShotProbe" type="Node"]
script = ExtResource("1")
@@ -5,7 +5,7 @@
# 硬约束:档位表是数据、断言是一份函数据——加档只改表不动断言(禁每档建一个探针)
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # 隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # 隔离样板单点
# 分辨率档位表(逻辑视口尺寸;数据侧——增删档位只改这里,断言代码零改动)
const VIEWPORTS := [
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://clayoutprobe01"]
[ext_resource type="Script" path="res://smoke/layout_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/layout_probe.gd" id="1"]
[node name="LayoutProbe" type="Node"]
script = ExtResource("1")
@@ -2,7 +2,7 @@
# 探针共用面:树寻址助手 + 存档/设置/元进度隔离样板单点。
# 覆盖:ui_probe / ui_click_probe / shot_probe / fx_shot_probe 四探针的树寻址样板
# 与隔离样板(各探针隔离文件名后缀 tag 保持不变)。
# 用法:探针侧 `const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd")` 后静态调用
# 用法:探针侧 `const ProbeUiUtil := preload("res://probe/probe_ui_util.gd")` 后静态调用
#(探针载体含 --script 场景两种,均无全局标识符——禁 class_name 裸引用)。
extends RefCounted
File renamed without changes.
@@ -4,10 +4,10 @@
# 与 ui_click_probe 的分工:那件走的是「点某个按钮有没有反应」的行为走查(含战斗推进与结算数值面);
# 本件只走屏壳与流程状态,不推进战斗、不碰结算数值——屏级互斥是最容易被装配顺序改动悄悄破坏
# 又最难被单测覆盖的面(全库 change_scene 零命中,屏切换全靠 visible 互斥)。
# 运行:Godot_console.exe --headless --path . res://smoke/screen_flow_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/screen_flow_probe.tscn
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd")
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd")
var main: Node
var _problems: Array[String] = []
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/screen_flow_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/screen_flow_probe.gd" id="1"]
[node name="ScreenFlowProbe" type="Node"]
script = ExtResource("1")
@@ -2,7 +2,7 @@
# 整屏截图探针(呈现层测试分级 B 档基建:视口截图程序化产出;七屏——
# 菜单/设置面/生涯页/营地/关卡画面/战斗/状态面板,现行事实源=tools/render_gate.sh)。
# 必须**窗口化**运行(真渲染设备——headless 无渲染面,get_image 得到空纹理):
# Godot_console.exe --path . res://smoke/shot_probe.tscn -- <输出目录>
# Godot_console.exe --path . res://probe/shot_probe.tscn -- <输出目录>
# 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档,
# 坑册「断点写盘随 save_manager 引用走」教训同款覆盖):菜单(启动态)→ 设置面(settingsbtn
# 真实信号路径)→ 生涯页(函数直调中间态——卡② mn10)→ 营地(进档开层新路径——mn9)→ 关卡画面(函数直调中间态→停点出图)→
@@ -14,7 +14,7 @@
# 到达不成立;合成投喂(ui_struct_probe 同款)破坏本探针真实路径口径 → 不纳屏。
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
var main: Node
var out_dir := ""
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/shot_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/shot_probe.gd" id="1"]
[node name="ShotProbe" type="Node"]
script = ExtResource("1")
@@ -6,7 +6,7 @@
# 存档/设置/元进度三面隔离(isolate_save 现行事实源,meta 经 autoload 链同源),零真实档触碰。headless 可跑(不抓帧)。
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # 隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # 隔离样板单点
var main
var _problems: Array = []
@@ -50,7 +50,7 @@ func _ready() -> void:
var settle_clock := ""
while guard > 0 and String(main.run_scope.settlement.battle_result) == "":
guard -= 1
var plan = load("res://smoke/auto_player.gd").choose_dig(ms)
var plan = load("res://sim/auto_player.gd").choose_dig(ms)
if plan.is_empty():
main.run_scope.settlement.settle_batch([{"action": "stop", "cell": Vector2i(-1, -1)}])
await get_tree().process_frame
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/t17_defer_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/t17_defer_probe.gd" id="1"]
[node name="T17DeferProbe" type="Node"]
script = ExtResource("1")
@@ -1,7 +1,7 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# 未开格类型微光渲染取证探针(像素侧——V4 禁侵/V5 不压破/V6 五组互辨)。
# 必须**窗口化**运行(headless 无渲染面,抓帧恒空):
# Godot_console.exe --path . res://smoke/type_glow_shot_probe.tscn -- <输出目录>
# Godot_console.exe --path . res://probe/type_glow_shot_probe.tscn -- <输出目录>
# 流程:起一板(真实 LevelRunner + settle_batch 驱动 18 步 novice——自然揭示数字/封印)→ 注入夹具身份回调
# (九 cell_type 循环 ⇒ 五组同屏齐现)→ BoardView 真渲染:
# 帧 A = 微光关(基线态)→ type_glow_off.png
@@ -11,7 +11,7 @@
# 零存档触碰(无 save_manager 引用)。取证件落调用方给的目录(库外),不入 git。
extends Node
const AutoPlayer := preload("res://smoke/auto_player.gd")
const AutoPlayer := preload("res://sim/auto_player.gd")
# 夹具:九 cell_type 全值域(地图战斗资源九型枚举同源)
const FIXTURE_TYPES := ["attack", "defense", "blast", "heal", "weaken",
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/type_glow_shot_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/type_glow_shot_probe.gd" id="1"]
[node name="TypeGlowShotProbe" type="Node"]
script = ExtResource("1")
@@ -6,11 +6,11 @@
# + 模态遮挡断言(缺陷⑤回归:图例/回看/终局 overlay 打开时上方遮挡层隐藏、输入锁定)
# + 性能 AC:场景实例化到首格可点 ≤500ms 探针计时。
# 行为序列由 PROBE_SEED 决定(shell 传参);程序玩法数值不受影响(随机只用于探针策略)。
# 运行:PROBE_SEED=7 Godot_console.exe --headless --path . res://smoke/ui_click_probe.tscn
# 运行:PROBE_SEED=7 Godot_console.exe --headless --path . res://probe/ui_click_probe.tscn
extends Node
const AutoPlayer := preload("res://smoke/auto_player.gd") # O4:自动玩家策略单一实现
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
const AutoPlayer := preload("res://sim/auto_player.gd") # O4:自动玩家策略单一实现
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
var main: Node
var _last_state := {}
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_click_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/ui_click_probe.gd" id="1"]
[node name="UIClickProbe" type="Node"]
script = ExtResource("1")
@@ -3,7 +3,7 @@
# 断言面 = 文字墨对直背景 ≥4.5:1(art-bible §7.2 无区域例外;文字禁直压纹理底——垫牌后按牌色计)。
# 测点表:血数垫牌 / 意图徽标四墨(PANEL_DATA 垫牌)/ C区槽位两态墨 / RAP 标签 + 全站锚点组。
# 测点对一律取 UiKit 常量实时求值——代码侧换色即本闸红,禁只改注释不动值;α<1 墨先对背景混成再算。
# 运行:Godot_console.exe --headless --path . res://smoke/ui_contrast_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/ui_contrast_probe.tscn
extends Node
const MIN_RATIO := 4.5
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_contrast_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/ui_contrast_probe.gd" id="1"]
[node name="UIContrastProbe" type="Node"]
script = ExtResource("1")
@@ -10,10 +10,10 @@
#(⑧–⑪=Node2D 展示几何/状态面单元化断言)。
# 事件路径:Viewport.push_input(ev, in_local_coords=true)——落点用 BoardView.cell_center_local
# (与 _cell_at 同一公式族)换算画布坐标,SubViewportContainer mouse_filter=IGNORE 不拦截。
# 运行:Godot_console.exe --headless --path . res://smoke/ui_input_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/ui_input_probe.tscn
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # T6 收口:隔离样板单点
var main: Node
var _problems: Array = []
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_input_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/ui_input_probe.gd" id="1"]
[node name="UIInputProbe" type="Node"]
script = ExtResource("1")
@@ -3,10 +3,10 @@
# 项目运行模式(autoload 在位)实例化 main.tscn,直接驱动 _start_adventure_from_menu()(完整冒险——唯一试玩入口),
# 断言真实构建(棋盘/主角站桩/敌方站桩/AP 点阵/明细带/数据框;无 A 区进度条断言与 E 区道具面板;
# 英雄/敌人 = 站桩断言)。
# 运行:Godot_console.exe --headless --path . res://smoke/ui_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/ui_probe.tscn
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # T6 收口:树寻址/隔离样板单点
func _ready() -> void:
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/ui_probe.gd" id="1"]
[node name="UIProbe" type="Node"]
script = ExtResource("1")
@@ -8,10 +8,10 @@
# ④zero_size 可见件宽或高 ≤0=红
# ⑤start 专项 标题屏左列(start_box)与右列(start_right)矩形不相交(双列契约——叠放缺陷回归闸)
# 豁免:WL 常量表按「屏名/规则名/件名」登记合法例外(登记须注理由于行尾注释)。
# 运行:Godot_console.exe --headless --path . res://smoke/ui_struct_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/ui_struct_probe.tscn
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd")
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd")
# 豁免清单(空 = 零豁免起步;红灯逐条核对后合法者入表并注理由)
const WL := {}
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_struct_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/ui_struct_probe.gd" id="1"]
[node name="UIStructProbe" type="Node"]
script = ExtResource("1")
@@ -8,10 +8,10 @@
# ⑨对局中可开(战斗屏角标真实信号路径)+棋盘输入不锁+状态角标不置灰(停机点回归闸)
# +对局中两钮禁用+当局数据六项值对(与只读访问器逐项一致)+只读巡检(白名单外零连接)+零动效契约
# ⑩种子三分单点断言(显式输入优先/首局恒 42/非首局空框连抽 4 次不全等 42)
# 运行:Godot_console.exe --headless --path . res://smoke/ui_tune_probe.tscn
# 运行:Godot_console.exe --headless --path . res://probe/ui_tune_probe.tscn
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:隔离样板单点
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # T6 收口:隔离样板单点
const SIM_GUARD_FRAMES := 1800 # ⑤ N=10 headless 模拟防挂死帧预算上限(探针内停滞检测第一道——坏态不等满预算才报,超时即断言失败)
File renamed without changes.
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_tune_probe.gd" id="1"]
[ext_resource type="Script" path="res://probe/ui_tune_probe.gd" id="1"]
[node name="UITuneProbe" type="Node"]
script = ExtResource("1")
@@ -7,7 +7,7 @@
# ② 全量操作日志 = playtest_logger 共享会话 JSONL(与真人试玩同合规口径,每策略一批一文件,
# run 行携带种子/策略切分局次,落 user://logs/)。
# 本工具只采集与落盘数据,不做统计判读(通关率/败因分布归分析会话)。
# 运行:Godot_console.exe --headless --path . --script res://smoke/adventure_monte_carlo.gd -- [N] [seed0] [normal|perfect|both] [route min|max]
# 运行:Godot_console.exe --headless --path . --script res://sim/adventure_monte_carlo.gd -- [N] [seed0] [normal|perfect|both] [route min|max]
extends SceneTree
@@ -96,7 +96,7 @@ func _initialize() -> void:
if not equipped.has(p):
equipped.append(p)
attune_profile = {"equipped": equipped, "refresh_y": 1}
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
var t0 := Time.get_ticks_msec()
print("=== 冒险全流程扫描:三关连探 · N=%d/策略 · 种子 %d 起逐局独立 · 策略=%s · atk+0%%/hp+0%% 零加成 · route=%s ===" % [n, seed0, policy_arg, route])
for policy in policies:
File renamed without changes.
File renamed without changes.
@@ -6,7 +6,7 @@
# 不经本面(含回归断言,禁并入);fx_shot_probe 为带墙钟抓帧的异步变体亦不在列。
extends RefCounted
const AutoPlayer := preload("res://smoke/auto_player.gd")
const AutoPlayer := preload("res://sim/auto_player.gd")
const GUARD_ACTIONS := 400 # 单轮动作步防挂死上限(被收口探针原值逐一同值)
File renamed without changes.
@@ -4,7 +4,7 @@
# 对 board_gen.tres 每行 (L, D) 生成 N 张板,统计幸存雷数 |M| 与安全格数 |S|
# 的均值 / 最小 / 最大("先布后删"后的落地值——名义值 density×(W×H−9) 不含删除段)。
# 只读诊断,零游戏代码改动;装载面与冒险扫描工具同源(config_db.load_tables)。
# 运行:Godot_console.exe --headless --path . --script res://smoke/board_stat_probe.gd -- [N] [seed0]
# 运行:Godot_console.exe --headless --path . --script res://sim/board_stat_probe.gd -- [N] [seed0]
extends SceneTree
File renamed without changes.
@@ -3,7 +3,7 @@
# 逐 board_gen 行真实生成 N 板,统计 实际雷数/安全格数/R₀ 初始展开占比——
# 生成期「先布后删+可推理率重试」使实际雷数远低于表口径 round(d×(W×H−9)),
# 日志侧只有清图板可反推 safe_total(未清图深度无样本),本工具给全网格精确分母。
# 运行:Godot_console.exe --headless --path . --script res://smoke/calibrate_boards.gd -- [N]
# 运行:Godot_console.exe --headless --path . --script res://sim/calibrate_boards.gd -- [N]
# 输出:stdout CSV 行 level,depth,w,h,n,mines_mean,mines_med,safe_mean,safe_med,r0_mean,inf_mean
extends SceneTree
File renamed without changes.
@@ -8,11 +8,11 @@
# 观测面:全部读战斗结算步骤行 / 表值 / 呈现快照(零核心穿透);池归属/档位/下限全读表(数据配置 Rule 1——零数值字面量)。
# 模式(-- 后参数):boss [seed](默认 42:Run A 零挖掘 fresh 池 + Run B 自动挖掘授予行为)
# level [seed](全关遭遇回放 + 多种子 spawn 扫描——报告 Bug#1 证据面)
# 运行:Godot_console.exe --headless --path . --script res://smoke/damage_probe.gd -- boss 42
# Godot_console.exe --headless --path . --script res://smoke/damage_probe.gd -- level 42
# 运行:Godot_console.exe --headless --path . --script res://sim/damage_probe.gd -- boss 42
# Godot_console.exe --headless --path . --script res://sim/damage_probe.gd -- level 42
extends SceneTree
const BattleDriver := preload("res://smoke/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
const BattleDriver := preload("res://sim/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
var _checks := 0
var _fails := 0
File renamed without changes.
@@ -2,7 +2,7 @@
# playtest-2026-09-12 Q1 复核——"安全格减伤是否过量导致满血打完 Boss"
# 口径:逐结算轮统计 ac_up 授予层数(AC10→11→12)与该轮敌方实伤,
# 分割"高 AC 轮"(叠满 = AC12,期望减免 28.75%)与基线轮(AC10,期望减免 21.25%)的承伤读数。
# 运行:Godot_console.exe --headless --path . --script res://smoke/defense_scan.gd -- [N] [seed0]
# 运行:Godot_console.exe --headless --path . --script res://sim/defense_scan.gd -- [N] [seed0]
extends SceneTree
@@ -19,7 +19,7 @@ func _initialize() -> void:
print("表加载失败")
quit(1)
return
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
print("=== 盾牌加护叠层扫描(AC 口径):第一关 · N=%d · 种子 %d+%d ===" % [n, seed0, n])
print("%-6s %-6s %-8s %-12s %-14s %-14s" % ["seed", "轮数", "战斗轮", "满层轮(AC12)", "满层轮承伤", "非满层轮承伤"])
var full_rounds := 0
File renamed without changes.
@@ -1,10 +1,10 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2)
# 一次性检查脚本:打印一场完整战斗的结算步骤流 + 棋盘摘要(肉眼验收 P2 归因质量)。
# 运行:Godot_console.exe --headless --path . --script res://smoke/dump_battle.gd
# 运行:Godot_console.exe --headless --path . --script res://sim/dump_battle.gd
extends SceneTree
const BattleDriver := preload("res://smoke/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
const BattleDriver := preload("res://sim/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
func _initialize() -> void:
var db = load("res://core/config_db.gd").new()
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -21,7 +21,7 @@
# 实现注:信号处理体全部为静态方法 + bind 传状态——GDScript 多行 lambda 内嵌 match/控制流的解析不可靠。
extends RefCounted
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现
# ── 普通档 v3 失误注入参数(踩雷期望=完美+2/板、每板少挖几个正确格)──
# 标雷→误挖转化率:主踩雷源=卡死赌挖(不确定性概率命中),误挖只作偶发真手滑——
File renamed without changes.
@@ -1,10 +1,10 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# 战斗期望蒙特卡洛:当前参数下"胜轮数 / 每轮承伤 / 清图次数 / 开格数"的分布实测。
# 政策 = 理性玩家近似:挖最近可挖格(AutoPlayer 单一实现)。
# 运行:Godot_console.exe --headless --path . --script res://smoke/monte_carlo.gd
# 运行:Godot_console.exe --headless --path . --script res://sim/monte_carlo.gd
extends SceneTree
const BattleDriver := preload("res://smoke/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
const BattleDriver := preload("res://sim/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
const N := 30
const SEED0 := 42
File renamed without changes.
@@ -2,7 +2,7 @@
# 奖励期望测量:逐深度实测 |非封锁格|(safe ∪ mines ∖ R₀)分布、格面资源类型频次
# (应涌现自正向行九型权重 attack 14 / defense 11 / blast 16 / heal 4 / weaken 8 / pierce 8 / magic 8 / action 6 / gp 2,合计 77——reward.tres 现行)、
# 封锁格零泄漏(R₀ 格不在摇号清单)——走真实 地图战斗资源.roll_board 管线。
# 运行:Godot_console.exe --headless --path . --script res://smoke/reward_expectation.gd
# 运行:Godot_console.exe --headless --path . --script res://sim/reward_expectation.gd
extends SceneTree
const N := 200
File renamed without changes.
@@ -2,7 +2,7 @@
# 技能池节奏读数批量采集(06 待办「技能池节奏体验验证」机器半边正式读数):
# 60 distinct seeds × 双策略 × 两关,atk/hp 零加成基线——单网格组合避免种子重复
# (4200 系 0/484 假象教训:节奏/EV 读数须 ≥50 distinct seeds,见台账 89)。
# 运行:Godot_console.exe --headless --path . --script res://smoke/rhythm_batch.gd -- [seeds] [seed0]
# 运行:Godot_console.exe --headless --path . --script res://sim/rhythm_batch.gd -- [seeds] [seed0]
extends SceneTree
func _initialize() -> void:
@@ -22,7 +22,7 @@ func _initialize() -> void:
logger.ap_per_round = int(db.action_economy.ap_per_round)
var log_path: String = logger.start_session(seed0)
print("节奏批日志: %s" % log_path)
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
var t0 := Time.get_ticks_msec()
var total := 0
for L in [1, 2]:
File renamed without changes.
@@ -4,10 +4,10 @@
# ① 表侧:resolve_enemy_rowset(1, 1, "battle") 的池快照内容;
# ② 摇号侧:隔离 SkillLottery.draw 大样本份额;
# ③ 战斗侧:真实 (1,1) 战斗逐执行行按 skill_id 计数。
# 运行:Godot_console.exe --headless --path . --script res://smoke/skill_rhythm_probe.gd
# 运行:Godot_console.exe --headless --path . --script res://sim/skill_rhythm_probe.gd
extends SceneTree
const BattleDriver := preload("res://smoke/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
const BattleDriver := preload("res://sim/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
func _initialize() -> void:
var db = load("res://core/config_db.gd").new()
File renamed without changes.
@@ -7,7 +7,7 @@
# campaign 段 营地循环战役 × 双画像 × k 局——SaveManager 隔离档 + MetaProgression 真实账本:
# 逐局 hero_override() 注入 → 冒险 → settle_adventure 入账 → 花费策略买锻造,
# 回答「累计几次通关冒险后下一关可过」(元进度换算率标定的模拟读数源)
# 运行:Godot_console.exe --headless --path . --script res://smoke/verifier_batch.gd -- [k=v ...]
# 运行:Godot_console.exe --headless --path . --script res://sim/verifier_batch.gd -- [k=v ...]
# na=40(基线冒险局数) k=40(战役局数) seed0=8000
# only=adventure,campaign(缺省全段) spend=hp_first|atk_first|armor_first(锻造花费优先序)
# inject=max_hp:3,atk:1(冒险段 flat 注入档——三键 {max_hp, atk, armor_class},缺省全零白板;
@@ -42,7 +42,7 @@ func _initialize() -> void:
logger.ap_per_round = int(db.action_economy.ap_per_round)
var log_path: String = logger.start_session(opt.seed0)
print("模拟日志: %s" % log_path)
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
var t0 := Time.get_ticks_msec()
var counts := {"adventure": 0, "campaign": 0}
if "adventure" in opt.only:
File renamed without changes.
File diff suppressed because it is too large. Load diff
-1
View File
@@ -1 +0,0 @@
uid://c4a3130vctg4d
+8 -8
View File
@@ -4,7 +4,7 @@
**Test Framework**: 标准四级测试层(冒烟/单元/集成/系统)+ headless 场景探针与渲染 golden;gdUnit4 **deferred**(D2 OQ1 关闭形态——本仓库不引第三方测试框架,需求见下「门禁」节)
**门禁**: 本地闸——`tools/run_all_gates.sh`(收口唯一验收入口,按改动域选档 `--code`/`--docs`,跨两域或改闸件本身不带参数=全量)。本仓库**无远端、无 CI**(`.github/workflows/` 已删除,不建不留不参考);闸清单与域划分只在本脚本定义,文档不另列
**Setup date**: 2026-09-12(2026-09-27 `7f24b640` 三层收敛:根 tests/ 并入 `game/tests/`、docs 并入 `design/engineering/`、production 解散)
**参考实现**: `game/smoke/`(场景探针族——正式工程的活样板;系统测试断言面过渡宿主 `smoke_all.gd` 亦在此,迁移归断言迁移批)
**参考实现**: `game/probe/`(场景探针族)· `game/sim/`(测量/诊断/模拟驱动件)(场景探针族——正式工程的活样板;系统测试断言面过渡宿主 `smoke_all.gd` 亦在此,迁移归断言迁移批)
## Directory Layout
@@ -27,8 +27,8 @@ tests/
| **冒烟测试** | 这版活着吗——能否启动、能否加载表、能否进主屏。零逻辑判定 | `tests/smoke_boot.tscn/.gd`(以项目运行目标拉起=真实开机路径) | `run_smoke.py`(闸 00) |
| **单元测试** | 最单元的逻辑代码对不对(公式/状态机/纯逻辑) | `tests/unit/` | `run_all.gd` manifest(闸 02) |
| **集成测试** | 跨系统的闭环对不对 | `tests/integration/` | 同上(与单元测试同一入口、同一协议) |
| **系统测试** | 启动真实工程走真实玩法路径 | 过渡期 `game/smoke/smoke_all.gd`(断言迁移批后=`tests/system_test.gd`) | `run_system_test.py`(闸 01) |
| **UI 探针+渲染 golden** | 跑起来之后 UI 与场景切换对不对;画面基线 | `game/smoke/*.tscn` 探针 | `probe_gate.sh`(闸 03/04)、`render_gate.sh`(闸 05) |
| **系统测试** | 启动真实工程走真实玩法路径 | 过渡期 `game/probe/smoke_all.gd`(断言迁移批后=`tests/system_test.gd`) | `run_system_test.py`(闸 01) |
| **UI 探针+渲染 golden** | 跑起来之后 UI 与场景切换对不对;画面基线 | `game/probe/*.tscn` 探针 | `probe_gate.sh`(闸 03/04)、`render_gate.sh`(闸 05) |
> **integration/ 已建承载**(迭代 29 T3——此前只有章程句无实体,空壳曾于迭代 19 卡① T4 删过一次)。
> 首个集成用例 = `save_rng_roundtrip_test.gd`(存档⇄RNG 快照往返)。章程登记的四类集成用例里,
@@ -61,7 +61,7 @@ godot --headless --script tests/unit/example_test.gd
python tools/run_system_test.py
# 场景探针(UI 探针层)——以探针场景为运行目标,走完整项目引导(autoload 在位)
godot --headless --path . res://smoke/<probe>.tscn
godot --headless --path . res://probe/<probe>.tscn
# 本地闸必须配外部 wall-clock 超时(引擎无死锁探测;run_all_gates.sh 已内置)
timeout 120s godot --headless --script tests/run_all.gd
@@ -94,9 +94,9 @@ timeout 120s godot --headless --script tests/run_all.gd
| UI | Manual walkthrough OR interaction test(场景探针为首选) | `tests/evidence/` |
| Config/Data | Smoke test pass | 跑批回执 `game/tests/.gates/receipt.json`(不入库)+结论随批记 `reports/` |
## game/smoke/ 游离脚本台账(迭代 29 T7 逐个定性)
## game/probe/ 游离脚本台账(迭代 29 T7 逐个定性)
`game/smoke/` 里的脚本两分:**在闸件**(探针有 `.tscn` 宿主、被 `probe_gate.sh`/`render_gate.sh` 调用;
`game/probe/` 里的脚本两分:**在闸件**(探针有 `.tscn` 宿主、被 `probe_gate.sh`/`render_gate.sh` 调用;
`smoke_all.gd` 被系统测试运行器调用——过渡期宿主)与**不入闸的手动测量/诊断件**(下表)。
判据 = 头注自陈用途 + 有无外部引用(工具脚本/产品码/文档)。**存疑一律按在役登记并标注**(不退役)。
@@ -158,6 +158,6 @@ S12 效果引擎无状态化旧件零残留:扫描 game/ 全域 `.gd` 与 `gam
| **冒烟测试** | 秒级存活检查——能否启动、能否加载表、能否进主屏。判断「这版还活着吗」,不判断「这版对不对」 | `tests/smoke_boot.tscn/.gd`、`tools/run_smoke.py` |
| **单元测试** | 隔离的公式/状态机/纯逻辑断言面,逐套件独立进程实跑 | `game/tests/unit/`、`run_all.gd` |
| **集成测试** | 跨系统闭环断言面(存档⇄RNG 往返、回放确定性等) | `game/tests/integration/`、`run_all.gd` |
| **系统测试** | 启动真实工程走真实玩法路径的断言面 | 过渡期 `game/smoke/smoke_all.gd`+`tools/run_system_test.py`;迁移后 `tests/system_test.gd` |
| **场景探针** | 以探针场景为运行目标、走完整项目引导(autoload 在位)的 UI/场景断言 | `game/smoke/*.tscn`、`probe_gate.sh` |
| **系统测试** | 启动真实工程走真实玩法路径的断言面 | 过渡期 `game/probe/smoke_all.gd`+`tools/run_system_test.py`;迁移后 `tests/system_test.gd` |
| **场景探针** | 以探针场景为运行目标、走完整项目引导(autoload 在位)的 UI/场景断言 | `game/probe/*.tscn`、`probe_gate.sh` |
| **渲染 golden** | 窗口化截图与基线图的逐像素容差比对 | `render_gate.sh`、`tests/golden/` |
@@ -14,7 +14,7 @@ extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
const ConfigDBScript := preload("res://core/config_db.gd")
const LevelAutoplay := preload("res://smoke/level_autoplay.gd") # 真局驱动(迁移期按现路径 preload——账本 §五夹具前提)
const LevelAutoplay := preload("res://sim/level_autoplay.gd") # 真局驱动(迁移期按现路径 preload——账本 §五夹具前提)
var _db
+1 -1
View File
@@ -97,7 +97,7 @@ fi
# 禁「板级」「门票」「正主」「落籍」「完美排雷」等退役词进注释面(完整词表见术语表解析)
# 权威出处:design/gdd/术语表.md「退役词对照」节+「对外命名纪律」节
# 同形异义豁免:机制词「去重闸」(封印重判去重的玩法判别器)与某闸档退役词后二字同形——
# 行内含「去重闸」即整行跳过(2026-10-22 测试术语重构批随闸档用语入表增设,否则 smoke_all.gd
# 行内含「去重闸」即整行跳过(2026-10-22 测试术语重构批随闸档用语入表增设,否则 adventure_feats_test.gd
# 在册断言标签成片误红;代价=该行同时出现的真闸档用词也不报,靠文档域 08 闸兜住)
# 扫描面:game/ 全域 .gd/.tres/.md/.json/.sh(.txt 不收=第三方许可证非本仓库文本)
# 注释文本提取:.gd/.sh 取 # 后文本;.tres 取 ; 后文本;.md 取整行;.json 无注释语法(保留扩展名但不产生注释段)
+3 -3
View File
@@ -1,6 +1,6 @@
# tests/system_test.gd — 系统测试宿主薄壳(SceneTree+构造注入)
# 系统测试 = 启动真实工程走真实玩法路径的断言面(标准四级测试层之一,闸 01)。
# 本件现宿主零断言——smoke_all.gd 的断言按「只剪切禁改写」纪律迁入(断言迁移批执行,
# 本件为系统测试宿主(标准四级测试层之一,闸 01)。(原过渡期自述作废——,
# 本批只落宿主薄壳,跑通即绿)。迁移完成后 tools/run_system_test.py 缺省 --script 改指本件。
# 协议照单元侧惯例:extends SceneTree 获得 quit(code);--script 模式不加载 autoload,
# 运行形态=--script 直跑+autoload 分派闸(ConfigDB/SaveManager 在座才进主断言面——闸 01 实跑 65 项 0 失败实证在案);摘要行由 tools/run_system_test.py 三闸判定
@@ -8,7 +8,7 @@
# 运行:python tools/run_system_test.py --script res://tests/system_test.gd
extends SceneTree
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现(lifecycle 活战斗驱动;smoke 库件迁移期按现路径 preload)
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(lifecycle 活战斗驱动;smoke 库件迁移期按现路径 preload)
var _failures: int = 0
var _checks: int = 0
@@ -24,7 +24,7 @@ func check(cond: bool, label: String) -> void:
func _initialize() -> void:
print("=== Dungeon Sweeper 系统测试(宿主薄壳——断言面待迁移批自 smoke_all.gd 迁入) ===")
print("=== Dungeon Sweeper 系统测试 ===")
_split_tail()
@@ -13,7 +13,7 @@ extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
const ConfigDBScript := preload("res://core/config_db.gd")
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
var _db
@@ -15,7 +15,7 @@ extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
const ConfigDBScript := preload("res://core/config_db.gd")
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
var _db
@@ -16,7 +16,7 @@ extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
const ConfigDBScript := preload("res://core/config_db.gd")
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
var _db
+2 -2
View File
@@ -68,7 +68,7 @@ func _smoke_adventure_api() -> void:
Kit.check("pick 后 node_entered 到达 + 首战在飞(接口①开始关卡——停点闭合直达战斗节点)", sig_seq.size() == 3 and String(sig_seq[2]) == "node_entered" and adr.runner().current_battle() != null)
Kit.check("战斗中 abandon 拒绝(战斗域单事务在飞)", not adr.abandon())
# 驱动首战到胜利 → 选路态(非战斗期)→ abandon 受理
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
var battle = adr.runner().current_battle()
var st := _battle_st("normal")
var guard := 30
@@ -107,7 +107,7 @@ func _api_mark_node(_node: Dictionary, _info: Dictionary, seq: Array) -> void:
# 重复拒绝/GP 跨关延续/加算区同账/恢复数学/放弃)
func _smoke_adventure() -> void:
print("--- 冒险结构验收(三关序列 · 大奖励 · 摘要五件事 · 账本封闭)---")
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
# ① 表与覆盖义务(序列关数 = 行集关数;行集内每个战斗/Boss 节点跨表精确行集——覆盖义务断言;
# enemy 侧键域 = (level_index, row_kind, depth_band)——战斗节点查 battle 键域、Boss 节点查 boss 键域,
# 同带多行合法,带键聚合天然兼容〔fv24〕)
@@ -44,7 +44,7 @@ func _init() -> void:
func _smoke_level() -> void:
print("--- 关卡节点地图·线性推进(战×2→道具→战×2→恢复→Boss)---")
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
var hero_base := {"atk": int(_db.hero.atk), "hp": int(_db.hero.max_hp), "ac": int(_db.hero.armor_class)} # 配置基线快照——⑤ 回基线对比用(改表自动跟随,不再硬编码)
# ① 满配通关路径(atk+200%/hp+100%——测试面板同源的属性覆盖)
var win = autoplay.run_level(_db, 42, 1, 200, 100)
@@ -91,7 +91,7 @@ func _battle_st(policy: String) -> Dictionary:
func _smoke_level_graph() -> void:
print("--- 关卡节点地图·分支节点图(L2 幽暗地域)---")
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
# ① L1 单链与 L2 图经同一套加载校验(单链 = 出边恰一的退化形态——load_tables 全绿已含,显式复述)
Kit.check("LevelTable 图合法性校验:L1 单链 + L2 图同套算法零错误", _db.level.validate().is_empty())
# ② L2 行集结构(网状图建议规模)
@@ -382,7 +382,7 @@ func _fresh_rng(seed_val: int):
func _smoke_gp_wallet() -> void:
print("--- GP 冒险钱包·到账(战斗完成入账恰一次 + Boss 加值)---")
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
# ① L1 首战(普通战档——掷定 [2,4] + 关级加值 0):runner 驱动,收集 battle_finished 与钱包事件
var runner = load("res://core/level_runner.gd").new(_db, _fresh_rng(42))
runner.set_hero_override(200, 100)
@@ -560,7 +560,7 @@ func _find_gp_dig(minesweeper, settlement) -> Dictionary:
func _smoke_shop_room() -> void:
print("--- 商店房三收口(现价/加算区/余额不足拒/离开回选路/收束清零)---")
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
# 行进到商店房(min 路径:0→1→3(恢复)→6→8)——种子扫描保证进店余额 ≥ 三件首购总价 16(6+4+6)
var shop_run := {}
for s in range(42, 92):
@@ -721,7 +721,7 @@ func _smoke_shop_graph() -> void:
func _smoke_shop_pool() -> void:
print("--- 商店共享池(抽3买1全重抽 · 乘法定价 ceil · 池空硬闸 · 切边零入店)---")
var autoplay = load("res://smoke/level_autoplay.gd")
var autoplay = load("res://sim/level_autoplay.gd")
var shelf_kinds: Array = []
for row in _db.shop_pool_rows():
shelf_kinds.append(String(row.get("kind_id", "")))
@@ -15,7 +15,7 @@ extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
const ConfigDBScript := preload("res://core/config_db.gd")
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
var _db
@@ -49,7 +49,7 @@ func _init() -> void:
# 理性策略挖到触发结算(≥1 行入队即达断言前提——AP 一次消耗;挖格须邻英雄——邻接优先排序)
var ms = battle.minesweeper
# 理性策略驱动(auto_player 单一实现复用——damage_probe 同款两步消费:先 move 到 hero_cell 再 dig)
var ap = load("res://smoke/auto_player.gd")
var ap = load("res://sim/auto_player.gd")
var acted := false
for guard in range(40):
var plan: Dictionary = ap.choose_dig(ms)
@@ -22,7 +22,7 @@ extends SceneTree
const Kit := preload("res://tests/unit/test_kit.gd")
const ConfigDBScript := preload("res://core/config_db.gd")
const AutoPlayer := preload("res://smoke/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(迁移期按现路径 preload——账本 §五夹具前提)
var _db
var _rng
+1 -1
View File
@@ -33,7 +33,7 @@
## 工具与格式
- 采集:`game/smoke/adventure_monte_carlo.gd`(git)——参数 n/seed0/policy,seed 逐局独立
- 采集:`game/sim/adventure_monte_carlo.gd`(git)——参数 n/seed0/policy,seed 逐局独立
- 锚格式:stdout 捕获,每局一行 `RUNSUM` JSON(81000 锚=800 行=400×2 档);自 2026-10-03 档位规起新锚统一=去前缀纯 JSONL 按种子升序(旧形态 analyze.py 直读会炸,见上「MC 采集档位表」配套纪律⑧)
- 分析:`analyze.py`+`growth_model.py`(git)。⚠ analyze.py 默认输入名系首批遗留(runsum_600.jsonl 已不存在),跑现行锚须 `RUNSUM=<锚文件>` 指定,其完成度%段对现行锚未验证
- fulllog 全量日志不留盘(.gitignore 排除);`iteration_log.md` 系 Package B 时代批日志留盘不入库;新模拟批的读数与结论写在该批的 git 提交信息与 `reports/` 报告里(2026-10-18 用户裁:根目录会话状态文件已废除)
+1 -1
View File
@@ -179,7 +179,7 @@ def main():
calib_wh[(p['w'], p['h'])].append(p['cleared_safe'])
safe_total_map = {k: int(st.median(v)) for k, v in calib.items()}
safe_by_wh = {k: int(st.median(v)) for k, v in calib_wh.items()}
# 生成器真值分母(smoke/calibrate_boards.gd 200 板/行——权威口径;日志清图校准仅作交叉核对)
# 生成器真值分母(sim/calibrate_boards.gd 200 板/行——权威口径;日志清图校准仅作交叉核对)
gen_safe = {}
gen_r0 = {}
with open(BASE + 'board_calibration.csv', encoding='utf-8') as f:
+1 -1
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""audit_type_hints.py — 类型闸机器审计(code-conventions §4 语言纪律的机器闸)。
产品码 = game/core + game/data + game/presentation(smoke/tests 豁免——测量面容器直构是惯例)。
产品码 = game/core + game/data + game/presentation(probe/sim/tests 不在扫描面——测量面容器直构是惯例)。
三条规则:
R1 无类型容器声明:显式 Dictionary/Array 非参数化类型注解(审计 §2.2「73 处」同口径——
`:= {}` 推断形态属类型推断合法面不算债)。
+2 -2
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
r"""数值验证工具(判定端)——自动化评判 + 元进度爬升测量,替代「亲手试玩再反馈」循环。
两段采集(数据源 = smoke/verifier_batch.gd,本文件驱动它并做全部判定):
两段采集(数据源 = sim/verifier_batch.gd,本文件驱动它并做全部判定):
adventure 段 全冒险连探基线(零永久强化)——逐关条件通关率派生 + 止步分布 + 败退节点归因(层/节点/敌人);
adventure 段支持 inject 注入档(永久强化 flat OFAT——与白板同种子流配对,行带
inject_tag/override,标定面 = 逐关条件通关率差)
@@ -51,7 +51,7 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
SLICE = ROOT / "game"
GODOT = r"D:\code\godot\Godot_v4.7.2-stable_win64_console.exe"
SCRIPT = "res://smoke/verifier_batch.gd"
SCRIPT = "res://sim/verifier_batch.gd"
READINGS_DIR = ROOT / "sim-data"
VJSON_PREFIX = "VJSON "
ERROR_MARKERS = ("SCRIPT ERROR", "Parse Error")
Loaded 100 of 110 files, more files were not shown because too many files have changed in this diff. Show more