Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76794be79b | ||
|
|
730c35aa0a | ||
|
|
c0190e1336 |
No files matched your search
@@ -16,7 +16,7 @@
|
||||
|
||||
## 运行与验证(工作目录 = 含 project.godot 的切片目录)
|
||||
|
||||
- **交付前验收 = 跑 `tools/run_all_gates.sh`,按本批改动域选档(`--code` 只跑代码域/`--docs` 只跑文档域/不带参数=两域全量),所选域全绿才合回 master**——它是全部验证闸的唯一入口与唯一清单,**域划分与选闸算法也只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单。域按**文件性质**判:代码域=`game/` 下非 `.md` 的行为载体(代码/测试脚本/探针/场景/数据表/素材),`game/` 内 `.md` 与 `game/` 外一切路径=文档域;同批两类都有时跑全量档。代码域按**关联档选测**(2026-10-29 用户裁):02 单元与集成只跑「需求卡片申报 ∪ diff 推导」并集的套件(关联档=只跑与本批改动关联的那部分测试),00 冒烟/01 系统测试/09 静态扫描三件保险恒跑不降,横切面改动(公共件/数据表/autoload/数值·存档·RNG·结算触面)回落全部套件;算法与套件族映射表只在闸脚本内定义。所选域全绿即可合回;全量回归由用户自发发起,合入后无自动兜底。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 与 `scope` 字段),合回时由 worktree-guard 按 diff 文件性质推出该验哪个域再校验回执(六况拦截细则见 process-conventions §3.9);非代码面的直改批验收=commit 点 git 钩子自动跑 `--docs`,无 worktree 与回执流程
|
||||
- **交付前验收 = 跑 `tools/run_all_gates.sh`,按本批改动域选档(`--code` 只跑代码域/`--docs` 只跑文档域/不带参数=两域全量),所选域全绿才合回 master**——它是全部验证闸的唯一入口与唯一清单,**域划分也只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单。域按**文件性质**判:代码域=`game/` 下非 `.md` 的行为载体(代码/测试脚本/探针/场景/数据表/素材),`game/` 内 `.md` 与 `game/` 外一切路径=文档域;同批两类都有时跑全量档。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 文件性质推出该验哪个域再校验回执(六况拦截细则见 process-conventions §3.9);非代码面的直改批验收=commit 点 git 钩子自动跑 `--docs`,无 worktree 与回执流程
|
||||
- 单件直跑(调试期最窄确认用,**不构成验收**):冒烟测试 `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/`)
|
||||
@@ -43,7 +43,7 @@
|
||||
| 批次开工 / 流程纪律 | `design/engineering/process-conventions.md`——车道铁律(代码面 worktree 批/其余主区直改)、五段流水线、批次清单、测试两入口与 MC/闸机细则、像素纪律 |
|
||||
| 流水线段入口 | 技能对照——doc-design=文档设计(兼任反哺点落文)/asset-ingest=美术录入/req-card=写卡/iter-plan=迭代编排/iter=实现(五者均装于项目 `.zcode/skills/`);登记不立技能;批后收尾与中间文档退役=batch-closure(同一目录);格式与状态机权威=`design/engineering/doc-conventions.md` §12 |
|
||||
| 定代码方案 / 写代码 / 改代码前 | `design/engineering/code-conventions.md`——结构/契约/语言/数值/流程五类硬纪律(反例库 = 同目录 code-conventions-cases.md) |
|
||||
| 定测试方案 / 写测试 / 改测试前 | `design/engineering/test-conventions.md`——探针标配 / 回归断言 / 提交前验证 / 验收清单落码 |
|
||||
| 定测试方案 / 写测试 / 改测试前 | `design/engineering/test-conventions.md`——探针标配 / 回归断言 / 全量验证 / 验收清单落码 |
|
||||
| 定文档方案 / 写文档 / 改文档前 | `design/engineering/doc-conventions.md`——白话写作 / 载体分工 / 用语 / 结构骨架 / 会话记录与生命周期 |
|
||||
| 概念切分与互链 | `design/engineering/concept-conventions.md`——概念封装 / 跨文档引用 / 归档与事实源 |
|
||||
| 系统设计 / 增删文档 | `design/gdd/02-系统清单.md`——根索引 + 中文规范名↔英文代号对照 |
|
||||
@@ -79,17 +79,13 @@
|
||||
|
||||
枚举用列表,二维对照用表格,按内容形态选;散文是最后手段。
|
||||
|
||||
## 主动检索提醒
|
||||
|
||||
- 训练记忆缺失或可能过时的问题,先搜最新主流的答案再回答。
|
||||
|
||||
## 硬性红线(勿违反;操作细则在 process-conventions.md 与各规约)
|
||||
|
||||
- 车道铁律(判据与改动域划分同一,按文件性质切)——代码面(`game/` 下非 `.md` 的行为载体)唯一强制独立 worktree(迭代批全套仪式不变);其余一切面(含 `game/` 内 `.md` 与 `.zcode/`、`.qoder/` 等不入 git 面)主工作区直改+直提,commit 点由 git pre-commit 钩子(`tools/hooks/pre-commit`,`core.hooksPath` 挂载)现场跑文档域闸,绿落地红拦;主区直提代码面被该钩子拦;`--no-verify` 仅属用户,agent 禁用(细则见 process-conventions §1)
|
||||
- **仓库根禁止设会话状态文件**(`active.md` 已废除)——现状看 roadmap「当前位」,待办看待办清单,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节)
|
||||
- 测试执行两入口铁规——只有迭代 loop 开发与用户点名两个触发入口;其余会话零测试,需测试支撑先请示并注明未跑测
|
||||
- 交付前验收 = 跑 `tools/run_all_gates.sh` **按改动域**全绿(唯一入口、唯一闸清单、唯一域划分与选闸算法,禁在文档另列);代码域按**关联档选测**——02 单元与集成跑「卡片申报 ∪ diff 推导」并集套件、三件保险(冒烟/系统测试/静态扫描)恒跑、横切面回落全量,所选域绿即可合回,全量回归由用户自发(2026-10-29 用户裁,合入后无自动兜底)(算法见闸脚本);合回 master 由 worktree-guard 按 diff 文件性质推域校验回执强制(process-conventions §3);非代码面直改批的验收=commit 点 git 钩子自动跑 `--docs`(process-conventions §1)
|
||||
- **改动四类**——**需求改动**(游戏代码,含随逻辑写/改的测试代码):唯一走「写需求卡片+编入迭代批次」通道;迭代实现批禁写 `design/` 整个目录、两份根流程清单(`待办清单.md`/`体验验证清单.md`)与 `game/tests/README.md`(能力清单,归写卡段维护)(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批禁止顺手改;产出物只准写 `reports/`;批末只跑代码域闸。**工程改动**(tools/、闸件、模拟测量工具、纯测试维护——不改变游戏行为的配套代码)、**文档设计改动**、**美术素材改动**:不写需求卡片、不编迭代批次,登记在案后由用户发令在主工作区直改+直提(commit 点 git 钩子自动跑文档域闸),完成即删条目;触及代码面的工程改动(如纯测试维护)仍走 worktree 批;文档设计类写入走 doc-design 技能(登记条目格式由流水线闸强制)
|
||||
- 交付前验收 = 跑 `tools/run_all_gates.sh` **按改动域**全绿(唯一入口、唯一闸清单、唯一域划分,禁在文档另列);合回 master 由 worktree-guard 按 diff 文件性质推域校验回执强制(process-conventions §3);非代码面直改批的验收=commit 点 git 钩子自动跑 `--docs`(process-conventions §1)
|
||||
- **改动四类**——**需求改动**(游戏代码,含随逻辑写/改的测试代码):唯一走「写需求卡片+编入迭代批次」通道;迭代实现批禁写 `design/` 整个目录与两份根流程清单(`待办清单.md`/`体验验证清单.md`)(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批禁止顺手改;产出物只准写 `reports/`;批末只跑代码域闸。**工程改动**(tools/、闸件、模拟测量工具、纯测试维护——不改变游戏行为的配套代码)、**文档设计改动**、**美术素材改动**:不写需求卡片、不编迭代批次,登记在案后由用户发令在主工作区直改+直提(commit 点 git 钩子自动跑文档域闸),完成即删条目;触及代码面的工程改动(如纯测试维护)仍走 worktree 批;文档设计类写入走 doc-design 技能(登记条目格式由流水线闸强制)
|
||||
- 五段流水线铁律——**需求改动**(游戏代码)按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」五段推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点——需求卡片任何工作量皆可写、皆可编入迭代,工作量限制只属迭代层(迭代估时总量 <5 个工作日=「冻结待凑批」、不可开工);流水线闸 `tools/pipeline_gate.py` 强制(已注册进 run_all_gates.sh 文档域);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12)。工程/文档设计/美术素材三类改动不走写卡与编排段:登记 →(如需设计讨论)→ 用户发令直改 → 主区直改+commit 点闸 → 完成删条目(车道细则=process-conventions §1)
|
||||
- MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起
|
||||
- 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
| 钩爪恐魔 hook_horror | 普通怪(钩爪/多足轮廓注意凹凸计数控制) | light | 第三关群行捕食者,小体量可辨 |
|
||||
| 灰矮人石君王 duergar_king | **Boss:锐角与不对称**,体量最大 | heavy | 第三关 Boss;紫赤色相独占+形状独占双通道 |
|
||||
|
||||
- **通用规格**:亮色描边+落影底盘轮廓通道硬规则;透明底 PNG;每敌种 2–3 版候选;护甲类型视觉区分方案已落 art-bible §5.3(已定稿)。
|
||||
- **通用规格**:亮色描边+落影底盘轮廓通道硬规则;透明底 PNG;每敌种 2–3 版候选;护甲类型视觉区分方案已落 art-bible §5.3(候选方案,样张冻结终稿)。
|
||||
- **来源**:✦ ComfyUI(prompt 卡 v2.0 §3,八敌种+L2 熊地精变体共 9 卡);理由同 §2.1——不复用。
|
||||
- **联动**:显示名以 `data/tables/enemy.tres` 与敌人系统文档为准(L2 熊地精=bugbear 复用,显示名熊地精系)。
|
||||
|
||||
@@ -141,13 +141,6 @@
|
||||
- **来源/规格**:♻ 复用开源——缝合像素字体(Fusion Pixel,SIL OFL 1.1,授权总表在册);墨色走主墨系(art-bible §7.2)。换字体是全局决策;样张用字即此定稿件,过样张闸第 1 项(数字可读性 ≥4.5:1,禁以换字形逃避)。
|
||||
- **现状**:✅ 已定稿在役(现状即终稿)。
|
||||
|
||||
### 3.7 护甲类型图标三枚 ♻优先/⚙兜底
|
||||
|
||||
- **要什么**:`ui_armor_light.png` / `ui_armor_ward.png` / `ui_armor_heavy.png` 三枚,站桩名字行与护甲图标同排挂载(原为 ◇/◆ 字形占位)。
|
||||
- **风格/规格**:源 24×24、显示 24px = 1×(甲类整数倍缩放纪律,art-bible §8.2);形状 + 色彩双通道,灰度下按甲面覆盖率三档可辨(character-design §5.3 已定稿:轻甲覆盖率≈0/魔法护甲符纹饰带/重甲金属甲板);不触 §5.1 剪影 archetype。
|
||||
- **来源**:♻ 素材站通用护甲/符纹图标改色优先,过 §0 复用闸四道;⚙ 兜底程序化。
|
||||
- **现状**:未开始(占位 = 站桩名字行裸 12px 字形 ◇/◆,随本条到位后改挂图形件并把名字行提到 `FS_HINT` 14)。
|
||||
|
||||
---
|
||||
|
||||
## 4. P3 —— 演出类(战斗打磨项,样张后排期)
|
||||
@@ -155,8 +148,6 @@
|
||||
| 资产 | 需求 | 风格/规格要点 | 来源 |
|
||||
|---|---|---|---|
|
||||
| 受击反馈 / 死亡表现 / 顺位标记 | 敌人系统登记的资产需求**下限三类** | 死亡=血条归零后**灰化+碎裂退场,禁止瞬间消失**;顺位标记需在敌多时可读 | ⚙/✦ 挂自产精灵——死亡灰化碎裂是语义硬规则,不可整包复用;烟尘碎屑粒子可 ♻ 改色 |
|
||||
| B 区舞台背景插画 `scene_stage_bg.png` | 战斗舞台背景(art-bible §6.1 资产契约) | **✦ 插画级**;源 1280×270、B 区全高含明细带底、显示 1×;**只出远景 + 中景两带**(近景带在结算期被 84px 明细带底整条盖住);三关换挡走 §4.3 `wall_ambient` tint 槽,不按板出三张 | ✦ 插画级(作者自跑远程生图管线) |
|
||||
| 站桩石板地台件 `scene_stage_plaza.png` | 近景地台独立件(art-bible §6.1/§8.2) | 源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形;跨三关恒定,不吃 `wall_ambient` tint | ⚙/✦ 自产 |
|
||||
| 特殊技动画终稿 | 并入 §2.3 三档意图动画,不另起体系 | 攻/防两型旧口径由三档替代 | ✦/⚙ 自产(同 §2.3) |
|
||||
| 连锁坍塌显形演出 | 连锁展开触发时的连锁演出 | 与音频方向同批配对登记;「坍塌显形」=连锁展开的玩家可见名 | ♻ 粒子/碎块改色 + ⚙ 坍塌结构自产 |
|
||||
| 封印特效 | 该动作的呈现名 = **封印**(art-bible §3.2):**施印瞬间特效 + 印记常显形态**两件 | 印记旗面走封印黑 `#000000`(现行封印色,色史归 art-bible §4.1);特效走运动+色相(§2:状态/情绪不走明度,空间光照可走);现行占位 = 封印黑「旗」字形;印记常显形态可与 §3.3 旗面像素化合并出 | ✦/⚙ 自产(精灵+粒子,烟尘光点可 ♻ 改色) |
|
||||
@@ -170,7 +161,7 @@
|
||||
- **秘宝图标**:内容归 Alpha 秘宝整体重设计,内容未定不能先做;渠道届时按 ♻/✦ 另评。
|
||||
- **封面图/宣传图**:Alpha 后另批,不阻塞切片;需项目角色出镜,素材站合成观感差,宜 ✦。
|
||||
- **地形变异专属纹理**:六类型已定稿,纹带需求 = 2 纹形(伤害轴刺缺形/信息轴遮蔽形)× 3 图类型色板,**样张后可排产**;形状通道规则见 art-bible §3.2。
|
||||
- **精英/Boss 护甲类型视觉区分**:已落 art-bible §5.3(甲面覆盖率×甲材质色三档,已定稿)。
|
||||
- **精英/Boss 护甲类型视觉区分**:已落 art-bible §5.3(候选方案:甲面覆盖率×甲材质色三档,样张冻结终稿)。
|
||||
|
||||
## 6. 执行顺序(依赖链)
|
||||
|
||||
|
||||
+17
-30
@@ -1,6 +1,6 @@
|
||||
# 美术圣经(Art Bible)— Dungeon Sweeper
|
||||
|
||||
> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**;现行为 v3.22,历次修订明细见 git 提交史
|
||||
> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**;现行为 v3.21,历次修订明细见 git 提交史
|
||||
>
|
||||
> **Art Director Sign-Off(AD-ART-BIBLE)**:历次批均未签核——此为 Lean/Solo 模式(非 PHASE-GATE)下的现行治理状态;full 门禁签核时机待用户表态。
|
||||
> 风格基调:地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身。
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
**判定与回退**:第 1 项不过时按原则二设计测试回退——先调格底明度档,复杂格底垫色牌后备,禁止缩字号换字形逃避;第 2–4 项不过时修形不修数。样张通过 = 砖面形态与色板冻结;新增图类型/变异色板须重跑本测试(§4.3)。执行时机:正式砖面资产开工前;《HUD框架》以本节为引用依据。验收:机检〈样张机检断言集全绿后方可冻结砖面形态与色板〉
|
||||
|
||||
**整屏样张闸**:格子样张验"格",整屏样张验"屏"——战斗屏/关卡屏/菜单屏/营地屏各出一张整屏样张,验收四项:①全部文字(含菜单/说明/tooltip/按钮)对其直接背景 ≥4.5:1(WCAG AA),大字(≥18px 或加粗档)底线 3:1、目标 4.5:1;②明度分层三档带成立(信息面层 > 世界中层 > 世界底层,层间灰度可分);③整屏焦点预算(§3.4:首焦唯一——数字区/立绘/主按钮,无第二焦点竞争;负空间服务焦点,不属空窗);④文字禁直接压纹理底(垫容器或罩层)。验收顺序 = **方向稿目检先行**(防"机检过闸但气质否决"式返工),目检过后机检冻结。执行时机 = 屏级视觉落码开工前;过闸前一切屏级视觉为占位临时态(§7.1 完成条款)。**样张判定物的产出手段与素材输入级别不进圣经定值**——圣经只定样张要验什么,不定样张以何种手段产出、也不定它取哪一级别素材输入。验收:机检〈整屏样张四项断言全绿,且目检先行过审〉
|
||||
**整屏样张闸**:格子样张验"格",整屏样张验"屏"——战斗屏/关卡屏/菜单屏/营地屏各出一张整屏样张,验收四项:①全部文字(含菜单/说明/tooltip/按钮)对其直接背景 ≥4.5:1(WCAG AA),大字(≥18px 或加粗档)底线 3:1、目标 4.5:1;②明度分层三档带成立(信息面层 > 世界中层 > 世界底层,层间灰度可分);③整屏焦点预算(§3.4:首焦唯一——数字区/立绘/主按钮,无第二焦点竞争;负空间服务焦点,不属空窗);④文字禁直接压纹理底(垫容器或罩层)。验收顺序 = **方向稿目检先行**(防"机检过闸但气质否决"式返工),目检过后机检冻结。执行时机 = 屏级视觉落码开工前;过闸前一切屏级视觉为占位临时态(§7.1 完成条款)。验收:机检〈整屏样张四项断言全绿,且目检先行过审〉
|
||||
|
||||
**样张现状**:格子样张已冻结,冻结凭据 = git 提交 7a847c7(机检报告)与 §4.1/§8.2 定值表;样张 v3 产物原件已丢失、未入 git。现行冻结态:色板与帧数档维持冻结;数字形制 = 亮墨三档直画 + 色牌后备(值见 §4.1);新增图类型/变异色板须重跑本节测试。验收:机检〈冻结项定值均以 §4.1/§8.2 对应 owner 表为准〉
|
||||
|
||||
@@ -68,8 +68,6 @@
|
||||
> 本节服从第 1 节宣言「明快的地牢,轻快的扫荡,仔细的推理」。能量值为全作统一 0–10 刻度:0 静谧,10 沸腾。
|
||||
>
|
||||
> **明度分层(硬规则)**:明度按视觉层分带——**信息面层**(数字/UI 数据/预告/语义标识)最高、**世界中层**(格底顶面/角色/物件)居中、**世界底层**(背景/纵深/远景/已开空间)可更低;层间明度差服务空间纵深与光照(Moonlighter 式洞穴层次)。**情绪明暗禁令**:明度变化禁止用于**情绪表达**——画面禁止靠压暗/渐晕阴沉下来;roguelike 失败重开,世界无光暗记忆;Darkest Dungeon 式压暗仍在 §9.2 反面清单。**状态表达不受本禁令约束**:状态可用明度、色相、饱和、运动、元素任一手段承载。**允许域**:空间纵深、光照氛围、形体塑造。类型微光的明度梯度(§4.2)属信息面层内梯度,不扰世界层明度档。验收:目检〈情绪表达不走压暗/渐晕;三档明度带层间灰度可分〉
|
||||
>
|
||||
> **世界底层两子带**:世界底层拆两条子带——**底层下沿带 L 0.014–0.06**(远景、洞窟纵深、B 区舞台底、屏幕根底)与**底层上沿带 L 0.08–0.14**(已开格底、迷雾记忆态合成底),子带间隔 ≥0.02。拆两子带用于解决**世界底层内部** B 区舞台底(L=0.036)与 D 区已开格底(L≈0.10)同层难辨的问题——两者同属世界底层,单带下跨度 0.126 吃掉层间间隔 0.08,灰度图上会表现为两个不同的底。§1.4 整屏②项约束的是层间可分(底层上沿 0.14 对世界中层下沿 0.22,差 0.08 本就满足),②项不约束同层内可分,故本条不属②项的成立要件,而是世界底层内部的可读性纪律。验收:机检〈同一屏的世界底层成员全部落进两条子带之一,两子带 L 区间不重叠且间隔 ≥0.02〉
|
||||
|
||||
### 2.1 挖掘阶段(核心状态,占时最长)
|
||||
|
||||
@@ -205,27 +203,18 @@
|
||||
- **收益金亮档 `#E0B860`(GOLD_BRIGHT)**|UI 徽标可读性亮档 token:敌顺位徽标①②③与重甲徽标对舞台底 6.47:1(GOLD_DEEP 3.26:1 不达 §7.2 带,故另立亮档);金族亮档,与奖励金 #F0A828 同族不同岗——奖励金 = 已兑现收益语义(§4.2 金条),本 token 只承载徽标可读性、不占收益语义。GOLD_DEEP/HERO_BLUE 常量本尊不动(standee 意图判据等语义岗现行使用)。验收:机检〈GOLD_BRIGHT 对舞台底 ≥4.5:1〉
|
||||
- **小人蓝亮档 `#7EBAF0`(HERO_BLUE_BRIGHT)**|魔法护甲徽标对舞台底 5.88:1(HERO_BLUE 3.23:1 不达带,故另立亮档);蓝族亮档,与小人蓝 #2E86DE 同族不同岗——本 token 只承载徽标可读性,不占用「蓝只说己方」的语义。验收:机检〈HERO_BLUE_BRIGHT 对舞台底 ≥4.5:1〉
|
||||
- **图标槽柔和档 `#806A4E`(SLOT_BACKDROP_SOFT)**|BCard 图标槽底:对米色卡面 PANEL_DATA 3.69:1(深档 SLOT_BACKDROP #3E362C 8.53:1 过强、像硬贴补丁,故槽底另立柔和档),槽内白图标 5.14:1,满足 ≥3:1 图形参考线硬约束;仅 BCard 图标槽换档,B 区状态槽仍用深档 SLOT_BACKDROP。验收:机检〈槽内白图标对槽底 ≥3:1〉
|
||||
- **群伤微光暗档 `#A61D37`(TG_GLOW_AOE)**|类型微光群伤组的**明度档**(UI token 板,占 1 枚额度,**余量 3→2**):色相 349° 与亮档 `#FF2D55` 零移动,明度落 V=0.65 档——即 §4.2「微光 = 色相+明度双码」里明度侧的落法;与 §4.2「红只说危险」不相撞(微光组色相刻意错开语义红,见 §4.2「类型微光色带」条)。已在役(`ui_kit.gd` 常量与 `type_glow_test.gd` 守门断言),本节为登记转正。验收:机检〈ui_kit.gd TG_GLOW_AOE 与 type_glow_test 断言的 H/S 逐位一致、V 落 0.65 档〉
|
||||
- **站桩石板地台板身 `#968264`(STAND_STONE)**|战斗屏场景环境子板(分层②,不占 48 token 额度):B 区站桩地台板身与顶缘的材质色,跨三关恒定、不吃 §4.3 `wall_ambient` tint(地台是 §6.1 定死的世界中层承载面,随关卡变会破 §2 明度分层的层间关系)。转正前即在役。验收:机检〈战斗屏场景环境子板色数 ≤32 且本值在册〉
|
||||
- **重甲冷灰金属材质色 `#868C9A`(ARMOR_PLATE_COLD,token 名暂拟、随实装批登记)**|语义/UI token 板(**分层①**,占 1 枚额度,**余量 2→1**;用户裁):重甲档甲材质色;character-design §5.3 通道 = 甲面覆盖率 × 甲材质色,甲材质色按甲档统一,故石君王岩石板甲**同引本枚、不另计额度**;材质色跨屏恒定,落分层①不落分层②(环境色才随场景走)。过门情况:第二道门按宽松口径(禁止三通道全 <8)与在册色逐一比对,**无三通道全 <8 的对 → 过门**;§4.2 语义检查过门(色相 222°,不占红/金/蓝/紫赤/绿语义段、不在 300°–345° 禁入带;材质色不进信息层与语义物件岗)。对比实测:对深素底 `#282220` 4.65:1、对舞台底 `#3E362C` 3.52:1(图形 ≥3:1 门槛);相对亮度 L≈0.261 落 §2 世界中层 0.22–0.45 带。验收:机检〈本值入板后全板色对中三通道差全部 <8/255 的对数 = 0〉
|
||||
- **卓尔浅紫灰皮 `#A79CB8`(DRIDER_SKIN,token 名暂拟、随实装批登记)**|语义/UI token 板(**分层①**,占 1 枚额度,**余量 1→0,额度用尽**;用户裁):蛛化卓尔精灵上体皮色(体块主色,L≈0.355 落 §2 世界中层带)。过门情况:第二道门同上行口径,**无三通道全 <8 的对 → 过门**;§4.2 语义检查过门(色相 264°,避开 300°–345° 禁入带,紫赤独占仍归 `#8F2F6A`;不占本节五语义段)。对比实测:对深素底 `#282220` **6.04:1**、对舞台底 `#3E362C` **4.57:1**——**两处均过图形 ≥3:1 门槛**(本轮新算)。验收:机检〈本值入板后全板色对中三通道差全部 <8/255 的对数 = 0〉
|
||||
- **换色合并登记五处(用户裁,部件色落值)**|按本表「不过门即触发换色合并、禁加色绕行」执行,五处**零新增额度**(各件原拟新增候选一律不取):① 主角铲刃浅铁灰(原拟 `#A8AEB8`)→ 并入 `FOG_MEMORY_INK #C4C4C4`,**部件取值 = `#C4C4C4`**;② 主角提灯铜色(原拟 `#C08A3A`)→ 并入 `GOLD_DEEP #B07A14`,**部件取值 = `#B07A14`**;③ 食人魔酋长暖褐皮(原拟 `#B08050` / `#A97C4E`)→ 并入 `暖石 #B8A582`,**部件取值 = `#B8A582`**;④ 石君王灰皮(原拟 `#9A968C` / `#949089`,按**次级皮**口径——板甲视同体块主色、灰皮属次级皮故不受 L 0.22–0.45 约束)→ 并入 `STONE #786E62`,**部件取值 = `#786E62`**;⑤ 轻甲护甲图标木色 `#8A5A34`(深素底下 2.72:1 不过门;原拟新增木色亮档 `#C49A5E`)→ 并入 `WARM_FAINT #CDB88C`,**部件取值 = `#CDB88C`**(8.08:1)。**一色两岗代价已随裁定接受**:① 的 `#C4C4C4` 语义岗 = 迷雾记忆墨(§6.5)、② 的 `#B07A14` 属金族(§4.2 金只说收益与兑现)——两者均作角色随身件材质色用,不进信息层与语义物件岗;③④⑤ 无语义岗冲突。验收:机检〈五处部件取值点全部改指合并目标色,四枚原拟新增候选值零入板〉
|
||||
- **换色合并登记三处**|按本表「不过门即触发换色合并、禁加色绕行」执行,三处零新增额度:`#3E342A`(舞台底,代码 `STAGE_BG`)→ 并入 `#3E362C`(状态槽底);`#C4AC84`(地台顶缘受光线,代码 `STAND_STONE_RIM`)→ 并入 `#C9AF83`(掩尘,并与 §8.2 高墙口沿高光 `Color8(196,172,132)` 统一为同一枚);`#5A4C3A`(地台描边,代码 `STAND_STONE_EDGE`)→ 并入 `#4C4038`。验收:机检〈全仓三枚源常量零引用,绘制点全部改指合并目标色〉
|
||||
|
||||
**对比硬指标(可测)**:数字可读性由**格底明度分档**承载——棋盘数字亮墨 **L≥0.75** 对**已开格底 L 0.08–0.14** ⇒ 直画对比 **≥4.5:1 恒成立**(WCAG AA,样张逐组合抽测冻结);**色牌后备**:色牌素色恒定 **L≥0.70**、牌上数字深墨 **L≤0.027** ⇒ 任意牌墨组合 ≥4.5:1(实测样例:#33261B/#F5EAD3 = 12.3:1)。未开格底槽(含全部图类型)相对亮度 **L≥0.30**(墙顶面受光档)、HSV 饱和 **≤0.55**、避 Boss 禁入色相带;已开格底走世界底层档(见上)。物件识别不依赖格底(§5.1 轮廓通道),旗面、金色不作识别依赖。验收:机检〈亮墨对已开格底 ≥4.5:1;未开格底 L≥0.30、饱和 ≤0.55;任意牌墨组合 ≥4.5:1〉 ←原二;地形变异 AC-9
|
||||
|
||||
**色板增量纪律(数值状态 = 待定现用)**:全作色板硬上限 **48 色**(防色板无限膨胀的封口条款;**额度已用尽、余量 0**,后续余量以色板检查器实报为准);新色入板须同时过两道门:①§4.2 语义检查(不占语义色段/禁入带);②**与既有任一色的 RGB 三通道差禁止全部 <8/255**——即三通道里至少一通道 ≥8/255 即过门,「三通道差全部 <8」才算不过门(条文原写的「三通道差 ≥8/255」有「逐通道全过」与「禁止全灭」两种互斥读法,前者下现行色板 247 对不达标、与本节自认的「现行即执法」合规状态不能同真,故取后者;用户裁)。**额度已用尽:后续任何新增须先压缩或合并既有色**——按本节「额度不足时呈报作者」口径呈报,**压缩或合并哪几枚由作者裁,本节不代裁、不预指对象**。反例实证:#3A2E22 ↔ #362B20 三通道差均 <5,肉眼不可辨,同板共存只增噪。不过门即触发「换色合并」(把意图色并进最近既有色),**禁加色绕行**;加色义务同时登记于本表修订。**「待定现用」态释义**:数值**现行即执法**(色板检查器按此拦,§8.3)——非候选(不存在"等冻结"空窗)、非死规(后续需求引入时可变);调整走本节修订并登记,改值 = 修订不是违约。验收:机检〈色板总数 ≤48;新色入板过两道门〉
|
||||
**色板增量纪律(数值状态 = 待定现用)**:全作色板硬上限 **48 色**(防色板无限膨胀的封口条款;额度余量以色板检查器实报为准);新色入板须同时过两道门:①§4.2 语义检查(不占语义色段/禁入带);②**与既有任一色的 RGB 三通道差 ≥8/255**——反例实证:#3A2E22 ↔ #362B20 三通道差均 <5,肉眼不可辨,同板共存只增噪。不过门即触发「换色合并」(把意图色并进最近既有色),**禁加色绕行**;加色义务同时登记于本表修订。**「待定现用」态释义**:数值**现行即执法**(色板检查器按此拦,§8.3)——非候选(不存在"等冻结"空窗)、非死规(后续需求引入时可变);调整走本节修订并登记,改值 = 修订不是违约。验收:机检〈色板总数 ≤48;新色入板过两道门〉
|
||||
|
||||
- **换色合并欠账清单(全板重扫 6 对不达标,逐对清偿)**:`#18120C` ↔ `#181410`、`#33261B` ↔ `#362B20`、`#362B20` ↔ `#3A2E22`、`#3E362C` ↔ `#3E3731`、`#3E4048` ↔ `#3F4147`、`#453723` ↔ `#4A3B2A`——六对按「不过门即换色合并」纪律逐对清偿(并进最近既有色);清偿前该对不视作合规,清偿动作落本节修订。**本节所举反例 `#3A2E22` ↔ `#362B20` 正在这 6 对之内**,与本口径自洽。验收:机检〈全板色对中三通道差全部 <8/255 的对数 = 0〉
|
||||
|
||||
- **色板分层**:色板分两层管理——① **语义/UI token 板**:全作共享,硬上限 **48 色**,管 UI 语义色、墨色、材质色,跨屏恒定;② **场景环境子板**:**每屏一套,≤32 色,允许跨屏不共享**(环境色 = 天空、地面、植被、石材、火焰等随场景走的颜色)。新增环境色仍须过两道门(§4.2 语义检查 + 与既有任一色 RGB 三通道差禁止全部 <8/255),但**不占用 48 token 额度**;不过门照旧走「换色合并」,**禁加色绕行**。单张 PNG 的像素域色数上限 **≤32 色**另由 `standee_asset_check` 执法(按单图像素域取值方式计数,与本表 token 计数互不干扰)。额度不足时向作者报告,由作者决定压缩或合并既有色。验收:机检〈token 板 ≤48;每屏环境子板 ≤32〉
|
||||
- **色板分层**:色板分两层管理——① **语义/UI token 板**:全作共享,硬上限 **48 色**,管 UI 语义色、墨色、材质色,跨屏恒定;② **场景环境子板**:**每屏一套,≤32 色,允许跨屏不共享**(环境色 = 天空、地面、植被、石材、火焰等随场景走的颜色)。新增环境色仍须过两道门(§4.2 语义检查 + 与既有任一色 RGB 三通道差 ≥8/255),但**不占用 48 token 额度**;不过门照旧走「换色合并」,**禁加色绕行**。单张 PNG 的像素域色数上限 **≤32 色**另由 `standee_asset_check` 执法(按单图像素域取值方式计数,与本表 token 计数互不干扰)。额度不足时向作者报告,由作者决定压缩或合并既有色。验收:机检〈token 板 ≤48;每屏环境子板 ≤32〉
|
||||
|
||||
### 4.2 语义色彩规则
|
||||
|
||||
> **适用域**:本节「X 只说 Y」约束**信息层**(格内信息/UI 数据/预告/语义标识)与**语义物件**(GP=收益金、血条=危险红等);**纯环境氛围**(背景/装饰变体/远景/非语义物件)不受色相独占约束,改受 §3.4 焦点预算与低饱和后退约束(不抢读即可用色)。禁入带 300°–345°:信息层与语义物件禁入不变;环境层可入但限低饱和(高饱和紫赤仍 Boss 独占,§2.6)。验收:目检〈信息层与语义物件不落禁入带、不占语义独占色相;环境层用色低饱和〉
|
||||
|
||||
- **红只说危险**:危险红 = 兑现档,红族单档。禁(信息层域):红禁止用于奖励、装饰性标识与常规 UI(微光群伤组除外——见「类型微光色带」条,其色相刻意错开语义红)。验收:目检〈信息层域红色仅出现在危险语义与微光群伤组〉 ←原三;P2;§2.1
|
||||
- **血条填充 = 危险红 `#A8321F`**(语义物件显式落法):血条是本节适用域点名的语义物件,填充色族一律归危险红,不因敌我分色、不因关卡换族。读数不依赖填充色对比——血量数字 11px 压 `HP_BAR_BACK` 素牌(§7.4 豁免①,14.3:1),填充只承载「剩余比例」的形状语义。**蓝族引擎默认近似值 `#689CE8` 登记为违例值、已退役**:它同时撞本条「血条=危险红」与蓝条「蓝禁止表示敌方危险」,禁再入任何血条绘制点。验收:机检〈血条填充绘制点取值为 #A8321F 且全仓零 #689CE8 字面量〉
|
||||
- **金只说收益与兑现**(奖励、结算、胜利)。禁(信息层与语义物件域):金禁止作危险障碍色、不上格底、不作日常 UI 强调(防通胀;微光通用增益组的芥末黄属「类型微光色带」条色带,非收益语义金)。验收:目检〈信息层与语义物件域金色仅承载收益与兑现〉 ←P2;P3;§2.2–2.4
|
||||
- **蓝只说己方与冷静信息**(小人、光标、工具信息——含可挖域接触带呼吸微光,蓝族浅一档 `#D6ECFF`)。禁(信息层域):蓝禁止表示敌方危险;暮蓝 `#5A6C8C` 为失败独占(§2.5),只作全屏氛围,不作物件色。验收:目检〈信息层域蓝色仅承载己方与冷静信息;敌方危险无蓝色〉 ←P1;§2.5
|
||||
- **紫赤只说 Boss 与精英** `#8F2F6A`(色相 323°):郑重来自色相独占,不来自压暗。禁:**HSV 色相 300°–345° 为信息层与语义物件禁入带**——UI、粒子、类型微光、语义物件及图类型色板信息面禁止落入;环境层(背景/装饰)可入但限低饱和,高饱和紫赤仍 Boss 独占。验收:机检〈信息层与语义物件色值色相不落 300°–345°;高饱和紫赤仅 Boss 战〉 ←§2.6;原三
|
||||
@@ -348,7 +337,7 @@
|
||||
| 线索通道 | 冻结内容 |
|
||||
|---|---|
|
||||
| 意图姿态 | **动画三档**:① 普通攻击 = 常态待机(零独立资产);② 攻击技能 = 特殊准备动画(放光/高举武器);③ 重击/硬化类 = 蓄力动作或防御姿态。不显示文字与技能名(信息定义见《敌人系统》意图线索节);三档在灰度/剪影层可辨(双通道纪律) |
|
||||
| 强度档位 | 体量通道:§5.1 archetype 体量/垂直延伸("大个子多半有重击");护甲类型(light/ward/heavy)视觉区分方案已落 §5.3(已定稿) |
|
||||
| 强度档位 | 体量通道:§5.1 archetype 体量/垂直延伸("大个子多半有重击");护甲类型(light/ward/heavy)视觉区分方案已落 §5.3(候选,样张验收时冻结) |
|
||||
| 预告时序 | 预告语义见《敌人系统》意图线索节,呈现义务(挖掘期全程可见)见《HUD框架》;本表只锁「结算不另设独立意图播片」的动画形态 |
|
||||
| 恒定义务 | enemy_id 键映射跨 run 恒定、禁重掷;图像不报数——精确数值的明细承载见《战斗结算》。验收:机检〈enemy_id 键映射跨 run 恒定、禁重掷〉 |
|
||||
|
||||
@@ -363,7 +352,7 @@
|
||||
|
||||
> **本节内容已整体迁至独立文档 [`character-design.md`](character-design.md)**(小节号 §5.1–§5.6 在该文档中沿用不变)。迁移动机:人设高频改动,独立成档免动圣经;本存根保证既有 "art-bible §5.x" 式引用(§4.1/§4.5/§4.6.4、art-assets-checklist、战斗表现)经此仍可达,新引用直指该文档。
|
||||
|
||||
内容速览:§5.1 角色剪影与轮廓通道 · §5.2 头身比与体量档位 · §5.3 护甲类型视觉区分(已定稿) · §5.4 主角三态规格(形象锚 = 蓝兜帽披肩的暖装小冒险者:圆头挖掘铲 + 冒险背包插朱红矩形旗(与棋盘封印色脱钩) + 护目镜腰灯) · §5.5 八敌种逐卡 · §5.6 意图准备动画三档。
|
||||
内容速览:§5.1 角色剪影与轮廓通道 · §5.2 头身比与体量档位 · §5.3 护甲类型视觉区分(候选,样张冻结终稿) · §5.4 主角三态规格(形象锚 = 蓝兜帽披肩的暖装小冒险者:圆头挖掘铲 + 冒险背包插朱红矩形旗(与棋盘封印色脱钩) + 护目镜腰灯) · §5.5 八敌种逐卡 · §5.6 意图准备动画三档。
|
||||
|
||||
---
|
||||
|
||||
@@ -374,11 +363,10 @@
|
||||
### 6.1 战斗舞台背景(B 区环境)
|
||||
|
||||
- **双舞台常驻下的 B 区环境**:战斗画面区(站桩立绘所在)的背景 = 明亮地窟,与 §1 风格基调同源——暖倾向、无压抑;背景整体**低对比自然后退**(§3.4 焦点预算延伸):背景禁止构成完整凸形、禁止抢 B 区立绘与 D 区数字的焦点,识别层级恒为 立绘 > 背景。验收:目检〈背景无完整凸形、立绘最抢眼〉
|
||||
- **舞台正面目标**:B 区 = **地窟看台**——立绘脚下地台/落影承载(世界中层),背景环境层低饱和后退、明度走世界底层档,允许光源氛围(洞顶光柱/暖光晕候选);角色禁止直接贴平色底。规格与终值归整屏样张闸(§1.4)冻结。**地台面上零文字**——暖白 `#F0E2C8` 对地台板身 `#968264` 实测仅 2.89:1,已越 §7.2 的 4.5:1 硬指标,落法按 §7.2「文字禁直接压纹理底」(垫容器、素牌或罩层),非新条款;站桩文字位改垫素底或落进结算明细带。验收:目检〈立绘脚下有地台/落影,非贴平色底〉+机检〈B 区站桩文字位正下方像素非地台板身色 #968264〉
|
||||
- **舞台正面目标**:B 区 = **地窟看台**——立绘脚下地台/落影承载(世界中层),背景环境层低饱和后退、明度走世界底层档,允许光源氛围(洞顶光柱/暖光晕候选);角色禁止直接贴平色底。规格与终值归整屏样张闸(§1.4)冻结。验收:目检〈立绘脚下有地台/落影,非贴平色底〉
|
||||
- **明度分层适用**:背景氛围的情绪表达仍禁止以压暗/渐晕实现(§2 禁令);空间纵深与洞穴感走明度分层允许域——世界底层档、光照氛围、色相饱和与形体承载(§3.2 同款逻辑)。验收:方向性
|
||||
- **图类型联动**:背景 tint 走 §4.3 `wall_ambient` 槽,随三关换挡(方向候选见 §6.3);紫赤仅 Boss 战允许短暂进入背景氛围纹样(§2.6 色相独占的舞台侧延伸,高饱和独占不变),非 Boss 战高饱和紫赤禁入。验收:机检〈背景吸色无非 Boss 高饱和紫赤〉
|
||||
- **资产渠道**:✦ 插画级(演出类场景贴图,清单 §4 联动登记);战斗一屏样张(§1.4 清单 1.2)含背景出样。**资产契约(尺寸候选,样张冻结终稿)**:基准一张 = `scene_stage_bg.png`(源 1280×270,B 区全高含明细带底;三关换挡走 §4.3 `wall_ambient` tint 槽,不按板出三张——换皮成本复用棋盘同款逻辑),显示 1×;呈现约束按本节各条(低对比后退/明度世界底层档/光柱氛围保留)。程序化平色+光柱现行使用 = 占位;插画工单归 PRD,交付后 art-status-checklist 同步 ✅。**出图只出远景 + 中景两带**:结算期明细带底 84px 会盖住 B 区 78%–100% 段(约 59px),近景带在结算期整条不可见——画进背景等于画一件永远看不见的东西。远景/中景的构图占比归整屏样张(§1.4)。验收:目检〈背景插画内零地台结构件〉
|
||||
- **近景地台走独立件**:`scene_stage_plaza.png`,源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形(规格见 §8.2)。独立的两条理由——① 上条的 84px > 59px 覆盖账;② §4.3 `wall_ambient` tint 作用于整张背景,地台若画进背景会随三关换明度,而 §6.1 舞台正面目标把地台定死为世界中层承载面,随关卡变会破 §2 明度分层的层间关系。独立件跨关恒定。验收:机检〈地台件按九宫格拉伸后顶缘受光线宽度恒为 2px〉
|
||||
- **资产渠道**:✦ 插画级(演出类场景贴图,清单 §4 联动登记);战斗一屏样张(§1.4 清单 1.2)含背景出样。**资产契约(尺寸候选,样张冻结终稿)**:基准一张 = `stage/stage_bg.png`(源 1280×270,B 区全高含明细带底;三关换挡走 §4.3 `wall_ambient` tint 槽,不按板出三张——换皮成本复用棋盘同款逻辑),显示 1×;呈现约束按本节各条(低对比后退/明度世界底层档/光柱氛围保留)。程序化平色+光柱现行使用 = 占位;插画工单归 PRD,交付后 art-status-checklist 同步 ✅。
|
||||
|
||||
### 6.2 营地场景
|
||||
|
||||
@@ -393,7 +381,7 @@
|
||||
|
||||
### 6.3 三关图类型色板候选(board_type 换挡方向)
|
||||
|
||||
- **模板与不变槽**:换皮只换 §4.3 四槽(`tile_closed`/`tile_open`/`wall_ambient`/`variant_tint`),信息与语义层全图类型恒定——本节只给三关**方向性候选**,终值按 §4.3 现行规则重跑 §1.4 格子样张冻结。**终值的取值程序**:先跑「三关色相 × 五组类型微光」互辨抽测(抽测任务登记在待办清单),再按 §4.3 现行规则重跑 §1.4 格子样张冻结——本节不填终值色值,待该抽测与格子样张重跑后落本节修订。验收:机检〈本节三关行无 `tile_closed`/`wall_ambient` 终值色值字面量(终值未冻结前禁填)〉
|
||||
- **模板与不变槽**:换皮只换 §4.3 四槽(`tile_closed`/`tile_open`/`wall_ambient`/`variant_tint`),信息与语义层全图类型恒定——本节只给三关**方向性候选**,终值按 §4.3 现行规则重跑 §1.4 格子样张冻结。
|
||||
- **深度轴叙事**(§2.7 下探过渡):色相层进预告「更深更险」,明度档不动——
|
||||
- **dungeon 地精洞窟**(第一关):现行掩尘系暖石棕(`#C9AF83` 基)即基准档,`wall_ambient` 暖棕;
|
||||
- **underdark 幽暗地域**(第二关;方向:**冷调幽暗**):主调**灰白蓝**候选(低饱和蓝灰域,`tile_closed`),少量紫黑倾向点缀——紫系取紫罗兰域(≈256°)候选,禁入带 300°–345° 不变;`wall_ambient` 冷蓝灰;
|
||||
@@ -436,7 +424,7 @@
|
||||
|
||||
### 7.2 UI 色板细则(自 §4.4 迁入)
|
||||
|
||||
**全局文字可读性硬指标**:**一切文字**(含菜单/说明/tooltip/按钮/底栏,无区域例外)对其直接背景 **≥4.5:1**(WCAG AA);大字(≥18px 或加粗档)底线 3:1、目标 4.5:1;**文字禁直接压纹理底**——垫容器或罩层。**站桩石板地台面同理**(显式落法):地台板身 `#968264` 是 §6.1 定死的世界中层承载面,暖白 `#F0E2C8` 对其实测仅 2.89:1,文字禁直接压地台面——须垫容器、素牌或罩层,或落进结算明细带的素底。核验闸 = §1.4 整屏样张。验收:机检〈ui_contrast_probe 全文字位 ≥4.5:1;B 区站桩文字位正下方像素非地台板身色 #968264〉
|
||||
**全局文字可读性硬指标**:**一切文字**(含菜单/说明/tooltip/按钮/底栏,无区域例外)对其直接背景 **≥4.5:1**(WCAG AA);大字(≥18px 或加粗档)底线 3:1、目标 4.5:1;**文字禁直接压纹理底**——垫容器或罩层。核验闸 = §1.4 整屏样张。验收:机检〈ui_contrast_probe 全文字位 ≥4.5:1〉
|
||||
|
||||
**数据素面的墨来自世界的墨**:UI 数字、进度、准线一律主墨 `#33261B` 系——棋盘与面板读同一种墨;容器穿木石材质色,数据只穿墨。**营地与棋盘**:菜单容器背景用全作最暖的烛光黄 `#F6C667` 与木色 `#8A5A34`(§2.8;场景构成 §6.2);战斗容器转中性石色,防暖色渗入棋盘分走数字对比预算——氛围色向可读色让路。UI 不新增语义色,一切强调沿用 §4.2。**暗底呈现态双色墨制**(样张冻结):暗底系(已过/未来/候选/Boss 方块、暗数据框)图标与读数一律暖白 `#F0E2C8`(WARM)、亮底(当前金 `#F0A828`)转深墨 `#181410`(INK_ROUTE)——各态对比 ≥4.5:1;已过节点暗金冻结 `GOLD_DONE #68562C`(专用呈现态值;旧 GOLD_DIM 对双色墨不达标、已退出该呈现位);Boss 描边 = 紫赤 2px + 外缘 1px 深墨环(灰度冗余通道——§4.2 色相独占本色不变,§4.5 灰度可分类承载)。验收:机检〈暗底/亮底各态文字对比 ≥4.5:1〉
|
||||
|
||||
@@ -453,8 +441,8 @@
|
||||
- **字体**:全局一套像素字,单套即终稿——缝合像素字体 Fusion Pixel(OFL,已接入 `game/assets/fonts/ui_font_fusion_pixel_zh_hans.ttf`),拉丁字符与数字沿用其自带拉丁字形,不另设拉丁专件(现状即终稿;旧拉丁候选 Kenney Fonts 已弃;生产工单=清单 §3.6);墨色走主墨系(§7.2);换字体 = 全局决策。验收:机检〈主题字体指向 Fusion Pixel 件〉
|
||||
- **字号**:像素字体**整数倍缩放,禁非整数缩放**(像素模糊);下限(1280×800 基座):棋盘数字 ≥18px(公式 = `max(18, ceil(格边长 × 0.5))`不变)、**正文/明细 ≥16px、tooltip ≥14px**(1280×800 低于 1080p 基准,同字号实际更小)。验收:机检〈静态文字位点字号 ≥ 档位表值〉
|
||||
- **字号档位表(六档)**:全站 UI 文字字号只经 `UiKit.FS_*` 单点取值,裸数字字号弃用——`FS_CAPTION 12`/`FS_HINT 14`/`FS_BODY 16`/`FS_SUB 18`/`FS_TITLE 24`/`FS_H1 34`。旧实测档按就近归档收编(10/11/12→CAPTION、13/14→HINT、15/16→BODY、17/18/20→SUB、21/22/24/26→TITLE、32/40→H1;静态位点全归档,数据驱动动态字号位点除外);棋盘数字公式 `maxi(18, ceil(格边长×0.5))` 与站桩血数 11px(条带内读数豁免)不入表。注:六档相邻比 12→14→16→18 三段 <1.25×,系裁决值优先于字重纪律的档差参考线,该参考线对新层级设计仍有效。验收:机检〈全站无裸数字字号,位点走 FS_*〉
|
||||
- **小字号豁免条款(合并单条不开两口子)**:下款两类**豁免于本节下限**——①**条带内读数**:压在窄条带(血条/进度条等 ≤12px 高带)内居中的数字,受条带高度物理约束,维持 11px 下限,且必须按 §7.2 垫素色牌后计对比(实装=B 区站桩血数 11px 压 HP_BAR_BACK 牌 14.3:1);②**装饰性 overline/caption**:不承载须精确读取的信息、仅作分区标题或氛围小字者,可至 **12px**。**豁免逐处清单(撤除史归 git 提交史,余清单如下)**:条带内读数=B 区站桩血数一处;装饰 caption 档(FS_CAPTION)在册面=棋盘底操作提示条/营地柜台说明文与结构位预留注记/图例 RAP 词条说明/设置警示文两处/关卡地图底栏组标(生命/属性/特性)与分隔系/站桩消散提示/B 区状态槽微计数(×N●○)/bcard 脚注/RAP 反馈行/刷新余量徽标——清单外 11-13px 文字一律按正文/tooltip 下限提档,新增 caption 位须同批增补本清单。**站桩顺位徽标 ①②③ 不增列本清单**:该处原为 13px 字形,既不在①条带内读数在册面、也不在②装饰 caption 在册面,属「清单外 11–13px 文字」,按本条纪律提档至 `FS_HINT` 14 即归六档;为它单独入册等于开第二口子,与「合并单条不开两口子」的立条理由正面相撞。②装饰 caption 在册面逐处维持不变。验收:机检〈豁免文字位均可对上本清单,清单外无 <14px;站桩顺位徽标绘制点取 UiKit.FS_HINT,且②在册面不含该位〉
|
||||
- **字重纪律(字重两档不启用)**:层级手段为两件——**字号档差(相邻层级 ≥1.25×)+ 墨色深浅**;全局单字重,不上第二个字重(**重开钩子已注销**——整屏样张设计轮已重开并复核:屏内各级文字全部能归进本节六档字号,顺位徽标与站桩名字行两处按本节纪律提档即可,屏内实测对比全部达标(暖白对舞台底 9.49:1、GOLD_BRIGHT 6.47:1、血数 14.3:1),**未实证标题层级不足**,维持单字重,不另立条目);数字禁描边/阴影伪加粗不变(字形为唯一数值载体,§4.1 同源纪律)。验收:机检〈主题仅注册单字重〉/目检〈屏内标题与正文层级仅靠字号档差与墨色深浅两件即可分辨,无一处需要第二字重才读得清〉
|
||||
- **小字号豁免条款(合并单条不开两口子)**:下款两类**豁免于本节下限**——①**条带内读数**:压在窄条带(血条/进度条等 ≤12px 高带)内居中的数字,受条带高度物理约束,维持 11px 下限,且必须按 §7.2 垫素色牌后计对比(实装=B 区站桩血数 11px 压 HP_BAR_BACK 牌 14.3:1);②**装饰性 overline/caption**:不承载须精确读取的信息、仅作分区标题或氛围小字者,可至 **12px**。**豁免逐处清单(撤除史归 git 提交史,余清单如下)**:条带内读数=B 区站桩血数一处;装饰 caption 档(FS_CAPTION)在册面=棋盘底操作提示条/营地柜台说明文与结构位预留注记/图例 RAP 词条说明/设置警示文两处/关卡地图底栏组标(生命/属性/特性)与分隔系/站桩消散提示/B 区状态槽微计数(×N●○)/bcard 脚注/RAP 反馈行/刷新余量徽标——清单外 11-13px 文字一律按正文/tooltip 下限提档,新增 caption 位须同批增补本清单。验收:机检〈豁免文字位均可对上本清单,清单外无 <14px〉
|
||||
- **字重纪律(字重两档不启用)**:层级手段为两件——**字号档差(相邻层级 ≥1.25×)+ 墨色深浅**;全局单字重,不上第二个字重(重开钩子:战斗一屏样张设计轮若实证标题层级不足,字重议题随该轮重开,不另立条目);数字禁描边/阴影伪加粗不变(字形为唯一数值载体,§4.1 同源纪律)。验收:机检〈主题仅注册单字重〉
|
||||
|
||||
### 7.5 营地界面
|
||||
|
||||
@@ -485,7 +473,7 @@
|
||||
|
||||
**(三)氛围层平滑件与抖动派并存**
|
||||
|
||||
- vignette / gradient_base / beams 三件程序化平滑渐变件**保平滑连续 alpha**(已裁),与卡顶类型色带 DitherBand 的 Bayer 有序抖动派**并存不一致**——**整屏样张已裁:维持三件保平滑,并存事实按本节登记,不再统一**。裁定的依据:三件保平滑有用户裁背书、且已在 §8.2 显式 LINEAR 豁免清单在册(该清单写的是「怎么继续维护」不是「要不要取消」),统一派等于推翻用户裁并清空该清单;「把两派调参拉到同一颗粒感知档」在圣经里无任何条款依据,属自造动作。本节只登记并存事实,不统一。验收:方向性(目检复核:三件氛围件与卡顶抖动带同屏时,两派颗粒语言差异不构成观感冲突)
|
||||
- vignette / gradient_base / beams 三件程序化平滑渐变件**保平滑连续 alpha**(已裁),与卡顶类型色带 DitherBand 的 Bayer 有序抖动派**并存不一致**——两派统一裁决留**整屏样张**(§1.4;战斗一屏样张未开工,待办清单在册),本节只登记并存事实与裁决去向,不提前统一。验收:方向性
|
||||
|
||||
> **主题色值双源注记**:主题色值现存两处——`main_theme.tres` 字面量与 ui_kit 常量(README 溯源表缓解)。长期收敛候选 = 程序化 Theme 生成回代码单点,属重构面、未排期;新增色值仍按现状双落并同批登 README 溯源表。
|
||||
|
||||
@@ -507,16 +495,15 @@
|
||||
- **缩放纪律(硬规则,按资产两类分级;不做个案豁免)**:
|
||||
- **甲类·文本与语义件**(数字、图标、旗、格面纹样):维持严格整数倍缩放硬规则——可读性与语义精确性优先,**禁非整数缩放不变**。砖面 tile 不属本类,随格边长整格铺满(见 §8.1)。验收:机检〈甲类件显示尺寸为源整数倍〉
|
||||
- **全局纹理过滤与平滑渐变件例外**:`project.godot` `default_texture_filter=0`(Nearest)全局——像素风 UI 皮(九宫格/主题石纹样式盒/滑轨抓子/勾选/箭头图标)翻 Nearest=意图面;**显式 LINEAR 豁免清单(有意例外)= vignette / gradient_base / beams 三件程序化平滑渐变件**——保平滑连续 alpha 的程序化氛围件(§7.6 三已裁);新增平滑件须同批入册本清单,禁静默挂 LINEAR。翻转面枚举与冒烟断言(6 条)在闸。验收:机检〈过滤面枚举与 LINEAR 清单逐项一致〉
|
||||
- **显示档登记例外(64 源 0.5×,待素材批消除)**:柜台四枚 `icon_forge/workshop/atlas/keystone`(64×64 源)显示档统一 **32px = 0.5×**;状态九枚(32×32 源)mini(站桩)档 **16px = 0.5×**。两处均系「显示尺寸侧唯一可调、素材一字节禁改」红线下的人工检整数半倍档,登记为**待消除例外**——素材设计出 32px 源后回归 1×。常规档显示一律 1×(状态九枚 32px、手绘十枚 20px/40px 双档、BCard 图标槽 40px=2×、**护甲类型图标三枚 24px=1×**——源 24×24,归甲类整数倍纪律)。验收:机检〈显示档与登记表一致〉
|
||||
- **显示档登记例外(64 源 0.5×,待素材批消除)**:柜台四枚 `icon_forge/workshop/atlas/keystone`(64×64 源)显示档统一 **32px = 0.5×**;状态九枚(32×32 源)mini(站桩)档 **16px = 0.5×**。两处均系「显示尺寸侧唯一可调、素材一字节禁改」红线下的人工检整数半倍档,登记为**待消除例外**——素材设计出 32px 源后回归 1×。常规档显示一律 1×(状态九枚 32px、手绘十枚 20px/40px 双档、BCard 图标槽 40px=2×)。验收:机检〈显示档与登记表一致〉
|
||||
- **乙类·角色与单位精灵**(有机形体、非文字):允许运行时非整数倍缩放(NEAREST 过滤不变),容忍轻度像素宽窄不均;判据 = 实机目检,可感不适即回整数档。乙类免逐案豁免。验收:目检〈立绘无可感拉花〉
|
||||
- **站桩立绘槽位=高定宽随**:立绘/精灵槽位只定「高度的整数倍档」,宽度随源图宽高比自适应——**禁止把全部立绘塞进统一方框强拉**(纵横倍率必须恒等)。反面实例:统一方框把窄条生物源(细长本体裁掉透明边)按主角比例横拉压扁发花。乙类的非整数豁免只覆盖**等比**缩放,不含纵横异倍变形。验收:机检〈立绘纵横倍率恒等〉
|
||||
- **1920×1080 档策略**:全局等比(stretch=canvas_items+aspect **keep**)——16:10 设计在 16:9 窗口=等比 1.35×+左右黑边各 ~96px,构图与 1280×800 基准档完全一致;甲类 1.35 非整数缩放例外注记:轻度宽窄不均系本档位接受代价(像素游戏 shipped 常态),实机目检可感不适→回乙案(1920 独立 2× 基准)重议;乙类同前款。验收:目检〈1920 档构图与 1280 档一致〉
|
||||
- **画布基准(暂定值)**:
|
||||
- **主角人设原图 = 48×72**(1× 基准,暂定;与站姿降采样可读性验证一致);
|
||||
- **棋盘小人 = 32×32 二头身派生版(暂定,允许更小)**——独立资产,自人设定稿压缩派生(character-design §5.4),不吞数字位、占位 ≤ 0.75× 格边长;板越小占比摩擦越大(13×13 / 14×14 更小,算例见 [battle.md](../gdd/ux/battle.md)「棋盘格尺寸公式」),32px 源档的去留已定终值 = **保留 32×32 源档**(沿「独立小源档」路线;N=12 板下显示占位上限 27px = 0.84 倍,正落本节乙类非整数缩放许可范围,**连豁免都不用再办**),待决标注注销;
|
||||
- **棋盘小人 = 32×32 二头身派生版(暂定,允许更小)**——独立资产,自人设定稿压缩派生(character-design §5.4),不吞数字位、占位 ≤ 0.75× 格边长;板越小占比摩擦越大(13×13 / 14×14 更小,算例见 [battle.md](../gdd/ux/battle.md)「棋盘格尺寸公式」),32px 源档沿「独立小源档」路线在样张定终值;
|
||||
- **站桩立绘源档 = 八敌逐键定档**:主角 48 不变;八敌源档高 = goblin 36 / giant_spider 38 / duergar 46 / hook_horror 58 / bugbear 62 / ogre_chief 74 / drider 90 / duergar_king 94,显示一律 **×2 整数档(NEAREST)** = 72–188。定档依据 = 生物体型三约束(钩爪恐魔>灰矮人、灰矮人<熊地精、食人魔>熊地精——体量=物种体型,非强度线性映射,见 character-design §5.2);可读性实测门槛 = 源高 ≥32(24 糊/32 可读/48 清楚/64 细节完整),全阶梯 36–94 达标;派生管线 = pixel-1.png 紧裁 → 等比缩至档高 → dom_block_resize 块内众数降采样(tools/pixelize_candidates.py `STANDEE_TIER_H`,`SIZES` 降格为管线上游中间分辨率表);体量存在感经整屏对比校验(B 区 270/立绘显示上限 188)。验收:机检〈standee_asset_check 逐键档高校验〉
|
||||
- **站桩立绘排版**:① 区高 B 区 270(≈1/3)/C 区 530(≈2/3),**扫雷盘 438×438 原尺寸不缩、格子不变**(区高事实源 battle.md 区表;压缩由 C 区面板空档吸收);② 站桩内部重排——立绘双脚落石台上缘(弃盒内居中)、**血条+状态/名字行落底排**(立绘→血条→状态 顺序,全场血条对齐一线;血条嵌石板位、台缘线留作地面线、落影保留接地感),状态空时该行退化为名字行;③ 大体档(显示 >150px 级:drider/duergar_king)**允许向上溢出盒顶 N px**(N 由实装批按实测尺寸算定,**与背景/光柱无关**——现行溢出区恰为临时光柱氛围层〔§6.1 方向稿四柱,x 基准 110/900/1055/1210@1280,`battle_stage_view.gd:55-63`〕,正式舞台背景插画 `scene_stage_bg.png` 到位后该层由背景绘制吸收,**溢出判定不随之变更**;横向禁止压到顶部中央轮次·阶段指示,溢出上限由实装批用真图复算 x 区间定),血条仍落底(落底排的第二个收益=头部探顶不带出血条);意图徽标悬浮头顶上方(探顶档压胸);④ 「血条悬浮头顶+立绘盒内居中」排式已弃——盒顶固定 y 与盒内居中在高盒下拉开血条-立绘空洞。验收:目检〈血条一线对齐、大体档溢出不压轮次指示〉
|
||||
- **站桩石板地台件**:`scene_stage_plaza.png`,源 48×12、九宫格横向拉伸、顶缘受光线 2px 不随拉伸变形;跨三关恒定、不吃 §4.3 `wall_ambient` tint(独立理由见 §6.1 近景地台独立件条)。验收:机检〈地台件按九宫格拉伸后顶缘受光线宽度恒为 2px〉
|
||||
- **站桩立绘排版**:① 区高 B 区 270(≈1/3)/C 区 530(≈2/3),**扫雷盘 438×438 原尺寸不缩、格子不变**(区高事实源 battle.md 区表;压缩由 C 区面板空档吸收);② 站桩内部重排——立绘双脚落石台上缘(弃盒内居中)、**血条+状态/名字行落底排**(立绘→血条→状态 顺序,全场血条对齐一线;血条嵌石板位、台缘线留作地面线、落影保留接地感),状态空时该行退化为名字行;③ 大体档(显示 >150px 级:drider/duergar_king)**允许向上溢出盒顶 N px**(N 由实装批按实测尺寸算定,**与背景/光柱无关**——现行溢出区恰为临时光柱氛围层〔§6.1 方向稿四柱,x 基准 110/900/1055/1210@1280,`battle_stage_view.gd:55-63`〕,正式舞台背景插画 `stage/stage_bg.png` 到位后该层由背景绘制吸收,**溢出判定不随之变更**;横向禁止压到顶部中央轮次·阶段指示,溢出上限由实装批用真图复算 x 区间定),血条仍落底(落底排的第二个收益=头部探顶不带出血条);意图徽标悬浮头顶上方(探顶档压胸);④ 「血条悬浮头顶+立绘盒内居中」排式已弃——盒顶固定 y 与盒内居中在高盒下拉开血条-立绘空洞。验收:目检〈血条一线对齐、大体档溢出不压轮次指示〉
|
||||
|
||||
### 8.3 导出格式与命名规范
|
||||
|
||||
@@ -528,7 +515,7 @@
|
||||
### 8.4 帧数规格(样张冻结)
|
||||
|
||||
- **帧数规格(样张冻结)**:待机循环 4 帧;攻击/技能准备 6 帧单次;受击 2 帧;死亡 = 灰化+碎裂退场(§4.6.4 语义硬规则),序列帧归 ✦ 缺料清单;帧时长与结算节拍对齐(预告时序见 §4.6.4)。验收:机检〈序列帧数与档位一致〉
|
||||
- **方向集**:棋盘小人=**4 向**(下/上/侧,侧向左右镜像共用一份画稿);斜向移动/挖掘按**主导轴吸附最近正交向**呈现,不出 45° 斜向帧(斜向信息由位移轨迹与目标格预告承载,ITB 实态同款)。镜像与「旗面恒画右」纪律(character-design.md 冒险背包条)的相容归属:棋盘小人默认镜像豁免、旗右纪律限立绘侧——代拟口径已追认(棋盘小人朝左时旗面朝左,与立绘侧「旗面恒画右」并存;画稿维持一份 + 镜像,零新增资产)。验收:目检〈四向帧齐、侧向镜像无破绽〉
|
||||
- **方向集**:棋盘小人=**4 向**(下/上/侧,侧向左右镜像共用一份画稿);斜向移动/挖掘按**主导轴吸附最近正交向**呈现,不出 45° 斜向帧(斜向信息由位移轨迹与目标格预告承载,ITB 实态同款)。镜像与「旗面恒画右」纪律(character-design.md 冒险背包条)的相容归属:棋盘小人默认镜像豁免、旗右纪律限立绘侧——代拟规则,样张确认。验收:目检〈四向帧齐、侧向镜像无破绽〉
|
||||
|
||||
### 8.5 结构件完整性与参考核验
|
||||
|
||||
|
||||
+3
-255
@@ -1,8 +1,8 @@
|
||||
# 生图提示词卡(角色级资产)v2.9
|
||||
|
||||
> **性质**:美术清单生图通道(✦ 用户自跑,现走线上 API)的执行侧文件——每资产一段**自包含完整提示词**:正向 = 通用底座+主体+动作已拼妥、负向 = 通用底座+增补已并妥,整段复制直接贴进工作流即可,**不需要读其他文件、不需要拼装**。人物规格转写自 [character-design.md](character-design.md)(人物设计 v1.0,自 art-bible §5 迁出,圣经 §5 为存根),风格/色彩条款转写自 [art-bible](art-bible.md)(§4.1 主色板 / §4.2 语义色规则);冲突时人物规格以 character-design 为准、色彩以 art-bible 为准。
|
||||
> **边界**:本文件只管**角色级**资产的生图通道。图标/格面/样张走脚本管线(⚙ 代理出),规格在 art-bible §4.6 与 [art-assets-checklist](art-assets-checklist.md),不需要提示词。**场景级资产(营地场景图的背景层与八个物件层)另立 [camp-scene-prompts](camp-scene-prompts.md),本文件不覆盖**;两卡的角色/场景分工以「谁的资产谁出卡」为界,同一段提示词不两处维护。战斗舞台的场景级两件与护甲类型图标三枚的**出图工单**登记在本文件 §5(camp-scene-prompts 只管营地场景图,战斗屏这两类无处可落);§5 只把各权威节的定值收进逐件工单,不立新值。意图动画三档是动画资产,等一屏样张锁方案后另立规格卡,本文件不覆盖。
|
||||
> **状态**:提示词卡成文,出图未开始;按「美术圣经 §5 现行」重生成(正序:B 路线),继承 seed 纪律 / 色相禁入带 / `#F2F2F2` 生成底色;沿革见 git 提交史。
|
||||
> **边界**:本文件只管**角色级**资产的生图通道。图标/格面/样张走脚本管线(⚙ 代理出),规格在 art-bible §4.6 与 [art-assets-checklist](art-assets-checklist.md),不需要提示词。**场景级资产(营地场景图的背景层与八个物件层)另立 [camp-scene-prompts](camp-scene-prompts.md),本文件不覆盖**;两卡的角色/场景分工以「谁的资产谁出卡」为界,同一段提示词不两处维护。意图动画三档是动画资产,等一屏样张锁方案后另立规格卡,本文件不覆盖。
|
||||
> **状态**:提示词卡成文,出图未开始;按「美术圣经 §5 现行」重生成(正序:B 路线),继承 seed 纪律 / 色相禁入带 / `#F2F2F2` 生成底色;沿革见 git 提交史。
|
||||
|
||||
---
|
||||
|
||||
@@ -284,259 +284,7 @@ Seamless tileable pixel art texture of dry dirt ground, top-down, for a dungeon
|
||||
|
||||
后处理(程序侧,生成器脚本归档 zip 内〔archive 备选案-terrain-walls〕):周期对齐无缝裁剪→BOX 降采样 32×32→环绕混合→量化(12 色)→结构件合成;②③亦可由①程序加纹理级裂纹/浅斑替代(实证更稳)。
|
||||
|
||||
## 5. 资产出图工单(四组九件)
|
||||
|
||||
> **范围注**:本文件原定位角色级(见文件头边界句),§4bis 已有「地形类同库登记」的先例,本节循同一先例补登记战斗屏两类——战斗舞台的场景级两件(① ②)与护甲类型图标三枚(③),两组在营地卡与清单里都无处落工单;角色级立绘重产(④)是本文件的本职。四组的规格定值清单 §4 已有登记,本节补的是「逐件照着就能出件」那一层。
|
||||
> **定值纪律(§8 头注 定值单点纪律)**:本节**指路不立值**——色值 = 圣经 §4.1(含场景环境子板)、尺寸与缩放 = §8.2、明度带 = §2、甲档 = character-design §5.3、命名 = §8.3 + asset-path-map。本节新增零定值;凡圣经未定的值,一律进本节 §5.5 缺口,不在本节填空。
|
||||
> **验收标注纪律**:逐条按三档标 `←机检: <断言>` / `←目检: <判据>` / `←方向性`,照圣经头注 2026-10-06 用户拍板的写法。
|
||||
> **流程**:出图前后一律走 §0 五步;出图登记义务(模型名 + 分辨率 + seed + 对话/日期)照 remote-gen-prompts 头注,随候选图存 `artwork/candidates/<资产名>/`,缺登记的候选不入正稿遴选。
|
||||
|
||||
### 5.1 组一 · B 区舞台背景插画(1 件)
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| ① 路径与命名 | `game/assets/art/scene/scene_stage_bg.png`——域键 `scene`(asset-path-map §3),命名照 §8.3 `<域>_<对象键>_<状态\|变体>[_<序号>].png`。**三关不按板出三张,文件名不带 `_dungeon`/`_underdark`/`_deep_underdark` 后缀**(三关换挡走 §4.3 `wall_ambient` tint 槽,与棋盘同款换皮逻辑) |
|
||||
| ② 尺寸档与像素网格 | 源 1280×270(B 区全高含明细带底),显示 1×;九宫格 = 否。甲/乙两分类不覆盖环境件(§8.2 甲类 = 文本与语义件、乙类 = 角色与单位精灵),本件在 1280×800 基座下满幅铺 1×、不缩放;1920 档口径见 §8.2「1920×1080 档策略」条,本节不另立值 |
|
||||
| ③ 色板约束 | 进**战斗屏场景环境子板**(§4.1 分层②:每屏一套 ≤32 色、跨屏不共享、**不占 48 token 额度**——48 额度余量现为 0(2026-10-28 用尽),本件不动它)。**零新增**——主体三色:远景最深 `#282220`(默认;备选 `#3A2E22`,二选一,选后者则图内禁用 `#362B20`,两者三通道差 4/3/2 全部 <8,是 §4.1 欠账清单六对之一);中景洞壁 `#3E362C` 与中景受光壁面 `#453723` 交替,**两色只靠笔触与纹理分出块面,不靠第三个色**;需过渡色时只从在册的 `#362B20`/`#4C4038` 取。单张 PNG 像素域色数 ≤32。第二道门 = 与既有任一色三通道差不得全部 <8/255(§4.1 增量纪律),不过门即换色合并、禁加色绕行 |
|
||||
| ④ 明度带归属 | **世界底层下沿子带 L 0.014–0.06**(§2 世界底层两子带)——全图落该子带,不得越进上沿子带 L 0.08–0.14(那是已开格底与迷雾记忆态合成底的地盘)。三色实测: `#282220` L≈0.016 / `#3E362C` L≈0.039 / `#453723` L≈0.042 |
|
||||
| ⑤ 是否程序化件 | 否 → **须出图**(✦ 插画级,清单 §4 已定来源 = 作者自跑远程生图管线)。现行程序化平色 + 光柱 = 占位(◐),按 §7.1 占位完成条款须在终稿闸前换代 |
|
||||
| ⑥ 验收判据 | 见下方逐条判据 |
|
||||
| ⑦ 出图操作要点 | 见下方提示词与负面约束 |
|
||||
|
||||
**逐条判据**
|
||||
|
||||
- 构图只出远景 + 中景两带:远景 0–35%、中景 35–78%,78%–100% 段不画 ←机检: 画布 1280×270 逐位相符;`y ≥ 210`(78%) 段内 `#968264` 像素数 = 0 且该段与中景段无独立地台结构件
|
||||
- 三关只走 tint 槽 ←机检: 仓内 `scene_stage_bg*` 文件名无 board_type 后缀变体(三关方向指路 §6.3,该节终值未冻结,属实装批,不阻塞本件出图)
|
||||
- 色板零新增 ←机检: 单张像素域色数 ≤32 且逐色在 §4.1 战斗屏场景环境子板在册
|
||||
- 明度带 ←机检: 全图取样点相对亮度 L 全部落 [0.014, 0.060]
|
||||
- 禁入带 ←机检: 全图无 HSV 色相 300°–345° 像素(清单 §0 复用闸②吸色检查同口径)
|
||||
- 临时光柱层退役 ←机检: 本件入包后 `battle_stage_view.gd` 四柱临时光柱层退役(§8.2 站桩排版③条;该条的立绘溢出判定不随之变更)
|
||||
- 背景自然后退 ←目检: 立绘与 C 区数字在前,本件不构成完整凸形、无第二焦点(§3.4 焦点预算 / §6.1 低对比后退)
|
||||
- 气质 ←方向性: 明亮地窟、暖倾向、无压抑(§1 风格基调;§9.2 Darkest Dungeon 式压暗在反面清单)
|
||||
|
||||
**出图画布**:2560×540(终稿 2×,保证整数倍降采样;平台不支持该宽高比时取可用的最宽档出图、按上下居中裁到 4.74:1,禁横向拉伸变形)。
|
||||
|
||||
**正向提示词(整段可贴)**:
|
||||
|
||||
```
|
||||
Pixel art style. True pixel art game background illustration drawn with chunky square pixels, strict pixel grid alignment, hard edges, no anti-aliasing, no gradients, flat colors only, a limited palette of about eight colors, retro 16-bit look, Aseprite style, all ages, bright cheerful fantasy cavern, not dark and not grim, flat side view, orthographic, no perspective distortion, very wide horizontal band about 4.7 to 1 aspect ratio. This is the BACK WALL of a bright underground cavern arena seen straight on, and it is a BACKGROUND ONLY: it must contain no characters, no creatures, no floor platform and no props, because the standing stone platform and the characters are drawn on top of it as separate pieces. TWO BANDS ONLY, and the bottom twenty-two percent of the frame stays completely empty. FAR BAND (the top zero to thirty-five percent of the frame height): the deepest hollow of the cavern, a flat dark far wall receding into shadow, one or two rows of very simple flat stalactite silhouettes hanging from the top edge, the darkest area of the picture, its darkest value is hex color #282220, no light sources, no small detail, everything reduced to a few large flat shapes. MIDDLE BAND (thirty-five to seventy-eight percent of the frame height): the cavern wall, broad flat facets of stone alternating between hex colors #3E362C and #453723, the facets separated only by their brush texture and by a few slightly darker seam lines, with two or three soft vertical light shafts falling from the cave roof across the wall, the shafts being flat low-contrast bands of light and not beams of particles. WHOLE IMAGE: every color is very dark and low in contrast, the entire background recedes behind the characters, there are no bright highlights and no rim lights, no single element forms a complete solid shape that competes for attention, and all wall facets stay large and simple.
|
||||
```
|
||||
|
||||
**负向提示词(整段可贴)**:
|
||||
|
||||
```
|
||||
Do not add any of the following: realistic, photorealistic or 3D rendering; painterly brushwork, smooth anti-aliased lines, gradient or dithered shading, glossy highlights; blur or compression artifacts; a vignette, dark corners, or any mood darkening; any purple or magenta anywhere, any color with a hue between 300 and 345 degrees; any text, letters, numbers, watermark, signature or logo; any frame, border, panel, arrow or UI element; any characters, people, creatures or animals; any floor, ground plane, stone platform, pedestal, stage floor or baseboard in the lower part of the frame, because the bottom twenty-two percent of the frame must stay completely empty; any torch, brazier, lantern, candle or glowing object as an object, only the flat light shafts described above; bright or saturated colors, any area lighter than hex #453723; high contrast edges, rim lights, black outlines; rubble, chains, bones, murals, paintings, furniture or any extra prop.
|
||||
```
|
||||
|
||||
**后处理**:§0 五步第 4 步——本件是**不透明全幅件**,去底与四联底测试条两步不适用,只走最近邻降采样到 1280×270 + 色板量化到本节 ③ 所列色;终稿入包后走 §1.4 整屏样张闸。
|
||||
|
||||
### 5.2 组二 · 近景地台件(1 件)
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| ① 路径与命名 | `game/assets/art/scene/scene_stage_plaza.png`——域键 `scene`(asset-path-map §3),命名照 §8.3。**跨三关恒定,文件名不带 board_type 后缀** |
|
||||
| ② 尺寸档与像素网格 | 源 48×12;**九宫格横向拉伸**,顶缘受光线 2px 不随拉伸变形(§8.2 / §6.1 定值);高度维持源档 12px、横向拉至站桩宽。九宫格件不在甲/乙两分类内(§8.2 甲类 = 文本与语义件、乙类 = 角色与单位精灵),本件高度恒为整数像素、横向拉伸区只取纯色 |
|
||||
| ③ 色板约束 | 进**战斗屏场景环境子板**(§4.1 分层②,不占 48 额度,余量 0 不动)。**零新增**——板身 `#968264`(STAND_STONE,§4.1 已转正进本子板)/ 顶缘受光线 `#C9AF83`(掩尘;2026-10-28 合并登记把地台顶缘受光线并进掩尘,并与 §8.2 高墙口沿高光 `Color8(196,172,132)` 统一为同一枚)/ 描边 `#4C4038`(2026-10-28 合并登记把地台描边并入此值)。单张像素域色数 ≤32。第二道门同本节 5.1 |
|
||||
| ④ 明度带归属 | **世界中层 L 0.22–0.45**(§2)——判定对象 = 板身 `#968264`(实测 L≈0.234)与顶缘受光线 `#C9AF83`(实测 L≈0.449,材质受光属 §2 形体塑造允许域)。§6.1 把地台定死为世界中层承载面,就是本件的立法理由。描边 `#4C4038` 是结构墨线(§3.2 高墙墨线同族,职责 = 分隔),不按明度带判定 |
|
||||
| ⑤ 是否程序化件 | 是 → **程序化直出即终稿,不须出图**。本件只有三块纯色 + 一条 2px 缘线,无材质纹理需求,按 §8.5「材质归模型、结构归程序」落脚本绘制即成立;它不属 §7.1 占位态 |
|
||||
| ⑥ 验收判据 | 见下方逐条判据 |
|
||||
| ⑦ 出图操作要点 | 见下方工艺要点(手绘/程序化,无须 AI 生图) |
|
||||
|
||||
**独立成件的两条理由(§6.1「近景地台走独立件」条,写进工单备查)**:① 结算期明细带底 84px 会盖住 B 区 78%–100% 段(约 59px),84 > 59,近景带在结算期整条不可见——画进背景等于画一件永远看不见的东西;② §4.3 `wall_ambient` tint 作用于整张背景,地台若画进背景会随三关换明度,而 §6.1 舞台正面目标把地台定死为世界中层承载面,随关卡变会破 §2 明度分层的层间关系。
|
||||
|
||||
**逐条判据**
|
||||
|
||||
- ←机检: 九宫格横向拉伸后顶缘受光线宽度恒为 2px(§6.1 / §8.2 既有定值断言,本节不另立值)
|
||||
- ←机检: 单张像素域色数 ≤32,且三个色值逐位等于 `#968264` / `#C9AF83` / `#4C4038`
|
||||
- ←机检: 地台绘制点取常量、不进 §4.3 `wall_ambient` tint 槽(跨三关恒定)
|
||||
- ←机检: 板身色相对亮度 L 落 [0.22, 0.45]
|
||||
- ←目检: 横向拉到站桩全宽后端头与板身无纹理接缝、无错位;横向拉伸区零纹理
|
||||
- ←方向性: 落影接地感成立(立绘双脚落石台上缘,§8.2 站桩排版条)
|
||||
|
||||
**工艺要点(⚙ 脚本绘制)**
|
||||
|
||||
1. 源 48×12 的十二行 = 1px 上描边 `#4C4038` + 2px 顶缘受光线 `#C9AF83` + 8px 板身 `#968264` + 1px 下描边 `#4C4038`;左右各 1px 描边,全周闭合。
|
||||
2. 九宫格切片:顶缘 2px 受光线**整行落进上切片**(九宫格的上下边只横向缩放、纵向不缩放),左右切片取端头纯板身段——端头与板身同为纯色,切片取值无视觉后果,取多少都行;**顶缘线绝不能落进可纵向缩放的中间段**,否则拉伸后厚度会变。
|
||||
3. 本件不参与 §6.1 的三关 tint:入包后绘制点直取 ③ 的三色常量。
|
||||
|
||||
### 5.3 组三 · 护甲类型图标三枚(3 件)
|
||||
|
||||
**三件共用字段**
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| ① 路径与命名 | `game/assets/ui/icons/ui_armor_light.png` / `ui_armor_ward.png` / `ui_armor_heavy.png`——域键 `ui`,落 `game/assets/ui/icons/`(与现役九枚状态图标同目录,asset-path-map §1);命名照 §8.3,对象键 = `armor`、变体 = 甲档键,与清单 §3.7 逐字一致 |
|
||||
| ② 尺寸档与像素网格 | 源 24×24,显示 24px = 1×;九宫格 = 否;**甲类**(§8.2 甲类 = 文本与语义件,图标在列)→ 维持严格整数倍缩放硬规则,禁非整数缩放 |
|
||||
| ③ 色板约束 | 进**语义/UI token 板**(§4.1 分层①),**占 48 额度——余量 0**(2026-10-28 用户裁:本组新增重甲冷灰 1 枚 + 5.4 组四新增卓尔浅紫灰皮 1 枚,全板余量 2 → 0,额度已用尽)。逐件取在册色(**素底明暗档已裁深档 `#282220`**,见 §5.5 缺口 2 已裁条):轻甲 = `WARM_FAINT #CDB88C`(深档下 8.08:1;原木色 `#8A5A34` 深档仅 2.72:1 不过门,按合并裁定改值、零额度)/ 魔法护甲 = 暖白 `#F0E2C8`(12.26:1,深档下本值不动)/ 重甲 = `#868C9A`(新入板,占 1 枚额度,深档下 4.65:1)。单张像素域色数 ≤32。第二道门同本节 5.1 |
|
||||
| ④ 明度带归属 | **信息面层**(§2:信息面层 = 数字 / UI 数据 / 预告 / 语义标识)——图标是语义标识,与站桩名字行同排挂载。**信息面层 L 区间维持定性、不新增区间**(§5.5 缺口 3 核实结论:执法已被 §7.2 文字 ≥4.5:1 与 §4.1 图形 ≥3:1 两条相对判据覆盖,层间序关系由 §1.4 整屏②项断言,不需要绝对区间),本节落地判据走 §4.1 图形对比 ≥3:1 |
|
||||
| ⑤ 是否程序化件 | 是 → **程序化产出即终稿**。来源照清单 §3.7:♻ 素材站通用护甲/符纹图标改色优先、⚙ 兜底程序化;♻ 件须过清单 §0 复用闸四道才入包 |
|
||||
| ⑥ 验收判据 | 见下方共用验收 + 逐件验收 |
|
||||
| ⑦ 出图操作要点 | 见逐件的来源与工艺要点 |
|
||||
|
||||
**共用验收(三件都要过)**
|
||||
|
||||
- ←机检: 源 24×24、显示 1× 整数倍(§8.2 显示档登记例外条:素材一字节禁改)
|
||||
- ←机检: 文件名逐位等于 `ui_armor_light` / `ui_armor_ward` / `ui_armor_heavy`
|
||||
- ←机检: 单张像素域色数 ≤32
|
||||
- ←机检: 三枚对其实际挂载底色的图形对比 ≥3:1(§4.1 图标槽柔和档条的图形参考线硬约束)。**挂载底色 = 站桩名字行的素底,不是舞台底也不是地台面**——站桩名字行是文字,§7.2「一切文字(含菜单/说明/tooltip/按钮/底栏,**无区域例外**)」+「文字禁直接压纹理底——垫容器或罩层」两条覆盖它;§6.1 舞台正面目标条(2026-10-28 v3.22 定值)已就站桩文字位显式落法:「站桩文字位改垫素底或落进结算明细带」,并明写「**非新条款**」,§7.2 同批加「站桩石板地台面同理」句、两处机检断言同文。舞台背景插画 `scene_stage_bg.png` 的中景两色只靠笔触与纹理分块面(5.1 ③),属纹理底,落法门触发。**故「站桩名字行落法 = 垫素底」是既有条款的落法,本节不立新条款**(§5 头注定值纪律:本节指路不立值)。素底明暗档 **2026-10-28 已裁 = 深档 `#282220`**(§7.4 血数垫牌 `HP_BAR_BACK` 在册同款,零新增;浅档 `#F5EAD3` 落选,两档对照与理据见 §5.5 缺口 2 已裁条)
|
||||
- ←机检: B 区站桩名字行与护甲图标正下方像素非地台板身色 `#968264`(§6.1 / §7.2 同文断言)
|
||||
- ←目检: 灰度下按甲面覆盖率三档可辨——无甲板 → 符纹带 → 大面积甲板(character-design §5.3 灰度通道条)
|
||||
- ←目检: 三枚互辨,身份只靠形状不靠色相(§4.5 ⑨ 图标键族:色相不承载身份)
|
||||
- ←方向性: 甲档不触 §5.1 剪影 archetype——不加肩甲外扩之类的轮廓改动,体量与凹凸计数仍由 archetype 独占承载
|
||||
|
||||
**5.3.1 轻甲 `ui_armor_light`(轻甲档)**
|
||||
|
||||
- 形状:甲面覆盖率 ≈ 0——一枚**皮条 / 布带**记号(斜跨的皮带扣或系带),主体留空,零甲板(character-design §5.3)
|
||||
- 色:**`WARM_FAINT #CDB88C`**(2026-10-28 用户裁:素底取深档后原皮革木色 `#8A5A34`〔§7.2 木色〕仅 2.72:1 不过门,按 §4.1「不过门即换色合并、禁加色绕行」并入本值——**零额度**;代价 = 暖白族非木色族,已随裁定接受)
|
||||
- **对比判据**(挂载底色 = 站桩名字行素底,2026-10-28 裁深档 `#282220`):**8.08:1 ✓**(≥3:1 图形门槛);对舞台底 `#3E362C` 6.12:1。木色族路线(新增木色亮档 `#C49A5E` 6.07:1)未取——须 +1 额度而余量已为 0
|
||||
- ←机检: 本枚对其实际挂载深素底 ≥3:1(实测 8.08:1);入板后全板色对中三通道差全部 <8/255 的对数 = 0
|
||||
- ←目检: 换色后本枚仍读作皮革/皮条,不与 5.3.2 符纹带、5.3.3 甲板在灰度下混读(character-design §5.3 灰度通道:三档按甲面覆盖率可辨)
|
||||
- 来源与工艺:♻ 素材站 belt / strap 类图标改色,过清单 §0 复用闸四道(色板量化 / 禁入带吸色 / 灰度可辨 / 授权干净);⚙ 兜底按 24×24 网格手修——3px 带宽、1px 深墨描边,不画甲板
|
||||
|
||||
**5.3.2 魔法护甲 `ui_armor_ward`(魔法护甲档)**
|
||||
|
||||
- 形状:**符纹饰带**——一条走轮廓的发光符纹带,覆盖率居中,零金属甲板(character-design §5.3)
|
||||
- 色:暖白 `#F0E2C8`(与轮廓描边同族,不占任何语义色,§5.3)
|
||||
- 来源与工艺:♻ 素材站 rune / glyph band 类图标改色 → 闸四道;⚙ 兜底 24×24 内一条横向符纹带 + 两枚符点,符点不超 3×3
|
||||
|
||||
**5.3.3 重甲 `ui_armor_heavy`(重甲档)**
|
||||
|
||||
- 形状:**金属甲板**覆盖肩与胸,覆盖率三档中最大(character-design §5.3)
|
||||
- 色:冷灰金属材质色 = **`#868C9A`**(2026-10-28 用户裁转定稿,见 §5.5 缺口 1 已裁条;新入 §4.1 分层①,占 1 枚额度)。**与 5.4.4 石君王岩石板甲是同一枚**——character-design §5.3 通道 = 甲面覆盖率 × 甲材质色,甲材质色按甲档统一,故石君王工单**直接引本枚 `#868C9A`、不另计额度**
|
||||
- **对比判据**(挂载底色 = 站桩名字行素底,2026-10-28 裁深档 `#282220`):须同时满足 §5.4 ④ 立绘体块主色带 L 0.22–0.45 与本节 ≥3:1 —— 深档窗 = **[0.220, 0.450]**;本值 L≈0.261 落窗,**对深素底 4.65:1 ✓、对舞台底 3.52:1 ✓**
|
||||
- ←机检: 本枚对其实际挂载深素底 ≥3:1(实测 4.65:1)且相对亮度 L 落 [0.220, 0.450](实测 0.261);入板后全板色对中三通道差全部 <8/255 的对数 = 0
|
||||
- ←目检: 灰度下本枚甲板覆盖率三档最大,与 5.3.1 无甲板、5.3.2 符纹带可辨(character-design §5.3 灰度通道)
|
||||
- ←方向性: 冷灰与全作暖底成材质对比(§5.3),不靠明度差与地台 `#968264`(L≈0.234)抢读——立绘与地台的可辨归 §5.1 轮廓通道
|
||||
- 来源与工艺:♻ 素材站 plate armor 肩甲/胸甲类图标改色 → 闸四道;⚙ 兜底 24×24 内肩 + 胸两块甲板,与全作暖底成材质对比(§5.3 冷灰金属与暖底对比)
|
||||
|
||||
### 5.4 组四 · 主角与三 Boss 立绘重产(4 件)
|
||||
|
||||
**四件共用字段**
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| ① 路径与命名 | `game/assets/art/character/character_hero_portrait.png` + `game/assets/art/character/character_enemy_<enemy_id>.png`(域键 `character`,对象键 = `hero` / enemy_id,命名照 §8.3 与 asset-path-map §3 现役写法) |
|
||||
| ② 尺寸档与像素网格 | **源档高逐键** = 主角 48 / ogre_chief 74 / drider 90 / duergar_king 94(§8.2 立绘源档表,逐件值见本节 5.4.1–5.4.4);**宽随源图宽高比,纵横倍率恒等**(§8.2 站桩立绘槽位 = 高定宽随条,禁把立绘塞进统一方框强拉);九宫格 = 否;显示一律 **×2 整数档** = 96 / 148 / 180 / 188;**乙类**(角色与单位精灵)——乙类允许非整数,本批按 §8.2 定案走 ×2 整数档 |
|
||||
| ③ 色板约束 | 进**语义/UI token 板**(§4.1 分层①);**48 余量 0**(2026-10-28 用户裁:本组新增卓尔浅紫灰皮 1 枚,全板余量 2 → 0,额度已用尽)。逐件沿用 character-design §5.4 / §5.5 已登记色值;该两节只给形容词未给色值的部件,**2026-10-28 用户裁已落值**——四处换色合并(零额度)+ 卓尔浅紫灰皮新增 1 枚,逐件取值见本节 5.4.1–5.4.4,额度账见 §5.5 缺口 4。**石君王岩石板甲 = 重甲甲材质色、与 §5.3.3 同一枚,工单直接引 `#868C9A`、不另计额度**。单张像素域色数 ≤32。第二道门同本节 5.1 |
|
||||
| ④ 明度带归属 | **世界中层 L 0.22–0.45**(§2 世界中层 = 格底顶面 / 角色 / 物件)——判定对象 = 角色体块主色。描边与落影底盘属轮廓通道(character-design §5.1)、紫赤点缀属 §4.2 色相独占的语义色,两者都不按明度带判定 |
|
||||
| ⑤ 是否程序化件 | 否 → **须手绘**。口径 = **精细手绘像素**(2026-10-14 用户裁:仍是像素风,手绘像素簇 + 更高源密度;不是插画、不是 HD-2D、不回退高清图);**禁 AI 降采样当终稿**。现行 AI 降采样立绘 = 占位态,按 §7.1 占位完成条款须在终稿闸前换代 |
|
||||
| ⑥ 验收判据 | 见下方共用验收 |
|
||||
| ⑦ 出图操作要点 | 见下方工艺要点(手绘,不产生图提示词) |
|
||||
|
||||
**共用验收(四件都要过)**
|
||||
|
||||
- ←机检: 源档高逐位等于 48 / 74 / 90 / 94,显示 = 源 ×2(96 / 148 / 180 / 188),过滤 = NEAREST
|
||||
- ←机检: 单张像素域色数 ≤32
|
||||
- ←机检: 脚底基线对齐(派生管线四条:等比整数缩放 + 降色 ≤32 + 脚底基线对齐 + 命名合规)
|
||||
- ←机检: 主角描边 = `(40,19,13)`;敌方描边取暖白族(非黑、非深褐)—— character-design §5.1 主角描边例外条
|
||||
- ←机检: Alpha 直出——不透明区外缘 1px 环内无生成底残留(无 R/G/B 三通道均 ≥230 且 alpha > 0 的像素),防抠图白边
|
||||
- ←机检: 零 HSV 300°–345° 像素(drider / duergar_king 两 Boss 除外,§4.2 独占)
|
||||
- ←机检: 落影底盘在位(character-design §5.1 轮廓通道)
|
||||
- ←目检: 放大 4 倍,轮廓与衣服是成组的像素,不是降采样噪点(三判据①)
|
||||
- ←目检: 显示 96–188px 下脸、铲、旗、物种能认出来,不必先读名字(三判据②)
|
||||
- ←目检: 显示仍用邻近采样,不出现插画那种平滑渐变(三判据③)
|
||||
- ←方向性: 精细手绘像素气质——不是插画、也不是半像素半高清
|
||||
|
||||
三判据出处 = `reports/美术审计-cursor会话存档-2026-10-14.md` §2.2。
|
||||
|
||||
**工艺要点(手绘)**
|
||||
|
||||
1. 出件顺序 = 先主角、再三 Boss(Alpha 范围 = 主角 + 三 Boss 重产,其余敌种当前可读则保留到 Beta)。
|
||||
2. **源密度判据 = 三判据②**:显示 96–188px 下脸、铲、旗、物种可认——照这条反推源档即可,逐键定档已完成(§8.2),本批不必再猜档位。
|
||||
3. 手绘起稿顺序 = 剪影(§5.1 archetype)→ 体块主色 → 暗部与受光 → 描边 → 落影底盘。
|
||||
4. 逐件 2–3 版候选;登记义务项 = 手绘者 / 日期 / 源档尺寸(手绘件无模型名与 seed,按此三项替换 §0 的登记项),随候选图存 `artwork/candidates/<资产名>/`。
|
||||
5. 候选评审 = 并排横评,**隐去文件名与来源后按三判据逐条判读**(§0 五步第 1 步「便于横评」的手绘侧落法),不靠记忆与印象拍板。
|
||||
6. 出件 = 透明 PNG(Alpha 直出,禁先出白底图再抠);入包前过 §8.3 色板检查器(报新增色 / 近色告警 / 超 48 上限拦截)。
|
||||
|
||||
**5.4.1 主角(源 48 / 显示 96)**
|
||||
|
||||
- 形象 = character-design §5.4 形象锚逐字执行:蓝兜帽取下披肩、暖米白上衣、深棕工装裤、额前护目镜、半指手套、卷裤脚皮护膝、圆头挖掘铲、结构式冒险背包配朱红矩形旗、腰挂提灯
|
||||
- 已登记色:兜帽 `#2E86DE` / 上衣 `#EFE3C8` / 长裤 `#6B4A2E` / 皮革 `#8A5A34` / 眼 `#33261B` / 旗 `#C63D22` / 描边 `(40,19,13)`
|
||||
- 已落值(2026-10-28 用户裁):**铲刃浅铁灰 = `FOG_MEMORY_INK #C4C4C4`**;**提灯铜色 = `GOLD_DEEP #B07A14`**——两件均走换色合并、零额度(character-design §5.4 对这两件只有形容词,账见 §5.5 缺口 4)。代价已随裁定接受:`#C4C4C4` 一色两岗(语义岗 = 迷雾记忆墨 §6.5)、`#B07A14` 属金族(§4.2 金只说收益与兑现);两者均为角色随身件材质色,不进信息层与语义物件岗
|
||||
- 破例记账:背包 + 旗 = 主角对 §5.1「对称」的唯一破例组,旗面朝向恒定画右;轮廓凹凸预算按背包 + 旗整组记账
|
||||
- 朝向:战斗画面的侧身面向怪物形象属状态图(§5.4 生成顺序口径);重产沿用现役朝向,不重新裁定
|
||||
|
||||
**5.4.2 食人魔酋长 ogre_chief(源 74 / 显示 148)**
|
||||
|
||||
- 档位 = 精英档(形状仍守精英档:普通怪形 + 恰一处垂直延伸 = 头顶骨与羽冠,底盘不变;第一关关底 Boss 战,不升 Boss 形)
|
||||
- 甲档 = 轻甲 → 甲面覆盖率 ≈ 0:皮条 / 骨饰点缀、裸身为主,零甲板零符纹
|
||||
- 主色域 = 暖褐皮、圆肚;**暖褐皮 = `暖石 #B8A582`**(2026-10-28 用户裁:换色合并、零额度;体块主色带 §5.4 ④ L 0.22–0.45 校验 L≈0.387 ✓;character-design §5.5 该行原只有形容词)
|
||||
|
||||
**5.4.3 蛛化卓尔精灵 drider(源 90 / 显示 180)**
|
||||
|
||||
- 档位 = Boss(敌类中唯一允许锐角与不对称者,体量最大)
|
||||
- 甲档 = 魔法护甲 → 符纹饰带(暖白,覆盖率居中);蛛腹几丁质属天然甲壳,不计甲档
|
||||
- 独占:紫赤 `#8F2F6A`(色相 323°)+ 形状独占双通道;全项目色相 300°–345° 只许本件与 5.4.4 出现
|
||||
- **卓尔上体浅紫灰皮 = `#A79CB8`**(2026-10-28 用户裁:**新增 1 枚**,入 §4.1 分层①——在册紫族四枚全部语义岗占用且 L <0.22,无一可复用)。体块主色带 L 0.22–0.45 校验 L≈0.355 ✓;色相 264° 避 300°–345° 禁入带,紫赤独占仍归 `#8F2F6A`。**对比实测(本节新算,此前未给值)**:对深素底 `#282220` **6.04:1**、对舞台底 `#3E362C` **4.57:1**——两处均过 §4.1 图形 ≥3:1 门槛
|
||||
- 大体档:显示 180 > 150 → 允许向上溢出盒顶(§8.2 站桩排版③ 甲案;溢出量 N 由实装批用真图复算 x 区间定,血条仍落底)
|
||||
|
||||
**5.4.4 灰矮人石君王 duergar_king(源 94 / 显示 188)**
|
||||
|
||||
- 档位 = Boss(锐角与不对称,体量最大档)
|
||||
- 甲档 = 重甲 → 金属甲板(冷灰,覆盖率最大)
|
||||
- 独占:紫赤 `#8F2F6A` + 形状独占双通道;大地 / 岩石主题
|
||||
- 岩石板甲与灰皮(2026-10-28 用户裁,character-design §5.5 该行原只有形容词):**岩石板甲 = 重甲甲材质色,与 §5.3.3 同一枚 → 直接引 `#868C9A`,不另计额度**;**灰皮 = `STONE #786E62`**(按**次级皮**口径——石君王重甲覆盖率最大、板甲视同体块主色,故灰皮属次级皮、不受 L 0.22–0.45 约束;换色合并、零额度)
|
||||
- 大体档:显示 188 > 150 → 溢出盒顶同 5.4.3
|
||||
|
||||
### 5.5 缺口(四条 · 缺口 1/2/4 于 2026-10-28 已裁转指路,缺口 3 结论已立)
|
||||
|
||||
> **核销口径(依 art-bible v3.22 现行条款)**:四条逐条先过「§4.1 在册既有色能否换色合并」——不过门即换色合并、禁加色绕行(§4.1 色板增量纪律)。**48 色余量:裁定前 2 → 2026-10-28 裁定后 0(额度已用尽)**;本节给的是「哪几枚必须新增 / 哪几枚可合并 / 合并后余量 / 全新增要压缩哪几枚」的账,**不替作者拍板**(§4.1:额度不足时呈报作者,由作者决定压缩或合并既有色)。本节所举候选色值,**缺口 1 / 2 / 4 已随 2026-10-28 用户裁落定(见各条「已裁」注,本节只留裁定依据账并指路 §5.3 / §5.4)**;其余仍为候选,落定须过 §4.1 两道门(①§4.2 语义检查;②与既有任一色 RGB 三通道差不得全部 <8/255——宽松口径)。
|
||||
|
||||
1. **重甲冷灰金属材质色——已裁(2026-10-28)= `#868C9A`**,本节转指路(原「阻塞 5.3.3 上色」状态解除——出形与上色均不再阻塞;**与 5.4.4 石君王岩石板甲同一枚**——character-design §5.3 通道 = 甲面覆盖率 × 甲材质色,甲材质色按甲档统一,两处只占一枚额度)。character-design §5.3 只写「冷灰金属材质色」;**落法见 §5.3.3(本组载值)与 §5.4.4(直接引 §5.3.3 同一枚、不另计额度),色值账见 art-bible §4.1 本枚条目**。
|
||||
- **换色合并逐枚核查——在册冷/中性灰全部不合格,无复用者**:`#3E4048` L≈0.052 / `#3F4147` L≈0.053(两者正在 §4.1 六对欠账清单内,清偿后只留一枚)/ `#3A3A3A` L≈0.042——三枚均越世界中层下沿 0.22;`#C4C4C4` L≈0.552 越上沿 0.45,且语义岗 = 迷雾记忆墨(§6.5);`#8A9AB0` L≈0.317 本落在带内,但色相 ≈215° 属蓝族,§5.4 语义约束 + §5.5「蓝族禁入敌方主色」拦;`#5A6C8C` 暮蓝为失败独占(§4.2);`#808080` L≈0.216 越下沿 0.004,且是引擎默认灰(§7.6 点名须接管,不宜作角色材质色)。
|
||||
- **归属板**:进 §4.1 **分层① 语义/UI token 板,占 48 额度**。理由:甲材质色 = 材质色、跨屏恒定,不属分层② 环境色(环境色随场景走);5.3 与 5.4 两组工单第 ③ 字段均已登记为分层①。
|
||||
- **裁定值(2026-10-28 用户裁,原候选值即本值,落定后转定稿)**:`#868C9A`(L≈0.261 / H≈222° / S≈0.13)。第二道门按宽松口径与在册色逐一比对,**无三通道全 <8 的对 → 过门**;§4.2 语义检查过门(不占红/金/蓝/紫赤/绿语义段,222° 不在 300°–345° 禁入带)。对比实测:对深素底 `#282220` 4.65:1、对舞台底 `#3E362C` 3.52:1、对浅素底 `#F5EAD3` 2.82:1(浅档已落选,不受该读数的门限约束)。
|
||||
- **风险(已随 2026-10-28 裁定接受)**:本值与地台板身 `#968264`(L≈0.234)灰度差仅 0.028、对比 1.10:1。立绘与地台的可辨归 §5.1 轮廓通道(亮描边 + 落影)与冷/暖材质对比承载,不靠明度差——§5.3 明写「冷灰与全作暖底成材质对比」;§2 只在世界底层内部立了「同层内两底难辨」的子带纪律(该条立法理由明写为解决底层内部问题),世界中层无同款要求。
|
||||
- ←机检: 本值入板后全板色对中三通道差全部 <8/255 的对数 = 0
|
||||
|
||||
2. **站桩名字行的落法 + 素底明暗档——已裁(2026-10-28)= 垫素底、素底取深档 `#282220`**,本节转指路(原记为「轻甲木色在深底上不过 3:1」;核出落法是它的前置,故先落这一条)。
|
||||
- **推导核实 = 成立,且是既有条款的落法、非新条款**:站桩名字行是文字,§7.2「一切文字(含菜单/说明/tooltip/按钮/底栏,**无区域例外**)」+「文字禁直接压纹理底——垫容器或罩层」两条覆盖它;§6.1 舞台正面目标条(2026-10-28 v3.22 定值)已就站桩文字位显式落法——「站桩文字位改垫素底或落进结算明细带」并明写「**非新条款**」,§7.2 同批加「站桩石板地台面同理」句,两处机检断言同文。舞台背景插画 `scene_stage_bg.png` 中景两色只靠笔触与纹理分块面(5.1 ③),属纹理底 → 落法门触发。**已回填**:站桩名字行落法 = **垫素底**(§5.3 共用验收条 + 5.3.1 / 5.3.3 对比判据)。
|
||||
- **原冲突 = 素底明暗档圣经未定死(2026-10-28 已由作者裁,本节不替裁的冲突至此闭合)**:§4.1 只在册浅档 `#F5EAD3`(数字色牌,圣经唯一素色牌值),§7.4 血数垫牌在用的深档 `HP_BAR_BACK #282220` 亦在册。两档后果**相反**(下表留作裁定依据账):
|
||||
|
||||
| 受影响的位 | 浅档 `#F5EAD3` | 深档 `#282220` |
|
||||
|---|---|---|
|
||||
| 站桩名字行墨(现役暖白 `#F0E2C8`) | 1.08:1 ✗ → 按 §7.2 双色墨制「亮底转深墨」改主墨 `#33261B`(12.3:1) | 12.26:1 ✓ 不动 |
|
||||
| 5.3.2 魔法甲暖白 `#F0E2C8` | 1.08:1 ✗ → 同须换深墨 | 12.26:1 ✓ 不动 |
|
||||
| 5.3.1 轻甲木色 `#8A5A34` | 4.87:1 ✓ 不动 | 2.72:1 ✗ → 须换色合并(`WARM_FAINT #CDB88C` 8.08:1,零额度)或新增木色亮档(`#C49A5E` 6.07:1,占 1 枚) |
|
||||
| 5.3.3 重甲冷灰 | 须 L ≤0.245,与 5.4 立绘体块主色带求交 → 窗 **[0.220, 0.245]**(候选 `#7E8492` L≈0.230,3.14:1) | 须 L ≥0.151 → 窗 **[0.220, 0.450]**(候选 `#868C9A` L≈0.261,4.65:1) |
|
||||
|
||||
- **裁定结论(2026-10-28 用户裁,取深档一列)**:① 站桩名字行墨(暖白 `#F0E2C8`)**不动**(12.26:1);② 5.3.2 魔法护甲暖白 `#F0E2C8` **不动**(12.26:1);③ 5.3.1 轻甲木色 → **接受换色合并 `WARM_FAINT #CDB88C`(8.08:1,零额度)**,不取新增木色亮档 `#C49A5E` 路线(须 +1 额度而余量为 0);④ 5.3.3 重甲冷灰 → 按深档窗 **[0.220, 0.450]** 落 **`#868C9A`**(4.65:1)。**素底值恒定 = `HP_BAR_BACK #282220`**(§7.4 血数垫牌同款,零新增)
|
||||
|
||||
- **推荐 = 深档 `#282220`**(四条理据)——**2026-10-28 用户采纳本推荐,裁定落深档**:① 与 §7.4 血数垫牌同款、既有素底,零新增;② 与 §4.1 在役亮档 token 同向——顺位徽标 `GOLD_BRIGHT` 对舞台底 6.47:1、魔法护甲徽标 `HERO_BLUE_BRIGHT` 5.88:1,现行徽标体系整体按暗底设计;③ 与 §7.4 v3.22 实测记录「暖白对舞台底 9.49:1 达标」不冲突,深档更暗则暖白更稳;④ 只动 5.3.1 一枚,名字行墨与 5.3.2 全部不动。**代价**:5.3.1 须换色(换色合并不需要额度,新增木色亮档要 1 枚)。**浅档的代价**:名字行墨与 5.3.2 两处换墨(零额度),但 5.3.3 被挤进 0.025 宽的窄窗,且与石君王灰皮(若亦须落 0.22–0.45)撞窗。
|
||||
- ←机检: B 区站桩名字行与护甲图标正下方像素非地台板身色 `#968264`(§6.1 / §7.2 同文断言)
|
||||
- ←目检: 名字行与三枚甲档图标同排挂载后,素底边缘与舞台底、地台轮廓不打架,不构成第二焦点(§3.4)
|
||||
|
||||
3. **信息面层 L 区间未定值**(5.3 明度带字段无区间可填):**结论 = 维持定性,不新增区间**——不为了与世界底层两子带对称而硬定一个区间。
|
||||
- 理由一:**执法已被三处既有数值判据全覆盖**——文字 ≥4.5:1(§7.2)、图形 ≥3:1(§4.1 图标槽柔和档条)、数字墨/色牌的 L 界(§4.1:亮墨 L≥0.55 / 色牌 L≥0.70 / 深墨 L≤0.027)。三者都是「对其直接背景」的**相对判据**,信息面层成员恒压在具体底上,相对判据比绝对区间更贴执法面。
|
||||
- 理由二:§1.4 整屏样张②项验的是**层间序关系**(信息面层 > 世界中层 > 世界底层),是相对断言,不需要信息面层的绝对上界。
|
||||
- 理由三:世界底层拆两子带的立法理由 = 解决**同层内**两底(舞台底 L≈0.036 与已开格底 L≈0.10)灰度难辨(§2 该条明写),信息面层**无同款实证问题**(成员尺寸与位置差异大,且有墨/牌强对比),无对称立法理由。
|
||||
- 理由四:硬定上界会误伤在册高亮档——`#F5EAD3` 色牌 L≈0.83、纯白 L=1.0 都在信息面层内,上界定死(如 0.90)会把它们拦在层外。
|
||||
- **机检断言写得出来(证明不定值也能执法)**:←机检: 屏内信息面层取样点 L > 同屏世界中层取样点 L > 同屏世界底层取样点 L(§1.4②项同口径);←机检: 信息面层成员对其直接背景,文字位 ≥4.5:1、图形位 ≥3:1(§7.2 / §4.1)
|
||||
|
||||
4. **五处角色部件色值——2026-10-28 用户裁已落值**(不阻塞开工;手绘口径下必须落值,现已落)。**逐件取值见 §5.4.1(铲刃 / 提灯)、5.4.2(食人魔皮)、5.4.3(卓尔皮)、5.4.4(石君王灰皮)**;下表留作裁定依据账,色值已逐件落定(见上),不再以「待裁」表述:
|
||||
|
||||
| 部件 | §5.4 ④ 明度带归属 | 换色合并候选(在册,零额度)**——2026-10-28 裁定采纳** | 合并代价 / 淘汰理由 | 新增候选(**未取**,裁定走合并路线) | 第二道门 |
|
||||
|---|---|---|---|---|---|
|
||||
| 主角铲刃浅铁灰 | 手持件,不属「体块主色」判定面 | `FOG_MEMORY_INK #C4C4C4`(L≈0.552,中性灰 S=0) | 一色两岗(语义岗 = 迷雾记忆墨 §6.5,与 §4.1「常量本尊不动」先例相左);若后续纳入明度带判定则越上沿 0.45 | `#A8AEB8`(L≈0.421 / H≈218° / S≈0.09) | 过门(无三通道全 <8 的对);非语义段 |
|
||||
| 主角提灯铜色 | 同上 | `GOLD_DEEP #B07A14`(L≈0.232 / H≈39°,落世界中层) | 金族语义岗(§4.2 金只说收益与兑现、禁作日常强调防通胀);与皮革木色 `#8A5A34`(L≈0.130)明度差 0.10,可辨 | `#C08A3A`(L≈0.297 / H≈36°) | 过门 |
|
||||
| 食人魔酋长暖褐皮 | **体块主色 → 须落 L 0.22–0.45** | `暖石 #B8A582`(L≈0.387 / H≈39°,在册于 theme README 溯源表) | 一色两岗(该值现为滑轨槽字面量);已排除 `#968264`(地台承载面 §6.1)、`#B39A78`/`#C9AF83`(格底语义,§5.1 剪影禁借格底成立)、`#8A5A34`(L 0.130 越下沿) | `#B08050`(L≈0.253)/ `#A97C4E`(L≈0.234) | 过门 |
|
||||
| 卓尔精灵浅紫灰皮 | **体块主色 → 须落 L 0.22–0.45** | **无可复用**:在册紫族四枚全部语义岗占用且 L <0.22——`#7C3AA8` 封印紫(退役)、`#7A4294` 妨害紫(§4.6.1 语义)、`#8A72C4` / `#7B5BD6` 类型微光族(§4.2 分域纪律:微光色相禁迁移复用为物件/阵营/UI 语义色) | — | `#A79CB8`(L≈0.355 / H≈264° / S≈0.15;避 300°–345°,紫赤独占仍归 `#8F2F6A`) | 过门 |
|
||||
| 石君王岩石板甲 | 与缺口 1 同一枚,**不另计额度** | 见缺口 1 | 见缺口 1 | 见缺口 1 | 见缺口 1 |
|
||||
| 石君王灰皮 | **口径已裁(2026-10-28)= 次级皮**:石君王重甲覆盖率最大(§5.3),板甲视同体块主色 → 灰皮属次级皮、不受 0.22–0.45 约束 | 不受约束口径下可合 `STONE #786E62`(L≈0.160 / S≈0.18 近中性暖灰) | 若按体块主色口径则 L 越下沿 0.06,不可合 | `#9A968C`(L≈0.306)/ `#949089`(L≈0.281 / S≈0.07) | 过门;两候选与地台 `#968264` 灰度差 ≥0.047 |
|
||||
|
||||
**额度账(48 余量:裁定前 2 → 2026-10-28 裁定后 0,额度已用尽)**
|
||||
- **必须新增 = 2 枚(已裁落定)**:① 重甲冷灰金属材质色(缺口 1,在册冷灰全部不合格)= **`#868C9A`**;② 卓尔浅紫灰皮(在册紫族全占岗且过暗)= **`#A79CB8`**。→ 余量 2 → **0**,额度用尽;后续新增须先压缩或合并既有色(压缩哪几枚由作者裁)。
|
||||
- **可合并 = 5 处,零额度(已裁接受)**:铲刃 → `FOG_MEMORY_INK #C4C4C4`;提灯 → `GOLD_DEEP #B07A14`;食人魔皮 → `暖石 #B8A582`;石君王灰皮 → `STONE #786E62`(按**次级皮**口径);轻甲木色 → `WARM_FAINT #CDB88C`。
|
||||
- **浮动一枚 = 5.3.1 轻甲木色(已裁)**:深档素底下**接受换色合并 `WARM_FAINT #CDB88C`**,零额度,余量不击穿;新增木色亮档 `#C49A5E` 路线未取。
|
||||
- (原「若作者选全部新增(7 枚)」一支,留作依据账):击穿 5 枚。压缩只能从既有色里腾——优先合「宽松口径下仍未清偿的在册近色对」,每合一对腾 1 枚。机检扫到的**活值**近色对(须先剔除退役值与场景环境子板成员再计数;本清单未逐枚核语义岗,合哪几对由作者裁):`GOLD_BRIGHT #E0B860 ↔ GOLD_LIT #E6BE5A`(差 6/6/6);`WARM #F0E2C8 ↔ MAP_BAR_PLATE #F0E4C8`(差 0/2/0);`RAP_DOT_CORE_WARM #F8E2A8 ↔ INK_L_GOLD #F8E3A8`(差 0/1/0);`DIGIT_PLATE #F5EAD3 ↔ CAMP_ROW_PLATE #F0E6CE`(差 5/4/5)。**注:这四对均不在 §4.1 已列六对欠账清单内**,属该清单未扫到的部分——按 §4.1 现有断言「全板色对中三通道差全部 <8/255 的对数 = 0」,它们同样在清偿范围内;是否随本批一并清偿由作者裁。
|
||||
- **本节不替作者决定压缩或合并哪几枚既有色**。
|
||||
- ←机检: 本节候选值落定后,全板色对中三通道差全部 <8/255 的对数 = 0,且板内色数 ≤48
|
||||
- ←目检: 五处部件色上稿后,灰度下铲 / 提灯 / 皮 / 甲互相可辨,不靠色相单独承载(§5.1 轮廓通道;§4.5 色弱清单)
|
||||
- ←方向性: 五处部件色服务于「随身件画得出来、认得出」(character-design §5.4 秘宝形象候选池条),不抢体块主色的读序
|
||||
|
||||
---
|
||||
|
||||
## 6. 明确不在本文件
|
||||
## 5. 明确不在本文件
|
||||
|
||||
- **意图准备动画三档、战斗演出类**:动画序列帧,等一屏样张锁动画方案后另立规格卡。
|
||||
- **格面徽章 19 枚 / 关卡节点图图标 / 砖面终稿 / 地形变异纹带**:脚本管线,规格锚 art-bible §4.6(图标键契约)、§1.4(样张验收)与 §3.2,不需要生成提示词。
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|---|---|---|
|
||||
| `character/` | 角色棋盘帧 + B 区立绘 | character_hero_idle/walk(棋盘 32×32 朝左基准)、character_hero_portrait(B 区立绘 46×48)+ character_enemy_<键> 八敌 |
|
||||
| `fx/` | 特效帧 | shovel_swing_f0/f1/f2(挥铲三帧,握把锚 (18,12)) |
|
||||
| `scene/` | **场景图**(背景层 + 可点物件层;营地场景图首批) | `scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_tent`(承载件,不可点)+ `scene_stage_bg`(B 区战斗舞台背景,✦ 插画级,只出远景+中景两带)+ `scene_stage_plaza`(B 区近景地台,48×12 九宫格件)——登记超前:营地场景图批落地前盘上未建 |
|
||||
| `scene/` | **场景图**(背景层 + 可点物件层;营地场景图首批) | `scene_camp_bg`(背景)+ `scene_camp_gate / forge / chest / notebook / dummy / board / campfire`(七个可点物件)+ `scene_camp_tent`(承载件,不可点)——登记超前:营地场景图批落地前盘上未建 |
|
||||
| `board/` | 砖面/封印印记(三关换皮 + 封印印记件) | terrain_floor_<board_type>_<n>.png(三关地面系)、seal_mark.png |
|
||||
|
||||
## 4. 坐标/朝向等工程侧约定备查
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
- **体量档位 = 生物体型通道(原「强度先验·普通 < 精英 < Boss 单调递增」读法已弃用)**:体量按**物种天性**定,禁按强度档位线性映射——小体型精英与大体型普通怪并存(锁定实例:钩爪恐魔 > 灰矮人、灰矮人 < 熊地精、食人魔酋长 > 熊地精);「大个子多半有重击」的强度先验读法改由意图徽标(§5.6)与甲档(§5.3)承担,体量不再报强度;图像不报数,精确数值只在结算明细。
|
||||
- 像素画布/精灵尺寸**不在本节**——归圣经 §8 资产规范;本节只锁比例关系与档位次序。
|
||||
|
||||
## 5.3 护甲类型视觉区分
|
||||
## 5.3 护甲类型视觉区分(候选方案,样张冻结终稿)
|
||||
|
||||
> **白话**:敌方有三种护甲类型——轻甲(light)/魔法护甲(ward)/重甲(heavy),克制博弈需要玩家从画面读出"这只怪穿什么甲";本节定三档甲怎么画。键与命名事实源 = `data/schemas/enemy_table.gd` 的 `armor_type` 枚举与 [术语表](../gdd/术语表.md)(轻甲/魔法护甲/重甲)。
|
||||
|
||||
- **通道 = 甲面覆盖率 × 甲材质色**,不触 §5.1 剪影 archetype(底盘与体量轴不动)——「重甲语义走色板不作形状独占」的落法:甲档不新增独占通道(独占 = Boss 双通道专属),装备配件画法不属独占。**本节已定稿**(候选标注注销):三档画法逐字按本节执行,甲档不触 §5.1 剪影 archetype——不加肩甲外扩之类的轮廓改动,体量与凹凸计数仍由 §5.1 archetype 独占承载。
|
||||
- **通道 = 甲面覆盖率 × 甲材质色**,不触 §5.1 剪影 archetype(底盘与体量轴不动)——「重甲语义走色板不作形状独占」的落法:甲档不新增独占通道(独占 = Boss 双通道专属),装备配件画法不属独占。
|
||||
- **轻甲 light**:甲面覆盖率≈0——皮条/布带点缀或裸露,体表以物种本色为主。
|
||||
- **魔法护甲 ward**:甲面覆**符纹饰带**——发光符纹走轮廓描边同族暖白,不占任何语义色(圣经 §4.2),覆盖率居中。
|
||||
- **重甲 heavy**:**金属甲板**覆盖肩/胸/盾沿,冷灰金属材质色(与全作暖底成材质对比),覆盖率最大。
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
## 文档状态
|
||||
|
||||
- 版本:1.24
|
||||
- 最近更新:2026-10-29(尾波清偿批设计闭合落文——「战斗编排域拆件定稿」节增补轴丙 BoardInstaller(`core/board_installer.gd`,实现批建件):装板域六函数迁出、宿主复位留薄壳、BoardGenerator 实例随件;battle_orchestrator 行 B1 域文件集句两新件→三新件随动;迭代 41 反哺注记转正文现状,沿革查 git)
|
||||
- 版本:1.22
|
||||
- 最近更新:2026-10-28(迭代 40 拆件批反哺落文——编排域拆件定稿节转现状登记:reward_economy 消费依赖改注入 Callable 口径、BattleFxHost 补 luck_bias_for 查询口、接线款补注入 Callable 款与 battle_hooks 三键回调束形态、补 RunLedger 退役后战斗域读面款、S13 豁免登记补第三条 battle_orchestrator 类变量键)
|
||||
- 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定)
|
||||
- 评审模式:solo(`review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调)
|
||||
- 覆盖 GDD:现行全集(根索引=`design/gdd/02-系统清单.md`,文档树构成以根索引为准)
|
||||
@@ -85,15 +85,15 @@
|
||||
|
||||
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|
||||
|---|---|---|---|---|
|
||||
| **ConfigDB**(autoload,D2) | 全部玩法数值表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机。**行族访问器归位各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面;表持有成员按域收进三张域容器 Resource(`config_domain_combat/run/crossrun.gd`——已建件(迭代 41),类型化成员 7/7/5);三张 resolver 表(board_gen.resolve_row/enemy.resolve_rowset/difficulty.resolve_modifiers)经 `load_tables` 装配段注入各容器,resolver 文件与键零搬移**——红线不变:本类仍是唯一加载与持有单点,"经 ConfigDB 单点读取"=经其持有的表对象 | 类型化域容器属性(每域一张容器);公开面 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload)、类变量 9 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
|
||||
| **SlotStore**(`core/slot_store.gd`,D3 存档槽位域件,已建件——迭代 41 存量债批) | 存档三槽位文件域唯一所有者(自 save_manager 收编槽位族):槽位挂载与模板、激活与建删、槽位摘要窥视(peek 族);改名覆盖原语(_rename_overwrite)留 save_manager(IO 原语单点) | 槽位读写原语族+摘要投影(公开 10/类变量 4;SaveManager 与菜单消费方经 `save.slots.` 直连) | save_manager(注入路径与模板配置);FileAccess——LOW |
|
||||
| **MetaStateStore**(`core/meta_state_store.gd`,D3 存档内元进度数据件,已建件——迭代 41 存量债批) | 存档内元进度数据的读写唯一层(自 save_manager 收编 accessor 族:钥石/道具解锁/树节点与叉侧/锻造路线/同调/真视/计数器/摘要——数据读写原语,不含业务规则);save_manager 与 meta_progression 双 God Class 的共同病根=该数据域摊在两文件,本件即其归一 | 写口原语 13+只读投影 6(tree_state/forge_state/attune_state/career_state 四投影+keystone_balance/item_unlocked)=公开 19(add_keystone 私有 `_add_keystone`),零 _data 副本零缓存;MetaProgression 业务层与营地/锻造 UI 消费方经 `save.meta_state.` 直连(meta 的纯转发读方法已退役) | save_manager(序列化接线);FileAccess——LOW |
|
||||
| **ConfigDB**(autoload,D2) | 全部玩法数值表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机。**2026-10-27 全清设计定稿:行族访问器归位各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面(≤20);表持有成员按域收进域容器 Resource(分组建档于实现卡,消费方改址随该批)**——红线不变:本类仍是唯一加载与持有单点,"经 ConfigDB 单点读取"=经其持有的表对象 | 类型化域容器属性(每域一张容器);`load_tables(root, collect_only)`;诊断门面;`set_reload_gate()`;`reload` | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
|
||||
| **SlotStore**(`core/slot_store.gd`,D3 存档槽位域件,2026-10-27 全清设计定稿——实现批建件) | 存档三槽位文件域唯一所有者(自 save_manager 收编槽位族):槽位挂载与模板、激活与建删、槽位摘要窥视(peek 族) | 槽位读写原语族+摘要投影(SaveManager 与菜单消费方直连) | save_manager(注入路径与模板配置);FileAccess——LOW |
|
||||
| **MetaStateStore**(`core/meta_state_store.gd`,D3 存档内元进度数据件,2026-10-27 全清设计定稿——实现批建件) | 存档内元进度数据的读写唯一层(自 save_manager 收编 accessor 族:钥石/道具解锁/树节点与叉侧/锻造路线/同调/真视/计数器/摘要——数据读写原语,不含业务规则);save_manager 与 meta_progression 双 God Class 的共同病根=该数据域摊在两文件,本件即其归一 | 数据读写原语族+只读投影(MetaProgression 业务层与营地/锻造 UI 消费方直连;meta 的纯转发读方法随件退役) | save_manager(序列化接线);FileAccess——LOW |
|
||||
| **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流词表现值以 `RngServiceCore.PURPOSE_TAGS` 为准;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 |
|
||||
| **action_economy**(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 意图与通知布尔面:notify_round_start / request_dig / request_stop / request_refresh / notify_settlement_done / notify_combat_end;预授权通道:grant_reserve_ap / finish_round_stop;ap/rap/phase 只读 | ConfigDB(ActionEconomyTable);effect_engine(事件发射 dispatch——基础层内同层引用);B1 回发 next_round_mode/battle_over | 无 |
|
||||
| **variation 定义**(A4) | VariationTable schema(现行 6 行:六 region——贫矿脉 global 行 2026-10-16 用户令屏蔽删行,global 型机制代码保留)与 F1 候选池门控谓词 | `variant_pool(level_index, board_type, node_type="")`(门控三维:unlock+board_types+节点身份——global 行仅 boss/elite 入池,缺省跳过零扰动);`global_variant_row(level_index, board_type, node_type)`(全局型单行决议访问器) | ConfigDB(VariationTable) | 无 |
|
||||
| **status_container**(B3) | 状态实例容器(战斗域生命周期、跨轮跨图延续) | 5 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB(StatusEffectTable) | 无(RefCounted) |
|
||||
| **effect_engine**(内容数据驱动扩展批 iter17 建域) | 零运行时可变状态的系统(见「架构原则」条 8):全同步解释器——事件由宿主在明确代码点位显式调 dispatch 进件,命中序=装载声明序(feats→treasure→树规则)写死保种子复放,不是事件总线/事件循环;事件/事实/效果类型/算子四词表封闭 + 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·adv_ 前缀走冒险桶跨战斗持久) | rebuild(每战重建订阅表)/`dispatch(ctx, event, payload, facts)`/`validate_trigger_row` + 静态计数口 `counter`·`counter_add`·`counter_spend`·`bucket_of`·`counter_id_legal`(计数器读写只经 EffectContext 引用束,无导出/灌入接口) | ConfigDB(feats/treasure 行集)、EffectContext(四桶引用由宿主持有:round/battle 桶归编排器、level 桶归关卡域、adventure 桶归应用层——RunLedger 已随迭代 39 拆件批退役,桶字典由 adventure_runner 持有) | 无(零随机全确定) |
|
||||
| **save_system**(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | (契约规范源:`../../gdd/systems/表现与支撑/存档序列化.md`——契约锚:SAVE_FORMAT_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW |
|
||||
| **save_system**(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | (契约规范源:`../../gdd/systems/表现与支撑/存档序列化.md`——契约锚:SCHEMA_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW |
|
||||
| **settings/localization**(D6,愿景) | 设置项、翻译数据 | (契约规范源:`../../gdd/systems/表现与支撑/设置与本地化.md`) | ConfigDB | 无 |
|
||||
|
||||
### 核心层
|
||||
@@ -101,7 +101,7 @@
|
||||
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|
||||
|---|---|---|---|---|
|
||||
| **board_generator**(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、生成期指标集、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version);生成姿态 = MVP 同步生成 + 加载幕(切片实证 10×10/12×12 同步可接受,WorkerThread 留扩展) | `generate(L, D, rng) -> Board`;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) | ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 |
|
||||
| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);查询只读面(current_board / hero_pos / is_revealed / has_seal 等);`compute_move_path(cell)` 只读;`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end(迭代 41 由属性改方法)/ 相位 | 无(零表读取、零 UI——切片实证) |
|
||||
| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);查询只读面(current_board / hero_pos / is_revealed / has_seal 等);`compute_move_path(cell)` 只读;`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end / 相位 | 无(零表读取、零 UI——切片实证) |
|
||||
| **unit_container**(B2) | hero/enemy 单位实例(hp/atk/实例池:池快照+冷却+摇定动作+保底计数)、行值快照 | spawn / query_alive / rollable_skills / special_skills / check_trigger_unlocks / set_pending_action / pending_action / basic_streak / commit_action / tick_cooldowns / apply_damage / heal / default_target / check_skill_unlocks / despawn_all(2026-09-16 敌人技能池批:query_beat/query_attack/advance 随行为环退役;rollable_skills/special_skills/check_trigger_unlocks 带 facts 参——2026-10-27 情境条件触发器实装,事实缺键=条件假拦下,百分比事实走阈值式折算) | ConfigDB(EnemyTable/SkillTable/HeroTable) | 无 |
|
||||
| **reward_economy**(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影 | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / phase / weighted_pick;另有 is_mapped 静默布尔投影(批量工具用) | ConfigDB(RewardTable);BattleFxHost 经注入 Callable `luck_bias_query` 取偏运合计(reward_roll 发射与 bias_rewards 求和移至效果层完成);reward_roll 流(scope = 每次 install 批) | 无 |
|
||||
| **helper_items**(A5,切片已实装秘宝域) | HelperItemTable、探测显影语义 | (契约规范源:`../../gdd/systems/跨局循环/秘宝.md`——桥接位:A2 查询接口 + A4 counter_item_ids) | A2 / A4 / B4 | 无 |
|
||||
@@ -115,16 +115,15 @@
|
||||
|
||||
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|
||||
|---|---|---|---|---|
|
||||
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主面与树规则挂点施加面(**已拆出 BattleFxHost 并实装(2026-10-28 迭代 40——battle_fx_host.gd/reward_grant.gd 两件在库,效果引擎宿主面归 BattleFxHost 行承载,拆件细则见「战斗编排域拆件定稿」节)**) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller + 拆件后三新件**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
|
||||
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主面与树规则挂点施加面(**已拆出 BattleFxHost 并实装(2026-10-28 迭代 40——battle_fx_host.gd/reward_grant.gd 两件在库,效果引擎宿主面归 BattleFxHost 行承载,拆件细则见「战斗编排域拆件定稿」节)**) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller + 拆件后两新件**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
|
||||
| **BattleFxHost**(`core/battle_fx_host.gd`,B1 域·效果引擎宿主件,2026-10-26 编排域拆件设计定稿——实现批建件) | 效果引擎挂点施加面唯一承载(自 battle_orchestrator 收编 fx 族):事件发射与事实判定(_fx_emit/_fx_fact)、主角 AC 基线与本轮/本战 AC 累积、bonus_delta 四轴累积(战末宿主 drain 汇入账本)、揭示待兑队列与兑付(含 _fx_revealing 再入闸——同步信号回环防二次缓冲二次兑付)、树规则合成订阅的 round/battle 桶计数器持有(桶随编排器生灭语义不变) | 构造=引用束注入(防 _init max-parameters 新键);bind 时注入 emit Callable(行发射经宿主协议面单点)与兑付 Callable(RewardGrant 授予面——揭示队列 flush 回调);只读投影分两类消费方:AC 累积/bonus_delta 供宿主呈现快照与战末 drain,揭示态供宿主 A2 订阅旁路判定;`luck_bias_for(cell_count) -> int` 偏运合计查询口(体内三参形 dispatch——reward_roll 发射与 bias_rewards 求和自 RewardEconomy 收回本件,RewardEconomy 经注入 Callable 消费) | EffectEngine(EffectContext 引用束);RngServiceCore(fx_reveal 封闭流——除该流外零随机);A2 minesweeper(板读与 fx_reveal 调用);A3 action_economy(queue_ap_delta/charge_layers 读);B3 status_container 读;B2 unit_container 读(hp_ratio);DamageController(set_hero_ac_override);ConfigDB;encounter 引用 | 无(零 await——效果引擎全同步解释器) |
|
||||
| **RewardGrant**(`core/reward_grant.gd`,B1 域·奖励授予件,2026-10-26 编排域拆件设计定稿——实现批建件) | 奖励授予唯一兑付管线(自 battle_orchestrator 收编 grant 族):极性字典路由与封印溢价兑付(_grant_routed)、三种行应用(flat/percent/gp)、伤害单据提交面(_submit 族)、清图奖励与身份授予、秘宝使用编排(use_treasure 四步)、战斗域 GP 缓冲 escrow 与授予段暂存伤害闸(_defer_board_damage/_deferred_board) | use_treasure 编排入口(treasure_interact_controller 经组合根现值回调直连);授予入口(结算段类直调);只读投影(escrow 读与 GP 掉落合计——宿主呈现快照与 _roll_gp_drop 消费) | B4 RewardEconomy(polarity_row/grant);B1 域 DamageController(开单);BattleFxHost 引用(treasure_used 事件发射与计数器消耗);A2 minesweeper(校验回调/fx_reveal/remove_mines_in);A3 action_economy(相位闸/grant_ap/queue_ap_delta);B3 status_container(apply_effect/池读);B2 unit_container(hero_unit/heal);ConfigDB;注入 emit Callable、宿主 fatal Callable(battle_result 状态机唯一写点留宿主)、宿主 attune 读投影(_attune_safe_seen)、encounter 账本引用;TreasureItems 经宿主 setter 转发注入(库存注入时序在宿主构造之后) | 无(零随机零 await——授予期零随机口径,roll 值授予前已定) |
|
||||
| **damage_controller**(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规) | 兑付入口(编排侧开单)+ fx 揭示回调注入位 | B2 单位实例(单据目标传入);B1 注入(EffectContext 引用束与编排回调) | 无 |
|
||||
| **BoardInstaller**(`core/board_installer.gd`,B1 域·装板域件,2026-10-29 尾波清偿批设计闭合——实现批建件,细则见「战斗编排域拆件定稿」节轴丙) | 棋盘安装与变异布置域唯一承载(自 battle_orchestrator 收编装板族六函数):生成受理、全局作用域变异决议、资源摇号资格域组装(roll_board 恰一次)、region 变异决议与连通片布置;BoardGenerator 实例随件自建自接线(宿主成员退役)——宿主侧装板后状态复位(封印/完美计数清零、板序推进、board_changed 发射、秘宝叠加层退役)留宿主薄壳,时序逐字保持 | `install(during_round) -> bool` 单入口;构造=引用束注入(rng/db/minesweeper/reward_economy/encounter 只读引用+宿主 fatal Callable——防 _init max-parameters 新键) | A1 board_generator(件内持有);A2 install_board;B4 roll_board/board_skew 写;A4 变异决议行集经 ConfigDB;board_gen/variant_place 两封闭流随件、流名与开流时点零漂移 | 无(零 await——装板全同步) |
|
||||
| **settlement/ 五段段类**(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);可直接 `new()` 单测 | B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 |
|
||||
| **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1(直构 BattleOrchestrator 接线战斗)、ConfigDB LevelTable | 无 |
|
||||
| **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 |
|
||||
| **difficulty**(C3) | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表(切片 monte_carlo 为工具原型) | 调参输出(经 D2 R1 解析/编排器传递,禁反向调用生成) | ConfigDB、B1 对账输出(调参约束清单)、A1 报告 C | 无 |
|
||||
| **meta_progression**(C4,Alpha) | MetaTable、钥石账本、天赋树域(MetaTreeTable 12 节点 v0.8——Fork 一节点双态/row 字段退役/RULE_KEYS 六键/彩蛋特化觉醒,迭代 21 T1 换代)+ 同调位槽位判定(树点亮数单源——T4 槽位收编)。**存档内元进度数据读写原语归 MetaStateStore——已落地(迭代 41):本类纯转发读已退役(消费方直连 meta_state),业务规则与写口编排留本类;hero_override 内联锻造加值与树淬炼 flat;并组三组(forge_select(kind,route_id)/hero_type_axes()→{attack,armor}/tree_camp_status()→{rows,fork_groups});补 meta_state 成员装配** | 公开面 20 定稿:buy_treasure_unlock / refresh_treasure_unlocks / treasure_shop_status / forge_buy_level / forge_buy_unlock / forge_select / hero_type_axes / forge_shop_status / settle_adventure / hero_override / tree_can_buy / tree_buy / tree_toggle_fork / tree_buy_fork / tree_rule_keys / tree_camp_status / toggle_attunement / attune_camp_status / attune_refresh_charges / buy_attune_refresh | D3、C2、ConfigDB | 无 |
|
||||
| **meta_progression**(C4,Alpha) | MetaTable、钥石账本、天赋树域(MetaTreeTable 12 节点 v0.8——Fork 一节点双态/row 字段退役/RULE_KEYS 六键/彩蛋特化觉醒,迭代 21 T1 换代)+ 同调位槽位判定(树点亮数单源——T4 槽位收编)。**2026-10-27 全清设计定稿:存档内元进度数据读写原语归 MetaStateStore(新件),本类纯转发读方法随件退役(消费方直连 store),业务规则与写口编排留本类(≤20)** | tree_can_buy/tree_buy/tree_buy_fork/tree_toggle_fork(写口唯一)、hero_override 注入(树淬炼 flat+锻造路线加值位预留 0)、tree_rule_keys | D3、C2、ConfigDB | 无 |
|
||||
|
||||
### 战斗域装配现状(迭代 27——2026-10-17 用户裁写入;RunLedger 段已随迭代 39 拆件批退役,四账去向见下「冒险域拆分(现状登记)」节)
|
||||
|
||||
@@ -133,7 +132,6 @@
|
||||
### 战斗编排域拆件定稿(2026-10-26 用户裁写入——gdstyle 存量债波 1 设计闭合;同日独立审查(grilling+godot-master 双子代理)阻断 8 条去重 6 组全折入本节,v1.18;2026-10-28 迭代 40 实现批合回(合并提交 514457d1),本节为现状登记)
|
||||
|
||||
- **轴甲两件**:battle_orchestrator(1313 行/50 成员,S13 全库单文件最大户)按变化原因拆出 BattleFxHost(效果引擎宿主域)与 RewardGrant(奖励授予域)两协作件;宿主保留架构在册职责全部——战斗状态机与生命周期、轮 facts 缓冲(_facts_reveals/seals/path)、A2 三事件订阅、结算五段驱动、attune 族原位、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影(presentation/diagnostic_snapshot 唯一出口不变)、刷新面、nest_preview_count(巢穴预告读数口——外部直读面 main.gd 与 treasure_effects_test 随批点名冻结)。拆件动机与残留债口径见待办清单「gdstyle 存量债全量清偿」条目。
|
||||
- **轴丙一件(2026-10-29 尾波清偿批设计闭合——实现批建件)**:battle_orchestrator 装板域六函数(`_install_new_board`/`_resolve_global_variant`/`_place_variants`/`_place_variants_apply`/`_variants_fringe`/`_adjacent_to_packs`,约 140 行;全仓仅宿主三调用点——begin_battle/中途刷新受理/player_request_refresh,实查零外部调用)按变化原因拆出 BoardInstaller,职责语句「棋盘安装与变异布置域」(生成→全局变异决议→装板受理→资源摇号→变异布置;单一变化原因=棋盘设置顺序与变异布置算法)。形态两修正(实测裁,与初案「逐字搬运」之差):①宿主复位块不随件——`_install_new_board` 体内五处计数清零、板序推进、board_changed 发射与秘宝叠加层退役留宿主薄壳 `_install_and_reset`,三调用点改调薄壳、时序逐字;②`_board_generator` 全文件仅装板族使用——实例随件自建自接线(fatal 经注入 Callable),宿主成员退役(类变量 38→37,禁无效成员义务)。encounter(23 处跨宿主)与 _reward_economy(18 处)确认留宿主、经引用束注入。文件长键(1035/1000)随本件迁出归绿;attune 族与 begin_battle 受理段序禁动不变。
|
||||
- **跨件单向接线**:RewardGrant 持 BattleFxHost 引用(treasure_used 事件发射与计数器消耗);BattleFxHost 对授予面走 bind 时注入的兑付 Callable(揭示队列 flush 回调)——禁双向强引用(两件均 RefCounted,环引用随每战新建泄漏)。行发射经 bind 时注入的 emit Callable(协议面单点留宿主——CurioDeck bind_handlers 同款先例,禁件回调宿主私有族);轮 facts 缓冲留宿主、fx 件经注入取值;_seal_consumed 留宿主(与 A2 seal_judged 订阅同域);fatal 经注入 Callable 转宿主 _fatal(battle_result 状态机唯一写点不变)。注入 Callable 亦属接线面、同单向纪律——禁为省参数改持对象引用。授予件对账本零强引用:战斗期消费经 `battle_hooks` 三键回调束(attune_consume/vision_add/negative_blast,bind_battle 缺键 assert),宿主侧三单点记账(2026-10-28 迭代 40 合并适配实装——RunLedger 类已随迭代 39 退役,直持对象引用无处可指)。
|
||||
- **战斗域读面(RunLedger 退役后)**:账本读经编排器 `_journal()`/`_attune_loadout()` 现值派生(GainJournal/AttuneLoadout,enc 派生、无成员接收);冒险桶经 `enc["adv_bucket"]` 下传 `battle_fx_host.mount_buckets`;战末 bonus 四轴经 `GainJournal.gain_bonus` 汇入(2026-10-27 迭代 39 主角账三件落地、迭代 40 合并适配承接)。
|
||||
- **settlement/ 段类随动**:段类构造注入直持宿主+两新件三引用(Middle Man 禁令封转发壳——调用点改指),授予段读写面点名:_grant_routed×5/_submit×6/escrow 写/_fx_new_resource_types/_feat_first_dig_used/_fx_bonus_delta 写/_apply_ac_bonus/_fx_enqueue_reveal/_flush_pending_reveals/_grant_clear_reward/counters_ctx;战斗段 _defer_board_damage 复位与 _deferred_board 结账改指 RewardGrant。四个授予段 helper(_feat_yield_adjust/_harmful_variants/_harmful_adjacent/_hits_of)与 _pool_effective/perfect_sweep_earned 留宿主(段类经宿主引用直调,现状形态)。
|
||||
@@ -141,7 +139,7 @@
|
||||
- **呈现零变化**:两快照出口签名与载荷逐字不变,内部改读两件只读投影(快照本体不读揭示态——揭示态投影消费方=宿主 A2 订阅旁路判定);treasure_interact_controller 三触点分家——use_treasure 经组合根现值回调改注 RewardGrant(每战新建编排器,禁一次性直引防悬挂),minesweeper 读与 attune_convert_state 仍走宿主取值回调(双取值面);nest_preview_count 直读面零变化。
|
||||
- **S13 键账收敛义务**:12 个超标键随函数迁入新文件=基线外 NEW(use_treasure 长度/分支/局部/返回×4、_grant_routed 参数 8、_dispatch_row 参数 6、_apply_percent_row 参数 6、_apply_gp_row 参数 6、_apply_flat_row 参数 7+返回 9、_submit_flat_hero 参数 7、_fx_fact 返回 7)——卡内同步收敛为本波义务(_grant_routed 等签名随引用束注入改形、use_treasure 体拆分),禁波 0 合并 refresh 吸收新文件未还键;新件 _init 引用束注入防 max-parameters 新键。
|
||||
- **验收红线**:游戏行为零变化(RNG 消费序零漂移——fx_reveal 封闭流随件迁移取号序不变、信号顺序契约冻结、明细行协议词表零触碰、同种子逐位一致);battle_orchestrator 头注发射点指址随拆件改写(词表不动,指址须真);行数恶化债清偿义务(迭代 38 特批带红合并挂账 c4c69701——本波还债归绿);PARITY 触面(battle_orchestrator.gd 被改)实跑对拍须经用户批准、不得借机重锚;S13 改善非清零口径(宿主残留 8–10 键+随迁键卡内收敛后新件零残留为达标线)。
|
||||
- **S7/S8 随动**:RewardGrant 调 B4 API,两新件一并登记进 S7 B1 域文件集与 S8 结算路径 await 文件集(static_scan.sh 两清单独立、同批更新——防 await 面漏闸);轴丙 BoardInstaller 同规(调 B4 roll_board,实现批随批增行)。
|
||||
- **S7/S8 随动**:RewardGrant 调 B4 API,两新件一并登记进 S7 B1 域文件集与 S8 结算路径 await 文件集(static_scan.sh 两清单独立、同批更新——防 await 面漏闸)。
|
||||
|
||||
### 冒险域拆分(现状登记——2026-10-26 设计闭合,2026-10-27 迭代 39 拆件批实装,本节各条即现行形态)
|
||||
|
||||
@@ -348,7 +346,7 @@ D1 ◀──呈现数据源:A2 事件流 / B1 步骤流 / A3 ap-rap / ConfigDB
|
||||
### 3. 存档/读档路径
|
||||
|
||||
- 存档系统已实装:格式、三槽位、断点域与迁移链的现行契约以 `design/gdd/systems/表现与支撑/存档序列化.md`(owner)为准。
|
||||
- RNG 快照契约(现行仍成立):断点续玩回填 = master_seed + 各流 scope 计数器;快照切出须发生在无正在执行中的 open_stream 实例时(scope 事件边界外——B1 编排保证:切点 = board install 边界);SAVE_FORMAT_VERSION 高版本拒读。
|
||||
- RNG 快照契约(现行仍成立):断点续玩回填 = master_seed + 各流 scope 计数器;快照切出须发生在无正在执行中的 open_stream 实例时(scope 事件边界外——B1 编排保证:切点 = board install 边界);SCHEMA_VERSION 高版本拒读。
|
||||
|
||||
### 4. 打包与字体(CJK 随包发行)
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
## 3. 测试纪律
|
||||
|
||||
已独立成文:`design/engineering/test-conventions.md`(探针标配 / 回归断言 / 提交前验证 / 验收清单落码规范)。
|
||||
已独立成文:`design/engineering/test-conventions.md`(探针标配 / 回归断言 / 提交前全量验证 / 验收清单落码规范)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -67,10 +67,8 @@
|
||||
| 一页纸节点 | 一节、一条规则 ≤一页纸(约 ≤80 行);装不下就拆节 |
|
||||
| 一系统一文档 | 不建 analysis 推演件;两三句能说清的"为什么"直接写进设计目的或规则正文 |
|
||||
| 正文只写现行规则 | 禁删除线、"(作废)"、"(日期+拍板)"式注记;审计信息入对应文档附录 |
|
||||
| 禁实现内容 | 系统文档与概念文档全文禁写实现细节——代码路径(`.gd`/`.py`/`.sh` 与运行时文件路径)、测试文件名、断言名、类名/方法名/信号名/常量名/调试与遥测入口名、提交号一律不出现;唯一例外=数据索引(`game/data/tables/*.tres` 这类表路径与表名、表字段名与表内枚值、存档键、封闭词表标签)。实现事实归 `architecture.md`;验收标准只写玩家或系统可观测面。本行由文档域闸的能力审计机检两个可判死的面(带后缀路径、反引号调用形态),其余靠写卡段人工核对;闸件清单与域划分的唯一出处=`tools/run_all_gates.sh` 头部 |
|
||||
| 正文单点维护 | 一条规则句只写在定义它的那份文档(owner 文档);其他文档要引用时写指针或语义概括,禁复制色值、尺寸、路径等可核对的具体值——上一句管不住数值之外的双写,本句补上。豁免面 = 执行侧文件必须带字面值才能工作时(生图提示词里的十六进制色、脚本参数),转写不算双写,但该文件头部必须写明"冲突时以 owner 文档为准" |
|
||||
| 禁写变更记录 | 文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁逐版本叙述「改了哪些条款」;沿革与改动明细只进 git commit log。版本号可作为文档现行身份标记出现在文首状态行与正文引用中,但不得再挂变更表 |
|
||||
| 后置 ≠ 删除 | P1/P2 后置内容逐条列出;复活后置项 = 修订文档,禁静默加回 |
|
||||
| 禁写变更记录 | 文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁逐版本叙述「改了哪些条款」;沿革与改动明细只进 git commit log。版本号可作为文档现行身份标记出现在文首状态行与正文引用中,但不得再挂变更表 || 后置 ≠ 删除 | P1/P2 后置内容逐条列出;复活后置项 = 修订文档,禁静默加回 |
|
||||
| 活体清单不冻结计数 | 对会生长的清单(文档树构成、UI 层项、RNG 流词表等)不写死计数与枚举——写指针到 owner(根索引/常量表/实现文件),现状值由 owner 承载;历史计数只进 git 提交信息 |
|
||||
|
||||
**数值纪律**:正文定规则、取值域、单位;平衡值进 `data/tables/`,provisional 必须标注;已锁数值事实源 = `game/data/tables/*.tres`(现行值)与 owner 文档正文(规则、取值域、单位)。
|
||||
@@ -98,7 +96,7 @@
|
||||
| `待办清单.md`(仓库根) | 流水线唯一登记处:条目=登记元数据标题+四属性正文,状态随流水线段推进(格式与状态机见第 12.1 节);各系统文档「待办」节只留指路存根 |
|
||||
| `roadmap.md`(根目录) | 里程碑表+迭代总表,一行一迭代,记录编排与实现进度(六列格式见第 12.2 节) |
|
||||
|
||||
**系统文档骨架**(`systems/` 下统一采用):文首引言(一句话定位+状态)/设计目的(2-4 句白话)/系统范围(负责/不负责两表)/在核心循环中的位置(字符画一行+两句白话)/核心规则(领域章节 ×2–6,每节一页纸)/依赖与输出(表格;引用纪律见 concept-conventions)/P0 最小闭环与 P1·P2 后置/调参表(取值域+provisional 标注)/验收标准(玩家或系统可观测的判据,禁实现细节)/待办(指路存根)。
|
||||
**系统文档骨架**(`systems/` 下统一采用):文首引言(一句话定位+状态)/设计目的(2-4 句白话)/系统范围(负责/不负责两表)/在核心循环中的位置(字符画一行+两句白话)/核心规则(领域章节 ×2–6,每节一页纸)/依赖与输出(表格;引用纪律见 concept-conventions)/P0 最小闭环与 P1·P2 后置/调参表(取值域+provisional 标注)/验收标准(可验证判据)/待办(指路存根)。
|
||||
|
||||
**命名**:中文、见名知意;禁 a1_/b1_ 编号前缀;不留纯空目录。正文指代子系统一律用中文规范名;英文代号对照表见 `02-系统清单.md`,旧代号(a1–d6)仅限解读归档。
|
||||
|
||||
|
||||
@@ -48,10 +48,10 @@
|
||||
7. **验收改动先行声明**——验收变化(基线换代/探针增改/旧断言改判)预先写进需求卡片,禁事后补
|
||||
|
||||
**完成**
|
||||
8. **批末按域验收才合并(worktree 批;直改车道无批末动作,验收在 commit 点由 git 钩子执行,见 §1 第 3 条)**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:按文件性质判——代码面=`game/` 下非 `.md` 的行为载体(代码、测试脚本、探针、场景、数据表、素材)→ `--code`;文档件=`game/` 内 `.md`(README、生成清单)与 `game/` 外一切路径(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;两类同批都有 → 全量档不带参数。代码域按**关联档选测**(2026-10-29 用户裁):02 单元与集成只跑「需求卡片申报 ∪ diff 推导」并集的套件——申报=在册需求卡片对照表「验收测试」列提到的测试文件名,推导=闸脚本内套件族映射表按改动文件归族;改动命中公共件/数据表/autoload/数值·存档·RNG·结算触面或映射不到 → 横切回落全部套件;00 冒烟/01 系统测试/09 静态扫描三件保险恒跑不降;03/04 探针与 05 渲染闸维持影响面口径(本批 game/ 改动全在测量面 game/tests、game/sim 时记 SKIP)。所选域全绿即可合回 master,全量回归由用户自发发起(合入后无自动兜底)。合回前独立验收审计通过(iter 技能第 5 步),未过不合回。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分(含选闸算法与套件族映射表)**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain`、`scope`(full|related,02 跑子集=related)与 `dirty_game` 字段),合回时由 worktree-guard 按 diff 文件性质推域强制校验(六况拦截:缺回执/quick 模式/回执未覆盖分支尖=回执 commit 之后代码面又有改动、或跑闸时代码面带着未提交改动(`dirty_game`)/域不覆盖本次改动/含新增红/master HEAD 非回执 commit 祖先=合并将产出未测内容;guard 只验域覆盖与全绿,不复核选套件清单)。回执与分支尖的对齐判据是**代码面**不是 commit 号:回执之后只追加文档件(`game/` 内 `.md`、`reports/`、`design/` 等)提交,回执照样有效,不构成复跑理由。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时人工确认闸可跑通且判据口径未变,闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底
|
||||
8. **批末按域验收才合并(worktree 批;直改车道无批末动作,验收在 commit 点由 git 钩子执行,见 §1 第 3 条)**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:按文件性质判——代码面=`game/` 下非 `.md` 的行为载体(代码、测试脚本、探针、场景、数据表、素材)→ `--code`;文档件=`game/` 内 `.md`(README、生成清单)与 `game/` 外一切路径(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;两类同批都有 → 全量档不带参数。所选域全绿才合回 master。合回前独立验收审计通过(iter 技能第 5 步),未过不合回。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 与 `dirty_game` 字段),合回时由 worktree-guard 按 diff 文件性质推域强制校验(六况拦截:缺回执/quick 模式/回执未覆盖分支尖=回执 commit 之后代码面又有改动、或跑闸时代码面带着未提交改动(`dirty_game`)/域不覆盖本次改动/含新增红/master HEAD 非回执 commit 祖先=合并将产出未测内容)。回执与分支尖的对齐判据是**代码面**不是 commit 号:回执之后只追加文档件(`game/` 内 `.md`、`reports/`、`design/` 等)提交,回执照样有效,不构成复跑理由。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时人工确认闸可跑通且判据口径未变,闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底
|
||||
9. **合并后主区零复跑**(2026-10-24 用户裁:合回重跑验的是与回执同一份字节,零信息)——合回落地后 code 批只做两件秒级事:`--editor --quit` 重刷类名缓存(在册坑:.godot 缓存不入 git,与合并后代码失配会假红假绿)+冒烟启动确认可开机(合计约 1 分钟);docs 批零动作。全量验证**每批跑一次**=worktree 批末按域闸,顺序是「先并入 master、再跑闸」(§1 第 2 条);只有两种情形允许把这次跑作废重来——① 闸红且修法动了 `game/`,② 闸已开跑后 master 又被推进(合并将产出未测内容,由合回闸祖先判定拦下,§3.9 第六况)。「跑都跑了再跑一遍保险」「闸后顺手改点 `game/` 再补一跑」都不构成复跑理由;master 上永不跑全量
|
||||
10. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进待办清单条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`/`待办清单.md`/`体验验证清单.md`)实现批禁写,见 §12
|
||||
11. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,**另禁写 `game/tests/README.md`(能力清单,归写卡段维护,test-conventions §8.9)**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务+实现决定记录——超白名单/超卡片明列范围事项逐条记「决了什么/为什么/代价/撤销方式」,全部按卡执行时只写一行「零拍板」)、GDD 反哺点清单 `reports/iter<N>-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由工程/文档设计改动批(直改类)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归工程/文档设计改动批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与待办清单;需求卡片必列「关联文档同步面」按两层标注
|
||||
11. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务+实现决定记录——超白名单/超卡片明列范围事项逐条记「决了什么/为什么/代价/撤销方式」,全部按卡执行时只写一行「零拍板」)、GDD 反哺点清单 `reports/iter<N>-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由工程/文档设计改动批(直改类)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归工程/文档设计改动批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与待办清单;需求卡片必列「关联文档同步面」按两层标注
|
||||
12. **实机目检归用户,只登记不阻塞**——真人检测项登记进实现报告目检总清单与体验验证清单即完成批内义务;禁把等目检当停工理由或完成前置
|
||||
13. **中间产物吸收即死**——细则见 AGENTS.md 硬性红线与 doc-conventions 第 11 节
|
||||
14. **改动级验收闭合**——写卡期列需求侧对照表,实现期补实际对照表(测试文件:行),每个行为改动的验收断言从真实入口进入、在当轮真实跑批中执行并通过(判据绑定面口径=test-conventions §8.4;禁变异类测试与撤销类取证,2026-10-24/28 用户两裁);合回前独立验收审计。细则=test-conventions §8
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
每个缺陷修复必须在探针或冒烟中留下能抓住该缺陷的断言(例:封印动作耗尽 AP → 必须进入第 2 轮;
|
||||
选用道具 → 库存态必须变 Used)。没有回归断言的修复视为未完成。
|
||||
|
||||
## 4. 提交前验证
|
||||
## 4. 提交前全量验证
|
||||
|
||||
交付前跑 `tools/run_all_gates.sh`(不带 `--quick`),按改动域选档、所选域全绿——该脚本是全部验证闸的唯一入口与唯一清单,域划分与选闸算法只写在脚本里,本文禁另列闸件清单。闸件增减只改脚本。代码域按**关联档选测**(2026-10-29 用户裁):02 单元与集成只跑「需求卡片申报 ∪ diff 推导」并集的套件,00 冒烟/01 系统测试/09 静态扫描三件保险恒跑不降,横切面改动(公共件/数据表/autoload/数值·存档·RNG·结算触面)回落全部套件;所选域全绿即可合回,全量回归由用户自发发起(合入后无自动兜底)。
|
||||
交付前跑 `tools/run_all_gates.sh`(不带 `--quick`)全绿——该脚本是全部验证闸的唯一入口与唯一清单,本文禁另列闸件清单。闸件增减只改脚本。
|
||||
行为探针使用随机化玩家行为(封印/停手/刷新/无效点击)——自动玩家不做的动作就是测试盲区。
|
||||
|
||||
## 5. 测试函数怎么写——验收清单条目的落码规范
|
||||
@@ -97,7 +97,7 @@
|
||||
- **反向**:diff 里每个行为改动至少一行;没有对应行的改动,必须写明「非行为改动」或「由第 X 行覆盖」。
|
||||
- **测试侧**:新增或改写的每条断言至少挂一行;挂不上的孤儿断言删掉或补挂到需求点。
|
||||
|
||||
**能力清单维护锚(2026-10-29 用户裁改版定稿)**:`game/tests/README.md`「能力清单」是**实现指导+阅读导航+义务声明**——只宣布「要验证什么」,不记「是否已验证/是否跑过」;落地账归现行验收闭合链(改动—验收对照表逐条挂断言+合回前独立验收审计),本清单不承载验证状态。表为四列:能力|系统|真实入口|代表用例(`文件:函数`)。**维护归写卡段,当场入表**:写需求卡片时,本批新增能力当场写入能力行——真实入口取自设计文档已定的入口,代表用例=卡里定死的计划测试(`文件:函数`);受影响存量行(入口/用例名变更)同批更新;能力退役删行。**实现照单落名**:测试函数名以清单为唯一依据,名实不符=卡片没写清=停卡退回。**收尾核对**:批末收尾只核对表上名字与实际落地一致(改名则回表),不刷任何批次字段;实现批禁写该文件的现行红线不变(process-conventions §3 第 11 条),核对义务归收尾提交。三层模型见 §8.9。改动—验收对照表纪律不变:新增或改写的每条断言仍须挂一行(上文「测试侧」);断言改判仍受 §8.4 真实入口口径约束。
|
||||
**能力清单维护锚(2026-10-28 用户裁,验证与清单体系整改阶段 1;阶段 2 后定稿)**:逐断言账本 `game/tests/验证集清单.md` 已随阶段 2「存量断言精简」完成退役——冻结对账基准(基点 `b9260138`/1587 条)与精简对账结果(33 站点并为 7、1587→1561,合回 `87d241c1`)留 git 历史。覆盖索引由 `game/tests/README.md`「能力清单 v1」唯一承担:每行一个能力,给真实入口与 2–3 个代表用例(`文件:函数`)。维护义务——**每批收口核对本批受影响能力行**:代表用例可 grep、在本批真实跑批中执行、真实入口未绕过改动点,并刷新「最后验证批次」;新增能力加行,能力退役删行。改动—验收对照表纪律不变:新增或改写的每条断言仍须挂一行(上文「测试侧」);断言改判仍受 §8.4 真实入口口径约束。
|
||||
|
||||
### 8.4 真实入口断言(验收闭合的主判据)
|
||||
|
||||
@@ -129,26 +129,3 @@
|
||||
### 8.8 生效与旧卡
|
||||
|
||||
本规自 2026-10-21 起对文件名日期不早于该日的需求卡片生效;旧卡不回头改。旧卡在开工前缺对照表的,由写卡段补,补完再开工。
|
||||
|
||||
### 8.9 三层模型(验收意图·义务清单·执行证据,2026-10-29 定稿)
|
||||
|
||||
验收体系分三层,各层各管一件事,互不代行:
|
||||
|
||||
| 层 | 载体 | 切分轴 | 一行是什么 |
|
||||
|---|---|---|---|
|
||||
| 验收意图 | 系统文档「验收标准」节 | 按 owner 文档 | 一条玩家或系统可观测的判据 |
|
||||
| 义务清单 | `game/tests/README.md`「能力清单」 | 按玩家旅程与系统归属 | 一条待验证义务:能力+真实入口+代表用例(`文件:函数`) |
|
||||
| 执行证据 | 测试套件断言 | 按代码归属 | 一条从真实入口进入的断言 |
|
||||
|
||||
四条法则:
|
||||
|
||||
1. **每格非空**:每个系统文档有验收标准节;每个能力行有真实入口与至少一个代表用例;每条断言挂在某个需求点或能力行上。
|
||||
2. **每条断言有归属**:孤儿断言删掉或补挂;不建无归属断言。
|
||||
3. **数量不守恒、承接守恒**:三层条数天然不等——一条验收意图可由多个能力承接,一条能力义务由多条断言覆盖。要守的是两个满射:每条验收意图至少有一条能力义务承接,每条能力义务至少有一条真实入口断言落地。数量对账只在批内做,见第 4 条。
|
||||
4. **无全局对账总账**:不建逐断言账本,不做跨层条数对账;对账只在每批的改动—验收对照表里做(§8.3)。历史教训:阶段 2 退役的逐断言账本正因把义务清单层与证据层压成一本账而失修。
|
||||
|
||||
**维护时序(2026-10-29 改版:废「滞后一个迭代」)**:能力清单归写卡段维护——写需求卡片时当场入表:本批新增能力当场增行(真实入口取自设计文档已定的入口,代表用例=卡内定死的计划测试 `文件:函数`),受影响存量行(入口/用例名变更)同批更新,能力退役删行;实现批禁写该文件(process-conventions §3 第 11 条)。实现照单落名:测试函数名以清单为唯一依据,名实不符=卡片没写清=停卡退回。批末收尾只核对表上名字与实际落地一致(改名则回表),不刷任何批次字段——清单不记「是否已验证/是否跑过」,落地账在改动—验收对照表(§8.3)与独立验收审计(§8.7)。
|
||||
|
||||
**文档纯度**:验收意图与能力描述只写玩家或系统可观测面,禁写代码路径(`.gd`/`.py`/`.sh`)、测试文件名、断言名;唯一例外=配置文件索引(`game/data/tables/*.tres` 这类表路径与表名)。规则正文见 doc-conventions §5「禁实现内容」。
|
||||
|
||||
**机器闸**:本节的结构由文档域闸「能力审计」机检——GDD 纯度(同款禁实现内容口径)、系统文档验收标准节非空、能力行四列与非空、代表用例(`文件:函数`)与真实入口可核(双通道:代码在或卡在——计划中的用例与入口由需求卡片锚定)、覆盖域表与能力行对得上;红项按新增红处理。闸件清单与域划分的唯一出处=`tools/run_all_gates.sh` 头部。
|
||||
@@ -59,4 +59,4 @@
|
||||
|
||||
注意:上表六件秘宝为旧目录,已全数退役、只作素材库(新现行事实源=[秘宝](systems/跨局循环/秘宝.md)「目录(重设计 v1)」节——新目录 15 件为代号制、正式命名归用户);新目录正式命名定稿后本表同步。
|
||||
|
||||
另:元进度系统资源定名**钥石**——每一层关底 Boss 看守他那块区域的钥石,击杀即取走,用于在存档内解锁永久提升(属性 / 怪物遭遇 / 道具池)。2026-09-14 用户拍板,登记册术语登记随元进度设计批补登。
|
||||
另:元进度系统资源定名**钥石**——每一层关底 Boss 看守他那块区域的钥石,击杀即取走,用于在存档内解锁永久提升(属性 / 怪物遭遇 / 道具池)。2026-09-14 用户拍板,registry 术语登记随元进度设计批补登。
|
||||
@@ -15,7 +15,7 @@
|
||||
| `术语表.md` | 全库专用术语的唯一对照表——危险格/安全格/同调位/RAP/GP/真视等定义+退役词对照(2026-10-11 建立,v1.23) |
|
||||
| `待办清单.md`(仓库根,不属本树) | 全项目待办事项的唯一登记处;各系统文档的「待办」节只留指路存根 |
|
||||
| `体验验证清单.md`(仓库根,不属本树) | 需要真人试玩观测的验证项登记处(与待办清单分工:待办清单是"要拍板的事",本篇是"要玩过才知道的事");每条注明结论回流路径 |
|
||||
| `08-Alpha版本标准.md` | Alpha 版本包含哪些东西的清单——里程碑 M3 的完成标准;只列条目不写内容,定义一律指路各权威文档(**已定稿 v1.20**,2026-10-13) |
|
||||
| `08-Alpha版本标准.md` | Alpha 版本包含哪些东西的清单——里程碑 M3 的完成标准;只列条目不写内容,定义一律指路各权威文档(**已定稿 v1.19**,2026-10-13) |
|
||||
|
||||
## systems/ 五个循环
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **一句话定位**:本文定义这个项目的 **Alpha 版本包含哪些东西**——它是里程碑 M3 的完成标准,也是判断"还差什么"的对照表。
|
||||
> **本文只列条目,不写内容**:每样东西是什么、规则怎么走,一律归各自的权威文档,本文只给指路链接。想知道某样东西的定义,请点链接,不要在本文里找解释。
|
||||
> **状态**:**已定稿(v1.20)**——2026-10-13 用户令定稿,历次升版明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。
|
||||
> **状态**:**已定稿(v1.19)**——2026-10-13 用户令定稿,历次升版明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。
|
||||
> **成文**:2026-10-13。
|
||||
|
||||
## 本文怎么用
|
||||
@@ -110,14 +110,14 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
| 战斗屏 | [battle](ux/battle.md) | 在役 |
|
||||
| 战斗结算总结框 | [settlement-summary](ux/settlement-summary.md) | 在役 |
|
||||
| 关卡结算屏 | [level-clear](ux/level-clear.md) | 在役 |
|
||||
| 三选一(奖励节点 / 关卡完成) | [node-reward](ux/node-reward.md) | 在役(两渠道均三选一停点:关卡完成与奖励节点各停一次,奖励节点经兑付拉起开三选一) |
|
||||
| 三选一(奖励节点 / 关卡完成) | [node-reward](ux/node-reward.md) | 在役(两渠道均三选一停点:关卡完成与奖励节点各停一次,奖励节点经 present_node_curio 拉起兑付) |
|
||||
| 商店 | [shop](ux/shop.md) | 在役 |
|
||||
| 状态面板(局内) | [元进度](systems/跨局循环/元进度.md)(「解锁界面:双入口框架」节) | 在役 |
|
||||
| 冒险终局面板 | —— | 在役 |
|
||||
| 图例面板 | —— | 在役 |
|
||||
| 设置面 | [设置与本地化](systems/表现与支撑/设置与本地化.md) | 在役 |
|
||||
| 调试浮窗 | —— | 在役 |
|
||||
| UI 全局主题资源(引擎原生控件接管皮肤) | —— | 在役(迭代 25 · 2026-10-13 入库:主题资源(theme 主资源)挂 gui/theme/custom) |
|
||||
| UI 全局主题资源(引擎原生控件接管皮肤) | —— | 在役(迭代 25 · 2026-10-13 入库:game/assets/theme/main_theme.tres 挂 gui/theme/custom) |
|
||||
| UI 按钮状态矩阵(悬停 / 按下 / 禁用 / 键盘焦点补齐) | [待办清单](../../待办清单.md) | 在役(迭代 26 入库:五态矩阵逐实例 override 补齐——悬停 modulate 提亮/禁用 α0.45 幽灵化/焦点 INK 2px 内缩 1px 环/危险钮本族按压态;键盘导航批量面归 Beta「棋盘战斗键盘/手柄输入」条连带点③) |
|
||||
|
||||
---
|
||||
@@ -128,11 +128,11 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战
|
||||
|---|---|---|
|
||||
| 存档与版本迁移 | [存档序列化](systems/表现与支撑/存档序列化.md) | 在役 |
|
||||
| 冒险中断续玩断点 | [存档序列化](systems/表现与支撑/存档序列化.md) | 在役 |
|
||||
| 冒烟套件 | ——(清单唯一出处=process-conventions 运行与验证节) | 在役 |
|
||||
| 单元测试套件 | ——(清单唯一出处=process-conventions 运行与验证节) | 在役 |
|
||||
| 界面探针 | ——(闸件清单唯一出处=process-conventions 运行与验证节) | 在役 |
|
||||
| 渲染闸(截图与黄金图比对) | ——(闸件清单唯一出处=process-conventions 运行与验证节) | 在役 |
|
||||
| 机器可读的呈现断言(对比度 / 结构) | ——(清单唯一出处=process-conventions 运行与验证节) | 在役 |
|
||||
| 冒烟套件 | `game/tests/` | 在役 |
|
||||
| 单元测试套件 | `game/tests/` | 在役 |
|
||||
| 界面探针 | `tools/probe_gate.sh` | 在役 |
|
||||
| 渲染闸(截图与黄金图比对) | `tools/render_gate.sh` | 在役 |
|
||||
| 机器可读的呈现断言(对比度 / 结构) | `game/tests/` | 在役 |
|
||||
| 分辨率两档(1280×800 / 1920×1080) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役 |
|
||||
| 绘制调用数达标 | —— | 在役 |
|
||||
| 真人试玩轮次 | [体验验证清单](../../体验验证清单.md) | 在役(义务维持;当前轮次未清:㉚/㉛ 未核销,迭代 34 三条目检项待登记) |
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
| 不合格产出禁止进玩法 | 产出不过产出规格即无效,无效图绝不上给玩家 |
|
||||
| 无兜底图 | 不设固定兜底图——软回退一律禁止 |
|
||||
| 参数无解即中止 | 参数档本身给不出合法图=配置错误,致命中止 |
|
||||
| 同种子同图 | 同种子+同参数档产出同一张图;随机只经统一随机流服务 |
|
||||
| 同种子同图 | 同种子+同参数档产出同一张图;随机只经 RngService 统一流 |
|
||||
|
||||
### 生成参数:五个旋钮与三套关卡参数档
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
## 调参表
|
||||
|
||||
数值事实源=data/tables(定值批落表);本表只留取值域与设计意图。
|
||||
数值事实源=game/data/tables(定值批落表);本表只留取值域与设计意图。
|
||||
|
||||
| 参数 | 取值域 | 设计意图 | 状态 |
|
||||
|---|---|---|---|
|
||||
|
||||
@@ -123,7 +123,7 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选
|
||||
|
||||
第二关的"新内容 = 既有池新技能"(技能池构成已定稿入[敌人系统](../战斗循环/敌人系统.md)技能池节)投放时,改的是战斗侧行里引用的技能池内容——节点图结构原样不动,本文无需为投放留任何新结构位。
|
||||
|
||||
**节点奖励 = 提升三选一(迭代 10 追加批——用户 2026-10-01 拍板:与通关三选一共享同池)**:奖励节点到达即开三选一(呈现 = 提升三选一覆盖层共用面,spec:[node-reward.md](../../ux/node-reward.md) v2.0)——从提升池七种(攻击/生命上限/护甲/GP 袋/行动点件/恢复件/刷新件)按同一令牌库洗牌不放回抽 3(同 kind 去重、同一封闭随机流),玩家点选一件兑付(选中踢池、未选回池;秘宝件已随迭代 11 第①批出池,满位替换子交互随之不再触发)。件获取次数计数与令牌库为冒险级单例——两渠道同一令牌库合计消耗。原「秘宝投放渠道三选一」(迭代 7 拍板②丙过渡形态)顺带退役;秘宝局外同调件形态已随同调实施批落地(迭代 11 第①批;原提案 §9 已退役)。「池空直通」为合法态——池耗即枯竭,空库 = 零候选合法态直通(见[冒险结构](冒险结构.md)令牌池节)。
|
||||
**节点奖励 = 提升三选一(迭代 10 追加批——用户 2026-10-01 拍板:与通关三选一共享同池)**:奖励节点到达即开三选一(呈现 = 提升三选一覆盖层共用面,spec:[node-reward.md](../../ux/node-reward.md) v2.0)——从提升池七种(攻击/生命上限/护甲/GP 袋/行动点件/恢复件/刷新件)按同一令牌库洗牌不放回抽 3(同 kind 去重、同 reward_pick 封闭流),玩家点选一件兑付(选中踢池、未选回池;秘宝件已随迭代 11 第①批出池,满位替换子交互随之不再触发)。件获取次数计数与令牌库为冒险级单例——两渠道同一令牌库合计消耗。原「秘宝投放渠道三选一」(迭代 7 拍板②丙过渡形态)顺带退役;秘宝局外同调件形态已随同调实施批落地(迭代 11 第①批;原提案 §9,git 57da58c 已退役)。「池空直通」为合法态——池耗即枯竭,空库 = 零候选合法态直通(见[冒险结构](冒险结构.md)令牌池节)。
|
||||
|
||||
### 关卡收束点:先清库、后宣布
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 冒险结构
|
||||
|
||||
> 一句话:整局冒险的关卡序列、失败与大奖励
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.3
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -142,17 +142,17 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜
|
||||
|
||||
| 收支口 | 方向 | 规则 |
|
||||
|---|---|---|
|
||||
| 战斗完成 | 入 | 每完成一场战斗统一到账一次:金额 = 掉落掷定 + 关级掉落加值 + 本战战斗内缓冲,随战斗结束信号携带的掉落额一笔入账 |
|
||||
| 战斗完成 | 入 | 每完成一场战斗统一到账一次:金额 = 掉落掷定 + 关级掉落加值 + 本战战斗内缓冲,随战斗结束信号携带的 gp_dropped 一笔入账 |
|
||||
| 商店购买 | 出 | 商店房购买按现行价扣减钱包,余额不足拒绝。价格公式(**v0.13 换代——pool 模式现行**):ceil(基价 × b^(关序−1) × A^(本次进店已购次数)),A=店内递增/b=跨关递增表因子(provisional 1.8/1.1),ceil 向上单一取整(玩家不利向,杜绝「差 1 GP 反复钓」套利角);legacy 固定三件模式(shop=off 对照承载)沿用旧式 = 基价 + 关级价格加成 + 步长 × 已购档数 |
|
||||
| 冒险收束 | 清零 | 完成 / 失败 / 放弃三种结局都清零;重开后钱包从零开始 |
|
||||
|
||||
**战斗内缓冲隔离**:战斗进行中从格面兑付拿到的 GP(GP 袋正向、破财负向——字典归[地图战斗资源](../战斗循环/地图战斗资源.md))不直接进钱包,而是记入战斗域的中间态缓冲;战斗完成时缓冲随掉落掷定与关级加值一并折进掉落额统一到账。钱包只在战斗边界变动,战斗域自身零钱包状态——这条隔离让战斗结算保持"折算归我、GP 归冒险结构"的既有边界。
|
||||
**战斗内缓冲隔离**:战斗进行中从格面兑付拿到的 GP(GP 袋正向、破财负向——字典归[地图战斗资源](../战斗循环/地图战斗资源.md))不直接进钱包,而是记入战斗域的中间态缓冲;战斗完成时缓冲随掉落掷定与关级加值一并折进 gp_dropped 统一到账。钱包只在战斗边界变动,战斗域自身零钱包状态——这条隔离让战斗结算保持"折算归我、GP 归冒险结构"的既有边界。
|
||||
|
||||
**统一冒险加算区**:商店购买的属性提升与奖励节点三选一的属性件记**同一笔**——加算区四轴 {攻击, 生命上限, 护甲等级, 行动点},入战参数 = 基础表值 + 加算区累加,经战斗开始入参的覆盖值通道生效(与生命的上参同一条通道)。购买生命上限时:pool 模式(v0.13——货架件=奖励件本体)只加上限不回当前生命(与三选一件同语义);legacy 模式当前生命与上限同步 +Δ(生命的连带写入口)。属性轴累加源 = 商店购买与奖励节点三选一属性件两类;行动点轴累加源 = 奖励节点三选一 AP 件与商店 AP 件两类(每场战斗开始的首轮行动点基线 +1,语义细节归[行动经济](../排雷循环/行动经济.md)跨冒险加成轴节;~~全冒险获取次数上限最紧 provisional 2 次~~——v0.14 次数上限退役,池消耗即上限,pool 模式下商店购买与三选一共用令牌库,见下)。
|
||||
|
||||
掉落掷定消费 gp_drop 封闭随机流(主种子派生、可回放)。**商店货架抽签消费 shop_draw 封闭随机流**(v0.13 扩签——每次抽 3〔进店+每次买后重抽〕恰一 scope,与三选一抽签分签防取数序互扰)。掉落与价格的现行行值读商店表,数值所有权归[难度曲线与Boss](难度曲线与Boss.md)曲线调参批——本批骨架先行,全部数值 provisional。
|
||||
掉落掷定消费 gp_drop 封闭随机流(主种子派生、可回放)。**商店货架抽签消费 shop_draw 封闭随机流**(v0.13 扩签——每次抽 3〔进店+每次买后重抽〕恰一 scope,与 reward_pick 分签防取数序互扰)。掉落与价格的现行行值读商店表,数值所有权归[难度曲线与Boss](难度曲线与Boss.md)曲线调参批——本批骨架先行,全部数值 provisional。
|
||||
|
||||
**共享池账本(v0.13 P1 共享池单点;v0.14 令牌库换代;迭代 20 案D 四级 104 张——池机制事实源=[奇物](奇物.md)「池结构与抽取」节)**:商店货架与奖励节点三选一是**同一个池**——货架候选 = 池∖{GP 袋, 刷新件}∪{凭证} = {攻击, 生命上限, 护甲, 行动点, 回复, 凭证} 六种(GP 袋计价物不自售切边、刷新件不上货架、秘宝件已随同调批出池;凭证与回复随迭代15② 入架——shop.tres pool_shelf 六行);**库存 = 剩余令牌数**(TP0——「池消耗即上限」,种类次数上限退役,与奖励兑付摘牌同一令牌库承载,全冒险一次性跨关卡不补给):商店买一件,奖励面就少一枚;「无限购买」收敛为**钱尽或池空为止**(池空=硬闸、A 链爬价=软闸),空货架合法态。货架 = **令牌级抽签**(同 kind 去重每 kind 至多一卡,价格公式 tier-blind 维持批②裁定,购买消费在架令牌本体 kind+tier)。禁止两渠道各自私记库存——消费走同一入口写同一令牌库(令牌多重集单点:池与判定归该单点持有,各 kind 的派生计数与断点附随件同在这一点上承载)。**货架独立刷新(v0.15 MC-1 2026-10-04——P-C2+Q2 裁)**:进店免费刷新次数(基础 0,天赋/营地侧增益位预留)用尽后 GP 付费刷新(ceil(20×1.8^已付费刷) provisional——调参表旋钮 shop_refresh_*);重抽=共享池抽签(shop_draw 恰一新 scope),池空=不可刷新合法态;进店/离开双向清零付费刷计数。**三选一同款付费档(v0.16 2026-10-06 用户令——刷新对齐商店)**:三选一免费双源(刷新件与冒险池两笔,机制现行事实源=[秘宝](../跨局循环/秘宝.md)三选一刷新双源节)用尽后 GP 付费刷新——读同 shop_refresh_* 两旋钮(单点调参)、扣同一 GP 冒险账本(同一扣账入口)、重抽同三选一共享池抽签;付费刷计数每停点清零(与进店清零同构);钮常驻选择态、免费与付费两源皆穷=禁用。
|
||||
**共享池账本(v0.13 P1 共享池单点;v0.14 令牌库换代;迭代 20 案D 四级 104 张——池机制事实源=[奇物](奇物.md)「池结构与抽取」节)**:商店货架与奖励节点三选一是**同一个池**——货架候选 = 池∖{GP 袋, 刷新件}∪{凭证} = {攻击, 生命上限, 护甲, 行动点, 回复, 凭证} 六种(GP 袋计价物不自售切边、刷新件不上货架、秘宝件已随同调批出池;凭证与回复随迭代15② 入架——shop.tres pool_shelf 六行);**库存 = 剩余令牌数**(TP0——「池消耗即上限」,种类次数上限退役,与奖励兑付摘牌同一令牌库承载,全冒险一次性跨关卡不补给):商店买一件,奖励面就少一枚;「无限购买」收敛为**钱尽或池空为止**(池空=硬闸、A 链爬价=软闸),空货架合法态。货架 = **令牌级抽签**(同 kind 去重每 kind 至多一卡,价格公式 tier-blind 维持批②裁定,购买消费在架令牌本体 kind+tier)。禁止两渠道各自私记库存——消费走同一入口写同一令牌库(实现=CurioDeck 件(`core/curio_deck.gd`)的令牌多重集单点——池与判定归件,AdventureRunner 为宿主构造与持有、停点编排留宿主;商店货架/定价/购买/刷新归 ShopSession 件(`core/shop_session.gd`),外部调用面由 LevelRunner 同签名委托承载;kind 维度派生计数 taken(件内成员)承载断点附随件与读数)。**货架独立刷新(v0.15 MC-1 2026-10-04——P-C2+Q2 裁)**:进店免费刷新次数(基础 0,天赋/营地侧增益位预留)用尽后 GP 付费刷新(ceil(20×1.8^已付费刷) provisional——调参表旋钮 shop_refresh_*);重抽=同 pool_draw 共享池抽签(shop_draw 恰一新 scope),池空=不可刷新合法态;进店/离开双向清零付费刷计数。**三选一同款付费档(v0.16 2026-10-06 用户令——刷新对齐商店)**:三选一免费双源(刷新件 X/冒险池 Y,机制现行事实源=[秘宝](../跨局循环/秘宝.md)三选一刷新双源节)用尽后 GP 付费刷新——读同 shop_refresh_* 两旋钮(单点调参)、扣同一 GP 冒险账本(LevelRunner.spend_gp 单口)、重抽同 reward_pick 共享池抽签;付费刷计数每停点清零(与进店清零同构);钮常驻选择态、免费与付费两源皆穷=禁用。
|
||||
|
||||
### 关卡大奖励:关卡完成回血 + 专长三选一(钥石退役出大奖励)
|
||||
|
||||
@@ -168,9 +168,9 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜
|
||||
|
||||
兑付次序:部分回血先行(按当刻生命与上限结算),随后呈现三选一**选择停点**——零自动推进,必须玩家点选才兑付,重复兑付被拒(结算受理只算一次语义同族)。选择停点可中断:断点附随件扩「奖励选择态 + 件获取次数计数」,续玩已选件不静默丢失;**候选逐位一致系停点快照承载的实现现状、非验收义务**(不一致不影响玩法——2026-10-01 用户裁决,见「冒险断点」节)。
|
||||
|
||||
**奖励节点三选一池(结构层——池机制事实源=[奇物](奇物.md)「池结构与抽取」节,2026-10-11 迭代 20 案D 换代)**:池 = 四级令牌库(案D——普通打底/优秀·稀有做翼/传说惊喜位空集;曝光槽 = 三选一 2 格全池 + 1 格优秀档以上子池,令牌 = 出现次数上限、概率与已拿上限解耦;构成数字与抽取细节全读[奇物](奇物.md)与 `adventure.tres`,provisional 归[难度曲线与Boss](难度曲线与Boss.md)曲线调参批,本节零复制)。**池为冒险级单例**(迭代 10 追加批):关卡内奖励节点的三选一与商店货架共享同一令牌库(同库同摘牌),库存 = 剩余令牌数;消费三选一封闭随机流(主种子派生、[数据配置](../表现与支撑/数据配置.md)口径),同种子同操作序列同三选项可复放;**MC 策略 316-f**:自动游玩 1 级优先度=最稀有(rarest>rare>common)、2 级=最左。断点附随件承载池余库逐枚还原;兑付语义归[关卡节点地图](关卡节点地图.md)。
|
||||
**奖励节点三选一池(结构层——池机制事实源=[奇物](奇物.md)「池结构与抽取」节,2026-10-11 迭代 20 案D 换代)**:池 = 四级令牌库(案D——普通打底/优秀·稀有做翼/传说惊喜位空集;曝光槽 = 三选一 2 格全池 + 1 格优秀档以上子池,令牌 = 出现次数上限、概率与已拿上限解耦;构成数字与抽取细节全读[奇物](奇物.md)与 `adventure.tres`,provisional 归[难度曲线与Boss](难度曲线与Boss.md)曲线调参批,本节零复制)。**池为冒险级单例**(迭代 10 追加批):关卡内奖励节点的三选一与商店货架共享同一令牌库(同库同摘牌),库存 = 剩余令牌数;消费 reward_pick 封闭随机流(主种子派生、[数据配置](../表现与支撑/数据配置.md)口径),同种子同操作序列同三选项可复放;**MC 策略 316-f**:autoplay 1 级优先度=最稀有(rarest>rare>common)、2 级=最左。断点附随件承载池余库逐枚还原;兑付语义归[关卡节点地图](关卡节点地图.md)。
|
||||
|
||||
**秘宝件受同调位约束**(2026-10-09 注:道具件已随迭代 11 第①批 T7 出池——三选一/奖励节点/战斗内渠道现行零道具件投放,下述渠道约束与替换交互无现役触发面,保留作渠道恢复时的契约口径;同调位读数现行事实源=attunement_growth.tres 谓词表实时求值):道具持有上限 = 同调位数。读数源 = 同调位里程碑谓词表 attunement_growth.tres 实时求值(0 起步、硬上限 3、增长 = 通关次数 + Boss 击杀数——同调实施批 2026-10-03 落地,过渡读数源已顺带退役;原提案八拍板已退役)。获取渠道约束形态(迭代 10 过渡承载):三选一道具件超位触发**替换交互**(现有件与新件 N+1 选 N——丢任一原有件腾位收新,或放弃新件不获取;终态恒 ≤ 同调位);奖励节点与战斗内渠道超位**不授予**(候选拒绝 + 掉落沉没,逐行归因留痕)——停点渠道全覆盖的替换交互随同调实施批统一完成(原待办清单条目已随完成移除)。
|
||||
**秘宝件受同调位约束**(2026-10-09 注:道具件已随迭代 11 第①批 T7 出池——三选一/奖励节点/战斗内渠道现行零道具件投放,下述渠道约束与替换交互无现役触发面,保留作渠道恢复时的契约口径;同调位读数现行事实源=attunement_growth.tres 谓词表实时求值):道具持有上限 = 同调位数。读数源 = 同调位里程碑谓词表 attunement_growth.tres 实时求值(0 起步、硬上限 3、增长 = 通关次数 + Boss 击杀数——同调实施批 2026-10-03 落地,过渡读数源 transitional_sync_slots 已顺带退役;原提案八拍板 git 57da58c 已退役)。获取渠道约束形态(迭代 10 过渡承载):三选一道具件超位触发**替换交互**(现有件与新件 N+1 选 N——丢任一原有件腾位收新,或放弃新件不获取;终态恒 ≤ 同调位);奖励节点与战斗内渠道超位**不授予**(候选拒绝 + 掉落沉没,逐行归因留痕)——停点渠道全覆盖的替换交互随同调实施批统一完成(原待办清单条目已随完成移除)。
|
||||
|
||||
末关完成不发三选一与部分回血:没有下一战可受益——只做冒险完成结算,末关 Boss 钥石照常入账。设计意图:清库之后才兑付、末关不兑付,都是从「奖励只朝下一战生效」这一条推出来的。
|
||||
|
||||
@@ -233,7 +233,7 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜
|
||||
|---|---|---|
|
||||
| 上游 | [难度曲线与Boss](难度曲线与Boss.md) | 逐关关卡完成率带是序列难度排布的输入;三关序列均已生效(地精洞窟→幽暗地域→灰矮人矿城),无未落前置;大奖励与恢复点数值的联动复验归它 |
|
||||
| 上游 | [数据配置](../表现与支撑/数据配置.md) | 关卡表与冒险表(单行全局)的承载与统一读取,本文是两表的内容与回填责任方;主种子的注入入口(随机服务) |
|
||||
| 上游 | [战斗结算](../战斗循环/战斗结算.md) | 主角战斗入参覆盖值通道(本文供生命与上限);关卡收束接口由关卡节点地图收束点调用,本文零直调;战后生命终值与本战 GP 掉落(掉落额)经上报读回 |
|
||||
| 上游 | [战斗结算](../战斗循环/战斗结算.md) | 主角战斗入参覆盖值通道(本文供生命与上限);关卡收束接口由关卡节点地图收束点调用,本文零直调;战后生命终值与本战 GP 掉落(gp_dropped)经上报读回 |
|
||||
| 下游 | [关卡节点地图](关卡节点地图.md) | 接口契约四件套 + 收束点语义,本文是定义源,也是其文档的强制输入 |
|
||||
| 下游 | [元进度](../跨局循环/元进度.md) | 冒险摘要承载钥石入账合计(元进度是消费方);冒险开始参数面预留(未来跨局加成在此注入,MVP 空参数) |
|
||||
| 下游 | [存档序列化](../表现与支撑/存档序列化.md) | 快照契约域单位 = 冒险(主种子 + 随机流计数器);摘要含主种子供复盘;断点域 `breakpoint` 内容 owner = 本文(迭代 8 卡①——七字段+附随件,见「冒险断点」节) |
|
||||
@@ -258,16 +258,16 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜
|
||||
|
||||
## 调参表
|
||||
|
||||
全部数值存配置表、经统一读取口读入,代码里零数值字面量;表本体与读取机制归[数据配置](../表现与支撑/数据配置.md)。已锁字段以关卡表与冒险表的字段声明及对应表行为准。
|
||||
全部数值存配置表、经统一读取口读入,代码里零数值字面量;表本体与读取机制归[数据配置](../表现与支撑/数据配置.md)。已锁字段以 `data/schemas/level_table.gd`/`adventure_table.gd` 声明与对应 `.tres` 行值为准。
|
||||
|
||||
| 参数 | 域 | 现行值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 关卡行集(关数与图的参数档) | 关卡表逐关行 | 三关现行(图由生成器按参数档产出,见[关卡节点图生成](关卡节点图生成.md)) | 加关 = 内容批(参数档 + 敌我数值 + 新元素同批);确定性 = 固定种子+固定参数档(首局教学与存档复现的固定图由此承载,无兜底模板) |
|
||||
| 恢复比例 | int [0,100],逐关行 | 见 level.tres rest_heal_pct(provisional) | 恢复点回复生效上限的百分比;随上限加成同步放大;100 = 恢复点变全满泉,0 = 死节点 |
|
||||
| 上限提升 | int [0,999],冒险表逐件列 | adventure_table value_segment.curio_value_attack/max_hp/armor_{common,excellent}(provisional) | 三选一属性件各自兑付值;值锚与上调约束归难度曲线与Boss |
|
||||
| 三选一件值(其余) | int [0,999],冒险表 kind×tier 列族 | adventure_table value_segment.curio_value_*(GP 袋 / AP 件 / 恢复 / 刷新,provisional) | 令牌件值读表;道具件授予件数随秘宝件出池退役 |
|
||||
| 上限提升 | int [0,999],冒险表逐件列 | adventure_table bonus_attack_flat / bonus_max_hp_flat / bonus_armor_flat(provisional) | 三选一属性件各自兑付值;值锚与上调约束归难度曲线与Boss |
|
||||
| 三选一件值(其余) | int [0,999],冒险表 kind×tier 列族 | adventure_table curio_value_*(GP 袋 / AP 件 / 恢复 / 刷新,provisional) | 令牌件值读表;道具件授予件数随秘宝件出池退役 |
|
||||
| ~~三选一权重~~(v0.14 退役——令牌池档位配额即分布、无独立权重 knob) | — | — | E-S 加权洗牌不放回抽样权重随 TP0 令牌池换代退役 |
|
||||
| 件次数上限 | ~~int [0,99],冒险表逐件键~~(v0.14 退役——池消耗即上限) | adventure_table quota_segment.curio_quota_*(TP0 令牌池——kind×tier 配额) | 达上限件先剔出牌库永不再现 → 池耗即枯竭 |
|
||||
| 件次数上限 | ~~int [0,99],冒险表逐件键~~(v0.14 退役——池消耗即上限) | adventure_table token_* 配额列族(TP0 令牌池——kind×tier 配额) | 达上限件先剔出牌库永不再现 → 池耗即枯竭 |
|
||||
| 关卡完成回血比例 | int [0,100],冒险表单行全局 | adventure_table clear_heal_pct(provisional 20) | 关卡完成部分回血回复生效上限的百分比;封顶上限不回满 |
|
||||
| ~~同调位过渡键~~(已退役——迭代 11 第①批 T7,过渡键随表退役) | — | 同调位读数源 = attunement_growth.tres 谓词表实时求值(slot_cap 3) | 切换义务已随 2026-10-03 同调实施批清偿 |
|
||||
| Boss 钥石掉落 | int [0,999],meta 表逐关行 | meta.tres boss_keystone 首杀 3 / 复杀 2(provisional) | 逐杀实时入账;精英怪掉 1 预留;消费方归元进度 |
|
||||
@@ -287,7 +287,7 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜
|
||||
- 生命一致性:每战开始的上参 = 生命当前值与生效上限;战后生命 = 上报终值;三处写入口均封顶在 [0, 生效上限]。
|
||||
- 恢复点:回复 = floor(生效上限 × 恢复比例 ÷ 100) 后封顶;满血腿回复 0 合法。
|
||||
- 大奖励覆盖:三选一兑付后首战的入参 = 基础表值 + 加算区累加含选中件(覆盖值通道);AP 件兑付后每场战斗开始首轮行动点基线 +1。
|
||||
- 抽签封闭:三选一掷 3 消费三选一封闭流,同种子同操作序列同三选项;单次零重复;令牌耗尽快即枯竭、不再出现在候选(池消耗即上限)。
|
||||
- 抽签封闭:三选一掷 3 消费 reward_pick 封闭流,同种子同操作序列同三选项;单次零重复;令牌耗尽快即枯竭、不再出现在候选(池消耗即上限)。
|
||||
- 同调位约束:道具终态持有恒 ≤ 同调位(谓词表实时求值);超位时停点渠道触发替换交互(丢旧收新 / 放弃新件两路),战斗内渠道沉没不入;奖励节点渠道同受约束。(现行零道具件投放——约束保留作契约,见「秘宝件受同调位约束」节注。)
|
||||
- 钥石逐杀:Boss 击杀后钥石累计增量 = boss_keystone 行值(首杀/复杀两档);大奖励面钥石入账零残留。
|
||||
- 收束次序:关卡完成宣布到达时库存已被关卡节点地图先行清空;重复的关卡结束宣布被拒绝,状态与摘要零变化。
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
>
|
||||
> **兑付频率(先看这条,它是三条渠道的共同前提)**:奇物**不是打一场战斗给一份**。关内的普通战斗节点打完了什么也不给;一关之内奇物**只兑付一次**,触发点是**关底 Boss 被击败**——而按 [冒险结构](冒险结构.md) 的定义,打掉关底 Boss 恰好就等于"通过这一关",这两件事是同一个时刻,不是一条链上的两步。
|
||||
>
|
||||
> 状态:**已实现**(2026-10-04 双层 BD 实施批落地);现行为 v1.1。本文件是奇物的唯一定义文档。
|
||||
> 状态:**已实现**(2026-10-04 双层 BD 实施批落地)。本文件是奇物的唯一定义文档。
|
||||
>
|
||||
> 数值纪律:本文件只写概念、取值域与指路;每件给多少、效果是什么一律不进正文,事实源是 `data/tables/feats.tres` 与 `data/tables/adventure.tres`。
|
||||
> 数值纪律:本文件只写概念、取值域与指路;每件给多少、效果是什么一律不进正文,事实源是 `game/data/tables/feats.tres` 与 `game/data/tables/adventure.tres`。
|
||||
|
||||
## 专长(重设计·基础框架 v1)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
4. **信息红线**:禁止任何效果让数字说谎(信息规则不豁免);揭示类效果只揭真格。
|
||||
5. **防兑换环**:互相转换的通道必须有损耗或每轮上限;单向通道优先。
|
||||
|
||||
> **落行注记(迭代 20 反哺写入,2026-10-12 追认⑤)**:「每第 N 次 / 积满触发」的数据行条件写 **N−1**——效果引擎分发时 when 先于 do 读计数器现值(预评估),故「满 N 触发」落行写 N−1(例:地质学家「满 4 种」写 eq 3、封印匠「每第 3 次」写 mod_eq ref 2、双管镐「每第 2 次」写 mod_eq ref 1)。行为仍为每第 N 次准点触发,单元测试钉住;新件落行照此口径。
|
||||
> **落行注记(迭代 20 反哺写入,2026-10-12 追认⑤)**:「每第 N 次 / 积满触发」的数据行条件写 **N−1**——效果引擎 dispatch 时 when 先于 do 读计数器现值(预评估),故「满 N 触发」落行写 N−1(例:地质学家「满 4 种」写 eq 3、封印匠「每第 3 次」写 mod_eq ref 2、双管镐「每第 2 次」写 mod_eq ref 1)。行为仍为每第 N 次准点触发,单元测试钉住;新件落行照此口径。
|
||||
|
||||
### 基础件表(27 件,五族 + 跨族桥 + 契约尖点)
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
| 代号 | 契约 | 账 |
|
||||
|---|---|---|
|
||||
| 血税 | 本局:踩雷 −2 最大生命;标中 +1 攻击(**均下一战起生效**——战末汇入冒险加算区) | 双向都痛都爽,一句话讲得清;双向同账、本局累积、冒险收束清零。生命上限/攻击系属战界重建属性,即时改会被重建冲掉,故滞后一战兑付(2026-10-12 追认⑨回写;卡面 desc 同步补「下一战起生效」) |
|
||||
| 血税 | 本局:踩雷 −2 最大生命;标中 +1 攻击(**均下一战起生效**——战末汇入冒险加算区) | 双向都痛都爽,一句话讲得清;双向同账、本局累积、冒险收束清零。max_hp/攻击系战界重建属性,即时改会被重建冲掉,故滞后一战兑付(2026-10-12 追认⑨回写;卡面 desc 同步补「下一战起生效」) |
|
||||
|
||||
### 迁入登记(秘宝域迁出件;实装批落地后并入件表)
|
||||
|
||||
@@ -104,11 +104,11 @@
|
||||
|
||||
惊巢反制=退役进素材库(不迁入)。
|
||||
|
||||
**资源类迁出件(2026-10-18 用户裁)**:完美保险自资源类迁入专长——理由:它给的是**规则豁免**而非可调动的余量(§1.1 判据「给规则的是专长」),效果=本场首次封印落空不计入完美封印判定。旧「资源类成员」归类系 2026-10-08 框架批写入、无用户裁断支撑,随本次改判注销。专长行已于迭代 31 卡② 落表:`feats.tres` 单行 `when counter(insurance_used) lt 1` 承载「本场首次」,效果类型 `forgive_seal_miss` 随引擎扩签;稀有档配额随净删重裁下调,现行值读 `data/tables/adventure.tres`。
|
||||
**资源类迁出件(2026-10-18 用户裁)**:完美保险自资源类迁入专长——理由:它给的是**规则豁免**而非可调动的余量(§1.1 判据「给规则的是专长」),效果=本场首次封印落空不计入完美封印判定。旧「资源类成员」归类系 2026-10-08 框架批写入、无用户裁断支撑,随本次改判注销。专长行已于迭代 31 卡② 落表(合并 `3e076e22`):`feats.tres` 单行 `when counter(insurance_used) lt 1` 承载「本场首次」,效果类型 `forgive_seal_miss` 随引擎扩签;稀有档配额随净删重裁下调,现行值读 `game/data/tables/adventure.tres`。
|
||||
|
||||
### 扩签登记(迭代 20 实装已承载——2026-10-12 追认④写入文档换代)
|
||||
|
||||
- **落地结果**:事实候选 10 条中 6 条落事实词位(边缘格判定/空白连锁判定/单次伤害量/被挖格当时有封印印记/雷罚伤害量/生命比例),4 条改道 adventure 域计数器(类型集合计数器/本轮挖格花费/本轮开格数/本轮踩雷数计数器——跨事件累积量走计数器+value_event 比较,不占 fact 词位,T0 定架构);停手事件已落(dig_stop);实现随裁补位=battle_won 事件(战地包扎所需,登记未列)、mod_eq 算子(周期触发)、hp_ratio(百分比 int 口径)等 3 项事实、新效果类型 7 项。
|
||||
- **落地结果**:事实候选 10 条中 6 条落 FACTS 词位(边缘格判定/空白连锁判定/单次伤害量/被挖格当时有封印印记/雷罚伤害量/生命比例),4 条改道 adventure 域计数器(类型集合计数器/本轮挖格花费/本轮开格数/本轮踩雷数计数器——跨事件累积量走计数器+value_event 比较,不占 fact 词位,T0 定架构);停手事件已落(dig_stop);实现随裁补位=battle_won 事件(战地包扎所需,登记未列)、mod_eq 算子(周期触发)、hp_ratio(百分比 int 口径)等 3 项事实、新效果类型 7 项。
|
||||
- **连带**:净化工兵退役,rewrite_board 效果类型自引擎除名(扩签「暂缓:清图事件」不受影响,继续挂起)。
|
||||
- **暂缓**:清图事件(随清图奖励题)。
|
||||
|
||||
@@ -122,13 +122,13 @@
|
||||
|
||||
### 凭证件表(新 3 + 留任 2;代号制命名归用户;稀有度档、配额与面值数值归调参批)
|
||||
|
||||
> **2026-10-18 用户裁削两件**:**同调电池**删除——秘宝是「局外同调件」、冒险中零更换途径,与撤换装券/删回能器同一原则(且 UI 层从未接线选件入口);**完美保险**迁出资源类改归专长——它给的是规则豁免,不是余量,见 §1.4 判据。两件原职责账(秘宝充能/完美资格)同步自 §1.3 账清单注销。
|
||||
> **2026-10-18 用户裁削两件**:**同调电池**删除——秘宝是「局外同调件」、冒险中零更换途径,与 `cf04bd66` 撤换装券/删回能器同一原则(且 UI 层从未接线选件入口);**完美保险**迁出资源类改归专长——它给的是规则豁免,不是余量,见 §1.4 判据。两件原职责账(秘宝充能/完美资格)同步自 §1.3 账清单注销。
|
||||
|
||||
| 代号 | 写进哪笔系统资源(寿命档) | 一句话 | 备注 |
|
||||
|---|---|---|---|
|
||||
| 刷新券 | 刷新存量账(冒险级) | 存量刷新次数 +1 | 语义=存量加仓(已裁);实现依赖刷新件写错账修复(同批) |
|
||||
| 储备金袋 | 储备池 RAP(节点级) | 储备池 +N | 给停手/刷新雷图经济加燃料;战斗结束清零系既有语义,兼容 |
|
||||
| 时沙 | 下一战首轮 AP 队列(拾取挂账,兑付即消尽) | 下一战首轮 AP +2 | 一次性节奏件;与「AP 上限+1」(属性轴)不撞——一个改池子、一个改上限(落法=AP 加成既有通道,2026-10-12 追认⑦回写;拾取时战斗在途同样等下一战首轮) |
|
||||
| 时沙 | 下一战首轮 AP 队列(拾取挂账,兑付即消尽) | 下一战首轮 AP +2 | 一次性节奏件;与「AP 上限+1」(属性轴)不撞——一个改池子、一个改上限(落法=hero_ap_bonus 既有通道,2026-10-12 追认⑦回写;拾取时战斗在途同样等下一战首轮) |
|
||||
| 小 GP 袋 | GP 钱包(冒险级) | (留任)+20 / +50 | 计价物不自售维持(不进商店) |
|
||||
| 应急口粮 | 生命账(冒险级) | (留任)回复 +6 | 在商店内(默认原则) |
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
|
||||
**补给类内部的异质性(统一表述)**:凭证全部即时消尽——不存在「持有凭证」这种状态;异质性不在凭证上,而在**被写入的系统资源的寿命**上:GP 钱包 / 生命 / 刷新存量 = 冒险级,储备池 = 节点级,时沙暂记 = 至下一战首轮兑付(系统资源清单对齐「凭证件表(新 3+留任 2)」节;「AP 上限」已归属性值提升轴,见 1.2)。
|
||||
|
||||
- 原在册的「秘宝充能」「完美资格」两笔随 2026-10-18 两件裁削注销——充能账本本身仍为秘宝基础设施保留(迭代 11,主动件充能每冒险重置),本次只删奇物侧写它的入口。
|
||||
- 原在册的「秘宝充能」「完美资格」两笔随 2026-10-18 两件裁削注销——`attune_charges` 账本本身仍为秘宝基础设施保留(迭代 11,主动件充能每冒险重置),本次只删奇物侧写它的入口。
|
||||
- 完美资格的豁免走**订阅式自有累加账**:授予段在 `seal_missed` 命中时累加豁免数,判定取「误标总数 − 豁免数」得有效数;**不改写误标账本身、不拦截事件**(迭代 31 卡② 契约 2/3)。
|
||||
- 登记此节防止把凭证当成会持续生效的东西去结算。
|
||||
|
||||
@@ -263,6 +263,8 @@
|
||||
|
||||
**为什么两层都要有**:分类名在卡面上不出现,不等于玩家对它没有概念——帮助手册、百科条目、成就名称三处一定会用到它(「首次集齐 4 件专长」「三件属性值提升」),效果描述里出现指代时也需要名字(如「本项属专长」类归类指代)。所以它必须是一个**玩家读得懂、读一遍就懂**的正式名词,不能是内部描述或自造词。
|
||||
|
||||
**代码侧词族对应**(本批只做命名对齐,代码改动见需求卡片):顶层 `curio_*`(奇物总称)/ 专长 `feat_*` / 属性值提升 `asi_*` / 资源 `res_*`。`reward_*` 已被既有标识符占用(`reward_pick` / `reward_node` / `reward_preview`),**禁止使用**。
|
||||
|
||||
### 2. 渠道轴:与分类的交叉
|
||||
|
||||
三个渠道各只取走分类的一部分。这张表是奇物概念的第二个维度——它和分类轴互不决定,改其中一根不必动另一根。
|
||||
@@ -431,12 +433,12 @@
|
||||
|
||||
| 参数 | 取值域 | 事实源 |
|
||||
|---|---|---|
|
||||
| 专长定义行(标识 / 显示名 / 稀有度 / 效果说明 / 订阅行〔订阅哪个事件 on / 什么条件 when / 什么效果 do〕) | 各字段封闭枚举,行键白名单封闭;事件 / 效果类型 / 条件事实 / 算子四词表封闭(效果引擎单一事实源);稀有度档=新四级(普通/优秀/稀有/传说),schema 字段双脱钩(字段在、设计面按档配比加权) | `data/tables/feats.tres` |
|
||||
| 专长凭证(出现概率 / 配额 / 限购次数 / 保底计数阈值) | 整数,四参数全 provisional | 已入表(`shop.tres` 凭证行 + 冒险表凭证三计数行) |
|
||||
| 属性值提升种类 | 封闭三项:生命上限 / AC / 攻击,扩项走文档修订 | 冒险表结构声明 |
|
||||
| 专长定义行(标识 / 显示名 / 稀有度 / 效果说明 / 订阅行〔订阅哪个事件 on / 什么条件 when / 什么效果 do〕) | 各字段封闭枚举,行键白名单封闭;事件 / 效果类型 / 条件事实 / 算子四词表封闭(效果引擎单一事实源);稀有度档=新四级(普通/优秀/稀有/传说),schema 字段双脱钩(字段在、设计面按档配比加权) | `game/data/tables/feats.tres` |
|
||||
| 专长凭证(出现概率 / 配额 / 限购次数 / 保底计数阈值) | 整数,四参数全 provisional | 已入表(迭代15② 凭证行——`shop.tres` + `adventure_table.gd`) |
|
||||
| 属性值提升种类 | 封闭三项:生命上限 / AC / 攻击,扩项走文档修订 | `game/data/schemas/adventure_table.gd` |
|
||||
| 补给种类 | 种类现行事实源=「凭证件表(新 3+留任 2)」节;凭证已入表(迭代15②) | 同上 |
|
||||
| 稀有度档位 | 封闭四级(普通 / 优秀 / 稀有 / 传说);配额是结构锚,改总量须重新拍板而非调参 | 同上 |
|
||||
| 各分类种类 × 档位的配额与值 | 整数 | `data/tables/adventure.tres` |
|
||||
| 各分类种类 × 档位的配额与值 | 整数 | `game/data/tables/adventure.tres` |
|
||||
| 专长获取的全局限量 | 整数(一局内可获得的次数上限) | 同上 |
|
||||
| 一次三选一的候选展示数 | [1,6] | 同上 |
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 难度曲线与Boss
|
||||
|
||||
> 一句话:难度曲线、期望值带与 Boss 设计
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.2
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
| 关内坡度(节点深度) | 同敌种数值平缓上移,深度也可表达为敌人成群 | 数量是比单体质变更优先的深度表达:保持技能池 EV 读数不变(权重即旋钮、EV 重锚顺带登记)、总量受控 |
|
||||
| Boss 与精英修饰(预留第三轴) | Boss 走最深深度直填行;精英只有字段命名空间预留 | Boss 不走修饰表;修饰乘数表 MVP 为空表、零行为,首个使用场景 = 精英节点(随[关卡节点地图](关卡节点地图.md)定稿联动);数值所有权在本系统,[棋盘生成](../排雷循环/棋盘生成.md)只按表生成。精英怪设定已登记预留(迭代 10 奖励重构批——与其他普通小怪同一立绘 + 附加特征标记 + 数值更强;视觉特征三件 = 名称前后缀「精英·」+ 底座光环 + 描边变色,色板合规与样张闸义务随怪物设定批实装) |
|
||||
|
||||
**结论**:关内坡度 = 每深一档同敌种基准上移,或按"深度也可表达为敌人成群"改由数量承载——单体生命随深度的具体走向以 `enemy.tres` 行值为准(数量优先于单体;s_hp 线性式为建模工具,现行行值不承诺随深度单调上移);关间台阶 = 相邻关同敌种基准乘 1.3–1.6(域语义如上;s_hp / k_L 现行行值读 `enemy.tres`,取值域归敌人表字段定义)。
|
||||
**结论**:关内坡度 = 每深一档同敌种基准上移,或按"深度也可表达为敌人成群"改由数量承载——单体生命随深度的具体走向以 `enemy.tres` 行值为准(数量优先于单体;s_hp 线性式为建模工具,现行行值不承诺随深度单调上移);关间台阶 = 相邻关同敌种基准乘 1.3–1.6(域语义如上;s_hp / k_L 现行行值读 `enemy.tres`,域见 `data/schemas/enemy_table.gd`)。
|
||||
|
||||
```
|
||||
hp_D = round( hp_0 × (1 + s_hp × D) ) s_hp ∈ [0.05, 0.20]
|
||||
@@ -111,7 +111,7 @@ MVP 行值并不逐式现算,而是按此式量级直填经切片验证过的
|
||||
|
||||
| 带 | 定稿口径 | 含义 |
|
||||
|---|---|---|
|
||||
| 通关率带 | 口径已换代·现行带 = 四带甲案(2026-10-03 用户拍板):带 A 白板完美执行战役全通率 [0%,10%] / 带 B 白板第一关通过率 [50%,85%] / 带 C 营地满成长战役全通率 [30%,60%](预立) / 带 D 响应曲线每雷边际 ≤15pp·S 形——旧普通档 L1 [35,55] / L2 [10,15] 与完美档 [35,65] 正式作废,全文见本节末「带换代」条。实证:直入口 L2 普通 5% vs 冒险条件口径 L2 90% 同期并存〔「营地检查点」= 数值验证工具营地循环判定段旧称(现名营地循环战役)——2026-09-30 词源考证完成,见审计报告拍板点 9(已按生命周期条款退役);与冒险结构「没有检查点」铁律的字面相撞就此解除〕 | 四带按类型基准锚定、每条带均有外部锚点:带 B 管首关 = 过滤器不是墙;带 A 管白板全通的顶尖难度;带 C 留元进度爬升空间(满成长实装后启用);带 D 管响应曲线无悬崖 |
|
||||
| 通关率带 | 口径已换代·现行带 = 四带甲案(2026-10-03 用户拍板):带 A 白板完美执行战役全通率 [0%,10%] / 带 B 白板第一关通过率 [50%,85%] / 带 C 营地满成长战役全通率 [30%,60%](预立) / 带 D 响应曲线每雷边际 ≤15pp·S 形——旧普通档 L1 [35,55] / L2 [10,15] 与完美档 [35,65] 正式作废,全文见本节末「带换代」条。实证:直入口 L2 普通 5% vs 冒险条件口径 L2 90% 同期并存〔「营地检查点」= balance_verifier 营地循环判定段旧称(现名营地循环战役)——2026-09-30 词源考证完成,见审计报告 git 提交 c095916 拍板点 9(已按生命周期条款退役);与冒险结构「没有检查点」铁律的字面相撞就此解除〕 | 四带按类型基准锚定、每条带均有外部锚点:带 B 管首关 = 过滤器不是墙;带 A 管白板全通的顶尖难度;带 C 留元进度爬升空间(满成长实装后启用);带 D 管响应曲线无悬崖 |
|
||||
| 关卡完成余量带 | 关卡完成者关卡完成时剩余生命的 p90 / p10 按现生命轴上限百分比表达(压缩前绝对血量带已作废;界值重标随验收批) | **关卡完成余量** = 关卡完成瞬间还剩多少血。余量太肥说明赢得太从容,压生存侧;太瘦说明"剩一两滴血惨胜"成常态,抬治疗供给或恢复点收益 |
|
||||
| 第一关形态带 | 教学位绿档 + 中段黄档 + Boss 黄档不红 | **形态带**管一关内各战三档判定的排布形状:第一战必须稳过,中段有输的可能,Boss 战紧但不许是配置事故 |
|
||||
|
||||
@@ -123,7 +123,7 @@ MVP 行值并不逐式现算,而是按此式量级直填经切片验证过的
|
||||
|
||||
**迭代 24 敌人表内容修批读数(只测不判——2026-10-14 反哺写入批登记,用户裁「全部按呈报写入文档」;数值终值归 M4 数值批)**:同种子配对 seed0=9000(沿用迭代 23 配对种子)改前/改后各 40 局×both——①**N2 普通敌技能投放**(毒吐/盾击两新行六池)后 perfect L2 通关 8/20→13/20(+25pp)、L3 全通 6/20→10/20(+20pp)——方向符合预期(L1 减压后更健康抵达 L2/L3),量级低于二档配对判读带 ~30pp,倍率 provisional 归 M4;normal 档基率地板(0/20)无判读力;②**N3 敌方攻击类型轴**(20 行全填 normal+敌方兑付路径克制消费)后全局平移 = 主角穿重甲受伤点数 −1 / 魔法护甲 +1 / 轻甲 0(V5 冒烟同种子三甲型配对实测单发恒 ±1:heavy 2==light 3−1 · ward 4==light 3+1);taken 中位 normal 29.5→27.5、perfect 76.5→97.0——后者系**构成效应**(全通 6→10 局通关更深自然累计更多承伤),非单发异常;③N1 (1,2) 降档(hp 50→22·ac 3→2)后 perfect L1 通关 19/20→20/20——5 倍墙消除方向符合预期。判读与带重锚随 M4 数值批,本注记只登记不判读。
|
||||
|
||||
**判读口径同步(迭代 5 基线重测批,2026-09-28)**:通关率带的测量口径 = 冒险条件通关率(打通 k−1 关才到达第 k 关,由数值验证工具冒险段派生;单关直入口口径已随 2026-09-23 拍板退役)——带值沿用 2026-09-20 分带修正(普通档 L1 [35,55] / L2 [25,45]、完美档 [35,65];迭代 5 计划书 C4 冻结:改带=用户拍板)。上方行 115 的「带退役待重锚、重锚前只测不判」注记按本条同步理解:迭代 5 基线重测已按现行带对冒险条件口径判读(读数报告已按生命周期条款退役);是否在新口径上重取带值,归迭代 5 出口判读由用户拍板,本批不动带数字。
|
||||
**判读口径同步(迭代 5 基线重测批,2026-09-28)**:通关率带的测量口径 = 冒险条件通关率(打通 k−1 关才到达第 k 关,balance_verifier 冒险段派生;单关直入口口径已随 2026-09-23 拍板退役)——带值沿用 2026-09-20 分带修正(普通档 L1 [35,55] / L2 [25,45]、完美档 [35,65];迭代 5 计划书 C4 冻结:改带=用户拍板)。上方行 115 的「带退役待重锚、重锚前只测不判」注记按本条同步理解:迭代 5 基线重测已按现行带对冒险条件口径判读(读数报告见 git 提交 e55dc10,已按生命周期条款退役);是否在新口径上重取带值,归迭代 5 出口判读由用户拍板,本批不动带数字。
|
||||
|
||||
> **⚠ 带失效待重锚(2026-10-01 数值修复批)**:模拟档位重构(普通档 v2 新手画像→v3=完美策略+受控失误注入;完美档补元游戏选路与商店购买)+数值三刀(hero max_hp 20→26/直伤雷 4/5/5→6/8/8/L1 系敌 atk 2→1)后,上方三条验收带的测量基准已失义——旧普通档=比真人弱 20 倍的新手画像(真人实证推翻),旧带值系照坏尺子校定。新尺读数(N=100/200)与调优轨迹见 `数值修复批读数(已退役,git 历史可查)`;~~新带值须新尺重测后用户拍板,重锚前只测不判~~(已由下行带换代完成)。
|
||||
|
||||
@@ -175,7 +175,7 @@ GP 与商店房随 2026-09-20 GP+商店房批落地,给难度引入第三族
|
||||
|
||||
公式语义与 GP 归[冒险结构](冒险结构.md)(GP 节),商店房编排归[关卡节点地图](关卡节点地图.md);行值读 `data/tables/shop.tres`,全部 provisional 归本文曲线调参批。
|
||||
|
||||
**分层验收 defer(2026-09-20 用户拍板成文)**:按"商店存在与否"分层的通关率验收——MC 双格(shop=off 现行基线 / shop=on 购买画像)、shop=on 的带平移量、商店属性提升的换算率登记(换算率强条目纪律同类)——**全部随曲线调参批执行**,与「基线通关率越带」同窗(原「L2 Boss 承伤微越带」「大奖励数值随难度曲线联动」两待办清单条目已完成移除——前者 2026-09-28 读数自愈、后者随迭代 10 大奖励退役失义)。执行前 shop=off 续用现行带判读,shop=on 读数只登记不判读、禁止用 shop=off 读数外推 shop=on。L3 首遇绿档冒烟断言仍按成长代理档口径,不因商店批改判。**v0.22 注记(迭代 11 第②批)**:shop=off 对照 = legacy 固定三件模式(MC 逐项比对 off_n60 逐位,迭代 11 第②批 T5);shop=on 首锚 = 共享池货架面 N=60 双策略(同调关闭同种子配对)——带平移判读仍归调参批,终局池读数(pool_stock)随行只测不判。
|
||||
**分层验收 defer(2026-09-20 用户拍板成文)**:按"商店存在与否"分层的通关率验收——MC 双格(shop=off 现行基线 / shop=on 购买画像)、shop=on 的带平移量、商店属性提升的换算率登记(换算率强条目纪律同类)——**全部随曲线调参批执行**,与「基线通关率越带」同窗(原「L2 Boss 承伤微越带」「大奖励数值随难度曲线联动」两待办清单条目已完成移除——前者 2026-09-28 读数自愈、后者随迭代 10 大奖励退役失义)。执行前 shop=off 续用现行带判读,shop=on 读数只登记不判读、禁止用 shop=off 读数外推 shop=on。L3 首遇绿档冒烟断言仍按成长代理档口径,不因商店批改判。**v0.22 注记(迭代 11 第②批)**:shop=off 对照 = legacy 固定三件模式(MC 逐项比对 off_n60 逐位,迭代 11 第②批 T5);shop=on 首锚 = 共享池货架面 N=60 双策略(`runsum_m4iter11b_t5shopon_n60_20261003.jsonl`,attune=off 同种子配对)——带平移判读仍归调参批,终局池读数(pool_stock)随行只测不判。
|
||||
|
||||
### Boss 设计:食人魔酋长与关底血量锚
|
||||
|
||||
@@ -220,13 +220,13 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板
|
||||
| 封印溢价系数 δ ↔ 完美乘数 p_perfect ↔ ap_per_round | [战斗结算](../战斗循环/战斗结算.md)、[行动经济](../排雷循环/行动经济.md) | 封印激励三件套同窗检算(防封印 rush 复发:δ 与 ×2 叠加通胀、AP 吞吐上限)——任一变动须重跑双画像封印率读数(2026-10-05 判式换代批新增) |
|
||||
| η 读数 ↔ 模拟画像定义 ↔ 可推理率 ι ↔ min_safe_count/生成尝试上限 | sim 档位、[棋盘生成](../排雷循环/棋盘生成.md) | η 是画像条件量:画像重构即锚漂移,重锚顺带;可推理率三元组既有联动扩一员(2026-10-05 判式换代批新增) |
|
||||
| β 带端点 β_lo/β_hi ↔ D_ref ↔ hero max_hp ↔ AC 折算档(5pp 系数) | [战斗结算](../战斗循环/战斗结算.md) | 带是 D_ref 的函数:换锚(D_ref/max_hp)须全带重推;AC 档值变更改 5pp 系数,同罪(2026-10-05 判式换代批新增) |
|
||||
| 直伤雷三行(6/8/8) ↔ 正向同轴行(heal_minor/pierce_strike/magic_bolt) | [地图战斗资源](../战斗循环/地图战斗资源.md) | **同轴镜像比入对账面**:负向/正向比超出 β 带内推导区间即越带;单边动负向三行今后必须带正向镜像行联合检算(2026-10-05 判式换代批新增——数值修复批两先例的单边动教训成文) |
|
||||
| 直伤雷三行(6/8/8) ↔ 正向同轴行(heal_minor/pierce_strike/magic_bolt) | [地图战斗资源](../战斗循环/地图战斗资源.md) | **同轴镜像比入对账面**:负向/正向比超出 β 带内推导区间即越带;单边动负向三行今后必须带正向镜像行联合检算(2026-10-05 判式换代批新增——d70f6c3/数值修复批两先例的单边动教训成文) |
|
||||
| clear_blast 区间(24/40/32) ↔ p_perfect | [地图战斗资源](../战斗循环/地图战斗资源.md) | 完美封印第二份的补贴基数进封印激励对账;单边动清图奖励 = 变相动封印(2026-10-05 判式换代批新增) |
|
||||
| 标中强化池权重 ↔ 正向池权重(77 分母) ↔ 关级恒等式奖励占比 [15,40%] | [地图战斗资源](../战斗循环/地图战斗资源.md) | 形态 (b) 专属池重摇启用时生效(现行不启):双池分布变动 = E_dig 与 W 同时漂移,须联合检算 + 恒等式占比复核(2026-10-05 判式换代批新增,条件生效行) |
|
||||
|
||||
五条经济契约的对账由[战斗结算](../战斗循环/战斗结算.md)闭合验收;挖掘风险不等式已于 2026-10-05 判式换代批重立(三层口径+β 带+条件二封印溢价——结构层接替与数值层带判读详见行动经济 F1 条款3 推导节),本系统的对账义务转为按 β 带逐 u 检算(清图支配性审计为常设重跑项,现行 u=3 β=1.17 微破下限登记态);清图支配性已于 2026-09-19 按现行值链重跑、裁决②"非支配设计态"维持——判式换代后的全套判值重跑随本系统下一次调参批顺带执行。完美封印乘数的调参权在本系统。
|
||||
五条经济契约的对账由[战斗结算](../战斗循环/战斗结算.md)闭合验收;挖掘风险不等式已于 2026-10-05 判式换代批重立(三层口径+β 带+条件二封印溢价——结构层接替与数值层带判读详见行动经济 F1 条款3 推导节),本系统的对账义务转为按 β 带逐 u 检算(常设重跑入口 `tools/clear_dominance_audit.py`,现行 u=3 β=1.17 微破下限登记态);清图支配性已于 2026-09-19 按现行值链重跑、裁决②"非支配设计态"维持(回执见 git 提交 2ca3e20,报告已退役)——判式换代后的全套判值重跑随本系统下一次调参批顺带执行。完美封印乘数的调参权在本系统。
|
||||
|
||||
元进度接口预留:**结论——元进度解锁对难度的影响,以生存链区间的平移换算率接入;接口启用形态已定稿(2026-09-18 元进度定稿批,用户拍板):永久强化影响折算为通关率带平移量,判读口径不变;换算率表首版三行(生命上限 / 基础攻击 / 护甲等级——护甲行强条目,验收读数须按解锁后参数重测)与键结构见元进度表字段定义,数值行读 `data/tables/`、标定随元进度设计批。** 元进度数值行落地前,本系统不为它预留任何数值行。
|
||||
元进度接口预留:**结论——元进度解锁对难度的影响,以生存链区间的平移换算率接入;接口启用形态已定稿(2026-09-18 元进度定稿批,用户拍板):永久强化影响折算为通关率带平移量,判读口径不变;换算率表首版三行(生命上限 / 基础攻击 / 护甲等级——护甲行强条目,验收读数须按解锁后参数重测)与键结构见 `data/schemas/meta_table.gd`,数值行读 `data/tables/`、标定随元进度设计批。** 元进度数值行落地前,本系统不为它预留任何数值行。
|
||||
|
||||
## 依赖与输出
|
||||
|
||||
@@ -260,7 +260,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| P1 | 加难杠杆扫描落带 | 候选杠杆已登记(血量锚走廊、群战上探、注入衰减上调候选),域内取样扫描已执行(迭代 5——r_boss 0.8 档,见「Boss 设计」节加难走廊行),全杠杆落带扫描未完成;护甲等级换装点锚定(基准护甲等级自带敌方输出期望的结构性削减 + 减伤墙退役 + 伤害下限)的方向性偏移并入本扫描一并调带(带宽补扫含暴击档与折扣档);落带前现行行值维持 provisional-pending-scan。第二关行集随分支节点图批落地后并入本扫描(L2 读数基线/加成档已顺带实测,见 v0.7) |
|
||||
| P1 | 挖掘风险不等式与清图支配性对账重跑 | **挖掘风险不等式半边已完成(2026-10-05 判式换代批,迭代14②号卡)**——判式三层重立写入文档+条件二封印溢价机制闭合+β 带判读制度化(残留=u=3 β=1.17 微破下限登记态,不强制回滚;δ 敏感度判读顺带出口报告),本行对挖掘风险不等式的「重跑义务」改判读回执:后续调参按 β 带检算执行,不再立独立重跑批。清图支配性已于 2026-09-19 按现行值链重跑(裁决②"非支配设计态"维持——缺口收窄主读数 L1≈24/L2≈45 当量〔u=1〕,重跑入口=清图支配性审计(常设重跑项));调参批执行时按当期行值顺带重跑 |
|
||||
| P1 | 挖掘风险不等式与清图支配性对账重跑 | **挖掘风险不等式半边已完成(2026-10-05 判式换代批,迭代14②号卡)**——判式三层重立写入文档+条件二封印溢价机制闭合+β 带判读制度化(残留=u=3 β=1.17 微破下限登记态,不强制回滚;δ 敏感度判读顺带出口报告),本行对挖掘风险不等式的「重跑义务」改判读回执:后续调参按 β 带检算执行,不再立独立重跑批。清图支配性已于 2026-09-19 按现行值链重跑(裁决②"非支配设计态"维持——缺口收窄主读数 L1≈24/L2≈45 当量〔u=1〕,设计权威回执=git 提交 2ca3e20,重跑入口 tools/clear_dominance_audit.py);调参批执行时按当期行值顺带重跑 |
|
||||
| P1 | 真人冒险成功率修正系数标定 | 带按模拟口径定义;试玩批次实测真人显著强于模拟者,系数待后续试玩批次定量 |
|
||||
| P1 | 迭代 10 奖励重构带重扫义务 | 恢复经济收紧(关卡完成回满血→部分回血 20%,难度上压方向)+ 局内成长节奏变动(三选一件值/权重/次数上限 knob 全读冒险表;AP 件 = 每场战斗开始首轮 +1 AP 的强度敏感轴)——关卡完成率带重扫随曲线调参批现行窗执行;Boss 钥石掉落重锚(首杀 3/复杀 2)连带元进度产出标定义务重开(归元进度设计批) |
|
||||
| P1 | 完美策略档的结构性加难杠杆 | 数值杠杆对完美档已被实测证伪,结构候选未裁决(登记 [待办清单](../../../../待办清单.md)) |
|
||||
@@ -270,7 +270,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板
|
||||
|
||||
## 调参表
|
||||
|
||||
本系统是全项目行值最多的系统。数值纪律(2026-09-17 降级批定稿):**正文与调参表只定规则、取值域与口径,具体行值一律读配置表(切片 `data/tables/` 的 enemy / skills / hero / board_gen / reward / settlement / status_effects 等),已锁数值以 `data/tables/` 对应表为准,本文不登记具体数值——防双写失同步**(切片 `.tres` 数值压缩批后文档行值滞后,双写失同步已被实证)。
|
||||
本系统是全项目行值最多的系统。数值纪律(2026-09-17 降级批定稿):**正文与调参表只定规则、取值域与口径,具体行值一律读配置表(切片 `game/data/tables/` 的 enemy / skills / hero / board_gen / reward / settlement / status_effects 等),已锁数值以 `data/tables/` 对应表为准,本文不登记具体数值——防双写失同步**(切片 `.tres` 数值压缩批后文档行值滞后,双写失同步已被实证)。
|
||||
|
||||
首发行值几乎全部 provisional,其中加难相关数值处于 provisional-pending-scan(扫描未执行);完整行集读表,不在此整表搬运。
|
||||
|
||||
@@ -296,7 +296,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板
|
||||
| 技能冷却(拍) | 逐技能行读表;普攻冷却恒 0 不可配(空池不可能的结构前提——域校验锁死);撕咬 = 与突刺同倍率错开冷却轴的高频小爆发轮廓;毒爆 = 蛛化卓尔精灵专属池独占技 |
|
||||
| 保底 M | 全局单旋钮,读技能表 pity_threshold;连续 M 拍执行普攻 → 下拍必出特殊技;单特殊技低权重池受保底支配 |
|
||||
| 触发条件 | 情境技与闩型解锁的 fact 阈值读技能表 trigger 行值(2026-10-26 触发条件批设计闭合——词表与机制归敌人系统「触发条件」节);情境技的池内份额照走池权重行。**已投放两示范(2026-10-27 迭代 39,provisional)**:地精池孤注守势(self_hp_pct lte 35,纯增益技)+ L2/L3 群行位趁隙偷袭(last_round_end eq 停手,伤害技)——fact 阈值、权重、倍率与冷却逐行读表,本表零复制;地精池投放稀释含闸长期速率,EV 抽样锚已随重锚批换代(带宽注记随 `enemy.tres` 表注) |
|
||||
| 池 EV 锚 | 静态份额与含闸长期速率实测读数登记于调参日志(EV 重锚与权重投值随本表修订)。**2026-09-19 节奏体验验证批登记**(60 组独立种子 × 双策略 × 两关的节奏实测,种子数下限 50 判读;20 种子以下批次有种子偏置假象):特殊技执行份额 对表成立——地精 10.4%(静态 10%)/ 地精一伙 8.4% / 熊地精系 28.9–42.4% / 巨蜘蛛 34.8% / 酋长 28.9% / 卓尔 35.4%;**L2 池含闸速率抽样复核完成**(上项即含闸读数);保底越界 0/247(间隔 4 = M=4 合法上界);过涝信号 8/1440 场(最长连击 3);过旱按用户判读带集中在短命杂鱼(生存时长问题非池配置——见待办清单清单 Alpha 条目移交注记) |
|
||||
| 池 EV 锚 | 静态份额与含闸长期速率实测读数登记于调参日志(EV 重锚与权重投值随本表修订)。**2026-09-19 节奏体验验证批登记**(60 distinct seeds × 双策略 × 两关,tools/skill_rhythm_audit.py——20 种子以下批次有种子偏置假象,读数须 ≥50 种子):特殊技执行份额 对表成立——地精 10.4%(静态 10%)/ 地精一伙 8.4% / 熊地精系 28.9–42.4% / 巨蜘蛛 34.8% / 酋长 28.9% / 卓尔 35.4%;**L2 池含闸速率抽样复核完成**(上项即含闸读数);保底越界 0/247(间隔 4 = M=4 合法上界);过涝信号 8/1440 场(最长连击 3);过旱按用户判读带集中在短命杂鱼(生存时长问题非池配置——见待办清单清单 Alpha 条目移交注记) |
|
||||
|
||||
主角表与棋盘参数表(行值分别读 `hero.tres` 与 `board_gen.tres`,provisional):
|
||||
|
||||
@@ -325,7 +325,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板
|
||||
- 零红档:全部行集经区间扫描,不存在"最好情况也打不过"的战斗组合。
|
||||
- 教学位绿档:第一关第一战与各新敌种首遇位的区间判定为绿档。
|
||||
- 形态带成立:第一关形态 = 教学位绿 + 中段黄 + Boss 黄不红。
|
||||
- 通关率带:**2026-10-03 带换代(用户拍板四带甲案)**——带 A 白板完美执行战役 [0,10%] / 带 B 白板 L1 [50,85%] / 带 C 满成长 [30,60%] 预立 / 带 D 响应曲线 ≤15pp·S 形;旧普通 L1 [35,55] / L2 [10,15]、完美 [35,65] 正式作废。测量口径维持冒险条件通关率(由数值验证工具冒险段派生);四带定稿全文见「期望值带」节「带换代」条。
|
||||
- 通关率带:**2026-10-03 带换代(用户拍板四带甲案)**——带 A 白板完美执行战役 [0,10%] / 带 B 白板 L1 [50,85%] / 带 C 满成长 [30,60%] 预立 / 带 D 响应曲线 ≤15pp·S 形;旧普通 L1 [35,55] / L2 [10,15]、完美 [35,65] 正式作废。测量口径维持冒险条件通关率(balance_verifier 冒险段派生);四带定稿全文见「期望值带」节「带换代」条。
|
||||
- 关卡完成余量带:关卡完成者剩余生命 p90 / p10 按现生命轴上限百分比表达,界值重标随验收批。
|
||||
- 恒等式闭合:关级恒等式逐项对账闭合,残差 <5%(provisional 阈值);奖励输出占比 ∈ [15%, 40%]。
|
||||
- Boss 锚在案:每个 Boss 行的血量锚比率记录在案且落在现行带内;越带须登记,不静默变更。
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# 地图战斗资源
|
||||
|
||||
> 一句话:格面资源的产出、极性字典与清图奖励封装
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
> 状态:已定稿(自旧体系迁移)
|
||||
|
||||
## 设计目的
|
||||
|
||||
地图战斗资源是战斗域的资源层:每张雷图上每个格子携带什么资源、资源怎么摇定、正向与负向各兑付成什么效果、清图时整张板发什么,由它统一裁决。核心抽象是**格面资源**——关联到格子上的资源对象:装板时摇定类型身份,安全格与危险格一视同仁、同一类型池;资源本身不分好坏,被当成奖励还是惩罚,由玩家对这一格做的动作在结算期决定——开安全格、标中雷是正向,开危险格、标错安全格是负向(极性矩阵的定义归本文,路由执行归[战斗结算](战斗结算.md))。开局初始展开白送的那批格是**封锁格**——恒无资源,不再有任何加成(定义见[排雷玩法](../排雷循环/排雷玩法.md))。
|
||||
地图战斗资源是战斗域的资源层:每张雷图上每个格子携带什么资源、资源怎么摇定、正向与负向各兑付成什么效果、清图时整张板发什么,由它统一裁决。核心抽象是**格面资源(CellResource)**——关联到格子上的资源对象:装板时摇定类型身份,安全格与危险格一视同仁、同一类型池;资源本身不分好坏,被当成奖励还是惩罚,由玩家对这一格做的动作在结算期决定——开安全格、标中雷是正向,开危险格、标错安全格是负向(极性矩阵的定义归本文,路由执行归[战斗结算](战斗结算.md))。开局初始展开白送的那批格是**封锁格**——恒无资源,不再有任何加成(定义见[排雷玩法](../排雷循环/排雷玩法.md))。
|
||||
|
||||
它守住三件事:每个非封锁格都有资源可兑(结构保证,不靠逐次掷运气);类型身份在装板期一次摇定、全程只读(在"数字恒真"的推理之外,类型是第二层规划素材);每个兑付都能在结算明细里指回挖开的哪一格。缺了这一层,挖格没有收益语言,"扫雷攒因、战斗结果"的兑现就断在最后一环。
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
### 候选集合:安全格与危险格的资源池
|
||||
|
||||
格面资源在每非封锁格上摇定身份时不区分格型——候选集合 = 格面资源池中全部正极性、权重大于零的类型行,不分格型一律参与摇号;负向兑付归战斗结算按极性路由。安全格与危险格候选集相同,权重分布相同,类型频次合计 = reward.tres cell 池正向行 weight 之和(现行值读表):
|
||||
格面资源在每非封锁格上摇定身份时不区分格型——`_rollable_rows()` 把 cell 池正向行全集作为权重表,对所有非封锁格一视同仁地 `weighted_pick`。安全格与危险格候选集相同,权重分布相同,类型频次合计 = reward.tres cell 池正向行 weight 之和(现行值读表):
|
||||
|
||||
| 格型 | 候选集合(cell 池正向行,weight>0) | 类型频次合计 |
|
||||
|---|---|---|
|
||||
@@ -79,6 +79,11 @@
|
||||
|
||||
清图槽(clear_default 池,clear_blast)独立于格面资源——作用域为整张板,不挂任何一格。
|
||||
|
||||
引用(代码事实源):
|
||||
- `game/core/reward_economy.gd#roll_board`:`_rollable_rows()` 第 207-213 行收 `pool_tag=cell & polarity=positive & weight>0` 全集;循环第 65-67 行对 `eligible` 清单(全部非封锁格)一视同仁。
|
||||
- `game/core/minesweeper_rules.gd#_do_dig` 第 256-264 行:chain/dig 通道 `cell_revealed` 事件 `resource=true` 字段对安全格与危险格一致——注释明确"安全格与危险格一视同仁(危险格亦携带,负向兑付归 战斗结算 极性路由)"。
|
||||
- `game/data/tables/reward.tres`:9 行正向行 weight 现行值读 `data/tables/reward.tres`。
|
||||
|
||||
候选集合具体行值(power / power_min / power_max / stacks / effect_id)随行更新——以 `data/tables/reward.tres` 为现行值源;GDD 表格只锁行集与权重分布语义。负向 9 行(enrage / off_guard / heal_backlash / enemy_alert / ap_drain / sapped / pierce_snare / magic_recoil / gp_loss——2026-09-20 八型批 ambush_double→enemy_alert 换装 + ap_drain 新增、同日 GP+商店房批 +gp_loss)weight=0 不参与摇号,按(类型, 极性)查表取用,不在候选集合内。
|
||||
|
||||
举证:本节为候选集合枚举,无计算。
|
||||
@@ -96,7 +101,7 @@
|
||||
|
||||
- **档由两个参数定义:概率位 + 保底上限**。「永不保底」不单立规则——T4 的保底上限 = 0 即其统一表达;T1/T2 上限同为 0。
|
||||
- **保底数量挂在型上、不挂在档上**:每个型各自登记「每板至少出几个」。档内登记保底的型数 ≤ 档上限 → 全部兑现;> 上限 → 每板从登记型中随机选定「上限」个兑现,其余型该板按普通概率出现、不保底。
|
||||
- **补签纪律**:执行序 = 装板摇号(含偏运硬币投影)→ 按上限定本期保底型集合 → 校验补签 → 板上全程只读。补签只改类型身份:危险格与安全格不动(补签格可为雷可为安全格,危险格与安全格同池不破)、不消费权重(补签不是一次取号)、清图判定不动、不泄露元信息(补签格与摇号格不可区分)。粒度 = 板,换板重新校验。
|
||||
- **补签纪律**:执行序 = 装板摇号(含偏运硬币/board_skew 投影)→ 按上限定本期保底型集合 → 校验补签 → 板上全程只读。补签只改类型身份:危险格与安全格不动(补签格可为雷可为安全格,危险格与安全格同池不破)、不消费权重(补签不是一次取号)、清图判定不动、不泄露元信息(补签格与摇号格不可区分)。粒度 = 板,换板重新校验。
|
||||
- **GP 数值锚**:以战斗结束 GP 奖励为锚——小 GP 袋 ≈ 其 1/10、大宝箱 ≈ 其 1 倍(具体数值归调参批)。
|
||||
- 大宝箱为枚举新增(九型→十型走本文修订流程,不随手加行);微光归通用增益组(五色相不变,组内不细分正好容下)。
|
||||
- **对外稀有度映射**(现行事实源=[核心循环](../../01-核心循环.md)「档位与获取规则」节):T1=普通 / T2=优秀 / T3=稀有 / T4=传说;任何概率提升禁止改变本档保底承诺(保底=承诺非概率)。
|
||||
@@ -123,13 +128,13 @@
|
||||
|
||||
| 类型 | 正向(奖励) | 负向(惩罚) |
|
||||
|---|---|---|
|
||||
| attack 增伤 | attack_up(主角输出池)——幅度/上限/权重见 `reward.tres` | enrage(敌方输出池)——幅度/上限见 `status_effects.tres` enrage 行 |
|
||||
| defense 护甲 | ac_up 盾牌加护(AC 掷点阈值轴——2026-09-16 换装,不入池)——幅度/上限/权重见 `reward.tres` | off_guard 失衡(AC 掷点阈值轴负向——2026-09-18 换装,不入池、退出主角防御池)——幅度/上限见 `status_effects.tres` off_guard 行 |
|
||||
| attack 增伤 | attack_up(hero_offense 池)——幅度/上限/权重见 `reward.tres` | enrage(enemy_output 池)——幅度/上限见 `status_effects.tres` enrage 行 |
|
||||
| defense 护甲 | ac_up 盾牌加护(AC 掷点阈值轴——2026-09-16 换装,不入池)——幅度/上限/权重见 `reward.tres` | off_guard 失衡(AC 掷点阈值轴负向——2026-09-18 换装,不入池、退出 hero_defense 池)——幅度/上限见 `status_effects.tres` off_guard 行 |
|
||||
| heal 回血 | heal_minor(满血零兑付照旧)——威力/权重见 `reward.tres` | heal_backlash 直伤:战斗结算直接扣血,不经增益状态——威力见 `reward.tres` |
|
||||
| blast 群伤 | spark_aoe 全体存活敌各吃一笔——威力/权重见 `reward.tres` | enemy_alert 警觉:敌方全体护甲等级 +1/层(`status_effects.tres` alert 行)——见 `reward.tres` |
|
||||
| weaken 削弱 | weaken(敌方输出池;同名重复授予只刷新剩余次数——2026-09-18 续时定案)——幅度见 `status_effects.tres` weaken 行 | sapped(主角输出池)——幅度见 `status_effects.tres` sapped 行 |
|
||||
| weaken 削弱 | weaken(enemy_output 池;同名重复授予只刷新剩余次数——2026-09-18 续时定案)——幅度见 `status_effects.tres` weaken 行 | sapped(hero_offense 池)——幅度见 `status_effects.tres` sapped 行 |
|
||||
| action 行动点 | ap_up:下轮行动点 +1——见 `reward.tres` | ap_drain 迟滞:下轮行动点 −1——见 `reward.tres` |
|
||||
| gp 财货 | gp_gain GP 袋:战斗内 GP 缓冲 +power,战斗完成随 GP 掉落统一入钱包账本(兑付编排归[战斗结算](战斗结算.md)、账本归[冒险结构](../冒险循环/冒险结构.md))——威力/权重见 `reward.tres` | gp_loss 破财:战斗内 GP 缓冲 −power,weight=0 纯字典不参与摇号——见 `reward.tres` |
|
||||
| gp 财货 | gp_gain GP 袋:战斗内 GP 缓冲 +power,战斗完成随 gp_dropped 统一入钱包账本(兑付编排归[战斗结算](战斗结算.md)、账本归[冒险结构](../冒险循环/冒险结构.md))——威力/权重见 `reward.tres` | gp_loss 破财:战斗内 GP 缓冲 −power,weight=0 纯字典不参与摇号——见 `reward.tres` |
|
||||
| pierce 穿刺 | pierce_strike 穿刺弹:单目标克制直伤(attack_type=pierce 查克制矩阵,必中全额不掷点;目标 = 固定顺位最前存活敌)——威力/权重见 `reward.tres` | pierce_snare 穿刺陷阱:主角直伤,不经增益状态——威力见 `reward.tres` |
|
||||
| magic 魔法 | magic_bolt 魔法矢:单目标克制直伤(attack_type=magic,同上)——威力/权重见 `reward.tres` | magic_recoil 魔法反噬:主角直伤,不经增益状态——威力见 `reward.tres` |
|
||||
|
||||
@@ -141,7 +146,7 @@
|
||||
|
||||
### 负向恒即时:惩罚没有库存语义
|
||||
|
||||
负向兑付的账户动作全部在授予段受理,不入库、不出窗口——惩罚不设库存、不留存量;其中**伤害形态(群伤/直伤类负向行)的扣血落地殿后到战斗段末**(2026-10-06 用户裁,单据暂存,见[战斗结算](战斗结算.md));主角在敌方还手中倒下则地图伤害账整体不兑(逐单留「未生效」行)。正向里的 percent 类(增益行)进[增益状态](增益状态.md)的状态池;heal 正向当场结算;gp 正负两向(GP 袋 / 破财)当场执行——记入战斗内 GP 缓冲,战斗完成随 GP 掉落与钱包结算(账本归[冒险结构](../冒险循环/冒险结构.md)),同样无库存语义。叠层饱和由战斗结算既有池 clamp 承载;blast 负向(警觉)与 action 负向(迟滞)直授无上限。
|
||||
负向兑付的账户动作全部在授予段受理,不入库、不出窗口——惩罚不设库存、不留存量;其中**伤害形态(群伤/直伤类负向行)的扣血落地殿后到战斗段末**(2026-10-06 用户裁,单据暂存,见[战斗结算](战斗结算.md));主角在敌方还手中倒下则地图伤害账整体不兑(逐单留「未生效」行)。正向里的 percent 类(增益行)进[增益状态](增益状态.md)的状态池;heal 正向当场结算;gp 正负两向(GP 袋 / 破财)当场执行——记入战斗内 GP 缓冲,战斗完成随 gp_dropped 与钱包结算(账本归[冒险结构](../冒险循环/冒险结构.md)),同样无库存语义。叠层饱和由战斗结算既有池 clamp 承载;blast 负向(警觉)与 action 负向(迟滞)直授无上限。
|
||||
|
||||
举证:本节为兑付语义,无计算。
|
||||
|
||||
@@ -210,23 +215,23 @@
|
||||
|
||||
| 行 | 类型 | 极性 | 取值域 / 字段语义 | 现行值 | 所在池 |
|
||||
|---|---|---|---|---|---|
|
||||
| attack_up | attack | 正向 | weight [0,999] · power 不消费(percent 行 effect_id → 状态效果表 attack_up 引用) | 见 `data/tables/reward.tres` | 格面池 |
|
||||
| ac_up | defense | 正向 | weight [0,999] · power 不消费(percent 行 effect_id → 状态效果表 ac_up 引用) | 同上 | 同上 |
|
||||
| attack_up | attack | 正向 | weight [0,999] · power 不消费(percent 行 effect_id → StatusEffectTable attack_up 引用) | 见 `data/tables/reward.tres` | 格面池 |
|
||||
| ac_up | defense | 正向 | weight [0,999] · power 不消费(percent 行 effect_id → StatusEffectTable ac_up 引用) | 同上 | 同上 |
|
||||
| spark_aoe | blast | 正向 | power [0,999]·power_min/power_max 可选区间·weight [0,999](flat 行 effect_id 恒空) | 同上 | 同上 |
|
||||
| heal_minor | heal | 正向 | power [0,999]·power_min/power_max 可选区间·weight [0,999](flat 行 effect_id 恒空) | 同上 | 同上 |
|
||||
| weaken | weaken | 正向 | weight [0,999] · power 不消费(percent 行 effect_id → 状态效果表 weaken 引用) | 同上 | 同上 |
|
||||
| enrage | attack | 负向 | weight=0 不参与摇号·power 不消费(percent 行 effect_id → 状态效果表 enrage 引用) | 同上 | 同上 |
|
||||
| off_guard | defense | 负向 | weight=0 不参与摇号·power 不消费(percent 行 effect_id → 状态效果表 off_guard 引用) | 同上 | 同上 |
|
||||
| weaken | weaken | 正向 | weight [0,999] · power 不消费(percent 行 effect_id → StatusEffectTable weaken 引用) | 同上 | 同上 |
|
||||
| enrage | attack | 负向 | weight=0 不参与摇号·power 不消费(percent 行 effect_id → StatusEffectTable enrage 引用) | 同上 | 同上 |
|
||||
| off_guard | defense | 负向 | weight=0 不参与摇号·power 不消费(percent 行 effect_id → StatusEffectTable off_guard 引用) | 同上 | 同上 |
|
||||
| heal_backlash | heal | 负向 | weight=0 不参与摇号·power [0,999](flat 行 effect_id 恒空) | 同上 | 同上 |
|
||||
| enemy_alert | blast | 负向 | weight=0 不参与摇号·effect_id=alert(敌方护甲等级 +1——effect 引用行,unit=ac) | 同上 | 同上 |
|
||||
| ap_up | action | 正向 | weight [0,999] 参与摇号 | 同上 | 同上 |
|
||||
| ap_drain | action | 负向 | weight=0 不参与摇号 | 同上 | 同上 |
|
||||
| gp_gain | gp | 正向 | weight [0,999] 参与摇号 · power [0,999]·power_min/power_max 可选区间(flat 行 effect_id 恒空) | 同上 | 同上 |
|
||||
| gp_loss | gp | 负向 | weight=0 不参与摇号 · power [0,999](flat 行 effect_id 恒空) | 同上 | 同上 |
|
||||
| sapped | weaken | 负向 | weight=0 不参与摇号·power 不消费(percent 行 effect_id → 状态效果表 sapped 引用) | 同上 | 同上 |
|
||||
| sapped | weaken | 负向 | weight=0 不参与摇号·power 不消费(percent 行 effect_id → StatusEffectTable sapped 引用) | 同上 | 同上 |
|
||||
| clear_blast | blast | 正向 | clear_default 池·power [0,999]·power_min/power_max 可选区间·weight [0,999] | 同上 | 清图槽 |
|
||||
|
||||
摇号只消费正向格面池的权重(类型频次由此涌现——具体权重读 `reward.tres`);负向行是纯兑付字典,按(类型,极性)查表取用,不消费权重。权重分布按四档概率结构组织(档成员与保底规则见「四档概率结构与保底」节;现行权重为基准锚,数值调整归调参批)。clear_blast 对全体存活敌各吃一笔当场兑付的 flat 伤害。奖励配置表已随可选类删除下线——注入概率、按板保底等参数全部失义(旧「按板保底」指已删除的可选类道具注入保底,与四档结构的型级保底无关)。
|
||||
摇号只消费正向格面池的权重(类型频次由此涌现——具体权重读 `reward.tres`);负向行是纯兑付字典,按(类型,极性)查表取用,不消费权重。权重分布按四档概率结构组织(档成员与保底规则见「四档概率结构与保底」节;现行权重为基准锚,数值调整归调参批)。clear_blast 对全体存活敌各吃一笔当场兑付的 flat 伤害。RewardConfigTable 已随可选类删除下线——注入概率、按板保底等参数全部失义(旧「按板保底」指已删除的可选类道具注入保底,与四档结构的型级保底无关)。
|
||||
|
||||
结构冻结(改动走本文修订流程,不走调参):九型封闭枚举(伤害道具批 2026-09-18 修订五→七、格面资源八型批 2026-09-20 修订七→八、同日 GP+商店房批修订八→九)、危险格与安全格同池、极性矩阵、装板期预分配且无重摇、负向恒即时无库存、清图恒非空、除摇号外零随机(四档保底补签属装板期校验环节,消费摇号环节随机流,非重摇——补签后身份全程只读)。
|
||||
|
||||
@@ -239,7 +244,7 @@
|
||||
- 类型封闭与字典完整:表里出现九型之外的类型、或任一型缺正向/负向行,加载拒绝。
|
||||
- 未生效可见:满层增益、满血正向治疗、无存活敌的群伤,各自在结算明细记"奖励未生效"行,零折算、零补偿。
|
||||
- 加载护栏:池空、清图池无正当量、增益引用悬空——任一命中即加载时返回错误并中止;默认内容加载通过。
|
||||
- 表实一致:数据表字段与奖励表字段定义逐字段一致。
|
||||
- 表实一致:数据表字段与 `data/schemas/reward_table.gd` 逐字段一致。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 增益状态
|
||||
|
||||
> 一句话:增益/减益的状态池、叠层与衰减
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.2
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -168,11 +168,11 @@
|
||||
| weaken 削弱 | 敌方攻击被削弱(同名重复标中只刷新剩余次数、层数恒 1) | 敌方 | 见 `status_effects.tres` weaken 行(取值域 [60,85],取负生效) | 时限读表 / 刷新(2026-09-18 续时定案) | 封印标中 |
|
||||
| enrage 暴走 | 敌方攻击提升 | 敌方 | 见 `status_effects.tres` enrage 行 | 时限/上限读表 / 叠加 | 标空封印反噬 / 踩雷(attack 型负向) |
|
||||
| off_guard 失衡 | 主角护甲等级降低(AC 轴——掷点判定阈值下调、更易被命中;2026-09-18 换装,原百分比承伤池已退) | 主角 | 见 `status_effects.tres` off_guard 行 | 时限/上限读表 / 叠加 | 标空封印反噬 / 踩雷(defense 型负向)/ 敌方妨害技(2026-09-19 新效应词汇批——蛛网束缚载体,duration 由技能行覆盖) |
|
||||
| sapped 乏力 | 主角输出降低(weaken 型负向,主角输出池) | 主角 | 见 `status_effects.tres` sapped 行 | 时限/上限读表 / 叠加 | 危险格负向 / 标空封印(2026-09-15 格面资源批)/ 敌方妨害技(大地脉动——L3 Boss 石君王独占,2026-09-20 第三关内容批) |
|
||||
| empower 蓄力 | 敌方输出倍率增益(敌方输出池——蓄力技载体;幅度读表) | 敌方 | 见 `status_effects.tres` empower 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
|
||||
| fortify 硬化 | 敌方防御提升(**敌方防御池**——硬化技载体;负值入池 = 主角攻击折半,2026-09-18 符号纠正——旧正值实际翻倍) | 敌方 | 见 `status_effects.tres` fortify 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
|
||||
| sapped 乏力 | 主角输出降低(weaken 型负向,hero_offense 池) | 主角 | 见 `status_effects.tres` sapped 行 | 时限/上限读表 / 叠加 | 危险格负向 / 标空封印(2026-09-15 格面资源批)/ 敌方妨害技(大地脉动——L3 Boss 石君王独占,2026-09-20 第三关内容批) |
|
||||
| empower 蓄力 | 敌方输出倍率增益(enemy_output 池——蓄力技载体;幅度读表) | 敌方 | 见 `status_effects.tres` empower 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
|
||||
| fortify 硬化 | 敌方防御提升(**敌方防御池 enemy_defense**——硬化技载体;负值入池 = 主角攻击折半,2026-09-18 符号纠正——旧正值实际翻倍) | 敌方 | 见 `status_effects.tres` fortify 行 | duration 读表 = 1 个有效增益拍 / 刷新 | 敌方技能施放(2026-09-16 敌人技能池批) |
|
||||
|
||||
empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(技能行 buff_ref 引用,施放时长由技能行覆盖——技能冷却与增益持续是两个计时器):两行 duration 表值(读表)的口径是"先兑付后衰减含施放当轮"——施放发生在第 N 结算战斗段,存活到第 N+1 结算战斗段才兑付"下一拍",即"持续 1 个有效结算"(proposal 语义的状态池落地)。敌方防御池是第四个乘区池:敌方作为防守方的百分比修正池,消费面 = [战斗结算](战斗结算.md)主角攻击的池乘区——四池对称(敌打主角 = 主角防御池 × 敌方输出池,主角打敌 = 主角输出池 × 敌方防御池),状态池语义零延伸:仍是同构实例、side-wide 加算、不封顶不保底。
|
||||
empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(技能行 buff_ref 引用,施放时长由技能行覆盖——技能冷却与增益持续是两个计时器):两行 duration 表值(读表)的口径是"先兑付后衰减含施放当轮"——施放发生在第 N 结算战斗段,存活到第 N+1 结算战斗段才兑付"下一拍",即"持续 1 个有效结算"(proposal 语义的状态池落地)。敌方防御池(enemy_defense)是第四个乘区池:敌方作为防守方的百分比修正池,消费面 = [战斗结算](战斗结算.md)主角攻击的池乘区——四池对称(敌打主角 = hero_defense × enemy_output,主角打敌 = hero_offense × enemy_defense),状态池语义零延伸:仍是同构实例、side-wide 加算、不封顶不保底。
|
||||
|
||||
削弱行是当量锚在状态池侧的数据落点:封印标中的收益折算成统一价值后,必须严格高于最低档主角增益——"封印标中必须比随便挖一格更值",否则没人愿意封印。这条锚的契约归[行动经济](../排雷循环/行动经济.md),对照验收归[战斗结算](战斗结算.md);暴走与失衡两行分别是 attack/defense 型负向(极性矩阵"标错/踩雷"分支兑付)在状态池侧的数据落点:行内容与载体裁决归它,本表只承载行值(失衡已换装 AC 轴不入池——2026-09-18 结构修复批)。**失衡另有第二来源**:敌方妨害技(2026-09-19 新效应词汇批——蛛化卓尔精灵"蛛网束缚",敌方技能施放来源、duration 由技能行 buff_duration 覆盖)——状态池零新语义,同构实例照常受理;乏力 sapped = 妨害第二词汇,载体已落地(L3 Boss 灰矮人石君王独占妨害技「大地脉动」,2026-09-20 第三关内容批)。
|
||||
|
||||
@@ -226,16 +226,16 @@ empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(
|
||||
| alert 幅度 | [0, 4] | ac 行 magnitude | 警觉(敌方护甲等级 +1/层 provisional);消费 = 战斗结算护甲等级掷点判定 |
|
||||
| weaken 幅度 | 百分比取值域 [60,85],取负生效 | percent 行 magnitude | 削弱;须过"封印标中锚"对照 |
|
||||
| enrage 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 暴走;attack 型负向行,进敌方输出修正池 |
|
||||
| off_guard 幅度 | 护甲等级 [−20,20] 且非 0 | ac 行 magnitude | 失衡;标空封印反噬载体,掷点判定阈值逐层下调(2026-09-18 换装 AC 轴,不入池、退出主角防御池) |
|
||||
| off_guard 幅度 | 护甲等级 [−20,20] 且非 0 | ac 行 magnitude | 失衡;标空封印反噬载体,掷点判定阈值逐层下调(2026-09-18 换装 AC 轴,不入池、退出 hero_defense 池) |
|
||||
| sapped 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 乏力;危险格负向 weaken 型,进主角输出修正池(2026-09-15 格面资源批补登记) |
|
||||
| empower 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 蓄力;敌方技能池增益技载体,进敌方输出修正池 |
|
||||
| fortify 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 硬化;敌方技能池增益技载体,进**敌方防御池**(负值 = 减伤方向——2026-09-18 符号纠正) |
|
||||
| 初始剩余次数 | 整数 [1,99] | duration_settlements | 一次性语义行逐行读表;续时行 = weaken(2026-09-18 定案,duration 2)+ empower/fortify(1 个有效增益拍——先兑付后衰减含施放当轮)+ **attack_up / ac_up(2026-09-20 主角增益续时批,duration 表值 1 维持——续时语义在 duration=1 下表现为重复拿重置当轮倒数;跨轮延续随将来 duration 拉长自然显形,数值归状态层重设计批)**;拉长 = 恢复跨轮延续、规划变简单 |
|
||||
| fortify 幅度 | 百分比 [−100,100] 且非 0 | percent 行 magnitude | 硬化;敌方技能池增益技载体,进**敌方防御池 enemy_defense**(负值 = 减伤方向——2026-09-18 符号纠正) |
|
||||
| 初始剩余次数 | 整数 [1,99] | duration_settlements | 一次性语义行逐行读表;续时行 = weaken(2026-09-18 定案,duration 2)+ empower/fortify(1 个有效增益拍——先兑付后衰减含施放当轮)+ **attack_up / ac_up(2026-09-20 主角增益续时批,duration 表值 1 维持——续时语义在 dur=1 下表现为重复拿重置当轮倒数;跨轮延续随将来 duration 拉长自然显形,数值归状态层重设计批)**;拉长 = 恢复跨轮延续、规划变简单 |
|
||||
| 叠层上限 | 整数 [1,16] | max_stack | 仅叠加策略消费;刷新行层数恒 1——weaken / attack_up / ac_up 表值上限在续时语义下不消费(2026-09-18 / 2026-09-20),empower/fortify ×1(冷却闸下不可能自叠加) |
|
||||
|
||||
非调参的冻结项:三类合并策略语义、两种量纲语义、来源类别枚举、"先兑付后衰减"时序、拒绝原子性、零随机——改动走本文修订流程,不走调参。
|
||||
|
||||
联动纪律:增伤与削弱是当量锚的两端;盾牌加护与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)的承伤预期联动(掷点折扣轴——AC 行值变更须复算生存链区间;2026-09-20 主角增益续时批后 ac_up 层数恒 1、局内可达 AC 上限 11,复算随调参批);削弱改续时后"单轮层数上限受[行动经济](../排雷循环/行动经济.md)行动点约束"的联动随之失效(2026-09-18 续时定案——同名重复标中只刷新剩余次数、层数恒 1;2026-09-20 起主角侧 attack_up / ac_up 同口径)。这些联动值禁止独立调参,修订须重跑锚对照并同步登记册。
|
||||
联动纪律:增伤与削弱是当量锚的两端;盾牌加护与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)的承伤预期联动(掷点折扣轴——AC 行值变更须复算生存链区间;2026-09-20 主角增益续时批后 ac_up 层数恒 1、局内可达 AC 上限 11,复算随调参批);削弱改续时后"单轮层数上限受[行动经济](../排雷循环/行动经济.md)行动点约束"的联动随之失效(2026-09-18 续时定案——同名重复标中只刷新剩余次数、层数恒 1;2026-09-20 起主角侧 attack_up / ac_up 同口径)。这些联动值禁止独立调参,修订须重跑锚对照并同步 registry。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -249,7 +249,7 @@ empower 与 fortify 是敌方技能池增益技在状态池侧的数据落点(
|
||||
- 合成不设上下限:状态池输出的有效值恒等于层数 × 行值,越出百分比域不封顶不保底;地板在战斗结算侧。
|
||||
- 快照抗重载:已授予实例的数值在战斗中不受配置表重载影响,只影响后续授予。
|
||||
- 确定性回放:同一授予序列驱动两个独立状态池实例,生效清单(含排列顺序)与衰减轨迹逐项相同。
|
||||
- 表实一致:配置表字段与状态表的字段定义逐字段一致。
|
||||
- 表实一致:配置表字段与 `data/schemas/status_effect_table.gd` 逐字段一致。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 战斗结算
|
||||
|
||||
> 一句话:轮末结算的编排与逐行兑现
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.2
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
| ④ 衰减段 | 移除到期的临时效果;每轮恰好一次,含末轮——清图奖励先兑付、效果后衰减 |
|
||||
| ⑤ 判定段 | 先判主角倒下(负),再判敌人清空(胜),都不满足则继续下一轮 |
|
||||
|
||||
结算本体是纯逻辑步骤流:零界面依赖、禁止动画等待,随机消费只走封闭随机流。触发只读行动经济的相位读数与轮末标记,这条消息有棋盘路径和停手路径两个发射源,到达先后不承载语义。这些性质共同保证结算可回放:同样的种子、同样的事件序列,跑出的步骤流逐位复现——录像回放与断言复测都建立在它上面。随机消费恰七处(2026-09-16 敌人技能池批由两处扩为三处;2026-09-17 分支节点图批换板入编排后扩为五处;2026-09-20 地形变异首批类型定稿批扩为六处——变异布置;同日 GP+商店房批扩为七处——战斗结束掉落掷定):战斗开始掷骰定敌方实际数量与攻击基线浮动,属于初始化随机、发生在结算步骤流之外;技能摇号属于回合内随机,但时点前置到每轮开轮、同样发生在结算步骤流之外(消费专用 `behavior_roll` 封闭流,每敌按生成序派生独立子流,单敌出招轨迹可独立复放、互不穿插);护甲等级掷点属于回合内随机、发生在步骤流之内(消费专用 `armor_roll` 封闭流,逐次掷逐次取号,可逐位回放);奖励格摇号(消费 `reward_roll` 封闭流,装板期格面资源批派发)、变异布置(消费 `variant_place` 封闭流,装板与资源预分配之后——棋盘设置顺序第 4 步)与换板棋盘生成(消费 `board_gen` 封闭流,清图轮换板时点)均属初始化随机、发生在结算步骤流之外;战斗结束掉落掷定属出口随机(消费 `gp_drop` 封闭流,按战斗节点身份查商店表掷定 GP 掉落,与关级加值、战斗内缓冲合成本战 GP 掉落),发生在结算步骤流之外。七处皆封闭随机流,同种子同输入逐位复现。
|
||||
结算本体是纯逻辑步骤流:零界面依赖、禁止动画等待,随机消费只走封闭随机流。触发只读行动经济的相位读数与轮末标记,这条消息有棋盘路径和停手路径两个发射源,到达先后不承载语义。这些性质共同保证结算可回放:同样的种子、同样的事件序列,跑出的步骤流逐位复现——录像回放与断言复测都建立在它上面。随机消费恰七处(2026-09-16 敌人技能池批由两处扩为三处;2026-09-17 分支节点图批换板入编排后扩为五处;2026-09-20 地形变异首批类型定稿批扩为六处——变异布置;同日 GP+商店房批扩为七处——战斗结束掉落掷定):战斗开始掷骰定敌方实际数量与攻击基线浮动,属于初始化随机、发生在结算步骤流之外;技能摇号属于回合内随机,但时点前置到每轮开轮、同样发生在结算步骤流之外(消费专用 `behavior_roll` 封闭流,每敌按生成序派生独立子流,单敌出招轨迹可独立复放、互不穿插);护甲等级掷点属于回合内随机、发生在步骤流之内(消费专用 `armor_roll` 封闭流,逐次掷逐次取号,可逐位回放);奖励格摇号(消费 `reward_roll` 封闭流,装板期格面资源批派发)、变异布置(消费 `variant_place` 封闭流,装板与资源预分配之后——棋盘设置顺序第 4 步)与换板棋盘生成(消费 `board_gen` 封闭流,清图轮换板时点)均属初始化随机、发生在结算步骤流之外;战斗结束掉落掷定属出口随机(消费 `gp_drop` 封闭流,按战斗节点身份查商店表掷定 GP 掉落,与关级加值、战斗内缓冲合成本战 gp_dropped),发生在结算步骤流之外。七处皆封闭随机流,同种子同输入逐位复现。
|
||||
|
||||
举证:五段为流程编排,无计算;段序常量存配置表,加载时校验与定稿顺序完全一致,不一致拒绝启动。
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
| 治疗行 | 治疗生效一行:封顶后的真实回复量 |
|
||||
| 奖励未生效行 | 满层拒收、满血治疗等合法例外一行 |
|
||||
| 封印未中行 | 封印落空的零值归因行,每颗雷只记一次;标错的负向兑付另记效果行 |
|
||||
| 蓄力行 | 敌人本拍蓄力不动手(攒下一击)时记一行 **(2026-09-16 敌人技能池批改型为施放行:敌人本拍施放增益技——0 伤害动作、具名技能、不掷不折〔原"不兑付伏击"读怪奖励语义随 2026-09-20 八型批伏击退役作废〕;蓄力语义改写为纯攻击增益技,见[敌人系统](敌人系统.md))** |
|
||||
| 蓄力行 | 敌人本拍蓄力不动手(攒下一击)时记一行 **(2026-09-16 敌人技能池批改型为施放行 `cast`:敌人本拍施放增益技——0 伤害动作、具名技能、不掷不折〔原"不兑付伏击"读怪奖励语义随 2026-09-20 八型批伏击退役作废〕;蓄力语义改写为纯攻击增益技,见[敌人系统](敌人系统.md))** |
|
||||
| 衰减行 | 到期临时效果移除一行 |
|
||||
| 判定行 | 胜 / 负 / 继续各一行;终局判定行同时是胜负画面的数据锚 |
|
||||
| 高光行 | 完美封印成立时一行,只记实际有效兑付 |
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
基础 9 类写的是裸机制的账:玩家没有任何专长时,结算流水的每一行都出得了这九类。有了专长之后,效果引擎会在段内挂点插入额外的结算效果,这类效果写**扩展行**。扩展行是**一个**行型,不是每种专长效果各占一个行型——具体插的是哪种效果,由行携带的效果身份(effect_id 载荷)说明,呈现层按身份取各自的行文案。专长会不断增加、效果种类不可穷举,行型词表因此对扩展类封口:新增专长效果只新增载荷身份,不再新增行型。
|
||||
|
||||
扩展行与基础行共用同一套行协议:公共字段、来源归因、两层豁免、无来源即炸,全部照常生效。发射时点由段序骨架的挂点决定(时序与挂点施加面归架构文档「战斗域装配现状」节),本节只管这行是什么、带什么字段。扩展行携带效果身份(effect_id 载荷);效果身份清单与各发射点归架构文档「战斗域装配现状」与「战斗编排域拆件定稿」节登记。
|
||||
扩展行与基础行共用同一套行协议:公共字段、来源归因、两层豁免、无来源即炸,全部照常生效。发射时点由段序骨架的挂点决定(时序与挂点施加面归架构文档「模块归属·战斗域装配现状」节),本节只管这行是什么、带什么字段。实现已收敛为单一扩展行型(`extended`)+效果身份载荷(`effect_id`);效果身份清单与发射点以实现侧 `battle_orchestrator.gd` 文件头注为准。
|
||||
|
||||
举证:本节为行协议约定,无计算。
|
||||
|
||||
@@ -123,7 +123,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
||||
| 层数 × 行值 | 单条效果的叠层数与行值,读[增益状态](增益状态.md)的实例数据 | 行值归该系统 |
|
||||
| 完美乘数 | 完美封印给清图奖励的乘数,配置值 | 读 `settlement.tres` p_perfect(现行值读表) |
|
||||
|
||||
**gp / ap 当量口径注记(2026-10-05 判式换代批 T3——口径空白登记)**:上式 flat 类枚举(直伤、治疗、行动点)不含 gp——现行对账按 **gp 当量 = flat power 代理**计(GP 袋 3 / 破财 2,方案报告假设 A5);ap 当量 = flat 表值 1,机会成本口径(+1AP ≈ 多挖一格 ≈ E_dig + 进度 + 信息价值)更高,差异仅登记不进主算(假设 A6)。gp 的精确口径应经商店定价换算(1 GP 的边际属性当量),归状态层/商店批复核后换代。封印溢价兑付(条款3 条件二形态 a,`settlement.tres` flag_hit_premium=125 provisional)按同型正向 ×(1+δ) 兑付——当量换算随同型行口径同步放大,整数量级取整四舍五入(与伤害管线向下取整口径分域,登记册顺带登记)。
|
||||
**gp / ap 当量口径注记(2026-10-05 判式换代批 T3——口径空白登记)**:上式 flat 类枚举(直伤、治疗、行动点)不含 gp——现行对账按 **gp 当量 = flat power 代理**计(GP 袋 3 / 破财 2,方案报告假设 A5);ap 当量 = flat 表值 1,机会成本口径(+1AP ≈ 多挖一格 ≈ E_dig + 进度 + 信息价值)更高,差异仅登记不进主算(假设 A6)。gp 的精确口径应经商店定价换算(1 GP 的边际属性当量),归状态层/商店批复核后换代。封印溢价兑付(条款3 条件二形态 a,`settlement.tres` flag_hit_premium=125 provisional)按同型正向 ×(1+δ) 兑付——当量换算随同型行口径同步放大,整数量级取整四舍五入(与伤害管线 round_direction=floor 分域,registry 顺带登记)。
|
||||
|
||||
### 授予段兑付:极性路由,四类动作各归各系统资源
|
||||
|
||||
@@ -138,7 +138,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
||||
| ① 插危险格、留到轮末判定 | 标中照常(该危险格资源正向) |
|
||||
| ② 插危险格、再直接挖开 | 只受挖雷一层惩罚(该危险格资源负向照常兑付;挖雷惩罚因惊动触发);标中不发(封印已随挖掘消失、不入判定基线) |
|
||||
| ③ 插安全格、留到轮末判定 | 标空惩罚照常(该安全格资源负向) |
|
||||
| ④ 插安全格、再直接挖开 | 零惩罚零奖励——正向兑付作废,记「奖励作废(封印格直接挖开)」归因行;标空判定同②自然缺席 |
|
||||
| ④ 插安全格、再直接挖开 | 零惩罚零奖励——正向兑付作废,记「奖励作废(封印格直接挖开)」归因行(reward_ineffective 行型);标空判定同②自然缺席 |
|
||||
|
||||
| 批 | 兑付 |
|
||||
|---|---|
|
||||
@@ -157,8 +157,8 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
||||
| 即时治疗(flat) | heal 正向 | 主角按表值回复并封顶上限 | 满血时零兑付,记"奖励未生效"行 |
|
||||
| 直伤(flat) | heal 负向 | 主角在战斗段末扣表值生命(暂存单殿后统一落地),不经增益状态 | 主角倒下则地图账整体不兑,逐单留"未生效"行 |
|
||||
| 警觉加层 | blast 负向 | 敌方全体护甲等级 +1/层(读 `reward.tres` enemy_alert 行 → `status_effects.tres` alert 行),入状态池 | 直授无上限;战斗段由防守方护甲等级读数消费 |
|
||||
| GP 缓冲(flat) | gp 正 / 负向 | GP 袋 / 破财按 power 记入战斗内 GP 缓冲(+power / −power);缓冲随战斗完成折进战斗结束信号的 GP 掉落统一到账(GP 归[冒险结构](../冒险循环/冒险结构.md)) | 无拒收态——缓冲只在战斗边界与钱包结算,战斗域零钱包状态 |
|
||||
| 行动点修正 | action 正/负向 | 下轮行动点 ±power(行动经济排队,下一轮开始兑现后清零;下限 0) | 排队净值不跨轮保留;明细记效果行(effect_id=ap_delta) |
|
||||
| GP 缓冲(flat) | gp 正 / 负向 | GP 袋 / 破财按 power 记入战斗内 GP 缓冲(+power / −power);缓冲随战斗完成折进 battle_finished 的 gp_dropped 统一到账(GP 归[冒险结构](../冒险循环/冒险结构.md)) | 无拒收态——缓冲只在战斗边界与钱包结算,战斗域零钱包状态 |
|
||||
| 行动点修正 | action 正/负向 | 下轮行动点 ±power(action_economy 排队,下一轮开始兑现后清零;下限 0) | 排队净值不跨轮保留;明细记效果行(effect_id=ap_delta) |
|
||||
|
||||
警觉(blast 负向——2026-09-20 八型批伏击退役换装)为敌方 side-wide 状态:多个敌人共享同一状态值、互不消耗,只活一轮、轮末清零;战斗段由防守方护甲等级读数消费(我打敌 = 敌方 armor_class + Σ敌方侧 ac 型状态)。其余各型负向受池 clamp 与叠层上限承载。
|
||||
|
||||
@@ -216,7 +216,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 ×
|
||||
| 穿刺 | 被克 | 克制 | 中性 | 对魔法护甲克制;对轻甲被克;**重甲中性**(挡得住刀刃、不排斥穿刺——2026-09-18 用户拍板;现行无重甲敌种,纯结构位) |
|
||||
| 魔法 | 中性 | 被克 | 克制 | 绕得过重甲,被魔法护甲吸收 |
|
||||
|
||||
修正三档:克制 +1 / 中性 0 / 被克 −1(加法点数,九格分布读 `settlement.tres` 甲效矩阵——2026-09-18 加法核换装:量纲由百分比改点数、五档词表退役;三档而非五档的理由 = 攻击基线个位数刻度下 ±2 触伤害下限或翻倍超重,假粒度;攻击成长后可扩弱档)。攻击类型是分量的固有属性(每个分量恒属普通 / 穿刺 / 魔法 之一),护甲类型是防守单位的固有属性,两者都不随层数、来源与轮次漂移;基础分量的类型归属是主角表的可配置值(营地永久强化的换型落点),矩阵键集 3×3 满格、结构冻结,数值 provisional。矩阵消费面 = 主角侧(奖励直伤道具 / 主角攻击基础分量)——敌方攻击现行不查矩阵,主角 armor_type 轴仍休眠、生效待敌方技能攻击类型批。主角增益与乏力经主角输出池修正攻击合计(2026-09-18 结构修复批:普通分量直乘旁路退役;2026-09-19 充能退役后合计 = 单分量,见池乘区公式行)。
|
||||
修正三档:克制 +1 / 中性 0 / 被克 −1(加法点数,九格分布读 `settlement.tres` 甲效矩阵——2026-09-18 加法核换装:量纲由百分比改点数、五档词表退役;三档而非五档的理由 = 攻击基线个位数刻度下 ±2 触伤害下限或翻倍超重,假粒度;攻击成长后可扩弱档)。攻击类型是分量的固有属性(每个分量恒属普通 / 穿刺 / 魔法 之一),护甲类型是防守单位的固有属性,两者都不随层数、来源与轮次漂移;基础分量的类型归属是主角表的可配置值(营地永久强化的换型落点),矩阵键集 3×3 满格、结构冻结,数值 provisional。矩阵消费面 = 主角侧(奖励直伤道具 / 主角攻击基础分量)——敌方攻击现行不查矩阵,主角 armor_type 轴仍休眠、生效待敌方技能攻击类型批。主角增益与乏力经 hero_offense 池修正攻击合计(2026-09-18 结构修复批:普通分量直乘旁路退役;2026-09-19 充能退役后合计 = 单分量,见池乘区公式行)。
|
||||
|
||||
主角攻击 = 单一基础分量(2026-09-19 充能退役批):量 = 攻击力基线(表值),类型 = 主角表 `attack_type`(营地永久强化换型 = 改字段;未来冒险前参数面承接"按关配型"的策略位)。原"普通 + 穿刺/魔法充能三分量"模型整体退役——挖掘期与战斗期之间不再有弹药供给线,克制应对从局内攒桶改为冒险前配型 + 棋盘火力(穿刺弹/魔法矢等直伤奖励道具,消费面不变)。
|
||||
|
||||
@@ -228,9 +228,9 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
|
||||
```
|
||||
敌方一次技能攻击 = max(damage_floor, floor( 掷点档位技能基础分量 ) × 主角防御乘数 × 敌方输出乘数 ) + 必中附加分量 rider(若有——2026-09-19 新效应词汇批:max(damage_floor, floor(攻击基线 × rider_mult)),rider 为后置加法不进乘区不掷不折);增益/妨害技 = 0 伤害施放行(不掷不折),妨害状态按状态行 target_side 落主角
|
||||
主角一次攻击 = max(damage_floor, floor( 攻击合计 × (100 + 主角输出乘数池合成值) ÷ 100 × (100 + 敌方防御乘数池合成值) ÷ 100 ) )——主角输出池(增伤/乏力载体)与敌方防御池(硬化载体)两池串乘在攻击合计之后(2026-09-19 充能退役后合计 = 单分量)
|
||||
主角一次攻击 = max(damage_floor, floor( 攻击合计 × (100 + 主角输出乘数池合成值) ÷ 100 × (100 + 敌方防御乘数池合成值) ÷ 100 ) )——hero_offense(增伤/乏力载体)与 enemy_defense(硬化载体)两池串乘在攻击合计之后(2026-09-19 充能退役后合计 = 单分量)
|
||||
粒度口径:增益池乘区作用在攻击合计层——合计为个位数时百分比档存在粒度取整(如合计 2 点 ×0.75 → 1,实际约 −33% 大于名义 −25%),为已知行为、接受现状;2026-09-18 数值语言拍板后百分比仅保留增益池 / AC 折扣档 / 暴击三处既有粗档,终值与量纲复核归状态层重设计批
|
||||
乘数 = 1 + 池合成值 ÷ 100;池内加算、每池独立封顶 ±100 百分点 → 乘数域 [0, 2];四池对称:敌打主角 = 主角防御池 × 敌方输出池,主角打敌 = 主角输出池 × 敌方防御池(2026-09-18 结构修复批:主角输出池乘区接线落地——attack_up 普通分量直乘旁路退役,旧"切片现状"注记销项)
|
||||
乘数 = 1 + 池合成值 ÷ 100;池内加算、每池独立封顶 ±100 百分点 → 乘数域 [0, 2];四池对称:敌打主角 = hero_defense × enemy_output,主角打敌 = hero_offense × enemy_defense(2026-09-18 结构修复批:hero_offense 乘区接线落地——attack_up 普通分量直乘旁路退役,旧"切片现状"注记销项)
|
||||
护甲等级掷点:掷单骰(骰面读表),掷点 ≥ 护甲等级 + 攻击加成 → 全额;低掷按缺口查减伤档位表(边界与档值读表,无零档)
|
||||
暴击:天然最大面(读表)→ 该次基础攻击分量 ×暴击倍率(读表)且恒全额(双方同规;掷点层概念,与技能重击严格区分)
|
||||
伤害下限:任何来源的伤害落地 ≥ damage_floor(读表,全局 max(damage_floor, ·)——折扣与池归零都不产生 v=0 伤害行;2026-09-20 扩全来源,取值域 [1, +∞))
|
||||
@@ -262,7 +262,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
└─ 关卡结束(上层显式调用)→ 清空秘宝背包,给出可见反馈
|
||||
```
|
||||
|
||||
停手与耗尽收轮的回合恒为同图继续;换图指令只允许出现在清图轮,其他轮发换图属于程序错误、立即上抛。秘宝背包以关卡为界:战斗结束不清背包,跨战斗延续;关卡结束时一次性清空,清空前先返回快照计数,作为"剩余秘宝随关卡结束清空"的可见反馈。战斗道具背包已随可选类删除(2026-09-15)下线。(2026-10-09 注:清空对象 = 关卡域秘宝库存——秘宝过渡形态的机械惰性承载,其投放渠道已随迭代 11 第①批全退役、现行恒空;现行秘宝=营地同调装配件、整局冒险生效不经此域,拆线归实装批——见[秘宝](../跨局循环/秘宝.md)沿革节。)
|
||||
停手与耗尽收轮的回合恒为同图继续;换图指令只允许出现在清图轮,其他轮发换图属于程序错误、立即上抛。秘宝背包以关卡为界:战斗结束不清背包,跨战斗延续;关卡结束时一次性清空,清空前先返回快照计数,作为"剩余秘宝随关卡结束清空"的可见反馈。战斗道具背包已随可选类删除(2026-09-15)下线。(2026-10-09 注:清空对象 = 关卡域库存 treasure_inventory——秘宝过渡形态的机械惰性承载,其投放渠道已随迭代 11 第①批全退役、现行恒空;现行秘宝=营地同调装配件、整局冒险生效不经此域,拆线归实装批——见[秘宝](../跨局循环/秘宝.md)沿革节。)
|
||||
|
||||
挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、资源预分配恰一次、变异布置"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美封印计数随装板重置。
|
||||
|
||||
@@ -294,13 +294,13 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
|
||||
| 呈现面 | 形态 | 载荷与语义 |
|
||||
|---|---|---|
|
||||
| 呈现状态快照 | 只读函数,全量 | 轮次、战斗结果、相位、行动点与储备、刷新可用性、主角(生命/上限/攻击/存活)、敌人数组(顺位/显示名/生命/敌种/护甲类型/护甲等级/摇定动作〔技能编号/类型/名〕/敌方增益/存活)、主角活跃效果投影——呈现层唯一的状态读取出口(敌人技能池批批 2 定稿:行为环当前拍/环进度字段随行为环退役拆除——2026-09-16,池与权重不公开) |
|
||||
| 战斗进行中谓词 | 只读函数,布尔 | 战斗未出结果且主角在场——组合根高频相位判断的低成本面 |
|
||||
| 奖励身份查询 | 只读函数,单格 | 已开格奖励身份解析的代理,转[地图战斗资源](地图战斗资源.md)的身份查询(就绪相位守卫归对方)——组合根注入棋盘徽章回调 |
|
||||
| 结算快照信号 | 信号,每次结算末 | 对象销毁前组装的全量状态快照(终局含胜负结果)——测试记录与数值分析消费 |
|
||||
| 战斗结束信号 | 信号,战斗结束时 | 载荷 = 胜负结果、主角余量生命与本战 GP 掉落(掉落掷定 + 关级加值 + 战斗内缓冲的合计;销毁前捕获)——呈现层在核心对象销毁后读状态的时序防护,钱包入账归[冒险结构](../冒险循环/冒险结构.md) |
|
||||
| 呈现状态快照 `presentation_snapshot` | 只读函数,全量 | 轮次、战斗结果、相位、行动点与储备、刷新可用性、主角(生命/上限/攻击/存活)、敌人数组(顺位/显示名/生命/敌种/护甲类型/护甲等级/摇定动作〔pending_skill/type/name〕/敌方增益 effects/存活)、主角活跃效果投影——呈现层唯一的状态读取出口(敌人技能池批批 2 定稿:行为环当前拍/环进度字段随行为环退役拆除——2026-09-16,池与权重不公开) |
|
||||
| 战斗进行中谓词 `is_battle_live` | 只读函数,布尔 | 战斗未出结果且主角在场——组合根高频相位判断的低成本面 |
|
||||
| 奖励身份查询 `query_reward_identity` | 只读函数,单格 | 已开格奖励身份解析的代理,转[地图战斗资源](地图战斗资源.md)的身份查询(就绪相位守卫归对方)——组合根注入棋盘徽章回调 |
|
||||
| 结算快照信号 `settlement_snapshot` | 信号,每次结算末 | 对象销毁前组装的全量状态快照(终局含胜负结果)——测试记录与数值分析消费 |
|
||||
| 战斗结束信号 `battle_finished` | 信号,战斗结束时 | 载荷 = 胜负结果、主角余量生命与本战 GP 掉落 `gp_dropped`(掉落掷定 + 关级加值 + 战斗内缓冲的合计;销毁前捕获)——呈现层在核心对象销毁后读状态的时序防护,钱包入账归[冒险结构](../冒险循环/冒险结构.md) |
|
||||
|
||||
另设一个诊断观测面(诊断快照)供组合根诊断转储与行为探针消费:它暴露编排内部状态,不属于呈现契约,不作其他用途。
|
||||
另设一个诊断观测面(诊断快照 `diagnostic_snapshot`)供组合根诊断转储与行为探针消费:它暴露编排内部状态,不属于呈现契约,不作其他用途。
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
@@ -321,7 +321,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
|
||||
## 调参表
|
||||
|
||||
结算用到的全部数值——当量、封顶、乘数、段序常量、甲效与护甲等级掷点参数——都存结算配置表,代码里零数值字面量;改数值就是改表回填。表值以快照进结算,战斗中途改表不生效。已锁字段与数值以结算表的字段定义与表行为准。
|
||||
结算用到的全部数值——当量、封顶、乘数、段序常量、甲效与护甲等级掷点参数——都存结算配置表,代码里零数值字面量;改数值就是改表回填。表值以快照进结算,战斗中途改表不生效。已锁字段与数值以 `data/schemas/settlement_table.gd` 与 `data/tables/settlement.tres` 为准。
|
||||
|
||||
| 参数 | 域 | 现行值 | 说明 |
|
||||
|---|---|---|---|
|
||||
@@ -360,7 +360,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值
|
||||
- 无来源即炸:每行明细都能指回一个来源事实(棋盘格、单位、清图或段级结论);找不到来源即断言失败,行型与来源类别两层豁免清单见明细流水一节,豁免行仍受其它契约约束。
|
||||
- 行型封闭:流水行型只出现本文登记的基础 9 类与扩展行;行型词表改动必须走本文修订并同步呈现层行格式化,未登记行型禁止落行。
|
||||
- 伤害单据管线(2026-09-24):全部伤害(主角先手、敌方伤害技、棋盘克制直伤、群伤、反噬、地形变异)经伤害控制器单据管线兑现,兑付配方封闭五种;目标在结账时刻照规则解析;死亡事件由单位自行宣布——怪死其未结单据作废(零行、不进冷却不进保底计数)、主角死兑付终止;段界结账为现行口径、开单即结为回切结构位,两模式各自同种子同输入逐位复现。
|
||||
- 条款3 对账(2026-10-05 判式换代批 T3——与行动经济 F1 条款3 重立同步):①聚合健康式 (1−ρ̂)·E_dig(u) − ρ̂·V_mine(u) ≥ 0 与 β 比值带 [1.2, 2.5] 判读逐 u 检算(清图支配性审计为常设重跑项,读数快照登记归 clause3 重立条);②封印溢价兑付正确:封印标中正向兑付 = 同型正向 ×(1+δ)(δ 读 `settlement.tres` flag_hit_premium,100=无溢价直通零扰动),三类形态全覆盖(flat power / percent 幅度 / gp 缓冲)、标空与挖格兑付不乘溢价、危险格与安全格同池结构零触碰。
|
||||
- 条款3 对账(2026-10-05 判式换代批 T3——与行动经济 F1 条款3 重立同步):①聚合健康式 (1−ρ̂)·E_dig(u) − ρ̂·V_mine(u) ≥ 0 与 β 比值带 [1.2, 2.5] 判读逐 u 检算(常设重跑入口 `tools/clear_dominance_audit.py`,读数快照归 registry clause3 重立条);②封印溢价兑付正确:封印标中正向兑付 = 同型正向 ×(1+δ)(δ 读 `settlement.tres` flag_hit_premium,100=无溢价直通零扰动),三类形态全覆盖(flat power / percent 幅度 / gp 缓冲)、标空与挖格兑付不乘溢价、危险格与安全格同池结构零触碰。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 战斗表现
|
||||
|
||||
> 一句话:战斗动画与演出(旧体系未单独成文)
|
||||
> 状态:范围草案(待设计);现行为 v1.1
|
||||
> 状态:范围草案(待设计)
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
附着在同一次样张上的还有一项已登记的裁决(登记出处 = 敌人系统的呈现契约):敌人层绘制优先级的插入位置——白话就是敌人的姿态精灵画在绘制顺序的哪一层,会不会、以及如何与棋盘上的数字、封印印记、小人发生遮挡。它随美术测试一并裁决,不在本文提前定。
|
||||
|
||||
两项相邻裁定已有结论,设计时直接继承:**敌人呈现形态已裁决(2026-09-20 用户看对照样张拍板)——全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条正下方,卡片式整体退役**(待办清单「敌人卡形态」解决移除,状态记录 99;battle.md 起草条款已随裁决改写,对照样张已在案存档);art-bible 的图标键契约已冻结,动画设计不必等图标终稿。
|
||||
两项相邻裁定已有结论,设计时直接继承:**敌人呈现形态已裁决(2026-09-20 用户看对照样张拍板)——全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条正下方,卡片式整体退役**(待办清单「敌人卡形态」解决移除,状态记录 99;battle.md 起草条款已随裁决改写,对照样张存档 `production/mockups/`);art-bible 的图标键契约已冻结,动画设计不必等图标终稿。
|
||||
|
||||
### 一屏样张的验收标准
|
||||
|
||||
@@ -100,13 +100,13 @@
|
||||
|
||||
**定义**:轮末结算的呈现节奏规则——结算行按演出层排播队列分组依次呈现、轮切换以「第 N 轮」横幅驻留,把核心层一帧同步跑完的结算翻译成玩家可跟读的逐行过程;与结算演出覆盖层(光带横扫/跨区弹道,迭代 6)共同构成结算期的演出面。
|
||||
|
||||
**作用对象与范围**:只作用于演出层——排播常量(段间间隔/段内间隔/横幅驻留)归演出层单点持有,本文登记现行值,横幅与节奏在演出层呈现。核心层零触碰:结算零界面等待、零动画等待,且「MC 与基线数据逐项比对」口径不受扰(T1 态 400/400 逐位实证在案)。
|
||||
**作用对象与范围**:只作用于演出层——排播常量在 `main.gd`(`PACE_SEGMENT_GAP` / `PACE_ROW_GAP`)与 `settlement_fx_view.gd`(`BANNER_DWELL`),横幅与节奏经 settlement_fx_view 呈现。核心层零触碰:`battle_orchestrator` 的「零 await」契约与「MC 与基线数据逐项比对」口径不受扰(T1 态 400/400 逐位实证在案)。
|
||||
|
||||
**生命周期**:进结算期起播——结算行按五段分组依序进明细带(段间 0.3s、段内 0.22s;段内值 0.06→0.22 系迭代 8 三轮修改批用户裁决「逐条演出可感知」);轮切换横幅驻留 0.6s 后消隐进下一轮;战斗结束排播收尾。**减动效双态**:开关开启 = 延迟归零同帧直落 + 横幅静态化(与设置面减动效联动——「可加速不可整体跳过」承诺的节奏侧兑现)。
|
||||
|
||||
**关联与边界**:结算顺序与结果归[战斗结算](战斗结算.md)(本节零触碰,逻辑先行、演出后行);减动效开关归[设置与本地化](../表现与支撑/设置与本地化.md);节奏常量由演出层单点持有,本文登记现行值与沿革,表值化随演出批再议;横幅发射计数构成验收判据。
|
||||
**关联与边界**:结算顺序与结果归[战斗结算](战斗结算.md)(本节零触碰,逻辑先行、演出后行);减动效开关归[设置与本地化](../表现与支撑/设置与本地化.md);节奏常量以代码为事实源(上列三常量),本文登记现行值与沿革,表值化随演出批再议;fx_probe 轮横幅发射计数为验收断言面。
|
||||
|
||||
**状态**:已实装(2026-09-29 迭代 8 卡⑦已入库、三轮修改批调参追认;验收套件第 15 套在册)。本节是本文第一块已落地内容,其余部分维持范围草案。
|
||||
**状态**:已实装(2026-09-29 迭代 8 卡⑦已入库、三轮修改批调参追认;pacing_queue_test 第 15 套在册)。本节是本文第一块已落地内容,其余部分维持范围草案。
|
||||
|
||||
## 依赖与输出
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 敌人系统
|
||||
|
||||
> 一句话:敌人数据、技能池出招、意图呈现
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.4
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.3
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
| 规则 | 含义 |
|
||||
|---|---|
|
||||
| 敌方效果对全体生效 | 范围效果作用于所有存活敌人——混编放开后(2026-10-07 行集多行批)场上可多种敌种共存,结算语义按存活单位逐一生效、不依赖"场上全同种"前提;"只打某一个"的单体寻址接口已在[增益状态](增益状态.md)〈单体寻址扩展位〉节定稿,随首个单体效果的内容批开放(见 P1) |
|
||||
| 行集构成纪律 | 敌人表按(关卡序号 × 深度带)存放;深度带=节点深度的区间——逐局生成使单点深度不再固定,配池按带不按点,难度坡随带递增。同一带键行集允许多行、允许不同敌种混编;Boss 行按终点配置,多终点各配一行(走哪条路决定打谁)。纪律三条,违规加载期返回错误并止动:①行集内 enemy_id 唯一(同一敌种在同行集仍只许一行);②同带键多行必须表文件内相邻,行序 = 声明序 = 生成序(行序即契约);③行集实例总数(各行骰后数量求和)≤ 4,单行数量域 [1,3] 不变(单行数量上限语义 = 单种数)。行数不设上限;同关随深度换敌种合法 |
|
||||
| 行集构成纪律 | 敌人表按(关卡序号 × 深度带)存放;深度带=节点深度的区间——逐局生成使单点深度不再固定,配池按带不按点,难度坡随带递增。同一带键行集允许多行、允许不同敌种混编;Boss 行按终点配置,多终点各配一行(走哪条路决定打谁)。纪律三条,违规加载期返回错误并止动:①行集内 enemy_id 唯一(同一敌种在同行集仍只许一行);②同带键多行必须表文件内相邻,行序 = 声明序 = 生成序(行序即契约);③行集实例总数(各行骰后数量求和)≤ 4,单行数量域 [1,3] 不变(UNIT_COUNT_MAX 语义 = 单种数)。行数不设上限;同关随深度换敌种合法 |
|
||||
| 主角数据行 | 主角战斗数值单独放一张全局单行表:生命上限、基础攻击力、护甲等级三字段(见调参表) |
|
||||
| 基础攻击恒存在 | 基础攻击不许配 0(配置为 0 加载期拒绝)——零基线乘任何百分比增益恒为零,"胜利路径恒有"的保障从数据层杜绝死锁 |
|
||||
| 先手攻击不是敌方技能拍 | 每次结算战斗段主角先手攻击顺位最前的存活敌人,这是固定动作;奖励侧的道具与增益是基础攻击之外的规划面伤害,归[地图战斗资源](地图战斗资源.md) |
|
||||
@@ -91,7 +91,7 @@
|
||||
| 钩爪恐魔 | 普通攻击 + 撕咬 + 蓄力 | 行值读表 | 行值读表 | L2/L3 群行位(蜘蛛同构池) |
|
||||
| 灰矮人石君王 | 普通攻击 + 重击 + 大地脉动 + **岩崩**(半血解锁) | 行值读表 | 行值读表 | L3 关底 Boss;大地脉动独占 |
|
||||
|
||||
护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据——**护甲列自 2026-10-05 技能池执行批起改读表口径**(本表轮廓列不再记具体甲型:现行 L1 全轻甲 / L2 仅 Boss 魔法甲 / L3 重甲登台的错峰投放以 `enemy.tres` 行值为准;历史「本表写魔甲/重甲」与表失同步的欠账顺带清偿)。护甲等级是另一条数值轴(防守方字段,基础攻击掷点的折扣判定读数):敌人表与主角表各增 `armor_class` 一列(域 [0, 999]),掷点与折扣的结算归[战斗结算](战斗结算.md),行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——三敌种首关与主角的护甲等级行值读配置表(第一关怪物 AC 相对较低,正式行值待怪物设定投值,登记[待办清单](../../../../待办清单.md)),两条轴的概念与字段禁止混用。举证:生成与护甲为数据面规则,无计算。
|
||||
护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据——**护甲列自 2026-10-05 技能池执行批起改读表口径**(本表轮廓列不再记具体甲型:现行 L1 全轻甲 / L2 仅 Boss 魔法甲 / L3 heavy 登台的错峰投放以 `enemy.tres` 行值为准;历史「本表写魔甲/重甲」与表失同步的欠账顺带清偿)。护甲等级是另一条数值轴(防守方字段,基础攻击掷点的折扣判定读数):敌人表与主角表各增 `armor_class` 一列(域 [0, 999]),掷点与折扣的结算归[战斗结算](战斗结算.md),行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——三敌种首关与主角的护甲等级行值读配置表(第一关怪物 AC 相对较低,正式行值待怪物设定投值,登记[待办清单](../../../../待办清单.md)),两条轴的概念与字段禁止混用。举证:生成与护甲为数据面规则,无计算。
|
||||
|
||||
### 技能池:每敌种一张带权技能池,每拍开轮摇号出招
|
||||
|
||||
@@ -111,12 +111,12 @@
|
||||
|---|---|---|
|
||||
| skill_id | 全部 | 主键,池条目引用键 |
|
||||
| display_name | 全部 | 玩家可见名(明细行与动画共用) |
|
||||
| type | 全部 | 封闭枚举 {普通攻击, 伤害, 增益, 妨害}——**新效应词汇批 2026-09-19 由三扩四**(设计权威 proposal-status-vocabulary.md〔提案已吸收退役——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0;多段命中经用户拍板退役不入枚举);新类型走本文修订 |
|
||||
| type | 全部 | 封闭枚举 {普通攻击, 伤害, 增益, 妨害}——**新效应词汇批 2026-09-19 由三扩四**(设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0;多段命中经用户拍板退役不入枚举);新类型走本文修订 |
|
||||
| damage_mult | 仅伤害 | 伤害倍率;域 [1.1, 16] provisional。普通攻击恒 1、不可配 |
|
||||
| rider_mult | 仅伤害、可省 | **必中附加分量(2026-09-19 新增)**:域 (0, 1],缺省无字段 = 无附加;分量值 = max(伤害下限, floor(攻击基线 × rider_mult))——随施放者攻击基线缩放,后置加法、必中全额、不进乘区、不出暴击(后置加法同族);价位锚 0.75 = AC 折扣档最轻档"不掉档的稳定伤害" |
|
||||
| cooldown_beats | 全部 | 施放后连续 N 拍不可摇中;普通攻击恒 0、不可配 |
|
||||
| buff_ref / buff_duration | 仅增益与妨害 | 效果引用(指向状态效果行)与持续回合数;**落点由状态行 target_side 路由**(增益 → 敌方侧 / 妨害 → 主角侧,施放类 side 守卫加载拒绝)——妨害技零新授予通道 |
|
||||
| trigger(触发条件) | 全部,可省 | {fact, op, value, latch} 四键——fact 与 op 取「触发条件」节封闭词表,value 类型与域随 fact,出域加载期拒绝;缺省无字段=无条件技,旧行为零变化(2026-10-26 情境条件触发器批立列、2026-10-27 迭代 39 实装落地;原池条目的血量百分比字段收编为本字段闩型首用例) |
|
||||
| trigger(触发条件) | 全部,可省 | {fact, op, value, latch} 四键——fact 与 op 取「触发条件」节封闭词表,value 类型与域随 fact,出域加载期拒绝;缺省无字段=无条件技,旧行为零变化(2026-10-26 情境条件触发器批立列、2026-10-27 迭代 39 实装落地;原池条目字段 unlock_hp_pct 收编为本字段闩型首用例) |
|
||||
| P1 字段位 | — | 命中段数、目标数——随对应后置批加列(触发条件位已由 trigger 立列收编——2026-10-26 立列、2026-10-27 实装;原"固定值分量"位已由 rider_mult 实装收编——2026-09-19;多段命中「命中段数」保留以防复活) |
|
||||
|
||||
普通攻击也是一行技能行,两条域校验锁死它的特殊性:倍率恒 1、冷却恒 0——想配倍率或冷却的就不是普攻,是伤害技。技能伤害存倍率、不存固定值:伤害 = 施放者攻击基线 × 技能倍率——同一行"重击",不同敌种按各自攻击基线缩放 = 基线 A × 技能倍率 M(行值读 enemy.tres / skills.tres),深层强化行自动缩放,这是共享技能表成立的前提;**固定的绝对值伤害不满足该前提**(不随基线缩放、跨关稀释——Brotato 教训),"固定值伤害"的合法形态是**必中附加分量 rider_mult**(×攻击基线的必中小倍率,2026-09-19 实装)。增益技带效果引用与持续回合,百分比天然按施放者同池生效,无缩放问题;妨害技同构,落点由状态行 target_side 路由到主角。
|
||||
@@ -179,7 +179,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
| 死亡作废 | 照常——摇定后兑现前死亡,本拍作废、不进冷却不进保底计数 |
|
||||
| 意图呈现 | 三档规格不变——情境技属特殊技,走类型级预告+结算明细具名,因果由技能名承载(如"趁隙偷袭");闩型保留解锁弹出规格(见"目标顺位与意图线索"节) |
|
||||
|
||||
半血解锁的收编:原池条目的血量百分比字段(2026-10-05 技能池执行批)收编为本字段闩型首用例——Boss 解锁技=trigger {fact: self_hp_pct, op: lte, value: 行值, latch: 真};解锁弹出规格(归因明细行+一次性技能名 toast)、单向闩语义、双面过滤行为全部不变(字段换代与三 Boss 行值迁移已随 2026-10-27 迭代 39 实装落地)。
|
||||
半血解锁的收编:原池条目字段 unlock_hp_pct(2026-10-05 技能池执行批)收编为本字段闩型首用例——Boss 解锁技=trigger {fact: self_hp_pct, op: lte, value: 行值, latch: 真};解锁弹出规格(归因明细行+一次性技能名 toast)、单向闩语义、双面过滤行为全部不变(字段换代与三 Boss 行值迁移已随 2026-10-27 迭代 39 实装落地)。
|
||||
|
||||
首批落地(已实装——2026-10-27 迭代 39):①三 Boss 解锁技迁移为闩型条件(行为零变化);②两个示范投放——地精池+低血防御增益「孤注守势」(self_hp_pct lte 35,纯增益)、L2/L3 群行位+停手偷袭伤害技「趁隙偷袭」(last_round_end eq 停手)。投放敌种、权重与阈值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md);"每池增益≤1"纪律不动,条件技照常计入预算。
|
||||
|
||||
@@ -203,7 +203,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
|
||||
即:普攻完全不可预测;特殊技有一次类型级预告,不可撤销,但给"继续挖还是停手"的决策依据。
|
||||
|
||||
**半血解锁弹出规格(2026-10-05 技能池执行批,D8 用户裁;内容数据驱动扩展批 T1 补登记——解锁判定点=通用事件「血量阈值 `enemy_hp_threshold`」的发射点,对所有带闩型血量触发条件的敌人逐个发射、非 Boss 专属——Boss 语义留给订阅条件判定;条件载体 2026-10-26 触发条件批起改技能行 trigger 闩型〔原池条目的血量百分比字段收编,行为零变化,见「触发条件」节〕)**:Boss 血量降至解锁阈值(trigger 行值,域 [1,99],缺省无字段=无门槛)时,下一个开轮摇号前出一次归因明细行「XX 解锁了 YY」(高光键为技能解锁,行型复用高光行零新增);呈现层对该行弹**一次性技能名 toast**(轻量提示,非演出——零动画资产、不改演出规格),只报技能名不报数值,池与权重不公开纪律不变。解锁=单向闩(治疗抬血不解锁);锁定条目双面过滤(不进可摇集合与保底特殊技集合——保底禁止逼出未解锁技);解锁后冷却初值 0 即可摇。投放纪律=机制通用、闩型解锁用例仅 Boss 专属技投放(enemy 表无 boss 编码位,硬闸须跨表查节点类型——不做硬闸,本句即文档纪律登记)。旧环"下一拍全程亮出(意图徽标 + 环点)"的预告粒度随行为环退役。技能动画的攻/防系映射归[战斗表现](战斗表现.md),敌人侧摇定动画位归[HUD 框架](../表现与支撑/HUD框架.md)(呈现载体 = 站桩立绘,2026-09-20 全站桩拍板),本系统只锁上面这张三档规格。
|
||||
**半血解锁弹出规格(2026-10-05 技能池执行批,D8 用户裁;内容数据驱动扩展批 T1 补登记——解锁判定点=通用事件「血量阈值 `enemy_hp_threshold`」的发射点,对所有带闩型血量触发条件的敌人逐个发射、非 Boss 专属——Boss 语义留给订阅条件判定;条件载体 2026-10-26 触发条件批起改技能行 trigger 闩型〔原池条目字段 `unlock_hp_pct` 收编,行为零变化,见「触发条件」节〕)**:Boss 血量降至解锁阈值(trigger 行值,域 [1,99],缺省无字段=无门槛)时,下一个开轮摇号前出一次归因明细行「XX 解锁了 YY」(高光键 `skill_unlock`,行型复用 highlight 零新增);呈现层对该行弹**一次性技能名 toast**(轻量提示,非演出——零动画资产、不改演出规格),只报技能名不报数值,池与权重不公开纪律不变。解锁=单向闩(治疗抬血不解锁);锁定条目双面过滤(不进可摇集合与保底特殊技集合——保底禁止逼出未解锁技);解锁后冷却初值 0 即可摇。投放纪律=机制通用、闩型解锁用例仅 Boss 专属技投放(enemy 表无 boss 编码位,硬闸须跨表查节点类型——不做硬闸,本句即文档纪律登记)。旧环"下一拍全程亮出(意图徽标 + 环点)"的预告粒度随行为环退役。技能动画的攻/防系映射归[战斗表现](战斗表现.md),敌人侧摇定动画位归[HUD 框架](../表现与支撑/HUD框架.md)(呈现载体 = 站桩立绘,2026-09-20 全站桩拍板),本系统只锁上面这张三档规格。
|
||||
|
||||
| 规格 | 含义 |
|
||||
|---|---|
|
||||
@@ -251,7 +251,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
| P1 | 情境条件触发器(低血触发防御、玩家停手时偷袭技等) | 已实装(2026-10-27 迭代 39——三 Boss 闩型迁移+两示范投放,见「触发条件」节与「首批落地」段) |
|
||||
| P1 | 个体化变体池(A 型好斗 / B 型守势、精英专属池) | 共识点 A 的 A2 案;登记[待办清单](../../../../待办清单.md) |
|
||||
| P1 | 全局特殊间隔旋钮 | 特殊技背靠背实测仍嫌时的备用闸;登记[待办清单](../../../../待办清单.md) |
|
||||
| P1 | 新效应词汇批(妨害技 + 必中附加分量已实装 2026-09-19——设计权威 proposal-status-vocabulary.md〔提案已吸收退役——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,实装面 = L2 Boss 卓尔;多段命中经用户拍板退役) | 妨害类型 + rider_mult 字段已落地;登记[待办清单](../../../../待办清单.md)(已解决移除,去向见状态记录) |
|
||||
| P1 | 新效应词汇批(妨害技 + 必中附加分量已实装 2026-09-19——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,实装面 = L2 Boss 卓尔;多段命中经用户拍板退役) | 妨害类型 + rider_mult 字段已落地;登记[待办清单](../../../../待办清单.md)(已解决移除,去向见状态记录) |
|
||||
| P1 | 敌种名录扩容与投放节奏(含第二关池与投放) | 投放节奏是关卡命脉,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| P1 | 单体寻址("只打某一个敌人"的目标指定) | 归集语义与呈现已裁定(2026-10-26;语义归[增益状态](增益状态.md)〈单体寻址扩展位〉节);实现随首个单体效果的内容批落地 |
|
||||
| P2 | 敌方技能图鉴 / 学习呈现(玩家侧技能知识系统) | 池不公开口径下的进阶信息面;登记[待办清单](../../../../待办清单.md) |
|
||||
@@ -269,7 +269,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
| unit_count_max | [unit_count, 3],可省略 | 数量区间上界;开战时在区间内掷定本战实际数量;缺省 = 定值 |
|
||||
| atk_min / atk_max | [0, 999] 可选配对 | 攻击基线区间:开战掷定一次、整战持久;缺省 = 定值行 |
|
||||
| armor_type | {轻甲, 魔法护甲, 重甲},缺省轻甲 | 克制结算归[战斗结算](战斗结算.md) |
|
||||
| attack_type | {普通, 穿刺, 魔法},缺省普通 | 敌方攻击类型轴(**2026-10-13 迭代 24 N3 开列实装**:20 行全填 normal,攻击类型闭集枚举+缺省回退向后兼容,与 armor_type 同位同款);消费面 = 战斗结算敌方技兑付路径的护甲克制矩阵查表(敌方开单第 9 参传值+克制消费点,见战斗结算);行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| attack_type | {普通, 穿刺, 魔法},缺省普通 | 敌方攻击类型轴(**2026-10-13 迭代 24 N3 开列实装**:20 行全填 normal,ATTACK_TYPES 闭集枚举+缺省回退向后兼容,与 armor_type 同位同款);消费面 = 战斗结算敌方技兑付路径的护甲克制矩阵查表(敌方开单第 9 参传值+克制消费点,见战斗结算);行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| armor_class(护甲等级) | int [0, 999],缺省 0 | 防守方护甲等级——基础攻击掷点的折扣判定读数,掷点结算归[战斗结算](战斗结算.md);与 armor_type(克制属性轴)两概念禁止混用;行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| hp | [1, 999] | 单位生命基线(难度修饰前) |
|
||||
| atk | [0, 999] | 攻击基线 |
|
||||
@@ -298,7 +298,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
|
||||
各敌种行值、池权重与池 EV 读数(含闸长期速率实测)一律读配置表与调参日志,本文不登记具体数值;EV 重锚与权重投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)。
|
||||
|
||||
结构冻结(非调参项,修订走本文流程):技能类型枚举封闭、每池恰一普攻、每池增益 ≤1、死亡即不动手(摇定后兑现前死亡作废不进账)、每结算每存活敌恰行动一次、行序、先作用后推进、固定顺位、**行集构成纪律(2026-10-07 行集多行批换代——原「每坐标恰一敌种」退役:行集内 enemy_id 唯一 + 同带键多行文件内相邻且行序 = 声明序 = 生成序 + 行集实例总数 ≤ 4)**、零随机(本系统自身语义零随机不变——摇号与掷点随机一律在[战斗结算](战斗结算.md)结算换算层按封闭随机流掷定,可回放契约 = 同种子同输入逐位复现,单敌出招轨迹可独立复放)。联动纪律:技能倍率 × 攻击(伤害拍支配)、权重 × 冷却 × 保底(池节奏三联动)禁止独立调参,联调须重跑方向性预检并同步登记册(登记 [待办清单](../../../../待办清单.md))。
|
||||
结构冻结(非调参项,修订走本文流程):技能类型枚举封闭、每池恰一普攻、每池增益 ≤1、死亡即不动手(摇定后兑现前死亡作废不进账)、每结算每存活敌恰行动一次、行序、先作用后推进、固定顺位、**行集构成纪律(2026-10-07 行集多行批换代——原「每坐标恰一敌种」退役:行集内 enemy_id 唯一 + 同带键多行文件内相邻且行序 = 声明序 = 生成序 + 行集实例总数 ≤ 4)**、零随机(本系统自身语义零随机不变——摇号与掷点随机一律在[战斗结算](战斗结算.md)结算换算层按封闭随机流掷定,可回放契约 = 同种子同输入逐位复现,单敌出招轨迹可独立复放)。联动纪律:技能倍率 × 攻击(伤害拍支配)、权重 × 冷却 × 保底(池节奏三联动)禁止独立调参,联调须重跑方向性预检并同步 registry(登记 [待办清单](../../../../待办清单.md))。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -314,7 +314,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错
|
||||
- 快照抗改表:实例化后修改敌人表,已生成单位的数值投影与实例池逐字不变;新实例才用新表值。
|
||||
- 表校验:越域值、池权重 ≤ 0、空池、普攻配倍率/冷却、池增益 > 1、skill_id 悬空、行集构成违例(行集内同敌种第二行 / 同带键多行不相邻)均在加载期返回错误并止动;域内合法极端(攻击基线 0)不拒;主角表恰一行、攻击配 0 拒绝。
|
||||
- 零随机回放:同一动作与受击序列驱动两个独立实例,存活投影、逐实例摇定轨迹、顺位返回序列逐项相同。
|
||||
- 表实一致:敌人表、主角表、技能表三张配置表的字段与各自字段定义逐字段一致。
|
||||
- 表实一致:三张配置表字段与 `data/schemas/enemy_table.gd`/`hero_table.gd`/`skill_table.gd` 逐字段一致。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 地形变异
|
||||
|
||||
> 一句话:格子的非雾变异(荆棘丛/藤蔓缠绕/岩浆/烬覆/落石/矿尘)与 Boss 图整图变异(贫矿脉),挖掘中可遭遇的地貌偏离
|
||||
> 状态:已定稿(首批类型随 2026-09-19 定稿批落地,第三关一对随 2026-09-20 第三关内容批落地;首个整图变异随 2026-10-04 全局作用域变异首发批落地);现行为 v1.1
|
||||
> 状态:已定稿(首批类型随 2026-09-19 定稿批落地,第三关一对随 2026-09-20 第三关内容批落地;首个整图变异随 2026-10-04 全局作用域变异首发批落地)
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
- 直伤量为加法核小整数(effect_value ∈ [1,9],行值 provisional 归难度曲线与Boss);每格携带单类型单 id。
|
||||
- 变异格未开时无预告呈现(遭遇式;视觉标识归表现层升级批)。
|
||||
|
||||
候选池门控(框架级现行机制):一种变异要进入本关的布置候选,须同时满足三个条件——它的解锁关号不大于当前关卡序号(直接整数比较)、它声明的地形(board_types)与本地形有交集(声明为空集等于通配)、且节点身份匹配(scope=global 行仅 Boss/精英节点入池,普通战斗节点静默跳过——2026-10-04 全局作用域变异批增第三维;elite 系前向词位,首发零表行)。候选池为空是合法状态:静默布置一张无变异的普通图,不返回错误、不警告。门控谓词与取值域见本文候选池门控节与变异表字段定义。
|
||||
候选池门控(框架级现行机制):一种变异要进入本关的布置候选,须同时满足三个条件——它的解锁关号不大于当前关卡序号(直接整数比较)、它声明的地形(board_types)与本地形有交集(声明为空集等于通配)、且节点身份匹配(scope=global 行仅 Boss/精英节点入池,普通战斗节点静默跳过——2026-10-04 全局作用域变异批增第三维;elite 系前向词位,首发零表行)。候选池为空是合法状态:静默布置一张无变异的普通图,不返回错误、不警告。门控谓词与取值域见本文候选池门控节与 `data/schemas/variation_table.gd`。
|
||||
|
||||
### 全局作用域型(scope=global——Boss 图整图变异)
|
||||
|
||||
region 型变异是「格子级」的:布置段往候选格域写格子快照。global 型变异是「整图」的:整图一个类型生效,不落任何格子(棋盘持有整图变异记录,逐格变异记录恒空)。**每图一型的整图推广(2026-10-04 用户裁决)**:普通图带 region 片,Boss/精英图带 global 型——两类图各自至多一型。
|
||||
region 型变异是「格子级」的:布置段往候选格域写格子快照。global 型变异是「整图」的:整图一个类型生效,不落任何格子(棋盘持有整图 `board_variants` 字段,逐格 `variants` 恒空)。**每图一型的整图推广(2026-10-04 用户裁决)**:普通图带 region 片,Boss/精英图带 global 型——两类图各自至多一型。
|
||||
|
||||
**替换制**:Boss/精英图命中全局型时,布置段跳过 region 布置(该图既无 region 片、也无格子级变异标记)——L2 完美 Boss 承伤已越 ≤50% 带,region 叠全局的叠加制火上浇油,不采纳。**兜底回落**:Boss/精英图的全局候选池为空时(含第 1 关 Boss 解锁门控未达=免疫,第 1 关是过滤器不是墙的教学保护)回落 region 布置,即回批前行为(保守向后兼容,防配置缺行静默裸奔——provisional)。
|
||||
|
||||
@@ -130,7 +130,7 @@ region 型变异是「格子级」的:布置段往候选格域写格子快照
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| 迭代 12(调研前置) | 反制路径重定(原:首批四类型的反制道具兑现,counter_items 回填——已作废) | 2026-10-03 用户终裁:同调位反制件=层级错配失败设计,义务作废;变异应对是否以局内形态补入,待双层 BD 调研仲裁后重新立项 |
|
||||
| ~~Alpha~~ **已落地** | 全局作用域变异(精英/Boss 图整图生效的变异形态) | **2026-10-04 全局作用域变异首发批落地**(迭代 14 ③号卡)——首批型=贫矿脉(案A 资源面·微贫向偏斜,替换制/恒定制/L1 Boss 免疫/三层预告);裁决全录见调研报告 §7(全局作用域设计空间调研(已退役,git 历史可查);原需求卡片已退役);带 A 杠杆注册全局难度批(Beta 阶段,未排期)顺带读数只测不判;精英图留词表前向位(首发零表行) |
|
||||
| ~~Alpha~~ **已落地** | 全局作用域变异(精英/Boss 图整图生效的变异形态) | **2026-10-04 全局作用域变异首发批落地**(迭代 14 ③号卡)——首批型=贫矿脉(案A 资源面·微贫向偏斜,替换制/恒定制/L1 Boss 免疫/三层预告);裁决全录见调研报告 §7(全局作用域设计空间调研(已退役,git 历史可查);原需求卡片已退役,git b3bbea5/01bfc15);带 A 杠杆注册全局难度批(Beta 阶段,未排期)顺带读数只测不判;精英图留词表前向位(首发零表行) |
|
||||
| P2 | "地形成本修饰"价目钩子启用 | 由行动经济持有;启用须随变异类型扩展,与行动经济重议按格定价的接口 |
|
||||
| P2 | 变异解锁节奏复核 | "每关至少引入一个新元素"的推进节奏,随[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)定稿复核 |
|
||||
| P2 | 变异格视觉标识与预告呈现 | 首批为遭遇式(未开无预告);标识位随表现层升级批 |
|
||||
@@ -145,7 +145,7 @@ region 型变异是「格子级」的:布置段往候选格域写格子快照
|
||||
| 直伤量 effect_value | 荆棘丛 1 / 岩浆 2 / 落石 3 | 难度曲线与Boss(provisional,加法核 [1,9]) |
|
||||
| 资源面偏斜 effect_value | 贫矿脉 30(生存族下调百分比;0=中性 off 锚;总期望微降 3-5% 为 provisional 设计目标——精确方向与幅度归读数批判读只测不判) | 难度曲线与Boss(provisional,域 [0,50]——2026-10-04 首发批投值) |
|
||||
|
||||
变异表字段集的现行口径(字段定义归变异表,条目归属即表行):标识 / 玩家可见名 / 解锁关号 / 作用域 / 效果 / 效果量 / 触发 / 布置约束 / 地形(board_types)/ 反制道具绑定(counter_items,恒空保留——回填义务 2026-10-03 作废,承载形态待迭代 12 重定)。
|
||||
变异表的结构历史(字段定义、条目归属)见 `data/schemas/variation_table.gd` 与 `data/tables/variation.tres`。字段集现行口径:标识 / 玩家可见名 / 解锁关号 / 作用域 / 效果 / 效果量 / 触发 / 布置约束 / 地形(board_types)/ 反制道具绑定(counter_items,恒空保留——回填义务 2026-10-03 作废,承载形态待迭代 12 重定)。
|
||||
|
||||
## 验收标准
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| P2 | 探测类道具的查询接口 | 接口已由身份解析只读面桥接,本系统不预写 |
|
||||
| P2 | 探测类道具的查询接口 | 接口已由 `query_reward_identity` 只读面桥接,本系统不预写 |
|
||||
| P2 | 地形变异接入的格面规则 | 地形变异已定稿落地(2026-09-19 四类型两轴×两关、2026-09-20 枚举化 schema 扩批),新增类型走双方修订流程 |
|
||||
|
||||
## 调参表
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 棋盘生成
|
||||
|
||||
> 一句话:棋盘怎么生成、怎么保证可推理可清图
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
> 状态:已定稿(自旧体系迁移)
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
**结论**:重试次数与图尺寸联合受成本闸约束。
|
||||
|
||||
```
|
||||
成本闸:max_gen_attempts × board_width × board_height ≤ 成本闸护栏常数 (结构护栏常数,见棋盘参数表字段定义;provisional 量级,正式值待实现期定)
|
||||
成本闸:max_gen_attempts × board_width × board_height ≤ 成本闸护栏常数 (结构护栏常数,见 `data/schemas/board_gen_table.gd`;provisional 量级,正式值待实现期定)
|
||||
```
|
||||
|
||||
| 出口 | 何时走 | 发生什么 |
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
### 图类型标签与第三轴预留:主题恒定、Boss 板有座位
|
||||
|
||||
每张图带一个图类型标签(board_type 字段;图类型即图的主题、题材,玩家侧显示名「地图类型」)。同关卡的所有图,主题静态恒定——不存在逐图重掷主题的接口,"不会上钓鱼的当"是结构保证而非文案。词表现行 v1.1(2026-09-20 第三关内容批增补;v1.0 两词 2026-09-19 定稿):**dungeon(地牢基线)/ underdark(幽暗地域)/ deep_underdark(灰矮人矿道方向)**,现行值见 board_gen.tres(L1 = dungeon,L2 = underdark,L3 = deep_underdark);域校验 = 词表成员检查(词表归棋盘参数表,扩词随内容批走修订)。这组标签是表现侧换色板与[地图战斗资源](../战斗循环/地图战斗资源.md)图类型差异化插槽的数据源。本节为数据约定,无计算。
|
||||
每张图带一个图类型标签(board_type 字段;图类型即图的主题、题材,玩家侧显示名「地图类型」)。同关卡的所有图,主题静态恒定——不存在逐图重掷主题的接口,"不会上钓鱼的当"是结构保证而非文案。词表现行 v1.1(2026-09-20 第三关内容批增补;v1.0 两词 2026-09-19 定稿):**dungeon(地牢基线)/ underdark(幽暗地域)/ deep_underdark(灰矮人矿道方向)**,现行值见 board_gen.tres(L1 = dungeon,L2 = underdark,L3 = deep_underdark);域校验 = 词表成员检查(board_gen_table.gd 词表常量),扩词随内容批走修订。这组标签是表现侧换色板与[地图战斗资源](../战斗循环/地图战斗资源.md)图类型差异化插槽的数据源。本节为数据约定,无计算。
|
||||
|
||||
参数表的键是关卡序号 × 节点深度,难度沿这两条轴雕刻;精英与 Boss 修饰是预留的第三条轴。本系统不定任何修饰数值,只锁定落点约定——这也是[关卡节点地图](../冒险循环/关卡节点地图.md)与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)两份文档的输入:
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
| shave_ring_radius | int [0, 2] | 现行 1(board_gen.tres 全行) | 先布后删剃雷半径:剃雷域=距出生中心切比雪夫距离 ≤1+r 的格(r=1 → 5×5=25 格;r=0 即只剃出生 3×3 本身=无环剃雷)。**2026-10-05 初始展开收窄批新参数**(调参项非结构冻结) |
|
||||
| r0_max_cap | int [出生格数 9, 板格数一半](护栏,违例加载期致命) | 现行按板形:10×10=45 / 12×12=43 / 13×13=51 / 14×14=59(board_gen.tres) | 自然 R₀(开局免费展开格数)上限闸=合法性门;超阈整板重掷、耗尽走三分出口。板面 30% 锚(30/43/51/59)经 S1 停机呈报用户裁上调:10×10→45(r=1 自然均值 39>30 结构性倒挂;其余行 30% 锚维持)。**2026-10-05 初始展开收窄批新参数** |
|
||||
|
||||
结构冻结(非调参项):键结构与每关深度 0 锚行、四阶段顺序(变异布置段 2026-09-20 已移出管线)、solver_rules、可推理率的合法信息源枚举、及格线域下限 0.85、成本闸常数(结构护栏,登记在案,调整走文档修订)、先布后删语义。
|
||||
结构冻结(非调参项):键结构与每关深度 0 锚行、四阶段顺序(变异布置段 2026-09-20 已移出管线)、solver_rules、可推理率的合法信息源枚举、及格线域下限 0.85、成本闸常数(结构护栏,登记于 registry board_gen_table 条目,调整走文档修订)、先布后删语义。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -225,10 +225,10 @@
|
||||
- 可清图:每个安全格都能从出生区沿安全格八向连通到达;合法性闸先于质量评分。
|
||||
- 及格线:每张图实测可推理率 ≥ 该行及格线;任何行及格线 ≥ 0.85。
|
||||
- 重试有界:实际重试次数落在 [1, max_gen_attempts];同一次生成内的重试不开新随机流。
|
||||
- 成本闸:max_gen_attempts × 宽 × 高超过成本闸护栏常数(结构护栏常数,见棋盘参数表字段定义)的行加载期被拒;同种子同参数在任意机器上出图逐位一致。
|
||||
- 成本闸:max_gen_attempts × 宽 × 高超过成本闸护栏常数(结构护栏常数,见 `data/schemas/board_gen_table.gd`)的行加载期被拒;玩法代码零墙钟依赖、零全局随机函数。
|
||||
- 降级诚实:零合法板照常出图,必带非法产物标记与最高级告警;进程不死锁,玩家界面得到诚实告知。
|
||||
- 加载期校验:布雷数下限、计数可行性、标签非空等违例组合加载期致命。
|
||||
- 黄金图回归:手工核验小板集的可推理率输出与登记整数对逐位相等(整数对比对,禁浮点容差);换生成参数(推理定义、信息源、定义版本号)必须重制向量并入版本库。
|
||||
- R₀≤cap 闸(2026-10-05 初始展开收窄批):每张出图自然 R₀ ≤ 该行 r0_max_cap(合法板),或带非法产物标记(接受最不坏·诚实降级);闸触发次数入指标集 r0_cap_rejected。
|
||||
- R₀≤cap 闸(2026-10-05 初始展开收窄批):每张出图自然 R₀ ≤ 该行 r0_max_cap(合法板),或带非法产物标记(accept_worst 诚实降级);闸触发次数入指标集 r0_cap_rejected。
|
||||
- 剃雷域参数化(同批):剃雷域=出生中心切比雪夫 ≤1+shave_ring_radius 的方域,出图 ring_removed ≤ 域内候选危险格数 (3+2r)²−9;同种子布雷序列与收窄前逐位一致(零 RNG 消费变化)。
|
||||
- 表实一致:配置表字段与棋盘参数表字段定义一致。
|
||||
- 表实一致:配置表字段定义与 `data/schemas/board_gen_table.gd` 一致。
|
||||
@@ -1,7 +1,7 @@
|
||||
# 行动经济
|
||||
|
||||
> 一句话:每轮行动点怎么花、停手与刷新的代价
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
> 状态:已定稿(自旧体系迁移)
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
### 停手与储备行动点
|
||||
|
||||
停手是玩家在挖掘期任意时刻的主动决定:立即结束本轮,剩余行动点按 1:1 原值存入储备池——基线没有乘数、没有加成。图没开完,下一轮接着在同一张图上挖。停手不是收入来源,而是纯粹的风险管理工具:它买到的是"退出权",不是战斗收益。停手意图经排雷玩法的批次提交入口进入账本(保证单一结算序),由账本仲裁后自行外发轮次结束消息。**转存率参数化(迭代 22 秘宝批反哺写入,2026-10-12)**:转存率实现为停手收轮时的转存率参数——缺省 100=1:1 与旧口径逐位一致;秘宝「储备罐」注入 125=1.25:1(整数除法向下取整——每 4 点剩余 AP 多转 1 点 RAP,零头顺延向下);无装配时行为与参数化前逐位相同。转存率归秘宝操作包络参数,本账本的仲裁与发射结构不变。
|
||||
停手是玩家在挖掘期任意时刻的主动决定:立即结束本轮,剩余行动点按 1:1 原值存入储备池——基线没有乘数、没有加成。图没开完,下一轮接着在同一张图上挖。停手不是收入来源,而是纯粹的风险管理工具:它买到的是"退出权",不是战斗收益。停手意图经排雷玩法的批次提交入口进入账本(保证单一结算序),由账本仲裁后自行外发轮次结束消息。**转存率参数化(迭代 22 秘宝批反哺写入,2026-10-12)**:转存率实现为 `finish_round_stop(transfer_pct)` 参数面——缺省 100=1:1 与旧口径逐位一致;秘宝「储备罐」注入 125=1.25:1(整数除法向下取整——每 4 点剩余 AP 多转 1 点 RAP,零头顺延向下);无装配时行为与参数化前逐位相同。转存率归秘宝操作包络参数,本账本的仲裁与发射结构不变。
|
||||
|
||||
储备池的生命周期以一场战斗为界:战斗内跨轮次、跨雷图一直累积;战斗结束立刻清零。清零必须在界面上可见,防止玩家觉得"攒的钱凭空没了"。MVP 阶段储备池没有上限。
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
### 下轮行动点修正(格面资源八型批 2026-09-20)
|
||||
|
||||
格面资源八型批(2026-09-20)新增 action 型格面资源:正向行 ap_up = 下轮行动点 +1,负向行 ap_drain(迟滞)= 下轮行动点 −1。修正不在授予当轮生效:结算期经行动经济的行动点修正队列登记(同轮多笔按净值累加),下一轮开始时(开轮通知)一次性兑现——兑现值 = 基线 ap_per_round + 排队净值,下限 0,兑现后队列清零;排队净值不跨轮保留。明细在结算流水记效果行(effect_id=ap_delta)。
|
||||
格面资源八型批(2026-09-20)新增 action 型格面资源:正向行 ap_up = 下轮行动点 +1,负向行 ap_drain(迟滞)= 下轮行动点 −1。修正不在授予当轮生效:结算期经 `action_economy.queue_ap_delta` 排队(同轮多笔按净值累加),下一轮开始时(notify_round_start)一次性兑现——兑现值 = 基线 ap_per_round + 排队净值,下限 0,兑现后队列清零;排队净值不跨轮保留。明细在结算流水记效果行(effect_id=ap_delta)。
|
||||
|
||||
跨轮携带量口径随之改写:RAP 仍是唯一显式携带的系统资源(停手转存、玩家可见可花),行动点修正队列是第二携带量——一次性、自动清零、不可主动消费。
|
||||
|
||||
@@ -132,13 +132,13 @@
|
||||
4. **清图奖励大于零**,并预留按图类型差异化分支的结构位。
|
||||
5. **清图支配性**:推到底清图的期望收益,不低于"确定格挖完就弃图刷新"的期望收益——否则清图玩法会被刷新策略淘汰。
|
||||
|
||||
**结论**:五条契约由战斗结算作为唯一对账责任方闭合验收;概率侧由棋盘生成的可推理率参数锚定;条款3 数值层由 β 比值带 [1.2, 2.5] 判读看护(清图支配性审计为常设重跑项),封印边际结构层由条件二封印溢价接替(机制载体 settlement.flag_hit_premium)。
|
||||
**结论**:五条契约由战斗结算作为唯一对账责任方闭合验收;概率侧由棋盘生成的可推理率参数锚定;条款3 数值层由 β 比值带 [1.2, 2.5] 判读看护(常设重跑入口 `tools/clear_dominance_audit.py`),封印边际结构层由条件二封印溢价接替(机制载体 settlement.flag_hit_premium)。
|
||||
|
||||
推导:
|
||||
|
||||
```
|
||||
条款 3(2026-10-05 判式换代批重立——三层口径并行立,2026-10-04 用户裁 P2;
|
||||
设计权威 = 方案报告 §四/§九(已退役;现行判式口径=本文条款③))
|
||||
设计权威 = 方案报告 §四/§九(已退役,git 1da9a41;现行判式口径=本文条款③))
|
||||
|
||||
条款 2(封印标中锚,既有不动):封印标中的减益档位必须严格高于最低档安全格增益。
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
η 读数(行为面,非判式——2026-10-04 用户裁 P1 乙降格读数):
|
||||
η = flag_hit ÷ flag_placed(分母 = 全部封印数,2026-10-04 grill Q5 裁),
|
||||
标空率 = flag_miss ÷ flag_placed 次读数分列。字段随结算摘要五字段承载
|
||||
标空率 = flag_miss ÷ flag_placed 次读数分列。字段随 runsum 五字段承载
|
||||
(flag_placed/flag_hit/flag_miss/标中兑付合计/标空惩罚合计——结算流水聚合)。
|
||||
|
||||
条款 5(清图支配性,不动):
|
||||
@@ -181,9 +181,9 @@
|
||||
|
||||
| 变量 | 含义 | 锚定来源 |
|
||||
|---|---|---|
|
||||
| E_dig(u) | 单安全格期望收益当量(77 权重池加权,随敌方单位数 u 缩放 side-wide 项) | 战斗结算的效果对照表 + 清图支配性审计读数 |
|
||||
| E_dig(u) | 单安全格期望收益当量(77 权重池加权,随敌方单位数 u 缩放 side-wide 项) | 战斗结算的效果对照表 + `tools/clear_dominance_audit.py` |
|
||||
| V_mine(u) | 单雷期望惩罚当量(九型负向字典同池加权) | 同上 |
|
||||
| ρ̂ | 雷率:名义 0.25 与实测幸存雷率(10×10 ≈ 0.129 / 12×12 ≈ 0.157)双口径并报,主表用名义(保守) | board_gen.tres + 棋盘统计读数 |
|
||||
| ρ̂ | 雷率:名义 0.25 与实测幸存雷率(10×10 ≈ 0.129 / 12×12 ≈ 0.157)双口径并报,主表用名义(保守) | board_gen.tres + board_stat_probe 读数 |
|
||||
| q | 玩家对目标格为雷的置信 | 玩家侧行为量(可推理格 q ∈ {0,1}) |
|
||||
| β 带 | V_mine/E_dig 判读带 [1.2, 2.5] | 本文条款③重立条 |
|
||||
| δ | 封印溢价系数 0.25 provisional | settlement.tres flag_hit_premium = 125 |
|
||||
@@ -238,7 +238,7 @@
|
||||
| refresh_cap_per_round | int | 表值(provisional,结构位预留) | 每轮刷新上限,开轮重置计数 |
|
||||
| (跨表)跨冒险行动点加成 | int [0,10] / int [0,99],冒险表 | adventure_table bonus_ap_flat / bonus_cap_ap(provisional) | 三选一 AP 件兑现值与全冒险次数上限;加成轴语义见「跨冒险行动点加成轴」节 |
|
||||
|
||||
字段名注记:2026-09-18 措辞完成批已全链对齐正式名——表字段与本文行名统一为 `refresh_cap_per_round`,刷新入口命名与表字段口径对齐(命名统一登记兑现,切片临时名零残留)。
|
||||
字段名注记:2026-09-18 措辞完成批已全链对齐正式名——表字段与本文行名统一为 `refresh_cap_per_round`,行动点入口统一为 `request_refresh`(registry naming_unification 兑现,切片临时名零残留)。
|
||||
|
||||
跨字段校验:任一动作成本禁止超过每轮预算,违反即加载期致命(fail-fast)。各域上界(8 / 64)是 MVP 量级护栏而非推导界,随调参需要修订。
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
- 储备清零:战斗结束信号到达后储备池归 0,行动点进入休眠。
|
||||
- 跨字段校验:任一动作成本配置超过每轮预算时,加载期致命中止。
|
||||
- 零随机:同一动作序列驱动两个独立行动点实例,轮次结束记录与储备轨迹逐项相同。
|
||||
- 表实一致:配置表字段与行动经济表字段定义逐字段一致。
|
||||
- 表实一致:配置表字段与 `data/schemas/action_economy_table.gd` 逐字段一致。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| 棋盘(封印印记、小人位置) | 意图批次调用返回后重查 |
|
||||
| 行动点 / 储备 | 每次写路径回执后重读 |
|
||||
| 状态效果 | 绑定结算编排完成时点 |
|
||||
| 已开格奖励身份 | 已开格揭显时经身份解析只读回调查询(组合根注入) |
|
||||
| 已开格奖励身份 | 已开格揭显时经身份解析只读回调查询(`query_identity`,组合根注入) |
|
||||
|
||||
就地更新指只改变化的字段、不整块重建界面——整块重建会把敌人立绘死亡灰化这类就地状态吞掉。
|
||||
|
||||
@@ -134,7 +134,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| 信息内容 | 只表达格面资源的类型(九类格面资源归五组色相呈现,色相/明度/画法规格归 [art-bible](../../../art/art-bible.md) §4.2);不表达极性(安全/雷)、不表达具体收益档位 |
|
||||
| 生命周期 | 资源身份装板期摇定(微光只是显示,不改任何游戏数据)→ 未开 ∧ 在 8 格内 → 亮;格子被挖开/连锁开/踩雷 → 灭;角色走远出圈 → 灭,走回 → 复亮;换图随旧图全重置 |
|
||||
| 关联与边界 | 信息本体(格面资源身份)归[地图战斗资源](../战斗循环/地图战斗资源.md);棋盘格态与动作合法性归[排雷玩法](../排雷循环/排雷玩法.md);与「接触带微光」同圈不同职责——接触带微光=可挖域的交互反馈光(「这里能挖」),类型微光=相邻格的类型先读(「这格是什么类型」) |
|
||||
| 实装状态 | 呈现契约已定稿(五组色相经样张 v2 冻结 2026-09-28);**已实装(迭代 30 卡① 2026-10-17 入库)**——2026-09-30 核证的「呈现层仅接触带微光在跑,类型微光无独立实现」状态自此注销;在役实现(五组色相 = 呈现套件色相常量、格面微光子件 + 距离场渲染)与验收转正见本节末「验收标准」类型微光行,登记面归 [待办清单](../../../../待办清单.md)「未开格类型徽章呈现时机」条(已完成) |
|
||||
| 实装状态 | 呈现契约已定稿(五组色相经样张 v2 冻结 2026-09-28);**已实装(迭代 30 卡① 2026-10-17 入库,合并 `7ffd1dc0`)**——2026-09-30 核证的「呈现层仅接触带微光在跑,类型微光无独立实现」状态自此注销;在役实现(五组色相 = ui_kit TG_GLOW_*、格面微光子件 + 距离场 shader)与验收转正见本节末「验收标准」类型微光行,登记面归 [待办清单](../../../../待办清单.md)「未开格类型徽章呈现时机」条(已完成) |
|
||||
|
||||
口径史注记(防复发):本概念曾只活在待办清单登记与 art-bible 复述里,「常显」「全部未开格」等无范围表述于 2026-09-30 酿成理解事故;用户裁决「英雄周围 8 格」为正确口径并落位本节。教训=概念必须落地权威文档,零散复述不是定义。
|
||||
|
||||
@@ -148,7 +148,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
|---|---|
|
||||
| 定义与作用范围 | 接触带微光 = 可挖域的交互反馈光(「这里能挖」)——英雄格与可挖域(8 向相邻未开格;概念本体与动作合法性归[排雷玩法](../排雷循环/排雷玩法.md))接触面上的呼吸微光;与「未开格类型微光」同圈不同职责(类型微光=「这格是什么类型」,本光=「这里能挖」) |
|
||||
| 画法 | 光画英雄格周界空间侧:正交邻墙=该侧整条边,斜向邻墙=共享角点+向两侧各延伸半条边;光只画英雄格一侧、不进墙格;色相=蓝族浅一档——画法细则归 [art-bible](../../../art/art-bible.md) §3.2 |
|
||||
| 生命周期 | 挖掘期呈现且呼吸(挖掘期唯一在动元素——art-bible §2.1;相位门控,结算期停息);减动效开启=呼吸停格(静态保留指界功能);换图/装板随新可挖域重算 |
|
||||
| 生命周期 | 挖掘期呈现且呼吸(挖掘期唯一在动元素——art-bible §2.1;相位门控 `set_dig_glow_enabled`,结算期停息);减动效开启=呼吸停格(静态保留指界功能);换图/装板随新可挖域重算 |
|
||||
| 关联与边界 | 逐格指认=悬停金框(pattern 4 悬停预承诺——微光是常驻指界、悬停是意图预承诺,两概念分工);不携带类型/极性信息(那是类型微光的职责);零信息写入(纯呈现层) |
|
||||
| 实装状态 | 已实装(呈现层现行在跑——2026-09-30 核证;程序化占位,画法终稿随样张批) |
|
||||
|
||||
@@ -163,9 +163,9 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| 关联与边界 | 与「未开格类型微光」同边界——灯光区起步半径=微光环 8 格(同圈起步,实测后可调);格态数据归[排雷玩法](../排雷循环/排雷玩法.md);黑暗区域渲染规格(暗淡态明度、迷雾过渡)归 [art-bible](../../../art/art-bible.md) 修订随实施批;初始展开收窄不在本案(后置与 Alpha 差异化批窗口合并再议) |
|
||||
| 实装状态 | **已实装**(2026-10-03 迭代 11 第④批已入库;四裁决逐条对账与验收线转正见本节末「实施状态」注记;渲染规格 = [art-bible](../../../art/art-bible.md) §6.5) |
|
||||
|
||||
配套拍板(同日):魔法提灯=灯甲形态(光照圈外扩 +2 格,flat 整数档)随迷雾立项;**类型微光不随视野扩大**(类型先读仍只贴身 8 格,微光锚=可挖域);提灯载体归 aux_items 新行(登记原文——2026-10-07 用户令改道为独立卡,2026-10-08 裁案A=秘宝·同调位新行落位,见下方实施状态注记;**2026-10-09 用户裁退役**——新目录 15 件未收提灯,提灯数据行与卡④接线拆除归退役删行批〔实装批〕,功能由新目录普通档「阔视野带」承接,待办清单登记条在册),呈现面挂「资产升档重产批」(挂账不动)。
|
||||
配套拍板(同日):魔法提灯=灯甲形态(光照圈外扩 +2 格,flat 整数档)随迷雾立项;**类型微光不随视野扩大**(类型先读仍只贴身 8 格,微光锚=可挖域);提灯载体归 aux_items 新行(登记原文——2026-10-07 用户令改道为独立卡,2026-10-08 裁案A=秘宝·同调位新行落位,见下方实施状态注记;**2026-10-09 用户裁退役**——新目录 15 件未收提灯,fog_lantern 数据行与卡④接线拆除归退役删行批〔实装批〕,功能由新目录普通档「阔视野带」承接,待办清单登记条在册),呈现面挂「资产升档重产批」(挂账不动)。
|
||||
|
||||
**实施状态(2026-10-03 迭代 11 第④批已入库)**:迷雾遮蔽+菱形灯光区跟随+暗淡记忆态上线,输入探针断言顺带扩(迷雾案)。四裁决逐条对账——①案甲视野迷雾立项(纯呈现层):迷雾开关分层验证可用(呈现态布尔,off 态=无迷雾基线),同板同动作序列与 MC 逐项比对逐位一致;②暗淡记忆态:区外已开格灰显+数字可读,明度按 [art-bible](../../../art/art-bible.md) §6.5 写入文档值(记忆板 #3A3A3A/记忆墨 #C4C4C4,provisional);③灯光半径=微光环 8 格同圈:半径 8 参数化(曼哈顿菱形,常量);④提灯 +2、微光不扩:提灯加成 +2,类型微光仍贴身 8 邻格零改动。**〔2026-10-05 迭代14⑤接线注记〕公共接线面已就位**——公共提灯开关接口(开=半径 8+2、关=复原 0;写入即重算雾态),迷雾批已在位消费该值;输入探针增接线断言(开=距离 9 格转可见+提灯 2/关=复原)。**〔2026-10-08 迭代 19 卡④入库注记〕载体到位+接线闭环=功能可达**——载体=秘宝·同调位新行「魔法提灯」(treasure_items.tres 表尾追加,desc「灯光区半径+2」,slot_cost 1、营地秘宝匣同调装配获渠,行字段=用户「按推荐」全收);生产路径=冒险装配→战斗装配集注入→公共只读出口查装配含否→组合根呈现桥每战首轮装配链**显式重算含否**(🔴 复原语义=禁战斗结束隐式复原——卸装/未装配写 0,断点续玩/跨关天然正确);未装配=零加成(缺省零扰动基线逐位不变)。顺带测试:载体级迷雾案(装配→提灯 2+距离 R+1 转可见+卸装复原)+冒烟行字段/同调目录投影(九件→十件)/装配贯通断言+存档回归 Part 6+单测提灯接线(全套 17→18 套)。原「提灯载体归 aux_items 新行随 Alpha 信息件重定批」登记去向就此注销(改道留痕=需求卡片-提灯载体道具批-2026-10-07 §一)。验收线(本篇「验收标准」视野迷雾行)逐条转正式验收:区内完整渲染/区外已开格灰显可读/区外未开格不可见/灯光区随移动跟随/两态结算逐位一致;实机目检人闸(迷雾观感/记忆态可读性/移动跟随流畅度)随出口闸。黑暗区域渲染规格承载 = art-bible §6.5(v3.5)。
|
||||
**实施状态(2026-10-03 迭代 11 第④批已入库)**:迷雾遮蔽+菱形灯光区跟随+暗淡记忆态上线,探针断言顺带扩(ui_input_probe case⑮)。四裁决逐条对账——①案甲视野迷雾立项(纯呈现层):迷雾开关分层验证可用(呈现态布尔,off 态=无迷雾基线),同板同动作序列与 MC 逐项比对逐位一致;②暗淡记忆态:区外已开格灰显+数字可读,明度按 [art-bible](../../../art/art-bible.md) §6.5 写入文档值(记忆板 #3A3A3A/记忆墨 #C4C4C4,provisional);③灯光半径=微光环 8 格同圈:LIGHT_RADIUS=8 参数化(曼哈顿菱形,常量);④提灯 +2、微光不扩:FOG_LANTERN_BONUS=+2(落码常量实名——本条旧记 LIGHT_RADIUS_LANTERN_BONUS 系文档侧拟名,随卡④入库对齐),类型微光仍贴身 8 邻格零改动。**〔2026-10-05 迭代14⑤接线注记〕公共接线面已就位**——`board_view.set_fog_lantern(enabled)`(true=半径 8+2、false=复原 0;写入即 refresh 重算雾态),半径算式消费 `_fog_lantern` 迷雾批已在位;ui_input_probe case⑮ 增接线断言(开=dist 9 格转可见+lantern=2/关=复原)。**〔2026-10-08 迭代 19 卡④入库注记〕载体到位+接线闭环=功能可达**——载体=秘宝·同调位新行 `fog_lantern`「魔法提灯」(treasure_items.tres 表尾追加,desc「灯光区半径+2」,slot_cost 1、营地秘宝匣同调装配获渠,行字段=用户「按推荐」全收);生产路径=runner set_attunement→enc.attunement→begin_battle 注入 orchestrator 装配集→公共只读出口 `attune_has`→组合根呈现桥 `main._sync_fog_lantern` 每战首轮装配链**显式重算含否**(🔴 复原语义=禁战斗结束隐式复原——卸装/未装配写 0,断点续玩/跨关天然正确);未装配=false 写 0=缺省零扰动基线逐位不变。顺带测试:case⑮ 载体级段(装配→lantern=2+dist R+1 转可见+卸装复原)+smoke 行字段/同调目录投影(九件→十件)/装配贯通断言+存档回归 Part 6+单测 fog_lantern_wiring(run_all 17→18 套)。原「提灯载体归 aux_items 新行随 Alpha 信息件重定批」登记去向就此注销(改道留痕=需求卡片-提灯载体道具批-2026-10-07 §一)。验收线(本篇「验收标准」视野迷雾行)逐条转正式验收:区内完整渲染/区外已开格灰显可读/区外未开格不可见/灯光区随移动跟随/两态结算逐位一致;实机目检人闸(迷雾观感/记忆态可读性/移动跟随流畅度)随出口闸。黑暗区域渲染规格承载 = art-bible §6.5(v3.5)。
|
||||
|
||||
### 营地:可点击场景图(旧四柜台并排形态已随卡④改版取代)
|
||||
|
||||
@@ -196,9 +196,9 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| 上游 | [排雷玩法](../排雷循环/排雷玩法.md) | 棋盘只读投影(格态、数字、封印印记、小人)与移动路径查询;玩家意图批次经组合根提交 |
|
||||
| 上游 | [行动经济](../排雷循环/行动经济.md) | 行动点 / 储备 / 相位只读值;刷新入口可用性预判加返回值兜底 |
|
||||
| 上游 | [战斗结算](../战斗循环/战斗结算.md) | 明细流水是结算明细带的统一数据源(现行 9 类行封闭协议);段序编排信号经组合根接线 |
|
||||
| 上游 | [敌人系统](../战斗循环/敌人系统.md) | 英雄与敌人的只读投影(血量、顺位、摇定动作〔技能标识·类型·名称〕、敌方增益、存活——经战斗结算呈现快照;敌人技能池批批 2 定稿:当前拍/行动环进度字段拆除,池与权重不公开) |
|
||||
| 上游 | [敌人系统](../战斗循环/敌人系统.md) | 英雄与敌人的只读投影(血量、顺位、摇定动作〔pending_skill/type/name〕、敌方增益 effects、存活——经战斗结算呈现快照;敌人技能池批批 2 定稿:当前拍/行动环进度字段拆除,池与权重不公开) |
|
||||
| 上游 | [增益状态](../战斗循环/增益状态.md) | 状态投影经战斗结算呈现面取得,零直读 |
|
||||
| 上游 | [地图战斗资源](../战斗循环/地图战斗资源.md) | 已开格奖励身份投影(只读回调,组合根注入)零直读 |
|
||||
| 上游 | [地图战斗资源](../战斗循环/地图战斗资源.md) | 已开格奖励身份投影(`query_identity` 只读回调,组合根注入)零直读 |
|
||||
| 上游 | [关卡节点地图](../冒险循环/关卡节点地图.md) | 节点链、当前节点、跨战斗生命携带的读数;胜利后推进 |
|
||||
| 下游 | [战斗表现](../战斗循环/战斗表现.md) | 交付三区布局、明细带呈现位、敌人呈现语义(站桩形态);它只叠加动画密度与演出 |
|
||||
| 下游 | [音频](音频.md) | 挂点事件源(明细行类型流、toast 触发);MVP 无音频 |
|
||||
@@ -218,7 +218,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| [地图战斗资源](../战斗循环/地图战斗资源.md) | 已开格的奖励身份常读;未开格类型微光(英雄周围 8 格内的未开格显示资源类型——概念定义见本篇「未开格类型微光」节) |
|
||||
| [秘宝](../跨局循环/秘宝.md) | 装配件与充能常读;使用交互与目标拾取;整图叠加层信息呈现(在役旧框架——随实装批整体替换,秘宝.md v1.7 同款口径) |
|
||||
| [棋盘生成](../排雷循环/棋盘生成.md) | 零合法板的诚实告知(数据面经战斗结算上抛,本系统只管提示形态) |
|
||||
| [地形变异](../排雷循环/地形变异.md) | 全局作用域型三层预告(2026-10-04 首发批——语义现行事实源=地形变异 §全局作用域型):①开战横幅一行(整图变异非空时显示;减动效=静态驻留,轮横幅先例同款双态)②HUD 常驻角标(C 区战斗全程可见防中局遗忘,空态整节隐藏=奇物段先例;摆位 provisional)③帮助手册一行(零交互教学,承载=玩法帮助文案块);数据面经呈现快照的整图变异投影(核心→呈现唯一读取面),普通图三层恒空态零打扰 |
|
||||
| [地形变异](../排雷循环/地形变异.md) | 全局作用域型三层预告(2026-10-04 首发批——语义现行事实源=地形变异 §全局作用域型):①开战横幅一行(整图变异非空时显示;减动效=静态驻留,轮横幅先例同款双态)②HUD 常驻角标(C 区战斗全程可见防中局遗忘,空态整节隐藏=奇物段先例;摆位 provisional)③帮助手册一行(零交互教学,承载=玩法帮助文案块);数据面经呈现快照 board_variants 投影(核心→呈现唯一读取面),普通图三层恒空态零打扰 |
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# 存档序列化
|
||||
|
||||
> 一句话:存档契约与版本迁移
|
||||
> 状态:已定稿(2026-09-21 存档序列化批落地);现行为 v1.2
|
||||
> 状态:已定稿(2026-09-21 存档序列化批落地);现行为 v1.1
|
||||
|
||||
## 设计目的
|
||||
|
||||
本系统管的是"关掉游戏之后,玩家的东西还在不在"。序列化(本文含义:把游戏运行中的数据写成可存盘的档案,下次启动再原样读回来)与版本迁移(本文含义:游戏更新后,旧版本写下的存档要能被新版本继续读懂,必要时把旧结构改写成新结构)合起来,就是"存档契约"这门生意的全部。
|
||||
|
||||
这件事是[核心循环](../../01-核心循环.md)里"存档在变厚"那条故事线的底层承载:钥石攒进存档、倒下也不丢——写在纸面上就是本系统的职责。本系统在切片里的落地面是存档管理器:Core 层,零界面依赖、零玩法依赖。本文描述的就是这份契约:存什么、何时读写、版本怎么走、坏了怎么办。
|
||||
这件事是[核心循环](../../01-核心循环.md)里"存档在变厚"那条故事线的底层承载:钥石攒进存档、倒下也不丢——写在纸面上就是本系统的职责。本系统在切片里的落地面是 `core/save_manager.gd`(SaveManager,Core 层零 UI、零玩法依赖),本文描述的就是这份契约:存什么、何时读写、版本怎么走、坏了怎么办。
|
||||
|
||||
## 系统范围
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
### 基础层身份:无上游依赖的承载方
|
||||
|
||||
存档系统不依赖任何玩法系统就能工作:它是被动的承载方,任何系统要把数据活过单局,都向本系统登记持久化归属,而不是本系统去追认每个系统。这条身份可验证:存档系统不引入任何玩法脚本、不碰数值表与随机服务,可以独立实例化、独立读写验证(冒烟独立段承载)。
|
||||
SaveManager 不依赖任何玩法系统就能工作:它是被动的承载方,任何系统要把数据活过单局,都向本系统登记持久化归属,而不是本系统去追认每个系统。这条身份可验证:SaveManager 不引入任何玩法脚本、不碰数值表(ConfigDB)与随机服务(RngService),可以独立实例化、独立读写验证(冒烟独立段承载)。
|
||||
|
||||
### 存什么:表与档分家,局内系统资源不入档
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
|
||||
第二条边界是反面清单:局内资源不入存档。行动点、储备行动点、道具库存、生命、GP 全部单局清零——各归各的系统管,没有局内数值需要持久化。若未来某局内资源要开放跨局携带(如储备行动点跨战斗携带),须修订其池规则并向本系统登记持久化归属,禁止静默超域。
|
||||
|
||||
**唯一豁免 = `breakpoint` 断点域**(2026-09-29 迭代 8 卡①顺带修订):断点是冒险进行中的瞬态快照,不是跨局携带——里面的生命/GP/道具库存只在「续玩上局」时还原进局内,冒险收束(通关/失败/放弃)即整域清除,永远不会渗进永久进度。反面清单的管辖对象因此收窄为 `meta` 永久进度域(冒烟域界扫描顺带收窄到 meta 域);断点域自身的字段口径归[冒险结构](../冒险循环/冒险结构.md)登记。断点顶层键(27 键+2026-10-27 迭代 39 获得日记键扩列至 28)的登记单源=冒险应用层的断点键表(键→回退策略;现行契约见架构文档「冒险域拆分」节);写读已换代为各件自交片段——主角账/停点件/关卡件各自写读自己的键(缺键回退策略随领域知识归各件),冒险应用层是唯一拼盘落盘口(收齐各件片段拼成顶层快照后写盘,写触发点不变)。**关卡完成停点的同调未用行留存**(2026-10-27 迭代 39 副卡边界裁定):`aux_items` 键在此停点形态含同调未用行(关卡末清空改选择性保留——「同调行始终留在 treasure_inventory」与「键值形态逐位不变」在关卡完成停点互斥,采行留存;玩家可见 C 区投影零变化,24 停点充能读数逐位一致)。
|
||||
**唯一豁免 = `breakpoint` 断点域**(2026-09-29 迭代 8 卡①顺带修订):断点是冒险进行中的瞬态快照,不是跨局携带——里面的生命/GP/道具库存只在「续玩上局」时还原进局内,冒险收束(通关/失败/放弃)即整域清除,永远不会渗进永久进度。反面清单的管辖对象因此收窄为 `meta` 永久进度域(冒烟域界扫描顺带收窄到 meta 域);断点域自身的字段口径归[冒险结构](../冒险循环/冒险结构.md)登记。断点顶层键(27 键+2026-10-27 迭代 39 获得日记键扩列至 28)的登记单源=`core/adventure_runner.gd` 内 `const BREAKPOINT_FIELDS`(键→回退策略标签);写读已换代为各件自交片段——主角账/停点件/关卡件各自写读自己的键(缺键回退策略随领域知识归各件),冒险应用层是唯一拼盘落盘口(收齐各件片段拼成顶层快照后写盘,写触发点不变)。**关卡完成停点的同调未用行留存**(2026-10-27 迭代 39 副卡边界裁定):`aux_items` 键在此停点形态含同调未用行(关卡末清空改选择性保留——「同调行始终留在 treasure_inventory」与「键值形态逐位不变」在关卡完成停点互斥,采行留存;玩家可见 C 区投影零变化,24 停点充能读数逐位一致)。
|
||||
|
||||
**三存档位(迭代 33 卡①,2026-10-22 反哺写入)**:存档是 3 个独立的 JSON 文件(三个独立存档文件,槽文件名只经存档系统单点派生,槽 1 禁复用旧单档名),字典键一律字符串。写盘目标=当前激活槽的文件;启动(boot)不读任何槽文件——启动态=无激活态,不读写;激活态由选档界面的「新档」或「进档」建立(选档界面归迭代 33 卡③)。数据模型(现行 = v7;示例值全为零值默认态):
|
||||
**三存档位(迭代 33 卡①,2026-10-22 反哺写入)**:存档是 3 个独立的 JSON 文件(`user://save_slot_1/2/3.json`,槽文件名只经 `slot_path()` 单点派生,槽 1 禁复用旧单档名),字典键一律字符串。写盘目标=当前激活槽的文件;启动(boot)不读任何槽文件——启动态=无激活态,不读写;激活态由选档界面的「新档」(`create_slot`)或「进档」(`activate_slot`)建立(选档界面归迭代 33 卡③)。数据模型(现行 = v6;示例值全为零值默认态):
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 7,
|
||||
"version": 6,
|
||||
"meta": {
|
||||
"keystone_balance": 0,
|
||||
"item_unlocks": {},
|
||||
@@ -95,28 +95,28 @@
|
||||
| `attune_refresh_level` | 营地刷新升级(Y 源)等级(v4) | [秘宝](../跨局循环/秘宝.md)(三选一刷新双源) |
|
||||
| `tree_nodes` | 天赋树已购等级(node_id→int,v5) | [天赋树](../跨局循环/天赋树.md) |
|
||||
| `fork_sides` | Fork 组激活侧(fork_group→a/b,v5) | [天赋树](../跨局循环/天赋树.md) |
|
||||
| `tree_struct` | 树结构版本标记(迭代 21 T5;缺失 = 换代前结构,加载废弃重置) | [天赋树](../跨局循环/天赋树.md) |
|
||||
| `tree_struct` | 树结构版本标记(=TREE_STRUCT_VERSION,迭代 21 T5;缺失 = 换代前结构,加载废弃重置) | [天赋树](../跨局循环/天赋树.md) |
|
||||
| `recent_summaries` | 最近冒险摘要副本,最新在前,最多 10 条 | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
| `first_adventure_done` | 首冒险完成标记(新档默认 false;旧档缺省按已完成兜底) | [元进度](../跨局循环/元进度.md) |
|
||||
| `adventure_total` | 冒险总局数终身计数(开局即计、含放弃与失败,v6) | [生涯](../跨局循环/生涯.md) |
|
||||
| `adventure_cleared` | 冒险成功局数终身计数(三关全通才计 1,v6;秘宝条件解锁计数键) | [生涯](../跨局循环/生涯.md) |
|
||||
| `vision_used` | 真视类工具累计使用次数终身计数(迭代 22 新增——信标网络解锁行为条件;**v6 域后扩列补零、不升版本**;写入唯一经真视计数入口,冒险收束聚合入账;断点随件键=`vision_counter_used`,续玩回填缺省 0) | [秘宝](../跨局循环/秘宝.md) |
|
||||
| ~~`forge_levels`~~ | ~~属性锻造三档等级~~ | **已退役**(迭代 21 T5:域与访问器随攻防所有权切分删除;继任 = 锻造路线等级域) |
|
||||
| `vision_used` | 真视类工具累计使用次数终身计数(迭代 22 新增——信标网络解锁行为条件;**v6 域后扩列补零、不升版本**;写入唯一经 `add_vision_used`,冒险收束聚合入账;断点随件键=`vision_counter_used`,续玩回填缺省 0) | [秘宝](../跨局循环/秘宝.md) |
|
||||
| ~~`forge_levels`~~ | ~~属性锻造三档等级~~ | **已退役**(迭代 21 T5:行族/访问器/域随攻防所有权切分删除——`save_manager.gd:12-14/:399-401` 白名单收窄;继任 = 锻造工坊路线等级域,见下行计划登记) |
|
||||
| `forge_routes`(**已落地 v7——锻造工坊实装批 T5,迭代 23**) | {levels: 六路线等级(sword/spear/staff/light/heavy/ward), unlocked: 直购解锁路线 id 清单, weapon: 当前武器路线 id, armor: 当前甲路线 id};无特效域;旧档缺键补齐 = 初始持有态 | [锻造工坊](../跨局循环/锻造工坊.md) |
|
||||
| `breakpoint` | 冒险断点快照(停点粒度续玩域;空字典 = 无断点合法态——「继续上局」隐藏) | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
|
||||
v4/v5/v6 各域缺键由读取方按默认值补齐(空集合/0),旧档零迁移损失;收束自增域(通关次数/Boss 计数/终身计数/真视使用计数)的唯一入账点 = 冒险摘要入账(vision_used 走真视计数入口收束)。**v6 域后扩列不升版先例**:`vision_used`(迭代 22,2026-10-12——迭代 21 同款口径;断点随件 `vision_counter_used` 同批新增;旧断点随件键 `bonus_aux_carry` 已随替换子交互拆除退役,迭代 22 T5)。
|
||||
v4/v5/v6 各域缺键由读取方按默认值补齐(空集合/0),旧档零迁移损失;收束自增域(通关次数/Boss 计数/终身计数/真视使用计数)的唯一入账点 = `apply_adventure_summary`(vision_used 走 `add_vision_used` 收束)。**v6 域后扩列不升版先例**:`vision_used`(迭代 22,2026-10-12——迭代 21 同款口径;断点随件 `vision_counter_used` 同批新增;旧断点随件键 `bonus_aux_carry` 已随替换子交互拆除退役,迭代 22 T5)。
|
||||
|
||||
消费面纪律:其他系统只经存档系统的类型化访问器(读余额/加钥石/花钥石、读写树等级等)与域更新原语(冒险摘要入账)操作存档,不碰内部数据结构。三条槽位纪律(迭代 33 卡①):一、无激活态下一切写盘路径拒绝并返回 false(boot 后未进档/未新档即结算或购买=不落盘,激活后照常);二、槽文件名单点派生——消费方禁各自拼槽文件名,测试与探针的隔离走注入口(槽模板注入/摘要窥视);三、UI 读别槽摘要只走窥视 API(不激活、不写内存、零盘面副作用),返回结构 = 可读标记 + 三项摘要值(钥石/通关数/总局数)——可读标记 = 槽文件可读(空槽=零值合法态可读;损坏/高版本/缺版本字段=不可读标记);槽主文件在盘与否不作摘要项、只供操作集二分判定(零 UI 语义),三项摘要值只在可读时有意义。
|
||||
消费面纪律:其他系统只经 SaveManager 的类型化访问器(读余额/加钥石/花钥石、读写树等级等)与域更新原语(`apply_adventure_summary`)操作存档,不碰内部数据结构。三条槽位纪律(迭代 33 卡①):一、无激活态下一切写盘路径拒绝并返回 false(boot 后未进档/未新档即结算或购买=不落盘,激活后照常);二、槽文件名单点派生——消费方禁各自拼槽文件名,测试与探针的隔离走注入口(`attach_slot_template`/`peek_summary_at`);三、UI 读别槽摘要只走窥视 API `peek_slot_summary(slot)`(不激活、不写内存、零盘面副作用),返回结构 `{"readable", "has_file", "keystone", "cleared", "total"}`——`readable`=槽文件可读(空槽=零值合法态可读;损坏/高版本/缺版本字段=不可读标记),`has_file`=槽主文件在盘与否(空槽/有档的操作集二分判定来处;非摘要第四项、零 UI 语义),三项摘要值(`keystone`/`cleared`/`total`)只在 `readable=true` 时有意义。
|
||||
|
||||
### 读写时机
|
||||
|
||||
```
|
||||
启动 ──▶ 不读盘(boot 无激活态,不读写任何槽;只做一次旧单档迁移,见「版本与迁移」节)
|
||||
选档界面「新档」/「进档」──▶ 建立激活态(读盘=该槽文件;迭代 33 卡①/卡③)
|
||||
正式冒险收束 ──▶ 冒险摘要入账 ──▶ 原子写盘(落当前激活槽)
|
||||
选档界面「新档」/「进档」──▶ create_slot / activate_slot(读盘=该槽文件,建立激活态;迭代 33 卡①/卡③)
|
||||
正式冒险收束(adventure_finished)──▶ apply_adventure_summary 入账 ──▶ 原子写盘(落当前激活槽)
|
||||
营地钥石消费(元进度实现批接线)──▶ 每笔变更后即时写盘(落当前激活槽)
|
||||
冒险停点(选路停点)──▶ 断点快照写盘(迭代 8 卡①)
|
||||
冒险停点(choices_presented 选路停点)──▶ 断点快照写盘(迭代 8 卡①)
|
||||
冒险三结局收束(冒险成功/失败/放弃)──▶ 清除断点 + 原子写盘(迭代 8 卡①/T3 退出口径)
|
||||
```
|
||||
|
||||
@@ -124,13 +124,13 @@ v4/v5/v6 各域缺键由读取方按默认值补齐(空集合/0),旧档零
|
||||
|
||||
断点写盘纪律(迭代 8 卡①):停点快照在每个选路停点(战斗胜利/兑付确认/入口呈现后的选路态)整体覆写——战斗进行中不写(棋盘中局不入档,续玩恢复至最近停点、当场战斗从头打)。因为快照总在每个停点即时落盘,「关游戏走人」在任何停点都不丢续玩进度,无需窗口关闭钩子。
|
||||
|
||||
写盘是原子操作:先写同目录临时文件,写完改名覆盖正式档——写一半断电不留烂档。
|
||||
写盘是原子操作:先写临时文件(`<路径>.tmp`),写完改名覆盖正式档——写一半断电不留烂档。
|
||||
|
||||
单局测试入口不写档:调试两层与 headless 单关测试路径(仅 QA 工具使用)不接写盘——测试模式不污染生涯数据;只有正式冒险收束才入账。
|
||||
单局测试入口不写档:调试两层与 headless 单关测试路径(LevelRunner.start_level,仅 QA 工具使用)不接写盘——测试模式不污染生涯数据;只有正式冒险(AdventureRunner)收束才入账。
|
||||
|
||||
### 版本与迁移
|
||||
|
||||
存档带版本字段(`version`,当前 = **7**;版本沿革:v2 = 断点域出生〔迭代 8 卡①〕→ v3 = 断点附随件扩列 + 摘要 keystone_drops〔迭代 10 奖励重构〕→ v4 = 同调批扩域〔boss_kill_count / attunement_equipped / attune_refresh_level,迭代 11 第①批〕→ v5 = 天赋树域〔tree_nodes / fork_sides,迭代 12〕→ v6 = 生涯终身计数域〔adventure_total / adventure_cleared,迭代 18 卡④〕→ **v7 = 锻造工坊域〔forge_routes,迭代 23 T5——已落地:{levels 六路线等级 + unlocked 直购解锁清单 + weapon/armor 当前选中标记},无特效域;旧档缺键按默认补齐 = 初始持有态(sword/light 在档、余四锁、选中=初始路线),v6→v7 空迁移 = 缺键补齐模式(v3→v4 先例);开发阶段禁迁移禁折算——契约 4〕**)。三条走向:
|
||||
存档带版本字段(`version`,当前 = **7**;版本沿革:v2 = 断点域出生〔迭代 8 卡①〕→ v3 = 断点附随件扩列 + 摘要 keystone_drops〔迭代 10 奖励重构〕→ v4 = 同调批扩域〔boss_kill_count / attunement_equipped / attune_refresh_level,迭代 11 第①批〕→ v5 = 天赋树域〔tree_nodes / fork_sides,迭代 12〕→ v6 = 生涯终身计数域〔adventure_total / adventure_cleared,迭代 18 卡④〕→ **v7 = 锻造工坊域〔forge_routes,迭代 23 T5——已落地:{levels 六路线等级 + unlocked 直购解锁清单 + weapon/armor 当前选中标记},无特效域;旧档缺键由 _normalize 按默认补齐 = 初始持有态(sword/light 在档、余四锁、选中=初始路线),v6→v7 空迁移 = 缺键补齐模式(v3→v4 先例);开发阶段禁迁移禁折算——契约 4〕**;与 `game/core/config_db.gd` 的 SCHEMA_VERSION 同源)。三条走向:
|
||||
|
||||
| 情形 | 处置 |
|
||||
|---|---|
|
||||
@@ -138,13 +138,13 @@ v4/v5/v6 各域缺键由读取方按默认值补齐(空集合/0),旧档零
|
||||
| 版本更高(未来版本的档) | **拒读且禁写**:不加载、后续写盘一律拒绝、内存以默认新档运行——保护未来版本的档不被当前版本覆写 |
|
||||
| 版本更低(旧档) | 读档时逐级迁移:从旧版本起逐个调用注册的迁移函数升到当前版本;任一步失败按损坏兜底处理 |
|
||||
|
||||
迁移函数按旧版本号逐一注册:函数把数据从「旧版本」改写成「旧版本 + 1」。生产迁移链现行六件(v2 起自注册):v1→v2 = 断点域补空;v2→v3 = 断点附随件与摘要 keystone_drops 补键(读取方 .get 兜底);v3→v4 = 同调三域补键;v4→v5 = 树域两键补齐(原挂接的「三体系迁移」体已随迭代 21 T5 攻防所有权切分删除;forge_levels 旧域同批清退,加载时按默认模型键集白名单收窄);v5→v6 = 生涯两终身计数域补零;**v6→v7 = 锻造工坊域 forge_routes 缺键补齐(迭代 23 T5——无结构迁移体,版本号推进仅随表结构变化;解锁态派生不落档:初始持有〔表 initial_owned〕∨ 直购〔unlocked 清单〕∨ 练满前一档〔levels[prereq]≥cap〕)**。任一步失败按损坏兜底处理。
|
||||
迁移函数经 `register_migration(旧版本号, 函数)` 注册:函数把数据从「旧版本」改写成「旧版本 + 1」。生产迁移链现行六件(v2 起自注册):v1→v2 = 断点域补空;v2→v3 = 断点附随件与摘要 keystone_drops 补键(读取方 .get 兜底);v3→v4 = 同调三域补键;v4→v5 = 树域两键补齐(原挂接的「三体系迁移」体已随迭代 21 T5 攻防所有权切分删除——`save_manager.gd:96-98`、`meta_progression.gd:294-295` 实证;forge_levels 旧域同批清退,加载时按默认模型键集白名单收窄,`save_manager.gd:399-401`);v5→v6 = 生涯两终身计数域补零;**v6→v7 = 锻造工坊域 forge_routes 缺键补齐(迭代 23 T5——无结构迁移体,版本号推进仅为 schema_version 对齐;解锁态派生不落档:初始持有〔表 initial_owned〕∨ 直购〔unlocked 清单〕∨ 练满前一档〔levels[prereq]≥cap〕)**。任一步失败按损坏兜底处理。
|
||||
|
||||
旧单档一次性迁移(迭代 33 卡①,用户裁决 Q1 甲):本系统从单档制换代为 3 存档位制时,盘上残留的旧单档文件在启动时被处理——文件**字节级原样搬运**进槽 1(零解析零改造:损坏或高版本的旧档也原样迁入,之后由该槽进档时的损坏兜底/高版本拒读接管,不静默丢数据),源文件改名留痕不删;槽 1 文件已存在则不重迁(幂等,二次启动零操作);迁移失败(拷贝或改名失败)源文件保留、下次启动重试。留痕与结果记在启动日志(开发者向,非玩家面)。
|
||||
旧单档一次性迁移(迭代 33 卡①,用户裁决 Q1 甲):本系统从单档制换代为 3 存档位制时,盘上残留的旧单档 `user://save.json` 在启动时被处理——文件**字节级原样搬运**进槽 1(`user://save_slot_1.json`,零解析零改造:损坏或高版本的旧档也原样迁入,之后由该槽进档时的损坏兜底/高版本拒读接管,不静默丢数据),源文件改名 `user://save.json.migrated.bak` 留痕不删;槽 1 文件已存在则不重迁(幂等,二次启动零操作);迁移失败(拷贝或改名失败)源文件保留、下次启动重试。留痕与结果记在启动日志(开发者向,非玩家面)。
|
||||
|
||||
### 损坏兜底
|
||||
|
||||
档案读不开(文件损坏、JSON 解析失败、结构出域、缺版本字段)时:原文件改名留一份坏档备份(已有同名备份则覆盖)留下现场,游戏用默认新档继续运行,并留下警告日志。两条底线:不静默丢档(坏档永远可人工找回)、不崩溃(坏档不挡玩)。
|
||||
档案读不开(文件损坏、JSON 解析失败、结构出域、缺版本字段)时:原文件改名为 `<路径>.corrupt.bak`(已有同名备份则覆盖)留下现场,游戏用默认新档继续运行,并留下警告日志。两条底线:不静默丢档(坏档永远可人工找回)、不崩溃(坏档不挡玩)。
|
||||
|
||||
## 依赖与输出
|
||||
|
||||
@@ -164,12 +164,12 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单
|
||||
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| ~~P1~~ | ~~快照与复盘的持久化承接~~ | **已兑现**(2026-09-29 迭代 8 卡①:断点域承载 + rng「主种子+计数器」快照契约回填面) |
|
||||
| ~~P1~~ | ~~快照与复盘的持久化承接~~ | **已兑现**(2026-09-29 迭代 8 卡①:断点域承载 + rng「主种子+计数器」快照契约回填面 `restore_adventure`) |
|
||||
| ~~P2~~ | ~~多存档槽位~~ | **已实现**(2026-10-22 迭代 33 卡①——3 存档位三文件制落地,口径见「三存档位」段;原「单档 MVP(2026-09-21 裁决)」后置条随兑现注销) |
|
||||
|
||||
## 调参表
|
||||
|
||||
本系统没有玩法调参数值。两个结构常量:存档版本号(当前 7)、最近摘要保留条数(10)。二者是结构契约不是平衡值,改动属于版本迁移事件,不走调参批。
|
||||
本系统没有玩法调参数值。两个结构常量:存档版本号(=6,与 `game/core/config_db.gd` 的 SCHEMA_VERSION 同源)、最近摘要保留条数(10)。二者是结构契约不是平衡值,改动属于版本迁移事件,不走调参批。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -179,7 +179,7 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单
|
||||
- 改版不弃档:旧版本档经迁移链读回;低版本档缺新域按默认补齐,既有值保留(冒烟承载)。
|
||||
- 断点域契约(迭代 8 卡①):七字段拍板面写读往返逐位一致;旧档无断点域迁移为合法空态;三结局清除(冒烟+单测承载)。
|
||||
- 域界干净:meta 永久进度域不含局内系统资源键(行动点/储备行动点/道具库存/生命/GP)——断点域按豁免条款单列(冒烟承载,2026-09-29 卡①修订)。
|
||||
- 零玩法依赖:存档系统不引入任何玩法脚本、不碰数值表与随机服务,可独立实例化验证(冒烟独立段承载)。
|
||||
- 零玩法依赖:SaveManager 不引入任何玩法脚本、不碰数值表与随机服务,可独立实例化验证(冒烟独立段承载)。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 数据配置
|
||||
|
||||
> 一句话:数值表与单一事实源管线
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.1
|
||||
> 状态:已定稿(自旧体系迁移);现行为 v1.0
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
| 负责 | 说明 |
|
||||
|---|---|
|
||||
| 全部数值表的结构与数据 | 表结构类(声明每列的类型、取值域与默认值)与数据文件成对交付;结构先行,数值由各回填责任方回填 |
|
||||
| 全局读取口与随机服务 | 两个进程级单例:类型化读取口与统一随机流服务 |
|
||||
| 全局读取口与随机服务 | 两个进程级单例:类型化读取口(代码标识符 ConfigDB)与统一随机流服务(代码标识符 RngService) |
|
||||
| 加载、校验与热重载管线 | 启动加载、fail-fast 校验、调试构建热重载的状态管理 |
|
||||
| 进度坐标查行 | 进度键表(跟着冒险进度成长的表)按(关卡序号 × 节点深度)两维坐标解析取行 |
|
||||
| 表清单与对账 | 表路径固定、清单封闭;表实与 schema 声明逐字段对账 |
|
||||
@@ -28,7 +28,7 @@
|
||||
| 不负责 | 归谁 |
|
||||
|---|---|
|
||||
| 各表数值定值与玩法公式 | 各回填责任方(清单见核心规则的表清单),平衡总归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| 存档格式与版本比较逻辑 | [存档序列化](存档序列化.md),本系统只出随机快照契约 |
|
||||
| 存档格式与版本比较逻辑 | [存档序列化](存档序列化.md),本系统只出版本常量与随机快照契约 |
|
||||
| 界面呈现 | [HUD 框架](HUD框架.md) |
|
||||
| 随机用途的设计合理性 | 消费方系统自证(随机须有界、可见或可推理),新增随机走扩签通道 |
|
||||
|
||||
@@ -52,24 +52,24 @@
|
||||
|
||||
一句话总结这条规则:改数值 = 改表回填,不动代码;表不变,行为逐位相同。仅调试构建存在两个额外通道:从命令行注入的根目录加载测试夹具表;调试覆盖值可临时改读数、不回写表文件,正式构建结构性不存在覆盖源。
|
||||
|
||||
现行表集合如下:
|
||||
现行表集合如下(表结构类名供代码标识与工具链检索):
|
||||
|
||||
| 表 | 载什么 | 回填责任方 |
|
||||
|---|---|---|
|
||||
| 行动经济表 | 每轮行动点、动作价目、停手与刷新门槛 | [行动经济](../排雷循环/行动经济.md) |
|
||||
| 棋盘生成参数表 | 板尺寸、雷密度、可推理率目标等(进度键表) | [棋盘生成](../排雷循环/棋盘生成.md) |
|
||||
| 变异表 | 变异类型清单(现行六行:region 六行两轴×三关〔2026-09-20 落地〕;首发 global 整图型贫矿脉 2026-10-16 用户令屏蔽删行,global 型机制代码保留) | [地形变异](../排雷循环/地形变异.md) |
|
||||
| 敌人表 | 敌种基线数值、遭遇数量区间、护甲类型、技能池模板(进度键表) | [敌人系统](../战斗循环/敌人系统.md) |
|
||||
| 技能表 | 技能行定义(类型/倍率/冷却/增益引用/触发条件)与保底阈值 | [敌人系统](../战斗循环/敌人系统.md) |
|
||||
| 主角表 | 主角生命上限、基础攻击与护甲等级(armor_class)等单行战斗数值 | [敌人系统](../战斗循环/敌人系统.md) |
|
||||
| 状态效果表 | 增益/减益效果定义行 | [增益状态](../战斗循环/增益状态.md) |
|
||||
| 奖励表 | 奖励条目、类别、权重与档位 | [地图战斗资源](../战斗循环/地图战斗资源.md) |
|
||||
| 结算表 | 结算段序、当量参考敞口、封顶与克制矩阵(单行全局) | [战斗结算](../战斗循环/战斗结算.md) |
|
||||
| 秘宝表(`treasure_items.tres`) | 秘宝定义行 | [秘宝](../跨局循环/秘宝.md) |
|
||||
| 难度表 | 难度修饰乘数(占位空表) | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| 关卡表 | 逐关节点图与层名 | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
| 冒险表 | 关卡大奖励与钥石入账(单行全局) | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
| 元进度表 | 元进度字段(已建表 2026-09-21——现行五行族:属性锻造 / Boss 钥石 / 工坊阈值 / 换算率 / 同调刷新升级行族,顺带扩列) | [元进度](../跨局循环/元进度.md) |
|
||||
| 行动经济表 `ActionEconomyTable` | 每轮行动点、动作价目、停手与刷新门槛 | [行动经济](../排雷循环/行动经济.md) |
|
||||
| 棋盘生成参数表 `BoardGenTable` | 板尺寸、雷密度、可推理率目标等(进度键表) | [棋盘生成](../排雷循环/棋盘生成.md) |
|
||||
| 变异表 `VariationTable` | 变异类型清单(现行六行:region 六行两轴×三关〔2026-09-20 落地〕;首发 global 整图型贫矿脉 2026-10-16 用户令屏蔽删行,global 型机制代码保留) | [地形变异](../排雷循环/地形变异.md) |
|
||||
| 敌人表 `EnemyTable` | 敌种基线数值、遭遇数量区间、护甲类型、技能池模板(进度键表) | [敌人系统](../战斗循环/敌人系统.md) |
|
||||
| 技能表 `SkillTable` | 技能行定义(类型/倍率/冷却/增益引用/触发条件)与保底阈值 | [敌人系统](../战斗循环/敌人系统.md) |
|
||||
| 主角表 `HeroTable` | 主角生命上限、基础攻击与护甲等级(armor_class)等单行战斗数值 | [敌人系统](../战斗循环/敌人系统.md) |
|
||||
| 状态效果表 `StatusEffectTable` | 增益/减益效果定义行 | [增益状态](../战斗循环/增益状态.md) |
|
||||
| 奖励表 `RewardTable` | 奖励条目、类别、权重与档位 | [地图战斗资源](../战斗循环/地图战斗资源.md) |
|
||||
| 结算表 `SettlementTable` | 结算段序、当量参考敞口、封顶与克制矩阵(单行全局) | [战斗结算](../战斗循环/战斗结算.md) |
|
||||
| 秘宝表 `TreasureItemTable`(`treasure_items.tres`) | 秘宝定义行 | [秘宝](../跨局循环/秘宝.md) |
|
||||
| 难度表 `DifficultyTable` | 难度修饰乘数(占位空表) | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) |
|
||||
| 关卡表 `LevelTable` | 逐关节点图与层名 | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
| 冒险表 `AdventureTable` | 关卡大奖励与钥石入账(单行全局) | [冒险结构](../冒险循环/冒险结构.md) |
|
||||
| 元进度表 `MetaTable` | 元进度字段(已建表 2026-09-21——现行五行族:属性锻造 / Boss 钥石 / 工坊阈值 / 换算率 / 同调刷新升级行族,顺带扩列) | [元进度](../跨局循环/元进度.md) |
|
||||
|
||||
举证:本节为数据纪律约定,无计算。违规检测 = 静态扫描加人工复核,随各表回填定稿与里程碑检查执行。
|
||||
|
||||
@@ -88,11 +88,11 @@
|
||||
|
||||
取数有两个入口。玩法代码用取号入口:每调用一次,全局计数器加一并派生新种子,同一事件内共享同一实例。测试与预览用纯函数入口:按指定全局序号计算种子、不推计数器——预览不污染正式序列。种子由登记的派生公式计算(单盐),纯函数、跨引擎版本恒定,并登记了可复算的黄金向量。
|
||||
|
||||
全事件日志(并流批新增):冒险开始即开日志会话(随机事件日志文件,每主种子一份),每次取数落一行——全局序号、用途标签、派生种子。号位在全序账本下不再单独回答"第 N 次某类事件"(路线依赖为已裁决代价),单点定位与复盘由日志承载。写盘失败只告警降级,不致命、不影响玩法随机。
|
||||
全事件日志(并流批新增):冒险开始即开日志会话(user://logs/rng_log_<主种子>.jsonl),每次取数落一行——全局序号、用途标签、派生种子。号位在全序账本下不再单独回答"第 N 次某类事件"(路线依赖为已裁决代价),单点定位与复盘由日志承载。写盘失败只告警降级,不致命、不影响玩法随机。
|
||||
|
||||
生命周期:进程启动后流待命(未注入主种子就取数,致命中止,禁止默认种子兜底)→ 冒险开始注入主种子并开日志会话 → 冒险中按事件取号(全局计数器只增不重置)→ 冒险结束流保留供复盘。续玩与复盘的快照 = 主种子加全局取数计数器,由[存档序列化](存档序列化.md)消费;快照切出须发生在没有在用取号实例的时刻。要新增随机用途(含战斗内随机),走扩签通道:改代码加用途标签并通过评审——词表封闭是刻意的设卡。
|
||||
|
||||
举证:派生公式(单盐)由随机服务持有,本文不转载;黄金向量已登记可复算,逐向量复算相等即验收判据。
|
||||
举证:派生公式与实现规约见 `game/core/rng_service.gd`(盐与派生常量为代码事实),黄金向量断言见 `game/tests/unit/data_config/rng_stream_boot_test.gd`;本文不转载。
|
||||
|
||||
### fail-fast 校验:宁可启动失败,不带病运行
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
热重载(不重启进程、当场重新加载表文件的调试手段,仅调试构建)单独一套处置:战斗进行中的重载请求被闸门拒绝(闸门由[战斗结算](../战斗循环/战斗结算.md)在战斗开始时置位、结束复位),重载校验失败时保留旧表继续运行并给出错误清单——不杀调试会话,这是全部规则里唯一的软着陆。调试构建之外,加载与校验在任何构建形态一律致命。随机服务的状态线独立于表加载:重载成败都不触碰主种子与计数器。
|
||||
|
||||
举证:本节为处置纪律约定,无计算。校验双通道与夹具注入为实现参照,本文不转载。
|
||||
举证:本节为处置纪律约定,无计算。校验双通道(正式通道致命、测试通道收集供冒烟逐类断言)与夹具注入为实现参照,见 `game/core/config_db.gd` 实现。
|
||||
|
||||
### 悬空引用校验:跨表引用指到的键必须存在
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 关卡表与冒险表承载(登记现状见「待办」);主种子注入入口 |
|
||||
| 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 难度表承载(占位);进度坐标查行的消费方 |
|
||||
| 下游 | [元进度](../跨局循环/元进度.md) | 元进度表占位承载 |
|
||||
| 下游 | [存档序列化](存档序列化.md) | 随机快照契约(主种子 + 全局取数计数器) |
|
||||
| 下游 | [存档序列化](存档序列化.md) | 表结构版本常量;随机快照契约(主种子 + 全局取数计数器) |
|
||||
| 下游 | [HUD 框架](HUD框架.md) | 调试热重载完成通知(仅调试构建) |
|
||||
| 外发 | 无订阅 | 本系统不订阅任何玩法事件 |
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
| 参数 | 现行值 | 说明 |
|
||||
|---|---|---|
|
||||
| 表路径清单 | data/tables/ 固定(调试注入根除外) | 冻结:散装路径破坏单点访问 |
|
||||
| 表结构版本常量 `SCHEMA_VERSION` | 当前 = 2(v2=断点域出生,迭代 8 卡①,与存档 SAVE_FORMAT_VERSION 同源) | 全部表结构携带版本字段;高于当前支持的版本拒读,比较逻辑归[存档序列化](存档序列化.md) |
|
||||
| 随机流口径 | 统一流单盐单计数器 + 七用途标签封闭词表 | 统一口径为 2026-09-27 裁决;扩签 = 改代码 + 评审,有意设卡 |
|
||||
| 进度坐标解析策略 | 可取范围内向上取整 + 警告(保证偏难);超出最大行封顶取最大值 + 警告;域越界致命(2026-09-18 两段拍板,原「就近向下」退役) | 冻结:静默降难会掩盖难度断档 |
|
||||
| 入口锚行校验 | 写死开 | 非调参项;重议走文档修订流程 |
|
||||
@@ -199,11 +200,12 @@
|
||||
- 黄金向量:随机派生纯函数对登记向量逐个复算相等;同输入恒同输出;同序号重复调用恒等。
|
||||
- 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;热重载成败都不改变主种子与计数器。
|
||||
- 向上取整解析:请求无精确行时返回**不低于**请求坐标的最近行并留一条警告;请求超出最大已有行时封顶取最大行并留警告;同类警告去重;精确命中零警告。
|
||||
- 越域与未播种:坐标低于合法域(关卡序号 <1、节点深度 <0)在进入解析前致命中止(Fatal 级诊断 + 进程非 0 退出,无兜底);高于最大已有行走封顶取最大行(警告留痕,不致命);未设主种子就取随机数致命中止,无默认种子兜底。
|
||||
- 越域与未播种:坐标低于合法域(关卡序号 <1、节点深度 <0)在进入解析前致命中止(Fatal 级诊断 + 进程退出码 1,致命类单测 `tests/unit/data_config/config_db_fatal_oob_test.gd` 验证——迭代 19 卡① T4 探针退役顺带改指,原切片探针断言面与 run_all 致命类单测重复故退役);高于最大已有行走封顶取最大行(警告留痕,不致命);未设主种子就取随机数致命中止,无默认种子兜底。
|
||||
- 热重载门:战斗中重载被拒绝且读数不变、不发通知;门未置位时新值可读且通知恰一次;校验失败保留旧表停留就绪态。
|
||||
- 版本常量在位:表结构版本常量存在且全部表结构携带版本字段(高版本拒读判定归存档序列化)。
|
||||
- 零字面量、零第二路径:静态扫描加人工复核确认玩法代码无数值字面量、无读取口之外的表加载、无全局随机函数调用。
|
||||
- 零界面依赖:本系统代码不引用任何界面类,无窗口实跑通过(静态扫描与实跑两项合成判定)。
|
||||
- 表实一致:各表结构与已锁字段和表结构声明逐字段一致。
|
||||
- 表实一致:各表结构与已锁字段和 `data/schemas/` 对应声明逐字段一致。
|
||||
|
||||
## 待办
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 设置与本地化
|
||||
|
||||
> 一句话:设置项与多语言
|
||||
> 状态:范围草案·最小设置面已兑现(2026-09-29 迭代 8 卡④);现行为 v1.1
|
||||
> 状态:范围草案·最小设置面已兑现(2026-09-29 迭代 8 卡④)
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -92,7 +92,7 @@ MVP 不要求本系统的闭环:[不做清单](../../05-不做清单.md)把设
|
||||
|
||||
| 优先级 | 内容 | 后置原因 |
|
||||
|---|---|---|
|
||||
| ~~P1~~ | ~~已承诺设置项落位:减动效开关、音量控制入口~~ | **已兑现**(2026-09-29 迭代 8 卡④最小设置面:音量 master bus 实时+持久、减动效开关转正〔测试调整板旧开关退役,设置面唯一入口〕、全屏切换、退出游戏;载体=独立设置存储 + 设置界面视图(一安装一份,不进存档);键位映射/多语言仍按后置表排期) |
|
||||
| ~~P1~~ | ~~已承诺设置项落位:减动效开关、音量控制入口~~ | **已兑现**(2026-09-29 迭代 8 卡④最小设置面:音量 master bus 实时+持久、减动效开关转正〔测试调整板旧开关退役,设置面唯一入口〕、全屏切换、退出游戏;载体 presentation/settings_store.gd 独立存储 + views/settings_overlay.gd 视图;键位映射/多语言仍按后置表排期) |
|
||||
| P1 | 多语言生产流程与首批语言清单 | 生产流程未定:文案怎么管理、谁负责校对 |
|
||||
| P2 | 设置项全集(画面 / 键位 / 可访问性 / 语言各类别) | 全集无来源,待设计问题清单裁决后展开 |
|
||||
| P2 | 结算风味词输入的承接 | 归档只登记了存在,各归各的时机 |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 元进度
|
||||
|
||||
> 一句话:跨局成长——钥石在营地换成永久强化,存档随冒险变厚
|
||||
> 状态:**已定稿(现行为 v1.26)**——2026-09-18 元进度定稿批用户拍板;历次升版明细见 git 提交史。
|
||||
> 状态:**已定稿(现行为 v1.25)**——2026-09-18 元进度定稿批用户拍板;历次升版明细见 git 提交史。
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -62,18 +62,18 @@
|
||||
| 功能界面 | 内容 | 解锁渠道 |
|
||||
|---|---|---|
|
||||
| 属性锻造 | 生命上限、基础攻击、护甲等级——三档可重复升级的属性强化 | 钥石直购 |
|
||||
| 秘宝匣 | 秘宝解锁与同调装配——**件的目录与效果权威定义在[秘宝](秘宝.md)「目录(重设计 v1)」**(12 件三档〔2026-10-11 裁回能器删/换装券撤/第四只手删〕;旧目录全退役只作素材库) | 解锁=混合制(基础件钥石购买/特定件条件解锁——见秘宝.md「道具从哪来」;装配只在冒险开始前配置,冒险中零更换途径〔2026-10-11 终裁〕);**迭代 22 实装批落地(2026-10-12)**:购买钮(余额不足禁用态)+条件解锁进度呈现+分档装配呈现(名后缀·档位/未解锁禁装)+空目录合法态;界面数据投影=秘宝匣柜台状态(解锁态/条件进度/价格单点);旧道具工坊渠道面(行族/词表/解锁函数)已顺带退役;钥石定价与阈值 provisional 归调参批 |
|
||||
| 秘宝匣 | 秘宝解锁与同调装配——**件的目录与效果权威定义在[秘宝](秘宝.md)「目录(重设计 v1)」**(12 件三档〔2026-10-11 裁回能器删/换装券撤/第四只手删〕;旧目录全退役只作素材库) | 解锁=混合制(基础件钥石购买/特定件条件解锁——见秘宝.md「道具从哪来」;装配只在冒险开始前配置,冒险中零更换途径〔2026-10-11 终裁〕);**迭代 22 实装批落地(2026-10-12)**:购买钮(余额不足禁用态)+条件解锁进度呈现+分档装配呈现(名后缀·档位/未解锁禁装)+空目录合法态;界面数据投影=`treasure_shop_status`(解锁态/条件进度/价格单点);旧道具工坊渠道面(行族/词表/解锁函数)已顺带退役;钥石定价与阈值 provisional 归调参批 |
|
||||
| 奖励格图鉴 | 特殊奖励格的解锁——更强效果的格面 | 结构位现定;格子内容排 Alpha,随[地图战斗资源](../战斗循环/地图战斗资源.md)差异化批落地 |
|
||||
|
||||
属性锻造的树形节点结构已随迭代 12 落地在役——**结构/节点/数值的现行事实源 = [天赋树](天赋树.md),本文不复制树侧内容、只作指路**;本界面三档直线强化与树淬炼 flat 在注入面叠加生效(注入口径见下文「跨局注入」节)。
|
||||
|
||||
属性锻造的攻击、护甲两档已按[锻造工坊](锻造工坊.md) v0.6(成文时名「武器锻造」,2026-10-11 更名)设计定案转为武器与护甲的独立等级路线——**行族本体随迭代 21 T5 退役、路线为新建行族,已随迭代 23 实装入库(2026-10-12,新表 `forge.tres`)**。营地钥石入口族换代(2026-10-13 v1.18 迭代 23 反哺写入):原逐级购买写口随 forge_products 退役删除后,本柜台钥石消费写口 = **逐级锻造价 / 一次性解锁价 / 免费选中武器·甲**——写口唯一经元进度锻造写口族(契约 9 写口单点,UI 只发意图);钥石定价历史考古参数 20 钥石/150% 公比见 `meta.tres` 退役批注,provisional 投值终值归 M4。
|
||||
属性锻造的攻击、护甲两档已按[锻造工坊](锻造工坊.md) v0.6(成文时名「武器锻造」,2026-10-11 更名)设计定案转为武器与护甲的独立等级路线——**行族本体随迭代 21 T5 退役、路线为新建行族,已随迭代 23 实装入库(2026-10-12,新表 `forge.tres`)**。营地钥石入口族换代(2026-10-13 v1.18 迭代 23 反哺写入):buy_forge 随 forge_products 退役删除后,本柜台钥石消费写口 = **forge_buy_level(逐级锻造价)/ forge_buy_unlock(一次性解锁价)/ forge_select_weapon·armor(免费选中)**——写口唯一经 MetaProgression 锻造写口族(契约 9 写口单点,UI 只发意图);钥石定价历史考古参数 20 钥石/150% 公比见 `meta.tres:82-84` 退役批注,provisional 投值终值归 M4。
|
||||
|
||||
**营地统一(2026-10-11 天赋树设计会话裁案甲;2026-10-13 v1.20 迭代 21 反哺写入——「落地前维持现役」过渡态终结)**:树=营地本体,本属性锻造柜台已随迭代 21 退役、属性升级唯一入口=树脊柱淬炼节点(四柜台并排已实装,2026-10-12 入库)。**完整模型(四柜台并排/钥匙工作间/图鉴常开)唯一事实源 = [天赋树](天赋树.md)「营地=树:统一模型」节——本文只登记本柜台在系统内的去留,不复制树侧内容。**
|
||||
|
||||
**投值语言锁定(2026-09-18 数值语言拍板)**:营地属性强化一律 **flat 整数加减**("每级 +1 基础攻击"式,而非"+50% 攻击"式)——避开百分比词条被数值成长稀释的先例陷阱、守住数字可读性锚;具体每级数值仍归元进度设计批投值。
|
||||
|
||||
各界面定价纪律:**定价曲线一律几何递增**(每级费用按公比上浮——原则已拍板,起步价与公比数字归设计批配读数),与产出逻辑配套:深层关钥石产出多、后级强化贵,逼玩家往深处走。~~秘宝匣首版只挂通关次数渠道~~(历史排期裁决已消解:秘宝匣现役=钥石直购+条件解锁混合制,迭代 22 落地,2026-10-12)。**存档义务随柜台产生**:钥石余额、永久强化等级表、每关通关次数表、Boss 首杀标记位——四件已逐域登记在存档登记条目(内容 owner = 元进度,承载 owner = [存档序列化](../表现与支撑/存档序列化.md))。
|
||||
各界面定价纪律:**定价曲线一律几何递增**(每级费用按公比上浮——原则已拍板,起步价与公比数字归设计批配读数),与产出逻辑配套:深层关钥石产出多、后级强化贵,逼玩家往深处走。~~秘宝匣首版只挂通关次数渠道~~(历史排期裁决已消解:秘宝匣现役=钥石直购+条件解锁混合制,迭代 22 落地,2026-10-12)。**存档义务随柜台产生**:钥石余额、永久强化等级表、每关通关次数表、Boss 首杀标记位——四件已逐域登记在 registry `save_file` 条目(内容 owner = 元进度,承载 owner = [存档序列化](../表现与支撑/存档序列化.md))。
|
||||
|
||||
护甲等级进首版属性柜台是 2026-09-18 拍板(用户选 A),其代价条款见下方换算率节的强条目登记。
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
解锁让玩家变强,难度验收区间随之需要平移——双方约定(难度曲线与Boss 定稿口径)永久强化的影响**不直接改难度判据**,而是按统一换算率折算成关卡完成率带的平移量后套用:完美档 gate 与 normal 目标带的判读口径不变,带随解锁等级平移。
|
||||
|
||||
换算率表(数值行读 `data/tables/meta.tres` conversion 行族)登记三个属性维度(2026-09-18 拍板;"行" = 表内一条记录,一个属性维度即一行条目,全仓与"行值"同义)。现行表值(2026-09-23 换算率标定批投值——OFAT 冒险注入档与白板同种子配对的逐关条件通关率差实测,冒险条件口径 + 当日数值包现行态;报告已按生命周期条款退役,判定端 ④ 段可复判):
|
||||
换算率表(registry 键 `meta_progression_conversion_table`,数值行读 `data/tables/meta.tres` conversion 行族)登记三个属性维度(2026-09-18 拍板;"行" = 表内一条记录,一个属性维度即一行条目,全仓与"行值"同义)。现行表值(2026-09-23 换算率标定批投值——OFAT 冒险注入档与白板同种子配对的逐关条件通关率差实测,冒险条件口径 + 当日数值包现行态;报告=git 提交 7f24b64(已按生命周期条款退役),判定端 ④ 段可复判):
|
||||
|
||||
| 换算行 | 折算语义 | 每级带平移量(现行表值) |
|
||||
|---|---|---|
|
||||
@@ -89,17 +89,17 @@
|
||||
| 基础攻击强化 | 每级折算为关卡完成率带平移量 | **9 点** |
|
||||
| 护甲等级强化 | 每级折算为关卡完成率带平移量 | **1 点** |
|
||||
|
||||
判定端按表值驱动消费:验收带按解锁状态折算后套用,表改则判定随动。护甲行强条目重测义务已于标定批履行(解锁后参数实测,非基线外推);标定同时暴露并修复一处缺口:主角护甲锻造与局内加算区护甲轴的生效值此前未进战斗(该轴此前无消费方=已知缺口,已随标定批修复并登记)。
|
||||
判定端(tools/balance_verifier.py)表值驱动消费:验收带按解锁状态 flat÷每级flat×表值平移后套用,表改则判定随动。护甲行强条目重测义务已于标定批履行(解锁后参数实测,非基线外推);标定同时暴露并修复护甲断链(begin_battle `hero_armor_class` 参数零消费——主角护甲锻造与加算区护甲轴的生效值此前未进战斗),修复见 battle_orchestrator `_defender_ac` 批注。
|
||||
|
||||
后续柜台商品(秘宝匣钥石价、奖励格图鉴)上架时逐条补行——每次上架新商品伴随一行换算登记,逐行归因纪律不破。
|
||||
|
||||
### 跨局注入:解锁怎么进下一局
|
||||
|
||||
注入通道沿用两处预留位(2026-09-18 拍板确认):[冒险结构](../冒险循环/冒险结构.md)的**冒险开始参数面**(无解锁时为空参数)+ 英雄覆盖参数传递通道(战斗初始化显式入参,-1 = 表值兜底)。
|
||||
注入通道沿用两处预留位(2026-09-18 拍板确认):[冒险结构](../冒险循环/冒险结构.md)的**冒险开始参数面**(无解锁时为空参数)+ registry `hero_override_parameter_passing`(begin_battle 显式入参,-1 = 表值兜底)。
|
||||
|
||||
执行口径:开始一次新冒险时,本系统按存档内的永久强化状态算好一份 override,逐字段显式传给战斗初始化——配置因此不是完全静态的,随游戏进程动态改变(用户拍板原话口径)。字段清单随柜台扩展:道具池、遭遇权重、奖励格解锁是集合操作,参数面登记**追加 / 替换**两种语义。
|
||||
|
||||
**开局属性四层叠加(2026-10-12 v1.16 补登记——事实源=[锻造工坊](锻造工坊.md)「注入衔接」节 v0.6 / [天赋树](天赋树.md);原「属性锻造三档是数值覆盖」随迭代 21 T5 行族退役换代为下述分层;2026-10-13 v1.18 迭代 23 反哺写入补终态句)**:开局属性 = 角色基础值 + 树生命/命中淬炼 flat + 锻造路线加值(当前选中武器的攻击加值 + 当前甲的 AC 加值——默认值由锻造工坊配置常驻持有、与柜台解锁状态解耦,当前选中读存档域)+ 局内加算区 flat。入战 AC 三层可加 = 甲型基础 AC + 甲路线等级加值 + 局内加算区累加——**第一层「甲型基础 AC」= 选中甲路线行 `base_ac`(`forge.tres`,轻 10/重 12/魔法护甲 9 provisional),已随迭代 23 实装在役(入战 AC 三层公式第一层,树 flat + 锻造路线加值同批在役)**。
|
||||
**开局属性四层叠加(2026-10-12 v1.16 补登记——事实源=[锻造工坊](锻造工坊.md)「注入衔接」节 v0.6 / [天赋树](天赋树.md);原「属性锻造三档是数值覆盖」随迭代 21 T5 行族退役换代为下述分层;2026-10-13 v1.18 迭代 23 反哺写入补终态句)**:开局属性 = 角色基础值 + 树生命/命中淬炼 flat + 锻造路线加值(当前选中武器的攻击加值 + 当前甲的 AC 加值——默认值由锻造工坊配置常驻持有、与柜台解锁状态解耦,当前选中读存档域)+ 局内加算区 flat。入战 AC 三层可加 = 甲型基础 AC + 甲路线等级加值 + 局内加算区累加——**第一层「甲型基础 AC」= 选中甲路线行 `base_ac`(`forge.tres`,轻 10/重 12/魔法护甲 9 provisional),已随迭代 23 实装在役(`effective_ac` 三层公式第一层,树 flat + 锻造路线加值同批在役)**。
|
||||
|
||||
### 解锁界面:双入口框架
|
||||
|
||||
@@ -132,7 +132,7 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)整体
|
||||
| P1 | 营地功能界面内容铺量与定价数字 | 界面结构已定稿;清单明细、几何定价的起步价与公比、Boss 两档产出数值,随设计批配读数投值 |
|
||||
| P1 | 秘宝匣钥石直购价 | **已投 provisional 占位**(普通档 10/优秀档 25 钥石,迭代 22 落地,2026-10-12);终值归调参批(原「首版只挂通关次数渠道」排期态随混合制落地消解) |
|
||||
| P1 | 奖励格图鉴的格子内容 | 排 Alpha,随[地图战斗资源](../战斗循环/地图战斗资源.md)差异化批 |
|
||||
| P1 | 换算率表数值行标定 | **已完成**(2026-09-23 换算率标定批——首版三行投值 6/9/1,护甲行强条目重测顺带履行并修复护甲断链)(原系笔误孤例,换算率登记与 meta.tres 均为 6/9/1——2026-09-30 勘误) |
|
||||
| P1 | 换算率表数值行标定 | **已完成**(2026-09-23 换算率标定批——首版三行投值 6/9/1,护甲行强条目重测顺带履行并修复护甲断链)(原系笔误孤例,registry 与 meta.tres 均为 6/9/1——2026-09-30 勘误) |
|
||||
| P2 | 营地界面与解锁呈现实现 | 归[HUD 框架](../表现与支撑/HUD框架.md)协作批,以表现层样张过审为前置 |
|
||||
|
||||
## 调参表
|
||||
@@ -141,7 +141,7 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)整体
|
||||
|
||||
| 表 | 键结构归属 | 数值行 |
|
||||
|---|---|---|
|
||||
| 换算率表 | 本文 owner,键结构见元进度表结构声明 | `data/tables/`,设计批投值(首版三行,护甲行强条目) |
|
||||
| 换算率表(`meta_progression_conversion_table`) | 本文 owner,键结构见 `data/schemas/meta_table.gd` | `data/tables/`,设计批投值(首版三行,护甲行强条目) |
|
||||
| 定价表(属性锻造 / 秘宝匣 / 奖励格图鉴费用曲线) | 随设计批建表 | `data/tables/`,几何递增参数 |
|
||||
| 钥石产出(Boss 首杀额 / 重复杀小额) | 入账挂点见[冒险结构](../冒险循环/冒险结构.md)调参表(boss_keystone 行);Boss 两档归本文设计批(每关入账值 keystone_per_level 已随迭代 10 奖励重构退役) | `data/tables/` |
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# 天赋树
|
||||
|
||||
> 一句话:营地本身——跨局成长的结构承载:钥石逐节点点亮一棵树,属性淬炼、工作间解锁、规则抉择与同调挂载全部组织在树上
|
||||
> 状态:**已定稿(现行为 v0.11)**——12 节点结构在役(脊柱=生命/命中一线一节点,Fork 三节点双态);「等级阈值前置」为机制位(前置节点等级 ≥ n 才可购;键悬空 / 阈值 <1 / 类型错加载即拒;未达标节点锁标 + 悬停门槛文案),现役 12 行零配置=零行为影响;全部数值行 provisional,归数值批。
|
||||
> 状态:**v0.10 R1 机制位批(2026-10-13,用户推翻迭代 21 追认单 #1 裁撤案)**——「等级阈值前置」以机制位形态顺带重立:schema 新增 `requires_level: {node_id: n}`(前置节点等级 ≥ n 才可购;键悬空/阈值 <1/类型错加载即拒)+ 购买判定分支 + 行板门槛呈现(未达标 🔒 标+悬停门槛文案)+ 单测八断言;**现役 12 行零配置=机制位空转零行为影响**,配置归表行随需填。承 v0.9 迭代 21 反哺写入(2026-10-13,用户裁「按呈报写入文档」)——全文档换代为 12 节点落地实态:头部实装态 / 节点总表前言 / schema 连带 / 已建未接面(三条→两接一维持)/ P0 段 / 依赖表 / 验收实态七处换代;「设计避让」句按卡片 v1.7 ⑪②裁决改写为折扣定义边界口径。承 v0.8 Fork 一节点双态换代(2026-10-11 用户裁——开局姿态/危险直觉/财富之道三天赋=三节点、购买解锁后 A/B 双态可切,现役 A/B 双行结构收编、全树 15→12)
|
||||
|
||||
> **📖 节点状态记录指引(读这份文档先看这里)**:本树全部 12 个节点=下方「核心规则 → 节点总表」,逐节点列名称/脉/类型/前置/效果方向;**全部数值行(价格 / 等级上限 / 每级效果取值 / 限次值)不在本文**,事实源 = 配置文件 `data/tables/meta_tree.tres`(provisional 归数值批)。要查"有哪些节点、怎么连"看本文总表,要查"多少钱、加多少"开配置文件。
|
||||
> **📖 节点状态记录指引(读这份文档先看这里)**:本树全部 12 个节点=下方「核心规则 → 节点总表」,逐节点列名称/脉/类型/前置/效果方向;**全部数值行(价格 / 等级上限 / 每级效果取值 / 限次值)不在本文**,事实源 = 配置文件 `game/data/tables/meta_tree.tres`(provisional 归数值批)。要查"有哪些节点、怎么连"看本文总表,要查"多少钱、加多少"开配置文件。
|
||||
|
||||
## 设计目的
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
| 负责 | 说明 |
|
||||
|---|---|
|
||||
| 节点结构与解锁规则 | 12 节点的一脊三脉构成、脊柱行门槛(节点第 N 级)、点亮前置(requires)+ **等级阈值前置(requires_level——R1 机制位 2026-10-13 顺带重立,现役零配置空转)**、Fork 一节点双态与免费切换、彩蛋觉醒——结构事实源 = `data/tables/meta_tree.tres`(**已实装在役,迭代 21 T1**) |
|
||||
| 节点结构与解锁规则 | 12 节点的一脊三脉构成、脊柱行门槛(节点第 N 级)、点亮前置(requires)+ **等级阈值前置(requires_level——R1 机制位 2026-10-13 顺带重立,现役零配置空转)**、Fork 一节点双态与免费切换、彩蛋觉醒——结构事实源 = `data/tables/meta_tree.tres` + schema MetaTreeTable(**已实装在役,迭代 21 T1**) |
|
||||
| 树的购买与货币规则 | 全树钥石单币;free 节点零币;购买校验四件套(等级上限 / 行门槛 / 前置 / 未解锁) |
|
||||
| 营地统一模型 | 树=营地本体(呈现=四柜台并排):生命/命中淬炼唯一入口=树脊柱淬炼节点,攻/AC 唯一入口=锻造工坊路线(所有权切分,2026-10-11 裁);工作间钥匙模型(锻造工坊 / 秘宝匣);图鉴常开;旧属性锻造柜台退役(生命归脊柱、攻防归锻造工坊) |
|
||||
| 树域存档的内容语义 | tree_nodes(node_id→已购等级)与 fork_sides(fork_group→激活态)两域语义;旧档废弃规则(开发阶段无迁移——2026-10-11 用户裁) |
|
||||
@@ -58,20 +58,20 @@
|
||||
|
||||
### 一脊三脉:节点构成
|
||||
|
||||
天赋树(玩家可见名)换代后 12 节点,按脉(vein)分四族:
|
||||
天赋树(玩家可见名;代码面 `meta_tree`)换代后 12 节点,按脉(vein)分四族:
|
||||
|
||||
| 脉 | 节点数 | 内容 | 结构要点 |
|
||||
|---|---|---|---|
|
||||
| 主干脊柱(spine) | 2 | 生命淬炼 / 命中淬炼——一线一节点(kind=stat),每节点内 4 个等级状态 | 行门槛:节点第 N 级可购需全树已购总等级 ≥ 4×(N−1)。2026-10-11 一线一节点换代(用户裁:一个内容一个节点、等级在节点内、不拆多节点)——原「一线 4 层×层内 3 购」收编为单节点 4 级(层=级),行门槛常量=4 的公式平移到等级轴,row 字段随层行退役;达成节奏重算=注记在册、值归数值批 |
|
||||
| 主干脊柱(spine) | 2 | 生命淬炼 / 命中淬炼——一线一节点(kind=stat),每节点内 4 个等级状态 | 行门槛:节点第 N 级可购需全树已购总等级 ≥ 4×(N−1)。2026-10-11 一线一节点换代(用户裁:一个内容一个节点、等级在节点内、不拆多节点)——原「一线 4 层×层内 3 购」收编为单节点 4 级(层=级),SPINE_ROW_GATE=4 公式平移到等级轴,row 字段随层行退役;达成节奏重算=注记在册、值归数值批 |
|
||||
| 锻造脉(forge) | 2 | 锻造工坊(kind=unlock,free,工作间钥匙)+ 彩蛋节点地脉共鸣(kind=easter) | 锻造工坊前置 = **无**(free,直接可点亮——2026-10-11 攻防所有权切分裁,原「攻击淬炼累计 ≥2 且 护甲淬炼累计 ≥2」等级阈值前置随两线砍除作废);彩蛋挂本脉 |
|
||||
| 钥石脉(keystone) | 2 | 秘宝匣(kind=unlock,free,工作间钥匙)/ 刷新升级(kind=rule) | 前置链:秘宝匣 ← 脊柱生命第 1 级;刷新升级 ← 秘宝匣 |
|
||||
| 同调脉(attune) | 6 | 同调位 1/2/3 三节点(kind=socket)+ Fork 3 节点(kind=fork,一节点双态)= **3 同调位 + 3 双态开关节点** | **同调位 1 为根节点、无前置**,其后逐级前置(1→2→3);全部 Fork 前置 = 同调位 1;Fork=开局姿态/危险直觉/财富之道各一节点(2026-10-11 用户裁:一节点双态、解锁后 A/B 可切——非六节点) |
|
||||
|
||||
节点类型是封闭枚举六类:stat(生命/命中两线数值)/ rule(全局规则)/ unlock(内容解锁)/ socket(同调位)/ fork(一节点双态开关)/ easter(彩蛋觉醒)。字段、词表与跨字段约束由 schema 校验(加载期校验:脉 / 类型 / 币出域即拒、effects 键封闭、Fork 三组每组恰一节点、彩蛋 ≤3、禁 archetype 键)。**schema 连带已随迭代 21 T1 落地**:Fork 由 A/B 双行改单行双态(行持 a/b 双效果键 effects_a/b+name_a/b,效果按激活态取值;Fork 组词表 4→3 组)、规则键词表 2→6 键(见 Fork 节)、row 字段随一线一节点退役;「等级阈值前置」机制位 **2026-10-13 顺带重立**(requires_level 字段+加载校验,现役零配置——见头部状态行)。
|
||||
节点类型是封闭枚举六类:stat(生命/命中两线数值)/ rule(全局规则)/ unlock(内容解锁)/ socket(同调位)/ fork(一节点双态开关)/ easter(彩蛋觉醒)。字段、词表与跨字段约束由 schema 校验(MetaTreeTable.validate:脉 / 类型 / 币出域即拒、effects 键封闭、Fork 三组每组恰一节点、彩蛋 ≤3、禁 archetype 键——加载期校验)。**schema 连带已随迭代 21 T1 落地**:Fork 由 A/B 双行改单行双态(行持 a/b 双效果键 effects_a/b+name_a/b,效果按激活态取值;Fork 组词表 4→3 组)、规则键词表 2→6 键(见 Fork 节)、row 字段随一线一节点退役;「等级阈值前置」机制位 **2026-10-13 顺带重立**(requires_level 字段+加载校验,现役零配置——见头部状态行)。
|
||||
|
||||
### 节点总表(12 节点)
|
||||
|
||||
换代后全名单(2026-10-11 Fork 一节点双态批换代:15→12)。数值行(价格/上限/效果取值)不在此表,读配置文件 `data/tables/meta_tree.tres`(**12 行结构已实装在役——迭代 21 T1,33 行旧结构已废弃重置不迁移**):
|
||||
换代后全名单(2026-10-11 Fork 一节点双态批换代:15→12)。数值行(价格/上限/效果取值)不在此表,读配置文件 `game/data/tables/meta_tree.tres`(**12 行结构已实装在役——迭代 21 T1,33 行旧结构已废弃重置不迁移**):
|
||||
|
||||
| 节点 | 脉 | 类型 | 前置 | 效果方向 |
|
||||
|---|---|---|---|---|
|
||||
@@ -94,9 +94,9 @@
|
||||
|
||||
所有付费节点只收钥石(2026-10-07 用户裁甲落定;行内 currency 字段保留为呈现元数据)。free 节点零币:两枚工作间钥匙(锻造工坊 / 秘宝匣)与彩蛋(觉醒)不经购买消费。
|
||||
|
||||
购买校验四件套,全部通过才受理:①当前等级未满上限;②行门槛——脊柱节点第 N 级需全树已购总等级 ≥ 4×(N−1)(总等级口径 = tree_nodes 全部节点等级之和,免费点亮与分叉激活均计入——2026-10-11 歧义扫描裁甲沿现役实态;常量行门槛=4;2026-10-11 一线一节点换代后门槛主语=节点目标等级,原层行判定作废;达成节奏重算归数值批);③requires 前置满足——点亮前置(前置节点全部已点亮)+ **等级阈值前置(requires_level:指定前置节点等级 ≥ n——R1 机制位 2026-10-13 顺带重立,2026-10-12 曾按卡片默认裁撤案执行、用户推翻补机制位;现役 12 行零配置空转,配置归表行随需填)**;④Fork 节点未解锁(一节点双态——解锁后的态切换走零币切换口,不经购买)。执行购买时另查钥石余额:余额不足则购买失败,存档零副作用(等级、余额、激活态均不动)。
|
||||
购买校验四件套,全部通过才受理:①当前等级未满上限;②行门槛——脊柱节点第 N 级需全树已购总等级 ≥ 4×(N−1)(总等级口径 = tree_nodes 全部节点等级之和,免费点亮与分叉激活均计入——2026-10-11 歧义扫描裁甲沿现役实态;常量 SPINE_ROW_GATE=4;2026-10-11 一线一节点换代后门槛主语=节点目标等级,原层行判定作废;达成节奏重算归数值批);③requires 前置满足——点亮前置(前置节点全部已点亮)+ **等级阈值前置(requires_level:指定前置节点等级 ≥ n——R1 机制位 2026-10-13 顺带重立,2026-10-12 曾按卡片默认裁撤案执行、用户推翻补机制位;现役 12 行零配置空转,配置归表行随需填)**;④Fork 节点未解锁(一节点双态——解锁后的态切换走零币切换口,不经购买)。执行购买时另查钥石余额:余额不足则购买失败,存档零副作用(等级、余额、激活态均不动)。
|
||||
|
||||
写口唯一:营地界面只发购买意图信号,扣币、升级、写盘全部经元进度系统的树上购买写口;Fork 节点购买走树上分叉购买写口(购即解锁、默认 A 态),态切换走树上分叉切换写口(零币、只改激活态)。
|
||||
写口唯一:营地界面只发购买意图信号(tree_buy_requested),扣币、升级、写盘全部经 MetaProgression.tree_buy;Fork 节点购买走 tree_buy_fork(购即解锁、默认 A 态),态切换走 tree_toggle_fork(零币、只改激活态)。
|
||||
|
||||
### Fork 三组:一节点双态与免费切换
|
||||
|
||||
@@ -108,11 +108,11 @@ Fork 组是封闭词表三组(2026-10-11 裁:克制专精整组砍除,类
|
||||
|---|---|---|---|
|
||||
| fg_posture 开局姿态 | 先手压制 = 每关首轮 AP +1 | 稳健拓荒 = 每关首轮内受击减伤 | 两侧同收**每关首轮窗**(每关第一场战斗的第一轮,第二关自动刷新——时间范围一致性裁甲) |
|
||||
| fg_sense 危险直觉 | 锋 = 踩中危险格伤害减半·每关限次 | 守 = 危险格标记错误返还行动点·每关限次 | 唯一根植排雷半边的组;玩家文案沿用「危险格 / 安全格」正主词,不出现雷字、不另造别名(2026-10-11 歧义扫描裁甲,废「陷阱/危险标记」自造词)。**前提核实在册**:标记错误机制存在性随实装批 T0 实查,查无则守侧换安全网向等价效果经用户裁 |
|
||||
| fg_economy 财富之道 | 聚 = 战斗掉落 GP 增益 | 散 = GP 消费折价 | 范围(2026-10-11 歧义扫描裁):聚 = **仅战斗掉落渠道**;散 = **全部 GP 消费面**。**折扣定义边界(2026-10-12 卡片 v1.7 ⑪②裁决写入文档——原「设计避让」句按裁决改写)**:散的折价只覆盖商品购买价(消费折价系数),不含三选一付费刷新与商店刷新(`shop_refresh_cost` 不折)——这是折扣的定义边界本身,非对外两处旋钮的临时避让 |
|
||||
| fg_economy 财富之道 | 聚 = 战斗掉落 GP 增益 | 散 = GP 消费折价 | 范围(2026-10-11 歧义扫描裁):聚 = **仅战斗掉落渠道**;散 = **全部 GP 消费面**。**折扣定义边界(2026-10-12 卡片 v1.7 ⑪②裁决写入文档——原「设计避让」句按裁决改写)**:散的折价只覆盖商品购买价(键 `gp_cost_mult`),不含三选一付费刷新与商店刷新(`shop_refresh_cost` 不折)——这是折扣的定义边界本身,非对外两处旋钮的临时避让 |
|
||||
|
||||
「每关限次」的计数生命周期(2026-10-11 歧义扫描裁甲):限次计数随单次冒险持久、按关重置、新冒险清零、断点续玩保留。
|
||||
|
||||
A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表六键——**已随迭代 21 T3 扩签落地**:posture 双键收每关首轮窗、sense 锋/守双键限次按关重置、economy 聚/散双键接线),效果按激活态取值,不接数值线。两侧的设计判据是「不同强、非强弱」:MC 配对锚验收两侧关卡完成率差 <~3pp(**迭代 21 V19 已验:perfect+max 档三组配对差全部 0.0pp 在带**)。
|
||||
A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表 RULE_KEYS 六键——**已随迭代 21 T3 扩签落地**:posture 双键收每关首轮窗、sense 锋/守双键限次按关重置、economy 聚/散双键接线),效果按激活态取值,不接数值线。两侧的设计判据是「不同强、非强弱」:MC 配对锚验收两侧关卡完成率差 <~3pp(**迭代 21 V19 已验:perfect+max 档三组配对差全部 0.0pp 在带**)。
|
||||
|
||||
层级纪律(红线):局外树只放全局规则件——effects 禁 archetype 键(schema 加载致命);规则改写型特性(流派件)只走局内随机渠道,永不入树。
|
||||
|
||||
@@ -124,40 +124,40 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表
|
||||
|
||||
存档 v5 起树域两键(meta 域下):tree_nodes = node_id→已购等级(Fork 节点购买态=1 级解锁标记);fork_sides = fork_group→激活态("a" / "b")。承载与读写归[存档序列化](../表现与支撑/存档序列化.md),本文登记内容语义。
|
||||
|
||||
**旧档废弃(2026-10-11 用户裁:开发阶段无迁移)**——Alpha 未出、无存量玩家,结构换代 = 破坏性废弃:加载检测到换代前结构(已删节点 id 残留)即废弃树域重置(或整档废弃),**禁做数据迁移与折算**;三体系迁移函数与旧域 `forge_levels` 随实装批清退删除。
|
||||
**旧档废弃(2026-10-11 用户裁:开发阶段无迁移)**——Alpha 未出、无存量玩家,结构换代 = 破坏性废弃:加载检测到换代前结构(已删节点 id 残留)即废弃树域重置(或整档废弃),**禁做数据迁移与折算**;三体系迁移函数 `migrate_tree` 与旧域 `forge_levels` 随实装批清退删除。
|
||||
|
||||
### 跨局注入:树效果怎么进下一局
|
||||
|
||||
树的效果经两条通道随冒险开始参数面下传(通道现行事实源 = [元进度](元进度.md)「跨局注入」节):
|
||||
|
||||
① 属性通道——开局属性 = **角色基础值 + 树生命/命中淬炼 flat(Σ 节点 effects × 等级)+ 锻造路线加值(当前武器攻击加值 + 当前甲 AC 加值,只按当前选中生效,正主 = [锻造工坊](锻造工坊.md))+ 局内加算区 flat**(2026-10-11 攻防所有权切分叠加公式换代:树脊柱只持生命/命中,攻/AC 唯一来源=锻造路线——每根数值轴全游戏单一来源;旧「柜台三档 flat」项随柜台退役移除,树淬炼成账号全局基础层、锻造路线成专精层,两层相加)。写入覆盖值通道(攻击 / 生命上限 / 护甲等级),开局显式传入战斗初始化。命中线已购等级已记但未入注入面——消费面(命中折扣档)归数值批(代码批注在册披露)。
|
||||
① 属性通道——开局属性 = **角色基础值 + 树生命/命中淬炼 flat(Σ 节点 effects × 等级)+ 锻造路线加值(当前武器攻击加值 + 当前甲 AC 加值,只按当前选中生效,正主 = [锻造工坊](锻造工坊.md))+ 局内加算区 flat**(2026-10-11 攻防所有权切分叠加公式换代:树脊柱只持生命/命中,攻/AC 唯一来源=锻造路线——每根数值轴全游戏单一来源;旧「柜台三档 flat」项随柜台退役移除,树淬炼成账号全局基础层、锻造路线成专精层,两层相加)。写入覆盖值通道(atk / max_hp / armor_class),开局显式传入战斗初始化。命中线已购等级已记但未入注入面——消费面(命中折扣档)归数值批(代码批注在册披露)。
|
||||
|
||||
② 规则通道——各 Fork 组激活态的效果键集经冒险开始参数面下传;每场战斗开始时由效果引擎重建合成订阅行生效。开新冒险与继续上局两入口同参同值。
|
||||
② 规则通道——tree_rule_keys = 各 Fork 组激活态的效果键集,经冒险开始参数面 tree_rules 下传;每场战斗 begin_battle 时由效果引擎 rebuild 合成订阅行生效。开新冒险与继续上局两入口同参同值。
|
||||
|
||||
### 已建未接面(接线落地态——2026-10-13 迭代 21 反哺写入换代)
|
||||
|
||||
三条原「已建表/已可购但消费面未接」的实态,**两条已随迭代 21 接线在役、一条维持纪律**:
|
||||
|
||||
- 同调位数量判定源——**已接(迭代 21 T4)**:同调位判定源已切树点亮数(同调位 1/2/3 三节点),旧条件表(按 Boss 击杀次数自动涨)已随迭代 21 T5 删除(attunement_growth.tres 谓词表退役)。
|
||||
- 刷新升级节点——**已接(迭代 21 T4)**:树上购买(刷新升级节点)同路由营地刷新升级写口,价格/cap 单一事实源 = Y 行表值;双入口并存(树上节点与秘宝匣装配段升级钮写同一笔,Q1 裁)。
|
||||
- 命中线 flat 不入注入面——**维持(契约 6 纪律)**:注入参数面无命中字段,命中未注入;消费面开启归数值批(M4)。
|
||||
- 同调位数量判定源——**已接(迭代 21 T4)**:`Attunement.slots` 判定源已切树点亮数(att_socket1..3),旧条件表(按 Boss 击杀次数自动涨)已随迭代 21 T5 删除(attunement_growth.tres 谓词表退役)。
|
||||
- 刷新升级节点——**已接(迭代 21 T4)**:树上购买(ks_refresh)同路由 `buy_attune_refresh`,价格/cap 单一事实源 = Y 行表值;双入口并存(树上节点与秘宝匣装配段升级钮写同一笔,Q1 裁)。
|
||||
- 命中线 flat 不入注入面——**维持(契约 6 纪律)**:override 无 hit 字段,命中未注入;消费面开启归数值批(M4)。
|
||||
|
||||
## 依赖与输出
|
||||
|
||||
| 方向 | 系统 / 文档 | 接口要点 |
|
||||
|---|---|---|
|
||||
| 上游 | [元进度](元进度.md) | 钥石——树是永久强化的承载结构与营地本体;消费经钥石余额(写口存档系统),注入通道现行事实源在对方;旧柜台退役面在对方登记 |
|
||||
| 上游 | [元进度](元进度.md) | 钥石——树是永久强化的承载结构与营地本体;消费经钥石余额(写口 SaveManager),注入通道现行事实源在对方;旧柜台退役面在对方登记 |
|
||||
| 上游 | [数据配置](../表现与支撑/数据配置.md) | meta_tree.tres 承载与 schema 校验机制——本系统为结构 owner、数值回填归数值批 |
|
||||
| 上游 | [存档序列化](../表现与支撑/存档序列化.md) | tree_nodes / fork_sides 持久化与旧档废弃承载 |
|
||||
| 上游 | [秘宝](秘宝.md) | 同调位槽位判定源 = 树点亮数(**已切换在役,迭代 21 T4**;旧条件表已删);秘宝匣工作间内目录与装配现行事实源在彼 |
|
||||
| 上游 | [锻造工坊](锻造工坊.md) | 武器/护甲路线升级现行事实源在彼——树持钥匙节点(无前置),工作间柜台=钥匙展开面板;攻/AC 数值唯一来源在彼(所有权切分红线) |
|
||||
| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 冒险开始参数面——树生命/命中淬炼 flat(叠加进覆盖值通道)与规则键集的注入通道 |
|
||||
| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 营地四柜台并排呈现——树淬炼柜台=树脊柱界面形态(案甲);信号 = 树上购买意图 / 树上分叉切换意图 |
|
||||
| 下游 | 战斗侧效果引擎 | 规则键消费面——每场战斗开始时重建合成订阅(机制硬编码,无表行) |
|
||||
| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 冒险开始参数面——树生命/命中淬炼 flat(叠加进覆盖值通道)与 tree_rules 键集的注入通道 |
|
||||
| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 营地四柜台并排呈现——树淬炼柜台=树脊柱界面形态(案甲);信号 = tree_buy_requested / tree_fork_toggled |
|
||||
| 下游 | 战斗侧效果引擎 | 规则键消费面——begin_battle rebuild 合成订阅(机制硬编码,无表行) |
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
**P0 语义已随迭代 21 全量落地(2026-10-12 入库;2026-10-13 反哺写入换代——原「33 节点现役态维持」过渡态终结)**:12 节点结构(脊柱 = 生命/命中一线一节点、Fork = 三节点双态)+ 营地统一(树 = 营地本体、生命/命中唯一入口、攻防归锻造工坊、工作间钥匙、四柜台呈现)+ 三组 Fork 双态真效果 + 购买/切换/门槛/彩蛋/注入/旧档废弃全链,逐条判据见「验收标准」节;残留人闸 = 实机目检营地四柜台(体验验证清单 ⑳)。旧 33 节点结构随树结构版本换代废弃重置(禁迁移,Q3 裁)。
|
||||
**P0 语义已随迭代 21 全量落地(2026-10-12 入库;2026-10-13 反哺写入换代——原「33 节点现役态维持」过渡态终结)**:12 节点结构(脊柱 = 生命/命中一线一节点、Fork = 三节点双态)+ 营地统一(树 = 营地本体、生命/命中唯一入口、攻防归锻造工坊、工作间钥匙、四柜台呈现)+ 三组 Fork 双态真效果 + 购买/切换/门槛/彩蛋/注入/旧档废弃全链,机检 = 冒烟 886/0 + run_all 22 套 + probe 全绿 + MC 三组配对差 0.0pp(迭代 21 出口闸读数);残留人闸 = 实机目检营地四柜台(体验验证清单 ⑳)。旧 33 节点结构随 `TREE_STRUCT_VERSION=2` 废弃重置(禁迁移,Q3 裁)。
|
||||
|
||||
## P1 / P2 后置
|
||||
|
||||
@@ -174,21 +174,23 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表
|
||||
|
||||
| 表 / 常量 | 键结构归属 | 数值行 |
|
||||
|---|---|---|
|
||||
| 节点表 `data/tables/meta_tree.tres`(换代后 12 行:价格 / 等级上限 / requires(点亮前置)/ **requires_level(等级阈值前置——R1 机制位,现役零配置)** / effects 取值(Fork 行持 a/b 双效果键)/ 限次值;row 字段随一线一节点退役) | schema 声明,本文 owner | 全 provisional,归数值批投值 |
|
||||
| 脊柱行门槛 = 4 | 节点表结构声明持有,本文 owner | 规则即门槛(节点第 N 级需全树总等级 ≥ 4×(N−1)) |
|
||||
| Fork 组词表(三组)/ 规则键词表(换代后六键,扩表随实装批) | 三组 Fork 词表与六键规则词表由节点表结构声明持有(封闭词表) | 词表即规则;规则键效果值由效果引擎合成 |
|
||||
| 节点表 `data/tables/meta_tree.tres`(换代后 12 行:价格 / 等级上限 / requires(点亮前置)/ **requires_level(等级阈值前置——R1 机制位,现役零配置)** / effects 取值(Fork 行持 a/b 双效果键)/ 限次值;row 字段随一线一节点退役) | schema MetaTreeTable,本文 owner | 全 provisional,归数值批投值 |
|
||||
| 脊柱行门槛常量 SPINE_ROW_GATE = 4 | `meta_tree_table.gd` 常量,本文 owner | 常量即规则(节点第 N 级需全树总等级 ≥ 4×(N−1)) |
|
||||
| Fork 组词表 FORK_GROUPS(三组)/ 规则键词表 RULE_KEYS(换代后六键,扩表随实装批) | `meta_tree_table.gd` 封闭词表 | 词表即规则;规则键效果值硬编码于效果引擎 rebuild |
|
||||
| 钥石产出、刷新升级行族 | 现行事实源 = [元进度](元进度.md)调参表 | `data/tables/meta.tres` |
|
||||
|
||||
## 验收标准
|
||||
|
||||
> **落地实态(2026-10-13 反哺写入注)**:下列各条已随迭代 21 实装并过出口闸——机检 = 冒烟 886/0(V1-V10/V16 断言顺带)+ run_all 22 套(tree_rules_v11_test 六键闭集)+ probe --click/--full 八探针 + render_gate + MC 三组同种子配对差 0.0pp(V19);残留人闸 = 实机目检营地四柜台(体验验证清单 ⑳)。命中线「暂不注入」括注 = 契约 6 纪律维持(非缺陷——消费面开启归数值批)。
|
||||
|
||||
- 结构封闭:meta_tree.tres 通过 schema 校验零违例——12 节点、脉 / 类型 / 币词表出域即拒、Fork 三组每组恰一节点且持 a/b 双效果键、彩蛋 ≤3、effects 键封闭、零 archetype 键。
|
||||
- 行门槛可判:全树已购总等级 < 4×(N−1) 时脊柱节点第 N 级不可购;总等级达标当刻该级开放购买。
|
||||
- 前置可判(点亮前置):requires 任一未点亮则节点不可购,逐一点亮后可购;锻造工坊钥匙无前置——初始即可点亮(free 零币)。**等级阈值前置:配置了该键的节点,指定前置节点等级 < n 时不可购、达标当刻开放(现役零配置,判定面已单独验证)。**
|
||||
- 前置可判(点亮前置):requires 任一未点亮则节点不可购,逐一点亮后可购;锻造工坊钥匙无前置——初始即可点亮(free 零币)。**等级阈值前置(requires_level):配置了该键的节点,指定前置节点等级 < n 时不可购、达标当刻开放(单测八断言承载——schema 四拒一过+判定三态+投影两态;现役零配置,判定面经测试夹具直构行验证)。**
|
||||
- 工作间可判:钥匙节点(锻造工坊 / 秘宝匣)未点亮时对应柜台锁定态、工作间不可进入;点亮后展开;图鉴无门槛常开。
|
||||
- 单币可判:任一付费节点购买只扣钥石;余额不足购买失败,且存档零变化(等级、余额、激活态均不动)。
|
||||
- 双态可判:Fork 节点购买解锁后默认 A 态;切换零币,切换后规则键集=新激活态效果键;同态重复切换零操作;未解锁 Fork 不可切换、不可重复购买。
|
||||
- 彩蛋可判:生命/命中两节点均买满(4 级拉满)且同调位 1/2/3 全部解锁时彩蛋节点自动点亮且零消费;任一条件不满足则不亮。
|
||||
- 注入可判:开局覆盖值 = 角色基础值 + 树生命/命中淬炼 flat(命中暂不注入——消费面开启归数值批,契约 6 纪律维持、非缺陷)+ 锻造路线加值 + 局内加算区(各层语义清晰可加);规则键集 = 全部 Fork 组激活态效果键集;开新冒险与继续上局两入口参数同值;全新存档(树全零)开局与零树状态完全一致。
|
||||
- 注入可判:开局覆盖值 = 角色基础值 + 树生命/命中淬炼 flat(命中未注入)+ 锻造路线加值 + 局内加算区(各层语义清晰可加);tree_rules = 全部 Fork 组激活态效果键集;开新冒险与继续上局两入口参数同值;全新存档(树全零)开局与零树状态完全一致。
|
||||
- 旧档废弃可判:加载换代前结构存档 → 树域废弃重置 → 后续游玩正常且无残留脏节点(开发阶段纪律,禁迁移);全新存档(树全零)开局与零树状态完全一致。
|
||||
|
||||
## 待办
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# 生涯
|
||||
|
||||
> **一句话定位**:营地里与三柜台平级的**局外只读界面**——营地管「花」(花钥石买永久强化),生涯管「看」(看自己跨局攒下的一切:累计战绩、历史冒险、图鉴收集)。冒险进行中不给任何数据回看(2026-10-04 用户裁决 P-C7 的延续),生涯是历史数据唯一的家。
|
||||
> **状态**:期一已实装(2026-10-07 迭代 18 卡④生涯界面实装批·期一——跨局汇总页+主菜单入口+终身计数域存档 v6 落地;期二/期三另行立项,本文不预占排期)。入口拓扑已随迭代 33 卡② 三入口化换代、营地里经笔记本接入归迭代 34 卡④(信息架构节 v1.1,2026-10-22 反哺写入)。现行为 v1.3。
|
||||
> **状态**:期一已实装(2026-10-07 迭代 18 卡④生涯界面实装批·期一——跨局汇总页+主菜单入口+终身计数域存档 v6 落地;期二/期三另行立项,本文不预占排期)。入口拓扑已随迭代 33 卡② 三入口化换代、营地里经笔记本接入归迭代 34 卡④(信息架构节 v1.1,2026-10-22 反哺写入)。现行为 v1.2(2026-10-28 迭代 39 反哺——历史回看节行号指路句改语义指认)。
|
||||
> **来源**:[待办清单「『生涯』界面——冒险中数据回看的唯一承接处」条](../../../../待办清单.md)(2026-10-04 用户裁决 P-C7——冒险中不给数据回看,历史战报与结算明细的查看去向 = 新「生涯」界面)。
|
||||
|
||||
## 一、信息架构
|
||||
|
||||
生涯入口经营地接入(目标结构=营地笔记本,迭代 34 卡④承载;迭代 33 卡② 三入口化后主菜单无生涯钮,现期无玩家可见入口,内部路径直调可达)。现行主菜单只有三个一级钮(迭代 33 卡②,用户裁决 1):「进入存档」「设置」「退出游戏」——「进入存档」为唯一进度入口,点击打开选档界面(3 存档位,迭代 33 卡③)。
|
||||
生涯入口经营地接入(目标结构=营地笔记本,迭代 34 卡④承载;迭代 33 卡② 三入口化后主菜单无生涯钮,现期无玩家可见入口,内部路径直调可达)。现行主菜单按钮组由 `build_start_overlay` 构造(`game/presentation/ui_assembler.gd:97`),只有三个一级钮(迭代 33 卡②,用户裁决 1):「进入存档」「设置」「退出游戏」——「进入存档」为唯一进度入口,点击打开选档界面(3 存档位,迭代 33 卡③)。
|
||||
|
||||
```
|
||||
主菜单(开始覆盖层,三入口)
|
||||
@@ -15,8 +15,8 @@
|
||||
├─ 设置
|
||||
└─ 退出游戏
|
||||
|
||||
调试浮窗(发布态恒隐:调试入口的写死行已随迭代 38 卡⑦ 删除,开始层与战斗屏/关卡地图屏均零调试入口与角标;
|
||||
开发期临时启用=本地改调试入口缺省、不提交)
|
||||
调试浮窗(发布态恒隐:`_debug_entry` 写死行已随迭代 38 卡⑦ 删除,开始层与战斗屏/关卡地图屏均零调试入口与角标;
|
||||
开发期临时启用=本地改 `_debug_entry` 缺省、不提交)
|
||||
|
||||
营地(存档内,进档/新档落点)
|
||||
└─ 生涯(局外只读面;入口=营地笔记本,迭代 34 卡④承载)
|
||||
@@ -40,24 +40,24 @@
|
||||
| 内容 | 数据源 | 现状 |
|
||||
|---|---|---|
|
||||
| 冒险总局数 / 通关局数 | `adventure_total` / `adventure_cleared` 两终身计数域(save v6——期一已落地) | 现成(2026-10-07 迭代 18 卡④期一实装) |
|
||||
| 各关完成次数 | 存档域 `level_clear_counts`(按关卡序号计) | 现成 |
|
||||
| Boss 首杀与总击杀 | Boss 首杀标记(存档域 `boss_first_kill`)/ Boss 击杀总数(存档域 `boss_kill_count`) | 现成 |
|
||||
| 钥石余额 | 存档域 `keystone_balance`;累计收支流水不入存档 | 现成。加钥石与花钥石只动余额——如要做属新增流水域,期一实装批另呈报,本文只登记 |
|
||||
| ~~三柜台解锁完成度概览~~ | (整行删——2026-10-12 用户裁:生涯页不统计天赋树与账号成长态,只统计终身计数;数据源属性锻造等级/工坊状态/树节点三投影随天赋树实装批退役,体验验证清单⑲两观测项同步摘除) | — |
|
||||
| 各关完成次数 | `clear_count(level_index)`(`save_manager.gd:238`) | 现成 |
|
||||
| Boss 首杀与总击杀 | `boss_first_kill_marked`(`save_manager.gd:242`)/ `boss_kill_count`(`:250`) | 现成 |
|
||||
| 钥石余额 | `keystone_balance`(`save_manager.gd:202`) | 现成。累计收支流水不在存(加钥石与花钥石只动余额,`:206`/`:211`)——如要做属新增流水域,期一实装批另呈报,本文只登记 |
|
||||
| ~~三柜台解锁完成度概览~~ | (整行删——2026-10-12 用户裁:生涯页不统计天赋树与账号成长态,只统计终身计数;数据源 forge_level/workshop_status/tree_nodes 三投影随天赋树实装批退役,体验验证清单⑲两观测项同步摘除) | — |
|
||||
|
||||
### 历史冒险回看(期二)
|
||||
|
||||
数据面现役事实:每局冒险收束时已有逐局摘要自动入档——存于存档域 `recent_summaries`:新局插最前、按上限截断,上限 10 条。摘要字段在冒险收束时组装(冒险收束受理:结局 result、完成关数 levels_cleared、止步关 stopped_at、钥石合计 keystone_total、本局主种子 master_seed,另附逐杀掉落 keystone_drops 与终局专长持有集 relics(存档键名沿用历史形态)等;钥石与逐杀明细、真视计数、特性持有集取数经主角账两件〔属性账 / 获得日记〕只读投影——2026-10-27 迭代 39 拆件后形态);摘要的内容口径 owner = [冒险结构](../冒险循环/冒险结构.md),本文不复述其口径。
|
||||
数据面现役事实:每局冒险收束时已有逐局摘要自动入档——`recent_summaries`(默认域 `save_manager.gd:116`、值拷贝访问器 `:316`、入账原语 `:325-338` 逐局插最前并按上限截断),上限 `SUMMARY_CAP := 10`(`:40`)。摘要字段在冒险收束时组装(`adventure_runner` 冒险收束受理 `_settle`:结局 result、完成关数 levels_cleared、止步关 stopped_at、钥石合计 keystone_total、本局主种子 master_seed,另附逐杀掉落 keystone_drops 与终局专长持有集 relics(存档键名沿用历史形态)等;钥石与逐杀明细、真视计数、特性持有集取数经主角账两件〔HeroStats/GainJournal〕只读投影——2026-10-27 迭代 39 拆件后形态);摘要的内容口径 owner = [冒险结构](../冒险循环/冒险结构.md),本文不复述其口径。
|
||||
|
||||
2026-10-06 用户裁(P2 甲):每局一行摘要,行内给**结局 / 到达关卡 / 钥石收入 / 用时**四件事,上限存最近 N 局。对应三件实绩(本批代码级复核确认的缺口,非新建数据面):
|
||||
|
||||
1. **扩容**:cap 10 → N。N 候选 20 / 50 / 维持 10,实装期按存档体积读数三选一;读数方法与列表形态的参数化维度由设计稿给出、实装期执行。
|
||||
2. **补「用时」埋点**:全仓现在没有任何用时采集点(摘要字段集〔冒险收束受理组装面〕无此项)——属新增埋点,随期二。
|
||||
2. **补「用时」埋点**:全仓现在没有任何用时采集点(`game/core/` 内 grep elapsed / ticks / duration / Time 零命中;摘要字段集〔`adventure_runner` 收束受理组装面〕无此项)——属新增埋点,随期二。
|
||||
3. **旧档迁移**:旧档既有 ≤10 条摘要原样保留迁移,向后兼容。
|
||||
|
||||
单局结算明细回看:遗留的单局结算明细界面本体仍在、未接入任何入口,由期二复活承接,改挂生涯(2026-10-06 用户裁 P5 甲)。
|
||||
单局结算明细回看:遗留件 `settlement_review_overlay.gd`(`game/presentation/views/`,文件本体在盘、全仓无实例化引用——仅 `ui_kit.gd:356` 样式注记提及)由期二实装批复活承接,改挂生涯(2026-10-06 用户裁 P5 甲)。
|
||||
|
||||
可选增强(不占期、不上列):关键构筑列——摘要已附终局专长持有集(存档键 relics,存档键名沿用历史形态),实装期评估是否呈现。
|
||||
可选增强(不占期、不上列):关键构筑列——摘要已附终局专长持有集 relics(`adventure_runner.gd:825`——存档键名沿用历史形态),实装期评估是否呈现。
|
||||
|
||||
### 图鉴(期三)
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
|
||||
| 界面 | 管什么(现状指证) | 与生涯的边界 |
|
||||
|---|---|---|
|
||||
| 营地([camp UX spec](../../ux/camp.md)) | 跨局成长**操作**面(花钥石买强化 / 装配 / 点树)+ 底栏「最近冒险」条带——营地底栏把摘要逐局拼行(行模板「完成/放弃/失败 · 通关 N 关 · 钥石 +N · 种子 N」)、无截断上限,数据源与生涯历史回看同属一份最近摘要 | 营地不改生涯只读定位;生涯不做任何购买入口,也不放「去买」按钮。营地条带的去留是本提纲必答项——见 §五 P6 |
|
||||
| 营地([camp UX spec](../../ux/camp.md)) | 跨局成长**操作**面(花钥石买强化 / 装配 / 点树)+ 底栏「最近冒险」条带——`camp_overlay_view.gd:431` `_rebuild_recent()` 逐局拼行(`:442`「完成/放弃/失败 · 通关 N 关 · 钥石 +N · 种子 N」,无截断上限),数据源 = `camp_shop_presenter.gd:85` 投影的同一份 `recent_summaries` | 营地不改生涯只读定位;生涯不做任何购买入口,也不放「去买」按钮。营地条带的去留是本提纲必答项——见 §五 P6 |
|
||||
| 状态面板(迭代 17 卡③,并行批开发中) | **局内**只读查看这一局进行中的钥石与本局冒险进度 | 状态面板看当局当前值,生涯看跨局累计与历史;局内无生涯入口(P4 甲) |
|
||||
| 结算屏([settlement-summary UX spec](../../ux/settlement-summary.md)) | 冒险收束当下的入账明细——冒险收束时由结算屏呈现入账明细与钥石明细(复用终局面账行的呈现形态) | 收束当下的呈现保留不动;生涯承接的是收束之后的任意时刻回看 |
|
||||
| 帮助手册(Beta 批,未实装——教学内容归 Beta 帮助手册) | 讲「怎么玩」 | 生涯讲「我玩过什么」。图鉴条目文案与手册是否共用内容源,接口登记归 Beta 批一并裁 |
|
||||
| 图例面板 | 局内符号/徽标即时解码 | 不合并——图例是局内解码面,图鉴是跨局收集面 |
|
||||
| 结算屏([settlement-summary UX spec](../../ux/settlement-summary.md)) | 冒险收束当下的入账明细——`main.gd:408` 的 `_on_adventure_finished`(实体在 `main_adventure_flow.gd:84`)收束时呈现摘要与钥石明细(复用终局面账行,`battle_end_overlay.gd:118-129`) | 收束当下的呈现保留不动;生涯承接的是收束之后的任意时刻回看 |
|
||||
| 帮助手册(Beta 批,未实装——教学内容归 Beta 帮助手册,`ui_assembler.gd:99` 注记) | 讲「怎么玩」 | 生涯讲「我玩过什么」。图鉴条目文案与手册是否共用内容源,接口登记归 Beta 批一并裁 |
|
||||
| 图例面板(legend_overlay) | 局内符号/徽标即时解码 | 不合并——图例是局内解码面,图鉴是跨局收集面 |
|
||||
|
||||
## 四、分期实装建议
|
||||
|
||||
@@ -81,11 +81,11 @@
|
||||
|
||||
| 期 | 内容 | 前置 | 建议窗口(候选) |
|
||||
|---|---|---|---|
|
||||
| 期一 | 跨局汇总页 + 主菜单生涯入口落位。总局数/通关局数两个终身计数域随该批做存档 schema 迁移——**✅ 已实装(2026-10-07 迭代 18 卡④)**:汇总段六类九项+营地与系统组生涯钮+存档 v6 两终身计数域〔v5 升 v6 幂等迁移〕;闸读数与代拍板追认单原记于该批出口报告,该件已按「吸收即死」删除,读数以本行与该批提交信息为准 | 提纲评审通过。实装批前置义务 = 对齐迭代 16 UI 批后的现行基线:字号六档 / 语义色 / 按钮最小高 40 点等现行界面基线 / 色板单源 / 页面壳的模态栈纪律——与卡③需求卡片同款红线,本文只登记、不展开 | Alpha 后最近一个 UI 窗口 |
|
||||
| 期二 | 历史冒险回看整段:N 扩容 + 用时埋点 + 旧档摘要迁移 + 逐局列表 + 单局明细(遗留明细界面复活承接)+ 营地条带处置(P6 裁案落地) | 期一。实装批开工前须向用户呈报两件:N 终值读数(20 / 50 / 维持 10 三选一)与「用时」埋点口径(计时起点、暂停是否计入——字段级细节本文不做) | 期一落地后独立批 |
|
||||
| 期一 | 跨局汇总页 + 主菜单生涯入口落位。总局数/通关局数两个终身计数域随该批做存档 schema 迁移——**✅ 已实装(2026-10-07 迭代 18 卡④)**:汇总段六类九项+营地与系统组生涯钮+存档 v6 两终身计数域〔v5 升 v6 幂等迁移〕;闸读数与代拍板追认单原记于该批出口报告,该件已按「吸收即死」在提交 8e02dcf0 删除,读数以本行与该批提交信息为准 | 提纲评审通过。实装批前置义务 = 对齐迭代 16 UI 批后的现行基线:`FS_*` 六档字号 / `TG_*` 语义色 / `BUTTON_MIN_H=40`(`ui_kit.gd:437`)/ 色板单源 / `page_shell` 模态栈纪律(`ui_kit.gd:394`)——与卡③需求卡片同款红线,本文只登记、不展开 | Alpha 后最近一个 UI 窗口 |
|
||||
| 期二 | 历史冒险回看整段:N 扩容 + 用时埋点 + 旧档摘要迁移 + 逐局列表 + 单局明细(`settlement_review_overlay.gd` 复活承接)+ 营地条带处置(P6 裁案落地) | 期一。实装批开工前须向用户呈报两件:N 终值读数(20 / 50 / 维持 10 三选一)与「用时」埋点口径(计时起点、暂停是否计入——字段级细节本文不做) | 期一落地后独立批 |
|
||||
| 期三 | 图鉴承接(敌人优先,范围与顺序随 P3 甲);「见过」记账面 schema 义务随该批执行 | 期二或独立评估 | Beta 窗口候选(与教学引导同段评估——图鉴的「认得」轴与教学相关;待办清单教学引导节各条 2026-10-04 起已整体标 Beta 阶段) |
|
||||
|
||||
本地化文案权:生涯界面本体按钮、页签、空态文案归[设置与本地化](../表现与支撑/设置与本地化.md)线(全仓无多语言实装;文案权先例 = 教学文案定稿权登记于待办清单),实装批承接。
|
||||
本地化文案权:生涯界面本体按钮、页签、空态文案归[设置与本地化](../表现与支撑/设置与本地化.md)线(全仓无多语言实装——`game/` 内 grep TranslationServer 零命中;文案权先例 = 教学文案定稿权登记于待办清单),实装批承接。
|
||||
|
||||
## 五、待裁点
|
||||
|
||||
@@ -93,7 +93,7 @@ P0-P5 六点已于 2026-10-06 用户全裁(案甲 × 6,备选案与淘汰依
|
||||
|
||||
### P6 · 营地底栏「最近冒险」条带去留(期二必答项)
|
||||
|
||||
**现状与问题**:营地底栏「最近冒险」条带把摘要逐行全部拼进同一个标签(行模板「完成/放弃/失败 · 通关 N 关 · 钥石 +N · 种子 N」,无截断上限),数据源与生涯历史回看同属一份最近摘要。生涯期二把上限扩到 N 后,条带按现行逻辑会把 N 行全拼进底栏——这是本批复核发现的实际耦合点,期二落地时必须给条带一个去处。
|
||||
**现状与问题**:营地底栏「最近冒险」条带把传入的摘要逐行全部拼进一个 Label(`camp_overlay_view.gd:431-443`,`:442` 行模板,无截断上限),数据源与生涯历史回看是同一份 `recent_summaries`(`camp_shop_presenter.gd:85`)。生涯期二把上限扩到 N 后,条带按现行逻辑会把 N 行全拼进底栏——这是本批复核发现的实际耦合点,期二落地时必须给条带一个去处。
|
||||
|
||||
| 案 | 内容 | 淘汰/保留依据 |
|
||||
|---|---|---|
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# 秘宝
|
||||
|
||||
> 一句话:营地装配、整局冒险生效的角色机能件——操作包络加强(视野/行动点/刷新/挖掘距离等),不出角色战斗属性值、不改战斗结算机制(经济与操作参数——视野/距离/行动点/刷新/转存率——属操作包络;分界规则归[核心循环](../../01-核心循环.md)「道具三层职责与分界」节)
|
||||
> 状态:已定稿(现行形态=局外同调件——2026-10-03 迭代 11 第①批同调实施批已入库);现行为 v1.1
|
||||
> 状态:已定稿(现行形态=局外同调件——2026-10-03 迭代 11 第①批同调实施批已入库)
|
||||
> 定位与形态:见下节
|
||||
> 术语:本文件的项目术语(同调位/RAP/GP/真视/危险格/整图等)定义见[术语表](../../术语表.md)
|
||||
|
||||
## 定位与形态
|
||||
|
||||
**现行形态 = 局外同调件**:开局前在营地装配(营地·秘宝匣柜台「同调装配」段)、占同调位(0 起步、固定 3 格,每件固定占 1 格)、被动件整局生效/主动件每冒险充能(冒险开始重置)。实现面 = `treasure_items.tres` + 同调系统件(同调位数量判定源=天赋树同调位节点点亮数——2026-10-11 Q2 裁甲、迭代 21 T4 槽位收编落地;原 `attunement_growth.tres` 谓词表已顺带退役;解锁条件=数据行内解锁条件字段承载——迭代 22 实装落地,2026-10-12)。**新目录 12 件已随迭代 22 实装批全量落地(2026-10-12,T1-T7)**,逐件实录见「目录(重设计 v1)」各表实态列。
|
||||
**现行形态 = 局外同调件**:开局前在营地装配(营地·秘宝匣柜台「同调装配」段)、占同调位(0 起步、固定 3 格,每件固定占 1 格)、被动件整局生效/主动件每冒险充能(冒险开始重置)。实现面 = `treasure_items.tres` + `game/core/attunement.gd`(同调位数量判定源=天赋树同调位节点点亮数——2026-10-11 Q2 裁甲、迭代 21 T4 槽位收编落地;原 `attunement_growth.tres` 谓词表已顺带退役;解锁条件=数据行内 `unlock_requires` 字段承载——迭代 22 实装落地,2026-10-12)。**新目录 12 件已随迭代 22 实装批全量落地(2026-10-12,T1-T7)**,逐件实录见「目录(重设计 v1)」各表实态列。
|
||||
|
||||
**沿革一句话**:本系统前身为切片期掉落消耗品形态(2026-09-29 迭代 7),2026-10-03 随同调实施批整体替换为现行形态;旧目录九件已全数退役入素材库(2026-10-08/10 用户裁)。历史细节见 git 提交史。
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
- **同调位分档**(2026-10-07 用户裁):同调位分三档=普通格/优秀格/稀有格;装配规则=**槽位可装 ≤ 槽位档位的件**(向下兼容,不惩罚早解锁);格品质随天赋树同调位节点递增(1=普通格/2=优秀格/3=稀有格,2026-10-10 用户裁;树侧接线=迭代 21 T4 槽位收编落地)。装配面呈现槽位档位(迭代 22 秘宝匣柜台落地)。
|
||||
- **旧目录退役指针**:旧目录九件、魔法提灯、机制向三件处置已全数退役入素材库(表一 14 件)——现行目录见下方「目录(重设计 v1)」节;代码旧行已全数删除(迭代 20 先行删 2 行+迭代 22 T1 删 12 行,2026-10-12)。
|
||||
- **三选一刷新双源**:刷新能力=**存量+临时**两笔系统资源——存量=持久(开局注入基值 0;来源=秘宝匣刷新升级行购买〔meta.tres attune_refresh_upgrade 行族〕+刷新练习件加仓;跨呈现持续、用完即无)、临时量=每次三选一呈现重置为基线 0(来源=效果件的临时注入,未用不结转);**消耗顺序=先扣临时、不足再扣存量**(2026-10-10 用户复述定案;代码字段名 X/Y 与两笔的字母对表归实装批 T0,正文不依赖字母)。重抽复用现有洗牌逻辑,池规则全保留;自动游玩模式默认不刷。**GP 付费档(2026-10-06 用户令)**:免费双源用尽后可 GP 付费刷新,价=ceil(20×1.8^本次停点已付费刷) provisional(与商店货架刷新读同两个调参参数 shop_refresh_*,单点调参);付费刷计数每停点清零;钱包=冒险 GP 同一笔系统资源(唯一入口=冒险 GP 扣账口);余额不足=钮禁用(不隐藏)。店内专长凭证三选一暂不挂刷新面(扩面须先裁凭证保底计数交互)。**两笔语义**两笔语义的框架定义见[核心循环](../../01-核心循环.md)「生命周期轴」节。「三选一呈现」是比节点更细的事件——奖励节点、Boss 通关奖励、商店(凭证)三处都触发。奇物「刷新次数+1」类资源件的语义=存量一次性加仓。
|
||||
- **三选一刷新双源**:刷新能力=**存量+临时**两笔系统资源——存量=持久(开局注入基值 0;来源=秘宝匣刷新升级行购买〔meta.tres attune_refresh_upgrade 行族〕+刷新练习件加仓;跨呈现持续、用完即无)、临时量=每次三选一呈现重置为基线 0(来源=效果件的临时注入,未用不结转);**消耗顺序=先扣临时、不足再扣存量**(2026-10-10 用户复述定案;代码字段名 X/Y 与两笔的字母对表归实装批 T0,正文不依赖字母)。重抽复用现有洗牌逻辑(reward_pick),池规则全保留;自动游玩模式默认不刷。**GP 付费档(2026-10-06 用户令)**:免费双源用尽后可 GP 付费刷新,价=ceil(20×1.8^本次停点已付费刷) provisional(与商店货架刷新读同两个调参参数 shop_refresh_*,单点调参);付费刷计数每停点清零;钱包=冒险 GP 同一笔系统资源(唯一入口 LevelRunner.spend_gp);余额不足=钮禁用(不隐藏)。店内专长凭证三选一暂不挂刷新面(扩面须先裁凭证保底计数交互)。**两笔语义**两笔语义的框架定义见[核心循环](../../01-核心循环.md)「生命周期轴」节。「三选一呈现」是比节点更细的事件——奖励节点、Boss 通关奖励、商店(凭证)三处都触发。奇物「刷新次数+1」类资源件的语义=存量一次性加仓。
|
||||
- **🔴 承重契约**(红线;其中真视范围等由数据加载校验强制):效果不允许写成直接加减属性的裸数值——效果类型只能取封闭白名单;真视(直接标出危险格的效果,定义见「核心规则」)单次范围 ≤3×3;核心逻辑不做异步等待;零随机;排雷玩法零特判;危险格与安全格的分布同池冻结——资源类件只能调整权重投影、不能改池结构;**棋盘事实不可变**(秘宝效果不移除、不增改危险格位置与邻接数字——效果形态只允许信息呈现与开格动作;2026-10-10 用户裁,原爆破工兵包「中立移除」即违规形态、随件退役废止)。
|
||||
- **验收分层**:难度验收分两层——同调系统关闭时沿用现行关卡完成率验收带;开启时验收带按投值平移(归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)投值;商店开关分层同法)。
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
|
||||
## 调参表
|
||||
|
||||
道具定义表的全部数值均为 provisional,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)调参;`aux_items` 条目已随迭代 22 换代为新目录 12 件登记(2026-10-12);表 schema 归[数据配置](../表现与支撑/数据配置.md)承载、本系统回填。
|
||||
道具定义表的全部数值均为 provisional,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)调参;registry `aux_items` 条目已随迭代 22 换代为新目录 12 件登记(2026-10-12);表 schema 归[数据配置](../表现与支撑/数据配置.md)承载、本系统回填。
|
||||
|
||||
结构冻结(非调参项,改动走本文修订流程):真视窄域护栏、零信息目标不消耗、边缘窗口照常受理、使用零行动点成本、同调位装配与充能每冒险重置、用后不可逆、零随机。
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# 锻造工坊
|
||||
|
||||
> 一句话:营地的武器与护甲成长——武器锻造区三条路线、护甲锻造区三条路线各练各的,钥石消费,一次冒险各选一件,满级特效留位本期不做
|
||||
> 状态:**v0.10(2026-10-29 实现内容清理:删「现役代码事实」「实装边界」两节与正文代码指证,规则与数值零变化)**——全部数值 provisional,终值归 Alpha 收官 M4 数值批〔未排期〕
|
||||
> 状态:**v0.9(2026-10-26 迭代 37 结项:实现载体行号引用改指现址,规则与数值零变化);承 v0.8 迭代 21 反哺④残余写入文档(2026-10-13)**——「树侧钥匙」句换代:钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归待办清单」悬置指针终结。承 v0.7 迭代 23 反哺写入(2026-10-13)——正文补 Q1 等级语义衔接(0 = 未练合法态)、效果类型闭集 24→31 订正、实装边界 1 回填实装实态(已随迭代 23 入库)。承 v0.6 完备性检查批(承 v0.5 B 组定案——**17 裁点全数清零**:1 丙 / 1a 一次冒险一件武器+一件甲 / 1b 营地可换·战斗禁换 / 1c 免费 / 2a 伪裁点消解 / 2b 随 3a 消解 / 3a 魔法护甲统一命名 / 3b 敌方攻击缺省普通·克制反向当下生效 / 3c 每型独立路线 / 4a 前缓后陡 / 4b 锻造内自闭环 / 4b-1 并联双通道 / 5b 纯钥石 / 5c 零材料 / 6 满级特效本期不做留扩展位 / 8a 工作间两区定名;2c、5a 已于 v0.4 结案)。**v0.6 变更(2026-10-12 完备性检查批·grilling 用户逐条裁)**:现役事实基线换代(forge_products 行族已随迭代 21 T5 退役、定价参数改历史考古口径);**两根类型轴所有权移交**(默认值归锻造工坊配置常驻持有、hero.tres 静态表两轴删除、选中态写存档+参数面注入);「与秘宝混合制同构」与「激活穿刺系专长」两处无依据表述订正删除。**满级特效本期不做**(只留扩展位);全部数值 provisional,终值归 Alpha 收官 M4 数值批〔未排期〕;实装已随迭代 23 入库(2026-10-12)
|
||||
> 成文底稿:提案过程稿《提案-武器锻造系统-2026-10-07》(**已退役**——中间产物吸收即死,2026-10-22 删除;全部备选案与淘汰依据、用户原案逐条对照已逐条落进本文,结论不依赖过程稿;**满级特效候选池已于 2026-10-21 迁入本文「满级特效扩展位」节**;考古=git 历史——删除批 603eba31,删除前全稿见历史版本 f958a03f)
|
||||
|
||||
## 设计目的
|
||||
|
||||
用户原案(playnote 2026-10-06):把现役"营地花钱买攻击 +1"改造成有等级、有成长、有满级特效的**武器升级路线**;新增长枪(穿刺)与法杖(魔法)实现武器间差异化;护甲同理——初始只有轻甲(升级只提 AC),最高等级后解锁重甲/魔法护甲,基础 AC 各异、各带满级特效。
|
||||
@@ -27,7 +29,7 @@
|
||||
|---|---|
|
||||
| 钥石与营地柜台结构 | [元进度](元进度.md)——本系统即属性锻造柜台攻击/护甲两档的改造,消费货币与柜台框架归彼 |
|
||||
| 数值终值(每级增量/等级上限/价格/基础 AC/特效值) | Alpha 收官 M4 数值批——本文全部数值只有量纲与锚点,标 provisional |
|
||||
| 代码与数据表落地 | 实装批(已入库) |
|
||||
| 代码与数据表落地 | 实装批(待办在册待办清单)——迁移面见下文,含数值验证义务 |
|
||||
| 克制矩阵与伤害结算 | [战斗结算](../战斗循环/战斗结算.md)——矩阵九格结构冻结是既有条款,本系统零改动 |
|
||||
| 局内属性奖励件 | [奇物](../冒险循环/奇物.md)——账号层永久强化与单冒险加算区分层并存,互不侵入 |
|
||||
| 存档读写 | [存档序列化](../表现与支撑/存档序列化.md)——实装后新增等级与当前选中域,旧档废弃口径随实装批(开发阶段无迁移) |
|
||||
@@ -49,11 +51,11 @@
|
||||
|
||||
**工作间内两区并列**(A③ 裁):武器区/护甲区并列呈现,机制层面零顺序门槛;同屏分栏或页签切换=呈现细节归 HUD 批。
|
||||
|
||||
**树侧钥匙(2026-10-11 裁:无前置)**:本柜台由天赋树「锻造工坊」钥匙节点展开——free 节点、**无前置条件、直接可点亮**(原「攻击淬炼累计 ≥2 级 且 护甲淬炼累计 ≥2 级」等级阈值前置,随树脊柱砍攻/护两线作废);未点亮时本柜台锁定态,点亮后开放。树侧结构换代(脊柱砍攻/护两线 + 一线一节点 + Fork 一节点双态,三轮换代 **29→21→15→12**,地脉共鸣条件效果随之换代——2026-10-12 订正:原记「29→21」系 v0.6 时点旧数,树侧现行终态 12 节点)设计权威文档 = [天赋树](天赋树.md);**钥匙节点已随迭代 21 实装在役(2026-10-12 入库——free 无前置、点亮展开本柜台、锁定态零购买路径),2026-10-13 反哺写入换代原「实装归待办清单」悬置指针**。
|
||||
**树侧钥匙(2026-10-11 裁:无前置)**:本柜台由天赋树「锻造工坊」钥匙节点展开——free 节点、**无前置条件、直接可点亮**(原「攻击淬炼累计 ≥2 级 且 护甲淬炼累计 ≥2 级」等级阈值前置,随树脊柱砍攻/护两线作废);未点亮时本柜台锁定态,点亮后开放。树侧结构换代(脊柱砍攻/护两线 + 一线一节点 + Fork 一节点双态,三轮换代 **29→21→15→12**,地脉共鸣条件效果随之换代——2026-10-12 订正:原记「29→21」系 v0.6 时点旧数,树侧现行终态 12 节点)设计权威文档 = [天赋树](天赋树.md);**钥匙节点 forge_workshop 已随迭代 21 实装在役(2026-10-12 入库——free 无前置、点亮展开本柜台、锁定态零购买路径),2026-10-13 反哺写入换代原「实装归待办清单」悬置指针**。
|
||||
|
||||
**注入衔接(所有权切分,2026-10-11 裁)**:每根数值轴全游戏单一来源——生命/命中唯一入口=树脊柱;**攻击唯一入口=武器路线、AC 唯一入口=甲路线(本系统)**,树零攻防来源(红线)。锻造路线加值 = 当前武器攻击加值 + 当前甲路线 AC 加值,与树淬炼 flat、局内加算区在开局属性注入面分层相加(通道现行事实源 = [元进度](元进度.md)「跨局注入」节);锻造加值只按**当前选中**的武器/甲生效(长剑的练度在换带长枪后回家待命,不丢级、不生效)。
|
||||
|
||||
**两根类型轴的所有权(2026-10-12 v0.6 订正,用户裁)**:`attack_type` / `armor_type` 的默认值由锻造工坊配置**常驻持有**(默认值 = 现役静态表现役值 normal / light),hero.tres 静态表两轴随实装删除——静态表不再存放这两项。冒险开始时参数面读「锻造工坊配置默认值 + 存档当前选中覆盖」注入。**默认值与柜台解锁状态解耦**:树钥匙节点未点亮时柜台为锁定态(玩家无交互入口),但配置表常驻可读、默认值照常注入——不存在「锻造工坊解锁前读不到默认值」的窗口。选中态写存档(与等级域同批新增),与现役「表运行期只读、永久强化写存档」纪律一致。
|
||||
**两根类型轴的所有权(2026-10-12 v0.6 订正,用户裁)**:`attack_type` / `armor_type` 的默认值由锻造工坊配置**常驻持有**(默认值 = 现役静态表现役值 normal / light),hero.tres 静态表两轴随实装删除——静态表不再存放这两项。冒险开始时参数面读「锻造工坊配置默认值 + 存档当前选中覆盖」注入。**默认值与柜台解锁状态解耦**:树钥匙节点未点亮时柜台为锁定态(玩家无交互入口),但配置表常驻可读、默认值照常注入——不存在「锻造工坊解锁前读不到默认值」的窗口。选中态写存档(与等级域同批新增),与现役「表运行期只读、永久强化写存档」纪律一致(`meta_progression.gd:12-13/119`)。
|
||||
|
||||
### 三件武器
|
||||
|
||||
@@ -63,10 +65,10 @@
|
||||
| 长枪 | **长枪锻造** | 穿刺 | 解锁后从 1 级练起 |
|
||||
| 法杖 | **法杖锻造** | 魔法 | 解锁后从 1 级练起 |
|
||||
|
||||
> **改名注(2026-10-12,8a 裁·Y 层)**:六条路线的行名统一为「件名 + 锻造」——长剑锻造 / 长枪锻造 / 法杖锻造、轻甲锻造 / 重甲锻造 / 魔法护甲锻造。其中第一件武器的正式显示名由「剑」改「长剑」(用户原话口径)。`attack_type` 字段值、矩阵语义、攻击类型词条登记均不受此改名影响——改的只是显示名。
|
||||
> **改名注(2026-10-12,8a 裁·Y 层)**:六条路线的行名统一为「件名 + 锻造」——长剑锻造 / 长枪锻造 / 法杖锻造、轻甲锻造 / 重甲锻造 / 魔法护甲锻造。其中第一件武器的正式显示名由「剑」改「长剑」(用户原话口径)。`attack_type` 字段值、矩阵语义、registry 攻击类型词条均不受此改名影响——改的只是显示名。
|
||||
|
||||
- 每件武器有**独立等级**(1 到上限,锚点 5 级量级,provisional;**0 级 = 未练合法态**——未解锁或已解锁未锻造均为 0 加值裸体态,锻出第 1 级 = 首个 +1,Q1 裁 2026-10-12)、独立成长曲线、独立的满级特效挂位(**本期为空位**——6 裁,见「满级特效扩展位」节)——三件武器的等级各自保留,换当前武器不丢任何进度。
|
||||
- **当前武器单选出场**:类型由武器决定(选长枪=穿刺)。选中态写**存档域**(与等级域同批新增),冒险开始经参数面注入;`attack_type` 的默认值归锻造工坊配置常驻持有、hero.tres 静态表该轴随实装删除(原「写入 hero.tres 休眠轴」口径与现役「表运行期只读、永久强化写存档」纪律冲突,且与本文存档域条目自相矛盾;现役静态值 normal 由锻造工坊配置默认值接管)。
|
||||
- **当前武器单选出场**:类型由武器决定(选长枪=穿刺)。选中态写**存档域**(与等级域同批新增),冒险开始经参数面注入;`attack_type` 的默认值归锻造工坊配置常驻持有、hero.tres 静态表该轴随实装删除(2026-10-12 v0.6 订正:原「写入 hero.tres 休眠轴」口径与现役「表运行期只读、永久强化写存档」纪律冲突——`meta_progression.gd:12-13/119`,且与本文存档域条目自相矛盾;现役静态值 normal 由锻造工坊配置默认值接管)。
|
||||
- **一次冒险 = 一个武器类型 + 一个甲型(1a 裁)**:同一时刻只有一件武器、一件甲生效(出场行显示"当前:长剑锻造 + 轻甲锻造")。多持轮换淘汰——棋盘穿刺/魔法直伤件已承载"对不同甲型换着打"的战术价值,战斗内换械要给结算管线新开"类型可变"维度,收益不成比例。(原裁点只问武器携带数,本裁把它扩到"一次冒险"粒度并同时覆盖甲侧。)
|
||||
- **营地内随时切换、免费(1b / 1c 裁)**:等级都是玩家花资源练出来的,切换只是决定"今天带谁出门";二次收费会惩罚尝试性构筑,与成长曲线诉求(低成本试错找匹配武器)相逆。**冒险开始后锁死**:伤害单据的类型在开单时声明、管线内不变。
|
||||
|
||||
@@ -81,7 +83,7 @@
|
||||
- **命名统一(3a / 2b 裁)**:**只有「魔法护甲」这一个名字**(= 现役甲域 ward)。用户原案里的「魔法甲」是**笔误**,不是别名、不做简称退役处理——正文与界面文案一律写「魔法护甲」([术语表](../../术语表.md) 已登记);仅历史版本行与过程稿引用原文时按记载保留。"第四甲型"不存在也不需要讨论(2b 随之自动消解)。
|
||||
- **每型独立等级路线(3c 裁)**:与武器路线同构;"当前甲"单选与"当前武器"单选同构,营地内免费切换。
|
||||
- **甲型差异当下双轴可感(3b 裁——推翻原「显式边界·诚实收窄」条款)**:**敌方攻击是有类型的**;未显式设置的敌方攻击一律按**默认普通(normal)**参与结算(用户裁)。矩阵 normal 行取值 = 轻甲 0 / 重甲 −1 / 魔法护甲 +1(整数点数:+1 被克 / 0 中性 / −1 挡住)。所以甲型差异不是"只有基础 AC 可感",而是 **基础 AC + 克制修正两轴当下同时生效**——不再有"克制反向要等敌方攻击类型批"的推迟。
|
||||
- **现役实态与本裁定的落差(跨系统汇合点,本系统只登记需求)**:现役敌方攻击单据的攻击类型栏为空(空串恒不查克制矩阵,与"群伤/反噬/地形/敌方技"同列无类型族),敌人表登记「敌方技能攻击类型轴仍未开(全部 normal 档)」——轴未开、开了也全 normal。**按 3b 裁执行 = 把该轴按「缺省填 normal」启用**;填值动作面落在敌人系统 / 战斗结算侧,不在本工作间内。本系统只登记该需求与它的数值影响。
|
||||
- **现役实态与本裁定的落差(跨系统汇合点,本系统只登记需求)**:现役敌方攻击单据的 `attack_type` 栏为 `""`(空串恒不查克制矩阵,`damage_controller.gd:19/:550-552`;该栏注释把"敌方技"列入无类型族),`enemy.tres:527` 登记「敌方技能攻击类型轴仍未开(全部 normal 档)」——轴未开、开了也全 normal。**按 3b 裁执行 = 把该轴按「缺省填 normal」启用**;填值动作面落在敌人系统 / 战斗结算侧,不在本工作间内。锻造工坊实装批只登记该需求与它的数值影响(见「实装边界」第 6 条)。
|
||||
- **连带后果(3b 裁的前置信息,用户裁定:不在本批考虑,留作后续开发改造的输入)**:按"敌方攻击缺省普通"落定后,现行数据下三型会成**纯序**——重甲(AC +2 且挡普通 −1)= 双正、轻甲 = 中性、魔法护甲(AC −1 且被普通克 +1)= 负向,且因现行敌方无魔法攻击而暂无优势窗口。这是**后续开发改造的前置事实**不是缺陷裁定:敌方攻击类型的差异化、魔法护甲的正当性由后续批次负责(含 M4 在基础 AC / 解锁价上的取值);本批只需按统一伤害轴把结构与字段落对即可。
|
||||
- 每 1 点 AC 的期望减伤约 3.75% 量级(现役 EV 复算锚:AC10 期望减免 21.25%、AC11 25%),终值归 M4。
|
||||
|
||||
@@ -95,7 +97,7 @@
|
||||
### 经济
|
||||
|
||||
- **纯钥石(5b 裁)**:与现役属性锻造、天赋树(树全钥石单币)、同调刷新升级同币同柜。原案语义是"攻击力提升改造"——同一笔钱换个花法。GP = 局内一次性货币、局内清零不入存档、与钥石永不互兑,两币分工是拍板条款,不引入局外 GP 余额域或第三货币。(用户裁定注:当前没有其他材料,钥石就是统一货币;**后续若要分出专用币或材料,届时再重构设计,不预先建面**。)
|
||||
- **几何递增定价**:每级价格 = 基础价 × 150%^(已购级数)(历史考古参数:单次 20 钥石、公比 150%——退役行批注;forge_products 行族已随迭代 21 T5 退役、无现役计价字段可沿,实装投值归 M4 从零标定);路线解锁 = 一次性解锁价(量纲 ≈ 中段几级锻造花费)。全部终值归 M4。
|
||||
- **几何递增定价**:每级价格 = 基础价 × 150%^(已购级数)(历史考古参数:单次 20 钥石、公比 150%——`meta.tres:82-84` 退役批注;forge_products 行族已随迭代 21 T5 退役、无现役计价字段可沿,实装投值归 M4 从零标定);路线解锁 = 一次性解锁价(量纲 ≈ 中段几级锻造花费)。全部终值归 M4。
|
||||
- **零材料经济(5c 裁)**:不引入账号层锻造材料。现役效果引擎的 grant_material 是**局内**材料计数器(如雷区图谱),不是账号层库存;账号层材料=全新经济面(存档域/获取渠道/囤积规则全套新建),原案全文只字未提材料,武器差异化的价值轴是类型(与预留的特效位)不是采集刷料。
|
||||
|
||||
### 满级特效扩展位(本期不启用——6 裁)
|
||||
@@ -110,30 +112,55 @@
|
||||
| 路线 | 候选特效(量纲方向) | 实现代价分档(2026-10-21 按现役代码复核) |
|
||||
|---|---|---|
|
||||
| 长剑 | 破甲:命中重甲时克制修正额外 +1 点量级 | 零新代码——`modify_ticket` 效果类型与 matchup 条件算子均在现役闭集 |
|
||||
| 长剑(第二条) | 暴击面扩大:暴击骰面 −1 量级 | **需新参数位**——暴击面现役是表上恒定值(`settlement.tres` 的 `crit_roll=20`),改成武器级可变=实装批改读表面 |
|
||||
| 长剑(第二条) | 暴击面扩大:暴击骰面 −1 量级 | **需新参数位**——暴击面现役是表上恒定值(`settlement.tres:52 crit_roll=20`),改成武器级可变=实装批改读表面 |
|
||||
| 长枪 | 先手连击:战斗开场追加一次普攻量级的攻击 | 零新代码——`attack_segments` 在册 |
|
||||
| 法杖 | 开局魔法矢:每场战斗开场自动对最前敌人放一次魔法直伤(必中全额量级) | 零新代码——`spawn_spell` 在册(次数/回合数 provisional) |
|
||||
| 轻甲 | 灵巧:掷点折扣临界档再缓一档量级 | **需新参数位**——折扣档现役读表恒定(`settlement.tres` 的 `roll_tier_discounts=[75,50,25]`) |
|
||||
| 轻甲 | 灵巧:掷点折扣临界档再缓一档量级 | **需新参数位**——折扣档现役读表恒定(`settlement.tres:51 roll_tier_discounts=[75,50,25]`) |
|
||||
| 重甲 | 反震:被命中时对攻击者反贴 1 点量级伤害 | 零新代码——`spike` 在册 |
|
||||
| 魔法护甲 | 护盾:每场战斗开场自带护盾(层数 X 量级,终值归 M4) | 零新代码+参数面桥接——`shield` 在册,护盾层数进战斗开场参数需接线 |
|
||||
|
||||
- 候选池的实现深度前提(沿用过程稿结论并经现役复核):七条全部可用现役效果类型闭集词或参数位表达,**无一条需要往闭集加新效果类型词**——加词是高代价变更面(加载校验/文档词表/回归测试三处连带),启用时禁走此路。
|
||||
- 候选池的实现深度前提(沿用过程稿结论并经现役复核):七条全部可用现役 `EFFECT_KINDS` 闭集词或参数位表达,**无一条需要往闭集加新效果类型词**——加词是高代价变更面(加载校验/文档词表/回归测试三处连带),启用时禁走此路。
|
||||
|
||||
**对相邻口径的两处连带**:① 设计目的节"能力解锁的节奏"台阶收缩为新武器 / 新甲型解锁(不再含特效);② 存档域不设特效域。
|
||||
**对相邻口径的三处连带**:① 设计目的节"能力解锁的节奏"台阶收缩为新武器 / 新甲型解锁(不再含特效);② 实装边界不再有"特效三条新参数位"条目;③ 存档域不设特效域。
|
||||
|
||||
## 与相邻系统的边界
|
||||
|
||||
- **奇物属性件**:分层并存,互不侵入。武器/护甲锻造动的是**账号层基础值**(营地永久强化,冒险开始时经参数面传入);奇物属性件动的是**单次冒险加算区**(关间不清零、冒险结束清零)。本设计不扩奇物"生命/AC/攻击"三轴封闭分类、不动渠道开关表、不往局内池加任何东西。入战 AC 的三层语义清晰可加:甲型基础 AC + 营地甲路线等级加值 + 局内加算区累加。
|
||||
- **克制矩阵(2a 裁:伪裁点消解)**:**伤害结算只有一套,类型不是待仲裁的槽位**。每份伤害单据自带攻击类型栏——主角基础攻击单据取当前武器的攻击类型,棋盘格面直伤件(穿刺弹 / 魔法矢)取奖励表自身的类型——各自按**同一张 3×3 克制矩阵**取克制修正。因此"叠加 / 替代 / 互斥"三分法不成立:两根参数之间无冲突可裁,也不需要任何共存规则。二者的真实差异只在**单据形态与生命周期**(主角基础攻击走掷点折扣 + 暴击;棋盘克制直伤走必中全额不掷点;且前者 = 账号层永久、后者 = 局内一次性)——那是两条不同的伤害来源,不是两种类型语义。矩阵九格满格结构冻结(2b 随 3a 自动消解:魔法护甲 = 现役 ward,不存在第四甲型)。
|
||||
- **克制矩阵(2a 裁:伪裁点消解)**:**伤害结算只有一套,类型不是待仲裁的槽位**。每份伤害单据自带 `attack_type` 栏(`damage_controller.gd:19` 单据九栏之一)——主角基础攻击单据取 `hero.tres` 的 attack_type(由当前武器决定),棋盘格面直伤件(穿刺弹 / 魔法矢)取 reward 表自身的类型(预期 `reward.tres:131/142`)——各自按**同一张 3×3 矩阵** `armor_effectiveness` 取克制修正(`_counter_delta`)。因此"叠加 / 替代 / 互斥"三分法不成立:两根参数之间无冲突可裁,也不需要任何共存规则。二者的真实差异只在**单据形态与生命周期**(主角基础攻击走掷点折扣 + 暴击;棋盘克制直伤走必中全额不掷点 `_resolve_board_typed`;且前者 = 账号层永久、后者 = 局内一次性)——那是两条不同的伤害来源,不是两种类型语义。矩阵九格满格结构冻结(2b 随 3a 自动消解:魔法护甲 = 现役 ward,不存在第四甲型)。
|
||||
- **工作间两区定名 + 路线行名(8a 裁)**:锻造工坊工作间内先立两个分区,各装三条锻造路线(路线行名统一为"件名 + 锻造")——①**武器锻造区**:长剑锻造 / 长枪锻造 / 法杖锻造;②**护甲锻造区**:轻甲锻造 / 重甲锻造 / 魔法护甲锻造。两区并列、机制层面零顺序门槛(A③ 裁),区内路线各自独立升级。
|
||||
- **局内不存在武器/护甲的提升(8a 裁连带核结)**:用户指出"局内没有可以提升武器的地方"——**属实**。查实:局内商店货架的三行(现役旧名"攻击锻升 / 生命锻升 / 护甲锻升"——**2026-10-12 已改名,见下**),**正是奇物「属性值提升」三轴(攻击 / 生命上限 / AC)的货架前台标签**——`shop.tres` pool_shelf 六行用种类字段指向冒险表的奇物种类词表(其中凭证行为显式豁免种、不入该词表,六行中五行命中),`display_name` 只是这层的前台名;买到的东西进**冒险加算区**、冒险结束清零。所以它们是**奇物属性件**,既不是武器也不是护甲,局内不改变任何锻造等级。命名上的隐患确凿:行名里的"锻"字与营地锻造同字,是误读的直接来源。**2026-10-12 用户裁决(8a 连带·C 项)**:三行按「属性 + 后缀」改名,后缀取 **祝福** ⇒ **攻击祝福 / 生命祝福 / 护甲祝福**(D&D 参照调研:Blessing 为"神赐恩惠"义;用户同时裁定——参考书目里出现过「祝福」一词不构成禁用)。**改名后这三条在语感上彻底脱离"锻造"一词,与营地工作间不再有字面关联**,而结构关系不变(仍是奇物「属性值提升」三轴,机制分类名不动,只改玩家向显示名)。**改名已于 2026-10-12 执行完毕并合入 master**(shop.tres 六行锻升→祝福;reward.tres / status_effects.tres 护甲强化→盾牌加护)。
|
||||
- **局内不存在武器/护甲的提升(8a 裁连带核结)**:用户指出"局内没有可以提升武器的地方"——**属实**。查实:局内商店货架的三行(现役旧名"攻击锻升 / 生命锻升 / 护甲锻升"——**2026-10-12 已改名,见下**),**正是奇物「属性值提升」三轴(攻击 / 生命上限 / AC)的货架前台标签**——`shop.tres` pool_shelf 六行用 `kind_id` 指向 `adventure_table.gd:29` 的 CURIO_KINDS 常量(其中 feat_ticket 为显式豁免种、不入该词表,5/6 命中——`config_db_cross_validator.gd:109-110`),`display_name` 只是这层的前台名;买到的东西进**冒险加算区**、冒险结束清零。所以它们是**奇物属性件**,既不是武器也不是护甲,局内不改变任何锻造等级。命名上的隐患确凿:行名里的"锻"字与营地锻造同字,是误读的直接来源。**2026-10-12 用户裁决(8a 连带·C 项)**:三行按「属性 + 后缀」改名,后缀取 **祝福** ⇒ **攻击祝福 / 生命祝福 / 护甲祝福**(D&D 参照调研:Blessing 为"神赐恩惠"义;用户同时裁定——参考书目里出现过「祝福」一词不构成禁用)。**改名后这三条在语感上彻底脱离"锻造"一词,与营地工作间不再有字面关联**,而结构关系不变(仍是奇物「属性值提升」三轴,机制分类名不动,只改玩家向显示名)。**执行归独立改名小批**(待办清单在册)——**已于 2026-10-12 执行完毕并合入 master**(commit `0c93a71` / `0144f60`:shop.tres 六行锻升→祝福;reward.tres / status_effects.tres 护甲强化→盾牌加护;smoke_all.gd:1199 断言同步;注记段四处残留肃清;冒烟两跑 864 项 0 失败)。
|
||||
- **专长联动**:现役专长均为跨攻击类型通用件(不按 attack_type 分系——既无 normal 条件件、也无 pierce/magic 条件件,`feats.tres` 29 行实证),武器类型差异只经克制矩阵的 matchup 行体现;「选某类型激活某系专长」在本项目专长体系下不成立(2026-10-12 v0.6 订正:原「选长枪激活穿刺系专长的价值」为无现役对应物的表述,删除)。现有死条件 `magic_vs_magic`(魔法打"魔法甲"——现行甲域无此型,永不可触发 = 废卡):**改值复活案已作废(2026-10-11 D 组核结——所属件魔网织者在素材库表二专长 27 件退役删除名单)**,该行随专长退役删行批整体消解,本系统零触碰(2026-10-12 订正:本节原写"推荐复活"与实装边界第 3 条结案口径冲突,随本批对齐)。「魔法打魔法护甲」的克制语义由矩阵九格承载(magic vs ward = −1),新专长框架如需同类件 = 彼批的新卡设计题。
|
||||
- **天赋树**:同钥石经济;注入面分层叠加且**所有权切分**(2026-10-11 裁)——树脊柱只持生命/命中淬炼(树零攻防来源),攻/AC 唯一入口=本系统路线加值(只按当前选中武器/甲生效)。
|
||||
- **冒险前资源配比预设批(挂起冻结中)**:本设计不预设该批的重启口径、不占用其任何冻结裁决、不改其冻结文本。该批重启时须显式核对两处交汇面:①预算包络是否把武器类型计入克制注;②容量柜台与锻造工坊工作间(同在营地)的资源竞争关系。
|
||||
|
||||
## 现役代码事实(设计所依据的实态,2026-10-07 复核)
|
||||
|
||||
| 事实 | 出处 |
|
||||
|---|---|
|
||||
| 局内商店货架三行 = 奇物「属性值提升」三轴的货架前台标签(攻击/生命/护甲祝福);营地属性锻造行族已随迭代 21 T5 退役,无"武器"实体 | `shop.tres:68-92`、`meta.tres:73-76` 退役登记 |
|
||||
| 主角攻击类型轴现役值 normal(枚举 normal/pierce/magic)——默认值所有权随本设计移交锻造工坊配置、hero.tres 该轴随实装删除 | `hero.tres:11`、`hero_table.gd:13` |
|
||||
| 主角甲型结构位现役值 light(域 light/ward/heavy);AC=10 现役生效——默认值所有权随本设计移交锻造工坊配置、hero.tres 该轴随实装删除 | `hero.tres:9-10` |
|
||||
| 克制矩阵 3×3 九格满格(普通/穿刺/魔法 × 轻甲/魔法护甲/重甲),结构冻结 | `settlement.tres:31-47` |
|
||||
| 敌方装甲分布:轻甲×14 / 重甲×4 / 魔法护甲×1(L2 Boss 蛛化卓尔精灵) | `enemy.tres` |
|
||||
| 甲效矩阵 normal 行取值:轻甲 0 / 魔法护甲 +1 / 重甲 −1(整数点数:+1 被克 / 0 中性 / −1 挡住) | `settlement.tres:31-47` |
|
||||
| 敌方攻击类型轴**未开**——单据 `attack_type` 栏现役为 `""`(空串恒不查矩阵,`""` 与"群伤/反噬/地形/敌方技"同列无类型族);`enemy.tres` 登记「敌方技能攻击类型轴仍未开(全部 normal 档)」 | `damage_controller.gd:19/:550-552`、`enemy.tres:527` |
|
||||
| 效果引擎效果类型闭集 **31 种**(原记 24 系 2026-10-07 旧快照——迭代 20 T1 +7、迭代 22 T3 +1,2026-10-13 迭代 23 反哺写入订正;冒烟断言钉 31,将来加词即转红提示复核) | `effect_engine.gd` |
|
||||
| 营地消费货币=钥石(现役入口 tree_buy / buy_attune_refresh → spend_keystone——buy_forge 随 forge_products 退役删除);GP=局内一次性货币,开局清零不入存档 | `meta_progression.gd:175/:354`、`adventure_runner.gd:100` |
|
||||
|
||||
## 实装边界(执行归实装批,本文只登记方案)
|
||||
|
||||
1. **锻造路线行族(新建)**:现役 `meta.tres` forge_products 行族已随迭代 21 T5 攻防所有权切分整体退役(`meta.tres:73-76`、`meta_table.gd:15-16`、`meta_progression.gd:33-35` 三处退役登记,buy_forge/forge_price 访问器随删)——武器/护甲路线为**新建行族**,行族命名、字段结构与落表位置归实装批定义,本文只登记内容口径(三武器/三甲各自等级、定价、解锁通道,见「工作间内容清单」);生命项不在本批(生命强化唯一入口=树脊柱生命线,2026-10-11 A① 裁)。同表 boss_keystone / workshop_items / conversion / attune_refresh_upgrade 四行族零触碰。**实态回填(2026-10-13 迭代 23 实装兑现)**:落表=新表 `data/tables/forge.tres`(ForgeTable:默认两轴常驻持有 + 六路线行族,`meta.tres` 三行族零触碰);路线 id = sword/spear/staff/light/heavy/ward(甲路线 id=甲型值本身);字段闭集 12 项;访问器 = `ConfigDB.forge_*` 六个(迭代 23 T1/T2 交付)。
|
||||
2. **两根类型轴的所有权移交**:`attack_type` / `armor_type` 的默认值由锻造工坊配置常驻持有,hero.tres 静态表两轴**删除**;营地选中态写存档域,冒险开始经参数面注入(与现役「表运行期只读、永久强化写存档」纪律一致——`meta_progression.gd:12-13/119`;原「写 hero.tres 休眠轴」口径随 v0.6 订正,见「注入衔接」节)。
|
||||
3. **`feats.tres` magic_vs_magic 死行**:复活案作废(2026-10-11 核结——所属件魔网织者已在素材库表二专长 27 件退役删除名单),随专长退役删行批整体消解,本批零触碰;「魔法打魔法护甲」克制语义由矩阵九格承载,新专长框架如需同类件=彼批新卡设计题。
|
||||
4. **存档域**:新增三武器等级 + 三甲等级 + 当前选中标记(各 1 个);**不设特效域**(6 裁)。旧档按开发阶段无迁移红线破坏性废弃(2026-10-11 用户裁,禁迁移/折算)。**已于 2026-10-12 v0.6 完备性检查批预登记**(存档序列化.md 域清单表 + 版本沿革 v7 计划行——用户令文档批次即登记、不等实装批)。
|
||||
5. **满级特效:本期不实装**(6 裁)——不开三条新参数位(暴击面 / 折扣档 / 护盾量),不加效果类型词,扩展位留空。
|
||||
6. **敌方攻击类型轴填值(3b 裁连带,跨系统汇合点)**:敌方攻击单据 `attack_type` 按「未设置 = 默认 normal」填值,使其参与克制矩阵查表(现役为 `""` 恒不查)。**执行面归敌人系统 / 战斗结算侧**,锻造工坊实装批只登记该需求与其数值影响——该改动会全局平移主角受伤点数(穿重甲 −1、穿魔法护甲 +1),属数值敏感变更,须纳入第 8 条的配对读数验证。敌方 attack_type 是敌方定义数据(enemy.tres / skills.tres 行级,与敌种名字/血量同批同时读写、无独立时序),填值归敌人系统/战斗结算侧自然推进——本批只按 3b 裁落结构面(矩阵查表现役已支持),与锻造工坊批期无耦合(2026-10-12 订正:原「两批排期协商(可同批做,也可先行)」句删除——用户裁:时序问题不存在)。
|
||||
7. **术语登记**:三型甲统一命名——**只有「魔法护甲」(「魔法甲」系笔误,不登记为别名)**;连同工作间两区定名(武器锻造区 / 护甲锻造区)顺带登记 `design/gdd/术语表.md`。
|
||||
8. **数值验证义务**:实装批必须带改前/改后同随机种子配对读数验证难度影响;统一调整归 Alpha 收官 M4 数值批。
|
||||
|
||||
## 裁决结果清单(17 裁点全表·2026-10-12 清零)
|
||||
|
||||
17 裁点全部拍板,本表即终态(含本会话呈报的两条子问 4a-1 / 4b-1,共 19 行)。「推翻推荐」四行已同步改正文对应节。
|
||||
17 裁点全部拍板,本表即终态(含本会话呈报的两条子问 4a-1 / 4b-1,共 19 行)。「推翻推荐」四行已同步改正文对应节。实装批以本表 + 下节「工作间内容清单」为需求卡片输入。
|
||||
|
||||
| # | 裁点 | 裁决结果 | 写入处 | 备注 |
|
||||
|---|---|---|---|---|
|
||||
@@ -155,7 +182,7 @@
|
||||
| 5b | 货币 | 纯钥石(用户注:当前无其他材料,钥石 = 统一货币;后续若要区分再重构,不预先建面) | 「经济」节 | 按推荐案(且受两币分工条款锁定) |
|
||||
| 5c | 材料经济 | 纯钥石零材料 | 「经济」节 | 按推荐案 |
|
||||
| 6 | 满级特效深度 | **本期不做,只留扩展位**——不设计清单 / 不定数值 / 不实装 / 不开参数位 | 「满级特效扩展位」节 | **推翻推荐案**(原 = 复用为主 + 三条新参数位) |
|
||||
| 8a | 货架现名 → 实裁 = 工作间命名(区名 + 路线行名)+ 局内核结 | **区名**:武器锻造区 / 护甲锻造区;**路线行名**统一「件名 + 锻造」= 长剑锻造 / 长枪锻造 / 法杖锻造、轻甲锻造 / 重甲锻造 / 魔法护甲锻造(第一件武器显示名 剑 → **长剑**)。**局内核结**:局内不存在武器 / 护甲的提升——商店货架三行「攻击锻升 / 生命锻升 / 护甲锻升」即奇物「属性值提升」三轴的货架前台标签(`shop.tres` pool_shelf 种类字段 → `adventure.tres` 奇物种类词表),与锻造无关;是否去"锻"字归实装批呈现面 | 「与相邻系统的边界·工作间两区定名 / 局内不存在武器提升」 | 裁点重定向 + Y 层命名 |
|
||||
| 8a | 货架现名 → 实裁 = 工作间命名(区名 + 路线行名)+ 局内核结 | **区名**:武器锻造区 / 护甲锻造区;**路线行名**统一「件名 + 锻造」= 长剑锻造 / 长枪锻造 / 法杖锻造、轻甲锻造 / 重甲锻造 / 魔法护甲锻造(第一件武器显示名 剑 → **长剑**)。**局内核结**:局内不存在武器 / 护甲的提升——商店货架三行「攻击锻升 / 生命锻升 / 护甲锻升」即奇物「属性值提升」三轴的货架前台标签(`shop.tres` pool_shelf kind_id → `adventure.tres` CURIO_KINDS),与锻造无关;是否去"锻"字归实装批呈现面 | 「与相邻系统的边界·工作间两区定名 / 局内不存在武器提升」 | 裁点重定向 + Y 层命名 |
|
||||
|
||||
## 工作间内容清单(实装批需求卡片输入)
|
||||
|
||||
@@ -202,7 +229,7 @@
|
||||
- 入战 AC 三层可加:甲型基础 AC + 甲路线等级加值 + 局内加算区累加。
|
||||
|
||||
### 8 · 存档域
|
||||
三武器等级 + 三甲等级 + 当前武器标记 + 当前甲标记;**无特效域**。旧档破坏性废弃(禁迁移 / 折算)。存档域见[存档序列化](../表现与支撑/存档序列化.md)(域清单与版本沿革 v7 行)。
|
||||
三武器等级 + 三甲等级 + 当前武器标记 + 当前甲标记;**无特效域**。旧档破坏性废弃(禁迁移 / 折算)。**已于 2026-10-12 预登记存档序列化.md**(域清单 + 版本沿革 v7 计划行)。
|
||||
|
||||
### 9 · 本期明确不做
|
||||
① 满级特效(清单 / 数值 / 参数位 / 存档域全不做);② 敌方攻击类型轴填值——跨系统需求,执行面在敌人系统 / 战斗结算侧,本批只登记。
|
||||
|
||||
+72
-72
@@ -1,10 +1,10 @@
|
||||
# UX Spec: 战斗屏(Battle Screen)
|
||||
|
||||
> **Status**: Complete(现行)
|
||||
> **Status**: Complete — /ux-review 修订落稿(2026-09-12,blocking 7 项已修,待复检)
|
||||
> **Author**: user + ux-designer
|
||||
> **Last Updated**: 2026-10-29
|
||||
> **Last Updated**: 2026-10-26(迭代 38 卡⑦ 调试入口发布态恒隐:DS_DEBUG 门控表述换代——见元素表「调试浮窗」行与「调试变体」行)
|
||||
> **Platform Target**: PC (Steam)——Keyboard/Mouse 主(全部操作纯鼠标可完成)、Gamepad Partial 非 MVP、Touch None(同 technical-preferences)
|
||||
> **上游修订依赖**: 弃图刷新挖掘期受理已随布局决策 4 落稿上游(2026-09-12:行动经济 Active 受理 + 每轮上限 2 次、排雷玩法 Active·仅刷新路径装板、战斗结算的挖掘期刷新编排 + 恒同盘不变、系统索引的刷新规则同步——见 OQ11)
|
||||
> **上游修订依赖**: 弃图刷新挖掘期受理已随布局决策 4 落稿上游(2026-09-12:行动经济 Active 受理 + 每轮上限 2 次、排雷玩法 Active·仅刷新路径装板、战斗结算 `refresh_board` 编排 + 恒 same_board、registry `rap_rules` 同步——见 OQ11)
|
||||
> **Template**: UX Spec
|
||||
> **覆盖子屏**: 挖掘阶段主界面 · 轮末自动战斗结算(战斗结算明细屏) · 胜利/失败终局 · ~~结算明细回看~~(2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——待办清单登记)
|
||||
> **输入义务**: 排雷玩法×6 + 行动经济 + 战斗结算×3 + 敌人系统×4 + 增益状态×4 + 地图战斗资源×5(旧版 systems-index 门禁增补记录,缺项即 blocking——承接落点见 §13 义务对照表)
|
||||
@@ -28,7 +28,7 @@
|
||||
## Player Context on Arrival
|
||||
|
||||
- **首次到达**:从关卡首节点(战×2 的第一战)进入。MVP 无引导流,chord 肌肉记忆提示等非模态提示承担首次教学(见 §States)
|
||||
- **到达前刚在做**:关卡画面(独立屏)上点击战斗节点(关卡推进方受理);或上一场战斗胜利后返回关卡画面再选下一节点
|
||||
- **到达前刚在做**:关卡画面(独立屏)上点击战斗节点(LevelRunner 推进);或上一场战斗胜利后返回关卡画面再选下一节点
|
||||
- **情绪状态**:棋手式清明专注(art-bible §2.1,能量 2/10)——挖掘期画面必须无杂音;结算期转为清算爽感(7/10)
|
||||
- **到达方式**:游戏推进送入(非自愿导航),进入即处于挖掘阶段(棋盘已 install、初始 3×3 已展开、小人出生)
|
||||
|
||||
@@ -41,14 +41,14 @@
|
||||
```
|
||||
存档 → 冒险 → 关卡(关卡画面 = 节点图选路常驻枢纽) → 【战斗屏】
|
||||
├─ 胜利 → 返回关卡画面选下一节点(落地奖励/恢复节点时开节点覆盖层确认 → 下一场战斗屏)
|
||||
├─ 胜利(末节点 Boss)→ 关卡结算(关卡完成,spec:[level-clear.md](level-clear.md))→ 下关
|
||||
├─ 胜利(末节点 Boss)→ 关卡结算(level_clear,spec:[level-clear.md](level-clear.md))→ 下关
|
||||
└─ 失败 → 冒险落幕 → 返回存档/营地
|
||||
```
|
||||
|
||||
战斗屏是**上下文相关屏**(仅由战斗节点进入),非顶层常驻。关卡内节点进度常驻关卡画面(独立屏的常驻枢纽形态,节点态即进度呈现:已过暗金、当前金、候选通道亮金、Boss 紫赤描边),战斗屏零进度承载——战斗结束返回关卡画面,玩家始终知道自己身处图中第几环。
|
||||
|
||||
- 上游屏:关卡画面(选路枢纽,屏级 spec:[level-map.md](level-map.md)——2026-09-27 建档;分支节点图形态,切片第一关为单链特例)
|
||||
- 下游屏:关卡画面(选路枢纽,spec:[level-map.md](level-map.md))——战斗胜利后返回选路;落地奖励/恢复节点时由关卡画面域开节点覆盖层(恢复点全量服务、奖励点=三选一构筑点)确认兑付——节点奖励屏 spec 已出生:[node-reward.md](node-reward.md) v1.0(2026-09-29 迭代 7 T5 顺带出生,待办清单条目兑现;2026-09-27「不立独立 spec」拍板随之被取代)
|
||||
- 下游屏:关卡画面(选路枢纽,spec:[level-map.md](level-map.md))——战斗胜利后返回选路;落地奖励/恢复节点时由关卡画面域开节点覆盖层(NodeOverlay,恢复点全量服务、奖励点=三选一构筑点)确认兑付——节点奖励屏 spec 已出生:[node-reward.md](node-reward.md) v1.0(2026-09-29 迭代 7 T5 顺带出生,待办清单条目兑现;2026-09-27「不立独立 spec」拍板随之被取代)
|
||||
- 下游屏:关卡结算([level-clear.md](level-clear.md),末节点 Boss 胜利——2026-09-27 建档)
|
||||
- 平行屏:图例面板 overlay(本屏内域屏);~~结算明细回看 overlay~~(2026-10-04 P-C7 退役——冒险中回看归「生涯」)
|
||||
|
||||
@@ -60,16 +60,16 @@
|
||||
|
||||
| Entry Source | Trigger | Player carries this context |
|
||||
|---|---|---|
|
||||
| 关卡战斗节点 | 点击节点(关卡推进方受理本场遭遇) | 携带 HP(跨战斗延续)、RAP=0(战斗域新开) |
|
||||
| 关卡战斗节点 | 点击节点(LevelRunner 推进 encounter) | 携带 HP(跨战斗延续)、RAP=0(战斗域新开) |
|
||||
| 上一场战斗胜利 → 返回关卡画面 → 选下一节点 | 同上 | 同上 |
|
||||
|
||||
**离开**:
|
||||
|
||||
| Exit Destination | Trigger | Notes |
|
||||
|---|---|---|
|
||||
| 关卡画面(选路枢纽) | 敌方全灭(战斗结算判定段判胜)且非末节点 | 不可逆:战斗结束已发生,RAP 清零;落地奖励/恢复节点时开节点覆盖层确认(关卡画面域) |
|
||||
| 关卡结算 | Boss 战胜利 → 关卡完成(spec:[level-clear.md](level-clear.md)) | 不可逆:~~关卡收束清库义务载体 = 秘宝背包~~(秘宝过渡形态〔关卡域库存/局内两步使用〕已随迭代 11 第①批退役——现行形态 = 营地同调装配、整局冒险生效,无关卡域清库面〔旧关卡域库存 treasure_inventory 为投放渠道全退役后恒空的机械惰性承载,拆线归实装批——见战斗结算「轮次生命周期」节注〕,见秘宝.md) |
|
||||
| 冒险落幕 | 主角 HP=0(判负) | 不可逆:Roguelike 死亡重开(art-bible §2.5 温柔惋惜调性) |
|
||||
| 关卡画面(选路枢纽) | 敌方全灭(战斗结算判定段 verdict=win)且非末节点 | 不可逆:battle_over 已发生,RAP 清零;落地奖励/恢复节点时开节点覆盖层确认(NodeOverlay,关卡画面域) |
|
||||
| 关卡结算 | Boss 战胜利 → level_clear(spec:[level-clear.md](level-clear.md)) | 不可逆:~~关卡收束清库义务载体 = 秘宝背包~~(秘宝过渡形态〔关卡域库存/局内两步使用〕已随迭代 11 第①批退役——现行形态 = 营地同调装配、整局冒险生效,无关卡域清库面〔旧关卡域库存 treasure_inventory 为投放渠道全退役后恒空的机械惰性承载,拆线归实装批——见战斗结算「轮次生命周期」节注〕,见秘宝.md) |
|
||||
| 冒险落幕 | 主角 HP=0(verdict=lose) | 不可逆:Roguelike 死亡重开(art-bible §2.5 温柔惋惜调性) |
|
||||
| 无中途退出 | — | MVP 不设战斗内放弃/暂停菜单(回合制无时间压力;如需暂停留 Playtest 诊断按钮,调试用) |
|
||||
|
||||
---
|
||||
@@ -125,7 +125,7 @@
|
||||
|
||||
> 布局为 B/C/D 三区——关卡进度条不在战斗屏(节点链进度常驻关卡画面,见 Navigation Position;字母不重编沿用 B/C/D)。
|
||||
|
||||
> 呈现术语注记(2026-09-25):封印 = 正式动作名(全库统一;登记册术语与术语表 v1.13;印记 = 封印印记,art-bible §3.2)——机制与键名不变;封印特效未实装,占位 = 封印黑「封」字形(棋盘视图程序化占位,现行代码仍为旧「旗」字形、随代码术语批换代,贴图在位=字形退役;旗朱→封印紫 2026-09-26→封印黑 2026-09-28 用户拍板)。
|
||||
> 呈现术语注记(2026-09-25):封印 = 正式动作名(全库统一;registry terminology 与术语表 v1.13;印记 = 封印印记,art-bible §3.2)——机制与键名不变;封印特效未实装,占位 = 封印黑「封」字形(board_view 程序化占位,现行代码仍为旧「旗」字形、随代码术语批换代,贴图在位=字形退役;旗朱→封印紫 2026-09-26→封印黑 2026-09-28 用户拍板)。
|
||||
|
||||
> 可挖域微光画法定稿(2026-09-25 用户拍板):**接触带·空间侧 + 蓝族**——光画英雄格周界接触面(正交邻墙=整边,斜向邻墙=角点+两半边),详见 art-bible §3.2;现行墙格整框绿相呼吸为待退役占位,实现切换归表现批(探针断言顺带)。
|
||||
|
||||
@@ -153,25 +153,25 @@
|
||||
|
||||
### Component Inventory
|
||||
|
||||
| 区 | 组件 | 类型 | 内容 | 交互 | 载体 |
|
||||
| 区 | 组件 | 类型 | 内容 | 交互 | 现有 demo 组件 |
|
||||
|---|---|---|---|---|---|
|
||||
| B | 主角站桩立绘 | 站桩(无框立绘+落影) | HP 条落底盘(2026-10-06 方案二拍板:站桩排式 = **立绘→血条→状态**,全场血条对齐一线;血条嵌石板位、台缘线留作地面线;原「悬浮头顶」退役——高盒下血条-立绘空洞,用户点名否决)、状态效果小图标一排挂血条正下方(形状+色相双通道、层数角标;空态不占位退化为空行)——**HP 与状态效果的唯一展示面(2026-09-26 信息归属拍板,原 C 区状态槽职责〔悬停 tooltip 来源+语义+剩余结算次数〕并入本组件)**;攻击值等规划数据仍归 C 区数据框(2026-09-20 全站桩拍板,英雄卡退役) | 悬停状态小图标看 tooltip | HUD 视图拆分改造 |
|
||||
| B | 主角站桩立绘 | 站桩(无框立绘+落影) | HP 条落底盘(2026-10-06 方案二拍板:站桩排式 = **立绘→血条→状态**,全场血条对齐一线;血条嵌石板位、台缘线留作地面线;原「悬浮头顶」退役——高盒下血条-立绘空洞,用户点名否决)、状态效果小图标一排挂血条正下方(形状+色相双通道、层数角标;空态不占位退化为空行)——**HP 与状态效果的唯一展示面(2026-09-26 信息归属拍板,原 C 区状态槽职责〔悬停 tooltip 来源+语义+剩余结算次数〕并入本组件)**;攻击值等规划数据仍归 C 区数据框(2026-09-20 全站桩拍板,英雄卡退役) | 悬停状态小图标看 tooltip | HUDView 拆分改造 |
|
||||
| B | 敌人站桩立绘 ×1–3 | 站桩(无框立绘+落影) | 血条+顺位徽标落底盘(同主角排式,2026-10-06 方案二;**大体档〔显示 >150px 级:drider/duergar_king〕允许向上溢出盒顶 N px(N 由实装批 C0 实算,与背景/光柱无关——现行溢出区为临时光柱氛围层,正式舞台背景插画到位后该层退役,判定不变),血条仍落底**)、状态小图标挂血条正下方(敌方 side-wide 增益各立绘同值呈现——蓄力/硬化/削弱/暴走/警觉;伏击层数通道随 2026-09-20 八型批退役——数据源 = 战斗结算流水经增益状态投影,敌人系统×4④;2026-09-16 敌人技能池批改型:行为环点拆除〔proposal §2.4〕,意图占位 = 本拍摇定结果的动画占位——普通攻击零表示 / 特殊技类型级提示,**意图徽标悬浮头顶上方,探顶档压胸**,敌方增益〔蓄力/硬化〕入状态图标行);死亡灰化加碎裂退场直接演在立绘上(2026-09-20 全站桩拍板,敌人卡退役);血条下名字行 = 纯名字 + 护甲类型图标(形状+色相双通道,与状态图标同行共存,状态空时为纯名字;原「底座下」随石板退位改落底排),AC 数值不展示——2026-09-26 终裁(用户口径:HP 信息已足够,攻防数值不直接写上;护甲类型图标保留克制对策可读性——类型可读、数值隐藏) | 只读 | 新建 |
|
||||
| B | 轮次·阶段指示 | 标签 | "第 N 轮 · 挖掘中/结算中"(终局定格「战斗结束」;Boss 变体附 Boss 名) | 只读 | 新建 |
|
||||
| B | 结算明细带 | 滚动列表 | 结算期逐行流水([战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋) 9 类行协议);挖掘期收起为上轮摘要 1 行 | 点击展开明细回看 overlay(2026-10-04 P-C7 退役——带保留单行摘要,回看归「生涯」) | 改造 |
|
||||
| B | ~~结算明细回看~~(已退役) | —— | 2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——回看覆盖层为未接线遗留件(待办清单登记) | —— | 未接线 |
|
||||
| C | 攻击数据框 | 直角细线数据框 | 攻击值 + 修正来源角标 + 护甲 AC(AC 二轮拍板 2026-09-26 补入——我方 AC 唯一展示面;原「HP/攻击/RAP 显示」——HP 与 RAP 随信息归属拍板迁出本组件) | 只读 | HUD 视图拆分 |
|
||||
| C | 秘宝槽 | 图标槽 ×4 | 四槽壳在役、空槽占位(标题「秘宝」,悬停「秘宝槽(空)」);局内两步使用与关卡域库存随秘宝过渡形态退役——现行秘宝 = 营地同调装配件(秘宝.md),本区展示重接归装配面批次 | 悬停 tooltip | 已实装 |
|
||||
| C | 奇物列表(现行标题「特性」) | 列表/图标行 | 已实装(迭代 9 卡⑫ 接线、迭代 12 呈现补齐;2026-10-12 呈现修复批整改——逐件行「件名 ×N」,零内部分类字样);锻造/大奖励/关卡奖励节点获得的属性提升——中循环数据,因改变战斗数学且无其他展示面准入战斗屏;与战斗内状态效果(B 区站桩)分区,防「战斗结束被清」误读 | 只读 | 已实装 |
|
||||
| D | AP 条 | 点阵 + 按钮组 | 本轮 AP 点阵、停手按钮(左)、**RAP 点阵+数字(自 C 区迁入 2026-09-26——RAP 唯一消费口 = 弃图刷新,资源数字贴消费按钮;RAP 清零可见反馈〔行动经济〕载体随迁)**、弃图刷新按钮(右端·雷图右上角;RAP−8 · 本轮剩 N 次——上限 2 次已随行动经济 2026-09-12 修订生效) | 点击提交意图 | HUD 视图拆分 |
|
||||
| D | 棋盘视图 | 网格 | 棋盘全部格态 + 小人 + 封印印记 + 变异纹带 + 奖励身份 icon(已开格;绘制优先级 数字>小人>封印印记>奖励徽章>变异纹带>底色——徽章不进数字区,样张验收项) | 左/右键意图提交 | ✅ 已实装 |
|
||||
| B | 结算明细带 | 滚动列表 | 结算期逐行流水([战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋) 9 类行协议);挖掘期收起为上轮摘要 1 行 | 点击展开明细回看 overlay(2026-10-04 P-C7 退役——带保留单行摘要,回看归「生涯」) | battle_log_view.gd 改造 |
|
||||
| B | ~~结算明细回看~~(已退役) | —— | 2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——settlement_review_overlay.gd 为未接线遗留件(待办清单登记) | —— | —— |
|
||||
| C | 攻击数据框 | 直角细线数据框 | 攻击值 + 修正来源角标 + 护甲 AC(AC 二轮拍板 2026-09-26 补入——我方 AC 唯一展示面;原「HP/攻击/RAP 显示」——HP 与 RAP 随信息归属拍板迁出本组件) | 只读 | HUDView 拆分 |
|
||||
| C | 秘宝槽 | 图标槽 ×4 | 四槽壳在役、空槽占位(标题「秘宝」,悬停「秘宝槽(空)」);局内两步使用与关卡域库存随秘宝过渡形态退役——现行秘宝 = 营地同调装配件(秘宝.md),本区展示重接归装配面批次 | 悬停 tooltip | hero_info_panel_view.gd |
|
||||
| C | 奇物列表(现行标题「特性」) | 列表/图标行 | 已实装(迭代 9 卡⑫ 接线、迭代 12 呈现补齐;2026-10-12 呈现修复批整改——逐件行「件名 ×N」,零内部分类字样);锻造/大奖励/关卡奖励节点获得的属性提升——中循环数据,因改变战斗数学且无其他展示面准入战斗屏;与战斗内状态效果(B 区站桩)分区,防「战斗结束被清」误读 | 只读 | hero_info_panel_view.gd |
|
||||
| D | AP 条 | 点阵 + 按钮组 | 本轮 AP 点阵、停手按钮(左)、**RAP 点阵+数字(自 C 区迁入 2026-09-26——RAP 唯一消费口 = 弃图刷新,资源数字贴消费按钮;RAP 清零可见反馈〔行动经济〕载体随迁)**、弃图刷新按钮(右端·雷图右上角;RAP−8 · 本轮剩 N 次——上限 2 次已随行动经济 2026-09-12 修订生效) | 点击提交意图 | HUDView 拆分 |
|
||||
| D | BoardView | 网格 | 棋盘全部格态 + 小人 + 封印印记 + 变异纹带 + 奖励身份 icon(已开格;绘制优先级 数字>小人>封印印记>奖励徽章>变异纹带>底色——徽章不进数字区,样张验收项) | 左/右键意图提交 | ✅ board_view.gd 迁移 |
|
||||
| D | 悬停预承诺光标 | 光标态 | 移动/挖/封印三语义光标 + 目标格边框高亮 | 自动 | 新建(排雷玩法×6③) |
|
||||
| D | 可挖域指示 | 常驻微高亮 | 小人 8 向相邻可操作格 | 自动 | 新建(排雷玩法×6③) |
|
||||
| D | 移动路径预览 | 路径高亮 | 悬停已开格显示 BFS 路径(合法性指示) | 自动 | 新建(排雷玩法×6⑤,裁决见下) |
|
||||
| D | toast 槽 | 非模态提示 | 拒绝原因(双源)、voided、满层溢出、chord 提示、零合法板告知 | 自动消退 2.5s | 新建 |
|
||||
| D | 图例按钮 + 面板 | 按钮+模态 overlay | 格态/变异语义图例 | 开/关 | 新建 |
|
||||
| 全屏 | 胜利/失败 overlay | 模态 | 金蜡封/暮蓝收印 + 判定行(明细回看入口已随 P-C7 退役——回看归「生涯」) | 继续/下一节点 | 已实装 |
|
||||
| 调试 | 调试浮窗 | 调试面板 | 种子/数值调整/批量模拟/两层调试入口(发布态恒隐,无 UI 开启口——写死行已随迭代 38 卡⑦ 删除,调试开关门控口径见「调试变体」行;调参面板已随迭代 15 卡①吸收退役) | 调试 | 调试浮窗 |
|
||||
| 全屏 | 胜利/失败 overlay | 模态 | 金蜡封/暮蓝收印 + 判定行(明细回看入口已随 P-C7 退役——回看归「生涯」) | 继续/下一节点 | battle_end_overlay.gd |
|
||||
| 调试 | 调试浮窗 | 调试面板 | 种子/数值调整/批量模拟/两层调试入口(发布态恒隐,无 UI 开启口——写死行已随迭代 38 卡⑦ 删除,DS_DEBUG 门控口径见「调试变体」行;TunePanel 已随迭代 15 卡①吸收退役) | 调试 | debug_overlay.gd |
|
||||
|
||||
**布局决策 2 —(已删除,编号留空)**:原「窗口形态 = 右栏原位激活」决策随可选类道具整体下线(2026-09-15 格面资源批)。编号留空,免布局决策 3/4 的既有交叉引用失锚。
|
||||
|
||||
@@ -179,10 +179,10 @@
|
||||
- 备选(登记不采纳):穿行动画轨道——移动免费高频,动画时间税违反 P4 点击摩擦护栏(每轮输入动作:AP ≤2 的观测假设);正式版若 playtest 反馈"移动太瞬"再议(留痕)
|
||||
|
||||
**布局决策 4 — 弃图刷新 = 挖掘期当场换图(2026-09-12 用户拍板,同日落稿上游)**:按钮置 AP 条右端(雷图右上角)。点击即当轮就地换新图继续挖——AP 不重置、剩余 AP 保留,RAP−8,本轮上限 2 次。
|
||||
- **上游修订(2026-09-12 已落稿,OQ11)**:① 行动经济 Active 相位受理刷新意图 + 每轮上限 2 次(Waiting 代理退役)② 排雷玩法装板受理域增 Active·仅刷新路径 ③ 编排 owner = **战斗结算的挖掘期刷新编排**(行动经济扣费 → 排雷玩法退役旧板 → 棋盘生成出新图 → 排雷玩法装板 → 地图战斗资源摇奖励恰一次;无结算段、无轮次结束——战斗结算编排唯一性原则保持)④ 旧板封印印记随旧板**作废**(零兑付、封印 AP 不返还——排雷玩法 EC11 全量重置承载;确认微交互须显式提示)。**经济预警**:当场刷新无结算发生,原「敌方时间税」自惩失效——行动经济 OQ3 弃图率/刷新率预警阈值联动复核。
|
||||
- **上游修订(2026-09-12 已落稿,OQ11)**:① 行动经济 `request_refresh` Active 相位受理 + 每轮上限 2 次(Waiting 代理退役)② 排雷玩法装板受理域增 Active·仅刷新路径 ③ 编排 owner = **战斗结算 `refresh_board`**(行动经济扣费 → 排雷玩法 retire → 棋盘生成 generate → 排雷玩法 install → 地图战斗资源 roll_board 恰一次;无结算段、无 round_end——战斗结算编排唯一性原则保持)④ 旧板封印印记随旧板**作废**(零兑付、封印 AP 不返还——排雷玩法 EC11 全量重置承载;确认微交互须显式提示)。**经济预警**:当场刷新无结算发生,原「敌方时间税」自惩失效——行动经济 OQ3 弃图率/刷新率预警阈值联动复核。
|
||||
- 备选(已否决):结算期决策提示(Waiting 内联)——结算期不做刷新决策(用户拍板);挖掘期预承诺 stop+reroll 复合——决策即终轮,不符「换图继续挖」语义。
|
||||
|
||||
**敌人意图线索映射目录(敌人系统×4① 成文占位,2026-09-12;2026-09-16 敌人技能池批改型注记:行为环三态〔攻击/蓄力/重击〕预告随行为环退役——现行数据面 = 敌人系统三档可见性规格〔普攻零表示 / 特殊技类型级动画〔攻击系/增益系两型〕/ 暴击掷点层无前置〕,池与权重不公开;下表 grub/ambusher 三态清单留档作废,终稿资产目录随战斗表现样张批重立;**命名双轨完成注记 2026-10-06**:grub/ambusher 两键本身已随敌人系统八型批退役——现行键集 = 八敌登记表〔goblin/bugbear/ogre_chief/giant_spider/drider/duergar/hook_horror/duergar_king〕,本表键名仅为历史留痕、禁止作为现行敌种 id 引用)**:
|
||||
**敌人意图线索映射目录(敌人系统×4① 成文占位,2026-09-12;2026-09-16 敌人技能池批改型注记:行为环三态〔攻击/蓄力/重击〕预告随行为环退役——现行数据面 = 敌人系统三档可见性规格〔普攻零表示 / 特殊技类型级动画〔攻击系/增益系两型〕/ 暴击掷点层无前置〕,池与权重不公开;下表 grub/ambusher 三态清单留档作废,终稿资产目录随战斗表现样张批重立;**命名双轨完成注记 2026-10-06**:grub/ambusher 两键本身已随敌人系统八型批退役——现行键集 = 八敌 registry〔goblin/bugbear/ogre_chief/giant_spider/drider/duergar/hook_horror/duergar_king〕,本表键名仅为历史留痕、禁止作为现行 enemy_id 引用)**:
|
||||
|
||||
| enemy_id | 视觉状态(意图线索) | 强度档位编码 | 环长编码 |
|
||||
|---|---|---|---|
|
||||
@@ -235,16 +235,16 @@
|
||||
| **结算阶段** | round_end 触发(AP 尽/停手/清图) | D 区锁输入(棋盘去饱和 + 金橙色相偏移,明度不变,数字保持全对比);B 区播放五段编排演出(授予段 → 增益/减益段 → 战斗段 → 衰减段 → 判定段,战斗结算 段序冻结);明细带展开 84px 逐行滚动;阶段指示→"结算中";能量 7/10 |
|
||||
| **清图瞬间** | 全部安全格开完 | 金粒喷泉 + 彩纸 3–5s 即收(§2.3);清图奖励行强调呈现(H2,地图战斗资源×④——金框高亮行);随后换新图 install |
|
||||
| **完美封印高光** | 战斗结算高光判定(全图标中/零误标类) | 全屏喝彩级反馈(§2.2 最高档):金光带加倍扫射 + 「完美封印 ×2」横幅——P2 爆发兑现节点(创意风险 #2 落点) |
|
||||
| **封印标中高光** | 封印判定·标中 | 该印记化暴击弹道加重 + 明细行金框——chord 缺席的即时兑现补偿(创意风险 #3 落点) |
|
||||
| **封印标中高光** | flag_judged{hit=true} | 该印记化暴击弹道加重 + 明细行金框——chord 缺席的即时兑现补偿(创意风险 #3 落点) |
|
||||
| **敌人死亡呈现** | 敌 hp=0(流水行击杀标记) | 该敌人立绘血条归零 → 立绘灰化 + 碎裂退场(**禁瞬消**——敌人系统资产下限「死亡瞬间须可辨识、禁止直接消失」,同等 blocking);战斗段短路的重击被掐灭不产行动明细行,由行序可推断(战斗结算);动画密度归战斗表现,呈现语义在本 spec |
|
||||
| **胜利终局** | 判定胜利 | 金蜡封落于**扫雷图区中央**(§2.4 字面锚定),全屏暖白金 overlay;判定行 + 「下一节点」;明细回看入口;状态图标行全清可见反馈(增益状态×4④——B 区主角站桩图标逐枚化光收回 + 微文案「状态随战斗结束消散」,防「我的增益哪去了」误读) |
|
||||
| **失败终局** | 判定失败(主角生命归零,战斗段短路) | 明度不变的暮蓝 #5A6C8C 氛围 overlay(全作唯一暮蓝档);小人坐砖掸灰、落下的封印印记逐枚化光点收回(§2.5);判定行 +「返回」(明细回看已随 P-C7 退役——回看归「生涯」);状态图标行全清可见反馈(增益状态×4④,同胜利) |
|
||||
| **胜利终局** | verdict=win | 金蜡封落于**扫雷图区中央**(§2.4 字面锚定),全屏暖白金 overlay;判定行 + 「下一节点」;明细回看入口;状态图标行全清可见反馈(增益状态×4④——B 区主角站桩图标逐枚化光收回 + 微文案「状态随战斗结束消散」,防「我的增益哪去了」误读) |
|
||||
| **失败终局** | verdict=lose(hero hp=0,战斗段短路) | 明度不变的暮蓝 #5A6C8C 氛围 overlay(全作唯一暮蓝档);小人坐砖掸灰、落下的封印印记逐枚化光点收回(§2.5);判定行 +「返回」(明细回看已随 P-C7 退役——回看归「生涯」);状态图标行全清可见反馈(增益状态×4④,同胜利) |
|
||||
| **Boss 遭遇变体** | encounter=boss(遗迹守卫) | 战斗开始一次性演出:紫赤 #8F2F6A 影子爬过棋盘(§2.6);敌人立绘体量最大+锐角剪影;阶段指示附 Boss 名 |
|
||||
| **空态:无状态效果** | 增益状态 EC12 | 状态小图标行隐藏(B 区主角站桩血条下图标行零图标时不占位;落底排〔2026-10-06 方案二〕后该行退化为名字行——主角无名字行则整行空置);原「C 区状态槽隐藏、HP/攻击/RAP 上移补位」裁决随 C 区槽退役(2026-09-26 信息归属拍板)作废;图例面板载空态说明(增益状态×① 成文项) |
|
||||
| **调试变体** | 测试模式 | 调试浮窗入口发布态恒隐(调试入口开关为写死行、已删,无 UI 开启口;开发期临时启用=本地改该字段缺省、不提交——调参面板已随迭代 15 卡①退役);Playtest 诊断按钮(卡死转储) |
|
||||
| **调试变体** | 测试模式 | 调试浮窗入口发布态恒隐(`_debug_entry` 写死行已删,无 UI 开启口;开发期临时启用=本地改该字段缺省、不提交——TunePanel 已随迭代 15 卡①退役);Playtest 诊断按钮(卡死转储) |
|
||||
|
||||
**拒绝/作废子态**(排雷玩法×6⑥、行动经济双源——每次拒绝玩家可感知):
|
||||
- 棋盘面拒绝(细分原因:非相邻/挖封印格等)→ 目标格 危险红 #A8321F 边框闪 + toast 文案(拒绝语义红族——旗朱已退役归封印色〔现行封印黑〕)(图标+文案冗余,色弱清单 #7)
|
||||
- 棋盘面拒绝(sub_reason:非相邻/挖封印格等)→ 目标格 危险红 #A8321F 边框闪 + toast 文案(拒绝语义红族——旗朱已退役归封印色〔现行封印黑〕)(图标+文案冗余,色弱清单 #7)
|
||||
- 资源面拒绝(AP 不足/RAP 不足)→ AP/RAP 数字脉冲 + toast「AP 不足 · 剩 0 点」
|
||||
- voided(stop 被作废等)→ toast「本轮已清图,停手未执行 · 剩余 AP 已作废」——防静默改判读感欺骗
|
||||
|
||||
@@ -256,15 +256,15 @@
|
||||
|
||||
| 组件 | 动作 | 输入 | 即时反馈 | 结果(经组合根) |
|
||||
|---|---|---|---|---|
|
||||
| 未开相邻格 | 挖掘 | 左键 | 格碎裂 + 连锁展开(免费)+ 奖励身份揭显 | 意图入当帧批次 → 排雷玩法的意图批次提交 |
|
||||
| 未开相邻格 | 挖掘 | 左键 | 格碎裂 + 连锁展开(免费)+ 奖励身份揭显 | 意图入当帧批次 → 排雷玩法 `settle_batch` |
|
||||
| 已开格 | 移动 | 左键 | 悬停时路径预览高亮(布局决策 3);执行 ≤150ms 短滑 | 意图入批(BFS 移动,免费) |
|
||||
| 未开格 | 封印 | 右键 | 封印印记落下(封印黑) | 意图入批(1 AP / 免费;已封印格右键无操作——封印印记无移除手段,封印不可逆批 2026-09-19) |
|
||||
| 停手按钮 | 主动结束轮次 | 左键 | 按钮下压 + AP→RAP 飞行数字 | 停手随当帧意图批次提交(**经排雷玩法批次,不直调行动经济**——单意图帧批次契约) |
|
||||
| 弃图刷新按钮(雷图右上角) | 当轮就地换图继续挖 | 左键 | 确认微交互(RAP−8 代价显式 + 旧板弃置提示);RAP<8 → 资源面拒绝可见(行动经济 EC13) | 刷新意图提交(**Active 相位当场换图继续挖**——AP 不重置、本轮剩 N 次扣减;**上游已修订受理——见布局决策 4/OQ11**) |
|
||||
| 停手按钮 | 主动结束轮次 | 左键 | 按钮下压 + AP→RAP 飞行数字 | `settle_batch([stop])`(**经排雷玩法批次,不直调行动经济**——单意图帧批次契约) |
|
||||
| 弃图刷新按钮(雷图右上角) | 当轮就地换图继续挖 | 左键 | 确认微交互(RAP−8 代价显式 + 旧板弃置提示);RAP<8 → 资源面拒绝可见(行动经济 EC13) | `request_refresh`(**Active 相位当场换图继续挖**——AP 不重置、本轮剩 N 次扣减;**上游已修订受理——见布局决策 4/OQ11**) |
|
||||
| 图例按钮 | 开图例 | 左键 | 模态 overlay | 恒可开(图例条目恒在) |
|
||||
| 结算明细带 | ~~展开回看~~(已随 P-C7 退役——带保留单行摘要,回看归「生涯」) | —— | —— | —— |
|
||||
| 状态小图标(B 区站桩) | 悬停 | hover | 状态 tooltip(来源+语义+剩余结算次数) | 只读 |
|
||||
| 胜利 overlay | 下一节点 | 左键 | → 关卡画面(选路枢纽)/ 关卡结算(末节点) | 关卡推进方推进 |
|
||||
| 胜利 overlay | 下一节点 | 左键 | → 关卡画面(选路枢纽)/ 关卡结算(末节点) | LevelRunner 推进 |
|
||||
| 失败 overlay | 返回 | 左键 | → 存档/营地 | 冒险落幕 |
|
||||
|
||||
**单意图帧纪律**(排雷玩法×6⑥):一帧内 collected 意图整批提交,stop 点击终结当帧收集;F4 语义序仲裁为防御性兜底。悬停预承诺三态光标:移动(箭头)/挖(镐)/封印(印记形)——左键双义(移动 vs 挖)的消歧完全依赖格态一瞥可辨 + 光标区分(误挖不可逆的感知保险)。
|
||||
@@ -279,18 +279,18 @@
|
||||
|
||||
## Events Fired
|
||||
|
||||
项目无分析系统;本节 = **呈现层订阅的核心信号**(组合根直连信号)+ 逐局遥测义务(逐局遥测日志已有五类行)。呈现层新遥测(写入逐局遥测的呈现层行):
|
||||
项目无分析系统;本节 = **呈现层订阅的核心信号**(组合根直连 signal)+ playtest 遥测义务(playtest_logger.gd 已有五类行)。呈现层新遥测(写 playtest JSONL `ux` 行):
|
||||
|
||||
| 事件(中文名) | 采集内容 | 载荷 / 数据 |
|
||||
| Player Action | Event Fired | Payload / Data |
|
||||
|---|---|---|
|
||||
| 每轮结束 · 轮次输入比遥测 | 原始输入动作数∶AP 消耗(行动经济 P4 ≤2 护栏观测,排雷玩法遥测义务) | —— |
|
||||
| 停手/清图 · 轮次出口遥测 | 弃图率(难度曲线与Boss OQ4)观测;出口路径对齐上游封闭枚举 | 出口路径标签 {停手 / AP 耗尽 / 清图} |
|
||||
| 弃图刷新(挖掘期,非轮出口) · 刷新尝试遥测 | 刷新使用(难度曲线与Boss OQ6)与行动经济 OQ3 预警阈值观测;每轮 0–2 次(布局决策 4 cap=2) | {受理结果: 受理 / 拒因 RAP 不足 / 拒因触上限, 本轮第几次刷新: 1..2} |
|
||||
| 拒绝/voided · 拒绝遥测 | 拒绝来源(板面/资源/相位三源)与细分原因 | {拒绝来源: 板面/资源/相位, 细分原因} |
|
||||
| 提示触发/关闭 · 提示展示遥测 | 提示类型 | {提示类型: chord 提示 / 无相邻可挖格} |
|
||||
| 呈现订阅(不改核心) | 排雷玩法三事件 / [战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行协议,含终局判定行) / 战斗结束 / 关卡完成 | 载荷 schema 成文义务见 §Data Requirements——旧版状态记录 entry 17①(HUD框架硬性要求) |
|
||||
| 每轮结束 | `ux_round_input_ratio` | 原始输入动作数∶AP 消耗(行动经济 P4 ≤2 护栏观测,排雷玩法遥测义务) |
|
||||
| 停手/清图 | `ux_round_exit` | path_tag {stopped, ap_exhausted, cleared}(对齐上游封闭枚举)——弃图率(难度曲线与Boss OQ4)观测 |
|
||||
| 弃图刷新(挖掘期,非轮出口) | `ux_refresh_attempt` | {result: accepted/rejected_rap/rejected_cap, round_refresh_index: 1..2}——刷新使用(难度曲线与Boss OQ6)与行动经济 OQ3 预警阈值观测;每轮 0–2 次(布局决策 4 cap=2) |
|
||||
| 拒绝/voided | `ux_reject` | {source: board/resource/phase, sub_reason} |
|
||||
| 提示触发/关闭 | `ux_hint_shown` | {hint_id: chord/no_adjacent} |
|
||||
| 呈现订阅(不改核心) | 排雷玩法三事件 / [战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行协议,含终局判定行) / battle_over / level_clear | 载荷 schema 成文义务见 §Data Requirements——旧版状态记录 entry 17①(HUD框架硬性要求) |
|
||||
|
||||
**持久状态写入**全部经组合根唯一路径(意图批次提交 / 刷新意图提交 / 关卡推进)——UI 层禁直调核心写(架构七原则"依赖单向组合根")。
|
||||
**持久状态写入**全部经组合根唯一路径(settle_batch / request_refresh / runner 推进)——UI 层禁直调核心写(架构七原则"依赖单向组合根")。
|
||||
|
||||
---
|
||||
|
||||
@@ -302,13 +302,13 @@
|
||||
| 挖掘→结算 | 明细带自底展开(150ms)+ 棋盘去饱和 + 金橙色相偏移 + 阶段指示翻转 | §2.2 色彩转金橙主导、饱和拉高、明度不变(状态区分经饱和/色相——art-bible §2 合规化 2026-09-12) |
|
||||
| 结算逐行兑现 | 光带自棋盘行起点横扫 → 开格化箭雨/印记化暴击弹道飞向敌人立绘 → 受击闪白 + 血条直角递减 | §2.2 承载元素;因果全程可见可归因(P2) |
|
||||
| 清图换新图 | 金粒喷泉 3–5s → 旧图碎裂淡出 → 新图 install 淡入 | §2.3 短促丰收不拖节奏 |
|
||||
| RAP 清零(战斗结束) | RAP 数字滚动归零(D 区 AP 条)+ 「随战斗结束消散」微文案 | 行动经济可见反馈义务 |
|
||||
| RAP 清零(battle_over) | RAP 数字滚动归零(D 区 AP 条)+ 「随战斗结束消散」微文案 | 行动经济可见反馈义务 |
|
||||
| 敌人死亡 | 血条直角递减至零 → 卡体灰化 + 碎裂退场(禁瞬消) | 敌人系统资产下限(同等 blocking);动画密度归战斗表现 |
|
||||
| 状态图标行全清(战斗结束) | 状态逐枚化光收回(B 区站桩图标行)+ 「状态随战斗结束消散」微文案 | 增益状态×4④;RAP 清零同款先例 |
|
||||
| 状态图标行全清(battle_over) | 状态逐枚化光收回(B 区站桩图标行)+ 「状态随战斗结束消散」微文案 | 增益状态×4④;RAP 清零同款先例 |
|
||||
| ~~关卡收束清库~~ | 义务随秘宝过渡形态退役消解——现行形态 = 营地同调装配、整局冒险生效,无关卡域清库面(秘宝.md) | —— |
|
||||
| 胜利 | 蜡封自上落下弹跳定格 → 碎砖拼纹章 → overlay 暖金渐显 | §2.4 克制不狂欢 |
|
||||
| 失败 | 全屏明度不变转暮蓝色相 → 印记化光点 800ms 逐枚收回 → overlay | §2.5 最静一拍 |
|
||||
| 减动效选项 | 上述全部动画提供时长减半/直接跳终态开关(基线权威 = HUD框架「可访问性基线」节;开关承载 = 设置面(迭代 8 卡④已转正)——2026-09-27 拍板不另立无障碍专项文档) | 动议:结算逐行兑现为信息载体不可整体跳过,可加速 |
|
||||
| 减动效选项 | 上述全部动画提供时长减半/直接跳终态开关(基线权威 = HUD框架「可访问性基线」节;开关承载 = 设置面(迭代 8 卡④已转正,settings_overlay)——2026-09-27 拍板不另立无障碍专项文档) | 动议:结算逐行兑现为信息载体不可整体跳过,可加速 |
|
||||
|
||||
---
|
||||
|
||||
@@ -316,24 +316,24 @@
|
||||
|
||||
| Data | Source System | Read / Write | Notes |
|
||||
|---|---|---|---|
|
||||
| 棋盘格态/数字/可挖域 | 排雷玩法 只读查询面 | Read | 呈现刷新面 = 排雷玩法 三事件信号(载荷 schema 成文——旧版状态记录 entry 17①) |
|
||||
| BFS 移动路径 | 排雷玩法 路径规划只读面 | Read | 布局决策 3 合法性指示消费 |
|
||||
| 拒绝原因 | 排雷玩法 细分原因封闭枚举 + 行动经济 资源面 | Read | 三源(板面/资源/相位)映射文案——呈现层契约成文;资源面原因无上游载荷(行动经济仅回受理与否,细分原因仅调试诊断可见),客户端按动作上下文推断 |
|
||||
| AP / RAP / 本轮刷新计数 | 行动经济 | Read | 常显;刷新入口可用性 = RAP 读数客户端预判(RAP≥8)+ 刷新意图提交的受理回执(行动经济 无刷新可用性预查询——仅受理与否的回执 + 只读观测量;行动经济 EC13 拒绝合法可见) |
|
||||
| 棋盘格态/数字/可挖域 | 排雷玩法 只读面(query) | Read | 呈现刷新面 = 排雷玩法 三事件信号(载荷 schema 成文——旧版状态记录 entry 17①) |
|
||||
| BFS 移动路径 | 排雷玩法 `compute_move_path` | Read | 布局决策 3 合法性指示消费 |
|
||||
| 拒绝原因 | 排雷玩法 `sub_reason` 封闭枚举 + 行动经济 资源面 | Read | 三源(board/resource/phase)映射文案——呈现层契约成文;资源面原因无上游载荷(行动经济 仅 bool + debug 诊断),客户端按动作上下文推断 |
|
||||
| AP / RAP / 本轮刷新计数 | 行动经济 | Read | 常显;刷新入口可用性 = RAP 读数客户端预判(RAP≥8)+ `request_refresh` 返回值(行动经济 无 `can_request_refresh` API——仅 bool 返回 + 只读观测量;行动经济 EC13 拒绝合法可见) |
|
||||
| 结算流水行(9 类封闭协议) | [战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋) 流水协议 | Read | 逐行来源标注(P2);未生效类行(奖励未生效)聚合计数呈现 |
|
||||
| 判定胜负 | 战斗结算 判定段 | Read | 终局画面数据锚 |
|
||||
| 敌单位 生命/顺位/摇定动作(技能标识·类型·名称)/敌方增益/敌单位标识/存活 | 敌人系统 只读面(经战斗结算呈现快照) | Read | 意图线索映射全局恒定(敌人系统×4②,技能池批三档口径);**销毁前捕获**(旧版状态记录 entry 17③——缺陷②教训) |
|
||||
| 状态效果投影(含空态/极性/溢出) | 增益状态 投影口径 | Read | 极性映射数据源 = 战斗结算效果表语义,非幅度符号(增益状态×③) |
|
||||
| 已开格奖励身份(奖励徽章) | 地图战斗资源 身份解析只读回调(经棋盘视图,组合根注入) | Read | 已开格身份常读——挖掘期 Active 相位内有效;reward_id 全局恒定、禁止重掷;徽章绘制优先级见 §Component Inventory 棋盘视图行 |
|
||||
| 节点图/当前节点/HP 携带 | 关卡节点地图轻量读面 · 关卡推进方 | Read | 关卡画面(独立屏)节点态呈现(战斗屏零进度承载) |
|
||||
| 意图提交 | 排雷玩法 | **Write** | 意图批次提交(stop 亦经此——不直调行动经济) |
|
||||
| 弃图刷新 | 行动经济 | **Write** | 刷新意图提交(挖掘期 Active 当场受理——布局决策 4 2026-09-12 上游已落稿;战斗结算的挖掘期刷新编排承载) |
|
||||
| 节点推进 | 关卡推进方 | **Write** | 胜利 overlay「下一节点」 |
|
||||
| 终局画面数据锚 | 战斗结算 判定行(流水行协议) | Read | 「终局判定行 = 胜负画面的数据锚」(战斗结算 UI Requirements);销毁前状态可见性纪律 = 旧版状态记录 entry 17③(销毁前捕获、**载荷数据自包含**、禁呈现层回读核心生命周期状态);若需独立终局快照信号,须回战斗结算 GDD 修订补登记(战斗结算 现无结算快照契约——2026-09-12 评审修正) |
|
||||
| 判定 verdict | 战斗结算 判定段 | Read | 终局画面数据锚 |
|
||||
| 敌单位 hp/顺位/摇定动作(pending_skill/type/name)/敌方增益/enemy_id/存活 | 敌人系统 只读面(经战斗结算呈现快照) | Read | 意图线索映射全局恒定(敌人系统×4②,技能池批三档口径);**despawn 前捕获**(旧版状态记录 entry 17③——缺陷②教训) |
|
||||
| 状态效果投影(含空态/极性/溢出) | 增益状态 投影口径 | Read | 极性映射数据源 = 战斗结算 SettlementTable 效果语义,非 magnitude 符号(增益状态×③) |
|
||||
| 已开格奖励身份(奖励徽章) | 地图战斗资源 `query_identity`(经 board_view 身份解析只读回调,组合根注入) | Read | 已开格身份常读——挖掘期 Active 相位内有效;reward_id 全局恒定、禁止重掷;徽章绘制优先级见 §Component Inventory BoardView 行 |
|
||||
| 节点图/当前节点/HP 携带 | 关卡节点地图 lite · LevelRunner | Read | 关卡画面(独立屏)节点态呈现(战斗屏零进度承载) |
|
||||
| 意图提交 | 排雷玩法 | **Write** | `settle_batch`(stop 亦经此——不直调行动经济) |
|
||||
| 弃图刷新 | 行动经济 | **Write** | `request_refresh`(挖掘期 Active 当场受理——布局决策 4 2026-09-12 上游已落稿;战斗结算 `refresh_board` 编排承载) |
|
||||
| 节点推进 | LevelRunner | **Write** | 胜利 overlay「下一节点」 |
|
||||
| 终局画面数据锚 | 战斗结算 判定行(流水行协议) | Read | 「终局判定行 = 胜负画面的数据锚」(战斗结算 UI Requirements);despawn 前状态可见性纪律 = 旧版状态记录 entry 17③(销毁前捕获、**载荷数据自包含**、禁呈现层回读核心生命周期状态);若需独立终局快照信号,须回战斗结算 GDD 修订补登记(战斗结算 现无 `settlement_snapshot` 契约——2026-09-12 评审修正) |
|
||||
|
||||
**架构注记**:UI 不拥有任何游戏状态——全部读经核心只读面,全部写经组合根。呈现层信号载荷 schema 须在《HUD框架》成文(旧版状态记录 entry 17①,缺项即 blocking);场景级 headless 测试进 AC(entry 17②);覆盖层层级断言(缺陷⑤——任何模态覆盖层必须有"打开时遮挡物隐藏"断言)。
|
||||
|
||||
**更新触发注记(2026-09-12 评审增补——防实现层等待不存在的信号,旧版状态记录 entry 17 教训同类)**:封印与移动成功反馈**零事件外发**(排雷玩法发射面封闭)——经意图调用的返回值命令式驱动;AP/RAP 读数:行动经济无推送信号——组合根每次调用返回后重查;状态效果:增益状态为纯被动状态池、零信号——状态栏刷新绑战斗结算的编排完成时点;奖励徽章:地图战斗资源 身份解析经只读回调(组合根注入棋盘视图),已开格揭显时查询——写路径回执后重查。
|
||||
**更新触发注记(2026-09-12 评审增补——防实现层等待不存在的信号,旧版状态记录 entry 17 教训同类)**:封印与移动成功反馈**零事件外发**(排雷玩法发射面封闭)——经意图调用 `ActionOutcome` 返回值命令式驱动;AP/RAP 读数:行动经济无推送信号——组合根每次调用返回后重查;状态效果:增益状态为纯被动状态池、零信号——状态栏刷新绑战斗结算的编排完成时点;奖励徽章:地图战斗资源 身份解析经 `query_identity` 只读回调(组合根注入 board_view),已开格揭显时查询——写路径回执后重查。
|
||||
|
||||
---
|
||||
|
||||
@@ -355,7 +355,7 @@
|
||||
|
||||
- **源语言中文(CJK)**:运行时默认字体无 CJK 字形——**CJK 字体随包为硬性前置**(已锁),实现 AC 覆盖
|
||||
- **按钮文案单行约束**:「停手」「弃图刷新」——按钮宽度按 4 汉字上限设计;译为英文("Hold"/"Reroll")不超 1.6× 不破版;德语长词("Aufgeben+Neu"类复合词)风险 HIGH——弃图刷新按钮允许两行或图标+缩写
|
||||
- **明细带行文案**:来源标注格式「{行为} {值} → {目标}(来源)」为模板插值,最长 token = 来源标签(4 汉字,如「清图奖励」「封印未中」——战斗结算的来源标签封闭枚举);行模板预留 40% 膨胀宽度(固定槽高 + 裁剪兜底)
|
||||
- **明细带行文案**:来源标注格式「{行为} {值} → {目标}(来源)」为模板插值,最长 token = 来源标签(4 汉字,如「清图奖励」「封印未中」——settlement source_label_map 封闭枚举);行模板预留 40% 膨胀宽度(固定槽高 + clip 兜底)
|
||||
- **数字格式**:全部整数,无本地化格式需求;AP 点阵为图形载体不依赖文本
|
||||
- **术语表锚定**:封印/雷/停手/弃图刷新/轮次/结算 已在 GDD 体系内定名,译文须同步 `design/gdd/术语表.md`
|
||||
|
||||
@@ -374,11 +374,11 @@
|
||||
|
||||
**交互与反馈**
|
||||
|
||||
- [ ] 挖/移/封印/停手/刷新全部操作纯鼠标可完成;stop 意图经意图批次提交(代码走查 + 探针断言)
|
||||
- [ ] 挖/移/封印/停手/刷新全部操作纯鼠标可完成;stop 意图经 `settle_batch` 提交(代码走查 + 探针断言)
|
||||
- [ ] 每次拒绝(棋盘面/资源面/相位)玩家可感知且两源可区分;voided(至少 stop 作废)可感知(排雷玩法×6⑥、行动经济双源)
|
||||
- [ ] 弃图刷新消耗 RAP 8 点、本轮上限 2 次可见(按钮文案实时「剩 N 次」;上限已随行动经济 2026-09-12 修订生效);RAP<8 资源面拒绝可见(行动经济 EC13);确认交互与常规确认不同位;换图后 AP 不重置、剩余次数扣减可见(**上游已修订受理——2026-09-12 布局决策 4 落稿**)
|
||||
- [ ] 战斗结束时 RAP 清零有可见反馈(行动经济);~~关卡收束清库反馈~~(义务随秘宝过渡形态退役消解——现行 = 营地同调装配整局生效,秘宝.md)
|
||||
- [ ] 战斗结束时状态图标行全清有可见反馈(B 区站桩逐枚化光 + 微文案)(增益状态×④)
|
||||
- [ ] battle_over 时 RAP 清零有可见反馈(行动经济);~~关卡收束清库反馈~~(义务随秘宝过渡形态退役消解——现行 = 营地同调装配整局生效,秘宝.md)
|
||||
- [ ] battle_over 时状态图标行全清有可见反馈(B 区站桩逐枚化光 + 微文案)(增益状态×④)
|
||||
- [ ] 敌人死亡瞬间可辨识(卡体灰化 + 碎裂退场,禁瞬消);战斗段短路被掐灭的重击由行序可推断(敌人系统资产下限)
|
||||
|
||||
**信息与归因**
|
||||
@@ -388,17 +388,17 @@
|
||||
- [ ] 状态效果:极性呈现映射成文且非 magnitude 符号;空态渲染成文(裁决:图标行隐藏——B 区站桩血条下零图标时不占位);满层溢出经明细行可见(增益状态×①③④)
|
||||
- [ ] 图例面板条目恒在可随时回看、非模态提示不劫持输入
|
||||
- [ ] 零合法板(棋盘生成 EC5 降级)出现时玩家侧诚实提示(toast,非静默)
|
||||
- [ ] 效果行数值为单次贡献值,禁止与池合成值相加呈现;零值伤害行可见不被吞;衰减行按聚合计数呈现(战斗结算 呈现细则)
|
||||
- [ ] 效果行 value 为单次贡献值,禁止与 pool_value(池合成值)相加呈现;零值伤害行可见不被吞;衰减行按聚合计数呈现(战斗结算 呈现细则)
|
||||
- [ ] 未生效类行(奖励未生效)携带形状冗余(icon/划线),非色相独载
|
||||
- [ ] 奖励徽章绘制优先级:封印印记之下、变异纹带之上、不进数字区;拾取瞬间 tier 档位可读(地图战斗资源 H1)
|
||||
|
||||
**场景级测试**(旧版状态记录 entry 17②③,缺项即 blocking)
|
||||
|
||||
- [ ] 场景级 headless 测试:真实实例化战斗屏场景 + 驱动完整对局 + 断言零脚本错误(呈现层点击探针模式扩展)
|
||||
- [ ] 场景级 headless 测试:真实实例化战斗屏场景 + 驱动完整对局 + 断言零脚本错误(ui_click_probe 模式扩展)
|
||||
- [ ] 任何模态覆盖层(图例/胜利/失败——明细回看已退役)有「打开时遮挡物隐藏/输入锁定」场景级断言(缺陷⑤对照)
|
||||
- [ ] 动态区全部固定槽高 + 裁剪兜底——悬停文案换行不推挤布局(缺陷①回归)
|
||||
- [ ] 动态区全部固定槽高 + clip_contents——悬停文案换行不推挤布局(缺陷①回归)
|
||||
- [ ] CJK 字体随包,全部中文文案渲染非豆腐块
|
||||
- [ ] 敌人销毁后呈现层不回读核心生命周期状态(快照纪律,缺陷②回归)
|
||||
- [ ] 敌人 despawn 后呈现层不回读核心生命周期状态(快照纪律,缺陷②回归)
|
||||
|
||||
---
|
||||
|
||||
@@ -407,14 +407,14 @@
|
||||
1. **Player journey map——已完成(2026-09-27 欠账处置拍板:不建)**:实现前补建的前提随战斗屏实装失效;情绪曲线事实源 = art-bible §2 能量档,真人体验观测与结论回流 = [体验验证清单](../../../体验验证清单.md)
|
||||
2. **无障碍专项文档——已完成(2026-09-27 拍板:不另立 design/accessibility-requirements.md)**:基线(对比/色弱/字号/闪烁/减动效/纯鼠标/中文字体)权威 = [HUD框架](../systems/表现与支撑/HUD框架.md)「可访问性基线」节;正式分层(文本缩放/色盲模式/按键重映射)归 [设置与本地化](../systems/表现与支撑/设置与本地化.md) 待设计问题清单 #1(设置项全集裁决时定);本 spec §Accessibility 为呈现侧落地承诺
|
||||
3. **interaction-patterns.md——已建成**(2026-09-12 /team-ui 批当日落稿,本条「未建」系过期陈述):本 spec 引入的四 pattern(双源拒绝反馈/逐行兑现明细带/悬停预承诺光标/点阵资源显示)均已入库成文(pattern 1/3/4/5)
|
||||
4. **战斗表现美术测试**(game-concept 已登记,战斗表现批次前强制):本 spec 的常驻双舞台分屏(布局决策 1)是测试的布局输入——**敌人卡形态已裁决(2026-09-20 用户看对照样张拍板):全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条下,卡片式整体退役**;本 spec 已随裁决改写(原"按卡片式起草"条款作废),站桩式不改变分区结构。对照样张已存档(敌人卡与站桩式对照样张)
|
||||
4. **战斗表现美术测试**(game-concept 已登记,战斗表现批次前强制):本 spec 的常驻双舞台分屏(布局决策 1)是测试的布局输入——**敌人卡形态已裁决(2026-09-20 用户看对照样张拍板):全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条下,卡片式整体退役**;本 spec 已随裁决改写(原"按卡片式起草"条款作废),站桩式不改变分区结构。对照样张存档 `production/mockups/enemy-card-vs-standee-mockup.html`
|
||||
5. **移动动画形态**(布局决策 3):≤150ms 短滑为推荐值,playtest 观测「移动太瞬/太拖」反馈后调
|
||||
6. **明细带挖掘期是否常驻上轮摘要**:常驻(现方案)vs 结算后即收起——playtest 观测回看频率
|
||||
7. **Gamepad 导航序**:Partial 支持(非 MVP 门禁)——焦点环顺序待 gamepad 批次定
|
||||
8. **NodeOverlay / 关卡结算屏——已完成(2026-09-27 欠账处置拍板;节点奖励屏部分被 2026-09-29 迭代 7 取代)**:关卡结算屏 spec 已建 [level-clear.md](level-clear.md)(本 spec 只锁出口锚点不变);节点奖励屏 spec 已出生 [node-reward.md](node-reward.md) v1.0(原「不立独立 spec、随秘宝内容重定批交付」拍板随之取代;节点覆盖层现行:恢复点全量服务、奖励点=三选一构筑点)
|
||||
9. **调参面板退役计划——已完成(迭代 15 卡①,2026-10-05)**:调参面板类整体吸收退役入调试浮窗(调试开关=1 门控);正式侧归元进度(天赋树)不变(门控表述属当期留痕——调试入口现发布态恒隐,现行口径见元素表「调试浮窗」行与「调试变体」行)
|
||||
8. **NodeOverlay / 关卡结算屏——已完成(2026-09-27 欠账处置拍板;节点奖励屏部分被 2026-09-29 迭代 7 取代)**:关卡结算屏 spec 已建 [level-clear.md](level-clear.md)(本 spec 只锁出口锚点不变);节点奖励屏 spec 已出生 [node-reward.md](node-reward.md) v1.0(原「不立独立 spec、随秘宝内容重定批交付」拍板随之取代;NodeOverlay 现行:恢复点全量服务、奖励点=三选一构筑点)
|
||||
9. **TunePanel 退役计划——已完成(迭代 15 卡①,2026-10-05)**:TunePanel 类整体吸收退役入调试浮窗 DebugOverlay(DS_DEBUG=1 门控);正式侧归元进度(天赋树)不变(门控表述属当期留痕——调试入口现发布态恒隐,现行口径见元素表「调试浮窗」行与「调试变体」行)
|
||||
10. **提示文案定稿**:chord 提示/空态文案归实现期文案 pass,本 spec 只锁必含要点与形态约束
|
||||
11. **弃图刷新上游修订(已落稿 2026-09-12,布局决策 4)**:行动经济(Active 相位受理 + 每轮上限 2 次 + Waiting 代理退役 + 旧旗作废裁决 + 时间税失效预警)、排雷玩法(Active·仅刷新路径装板受理)、战斗结算(停手与 AP 耗尽两出口恒同盘不变 + 挖掘期刷新编排;AC-29 改写/AC-30 恒同盘不变)、系统索引的刷新规则同步、旧版 systems-index 修订块登记。遗留观察项:当场刷新的节奏健康由行动经济 OQ3 弃图率/刷新率预警承载,playtest 复核
|
||||
11. **弃图刷新上游修订(已落稿 2026-09-12,布局决策 4)**:行动经济(Active 相位受理 + 每轮上限 2 次 + Waiting 代理退役 + 旧旗作废裁决 + 时间税失效预警)、排雷玩法(Active·仅刷新路径装板受理)、战斗结算(stopped/ap_exhausted 恒 same_board + `refresh_board` 挖掘期刷新编排;AC-29 改写/AC-30 恒 same_board)、registry `rap_rules` 同步、旧版 systems-index 修订块登记。遗留观察项:当场刷新的节奏健康由行动经济 OQ3 弃图率/刷新率预警承载,playtest 复核
|
||||
12. **教学引导缺口挂靠(成文时教学引导 GDD 尚未建,留痕)**:挖到雷 = 敌方优势而非死亡(排雷玩法登记「经典扫雷玩家最大预期违背」)、旗挡链(连锁止于旗属正常)、首次蓄力姿态一次性提示(敌人系统)——本屏 toast 体系为落点候选,随教学引导批次定
|
||||
13. **敌方 AC 展示——已终裁完成(2026-09-26)**:用户终裁——敌方 AC 数值**全屏不展示**(任何区均不直接写上);护甲类型改**图标方式**展示(形状+色相双通道,终稿图标资产归美术批);敌人站桩底座下名字行退回**纯名字 + 护甲类型图标**。与旧「克制对策可读性义务」(敌人技能池批)的关系 = **义务降级承载**:类型保留(图标可读,对策判断仍可做)、数值退役(不再直接展示);敌人技能池批相关义务措辞由并行代码批同步。我方 AC 仍按 2026-09-26 二轮拍板保留于 C 区攻击数据框(唯一展示面)
|
||||
14. **GP/钥石迁出战斗屏后的展示面归属——已拍板完成(2026-09-26 二轮)**:GP = 关卡画面常驻总量 + 战斗总结结算(总量+增量);钥石 = 冒险总结结算 + 营地。呈现 spec 已出生:[settlement-summary.md](settlement-summary.md) v1.0(2026-09-30——两面分节轻量 spec,本 OQ 为其命名与分工依据;「战斗结算画面」「结算画面」旧措辞随 spec 命名完成退役)
|
||||
@@ -437,7 +437,7 @@
|
||||
| 战斗结算×3 | ①高光行强调呈现(封印标中金框行/清图 H2 金框行)②完美封印呈现形态 ③棋盘生成 EC5 零合法板提示/补偿/回退形态(toast 提示;补偿/回退不提供——三形态选型留痕 2026-09-12) | §States 高光/清图 + §States 拒绝子态 + §AC;注:结算明细屏 = 战斗结算 UX Flag 事项(本 spec 即其 /ux-design 产物),非 战斗结算×3 状态记录 |
|
||||
| 敌人系统×4 | 意图映射/恒定/顺位/敌方池 | §Component Inventory 敌人站桩立绘 + **意图线索映射目录(敌人系统×4① 成文占位,资产定稿归战斗表现)** + AC |
|
||||
| 增益状态×4 | 常显+空态/来源标注/溢出/去留 | §States 空态 + §AC |
|
||||
| 地图战斗资源×5 | 身份恒读/明细行/清图强调(旧版状态记录五条中「窗口」「清空反馈」随格面资源批下线——清空反馈义务后载秘宝背包、复随秘宝过渡形态退役消解(现行 = 营地同调装配,秘宝.md)) | §Component Inventory 棋盘视图奖励徽章 + §States 清图/高光 + §Data Requirements 身份解析只读回调 + AC |
|
||||
| 地图战斗资源×5 | 身份恒读/明细行/清图强调(旧版状态记录五条中「窗口」「清空反馈」随格面资源批下线——清空反馈义务后载秘宝背包、复随秘宝过渡形态退役消解(现行 = 营地同调装配,秘宝.md)) | §Component Inventory BoardView 奖励徽章 + §States 清图/高光 + §Data Requirements query_identity + AC |
|
||||
| 棋盘生成 | EC5 零合法板诚实呈现(数据面经 战斗结算×3③ 上抛) | §States 拒绝子态(toast)+ AC |
|
||||
| 敌人系统资产下限 | 受击反馈/死亡表现/顺位标记 | §Transitions 受击 + §States 敌人死亡呈现(禁瞬消)+ §Component 顺位徽标;呈现语义在本 spec(同等 blocking),动画密度归战斗表现 |
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 营地场景 UX spec(camp)
|
||||
|
||||
> 状态:v2.1(现行)
|
||||
> 状态:v2.1(2026-10-24 营地场景图美术设计段;取代旧「四柜台覆盖层」形态)
|
||||
> 事实源:本 spec(呈现)+ [元进度](../systems/跨局循环/元进度.md)(机制)
|
||||
> 美术画法:[art-bible](../../art/art-bible.md) §6.2/§7.5;素材命名与路径:[asset-path-map](../../art/asset-path-map.md)
|
||||
> 相邻:[level-map.md](level-map.md)(主菜单语境)
|
||||
@@ -16,7 +16,7 @@
|
||||
| 大门(半开的门扇,门洞内一条通向远处的小路) | 冒险 | 点大门永远先出确认:有未完冒险=三出口(继续上一段/开始新冒险/取消);无=是否开始新冒险 |
|
||||
| 锻炉·铁砧 | 锻造工坊 | **未解锁=禁用态**(降明度+去饱和) |
|
||||
| 宝箱 | 秘宝匣 | **未解锁=禁用态**(同上) |
|
||||
| 帐篷旁笔记本 | 生涯记录 | 生涯页返回钮文案**禁含「营地」字样**(由呈现层结构校验兜底,口径见测试规约) |
|
||||
| 帐篷旁笔记本 | 生涯记录 | 生涯页返回钮文案**禁含「营地」字样**(`ui_struct_probe.gd` nojump 禁词表) |
|
||||
| 木桩 | 天赋树 | |
|
||||
| 布告板 | 奖励格图鉴 | 内容冻结未激活,点进看占位——**不是禁用态** |
|
||||
| 篝火 | 离开营地回主菜单 | **必须二次确认**;命中区只含火堆、不含火焰 |
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
## 点选反馈(根态)
|
||||
|
||||
悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附)+物件**名牌**(物件下方 8px 居中,提示字号 14,对比 ≥4.5:1);按下=位移 1px;禁用=降明度+去饱和;已解锁=常态。**四态零新素材**(全部程序化)。
|
||||
悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附)+物件**名牌**(物件下方 8px 居中,FS_HINT 14,对比 ≥4.5:1);按下=位移 1px;禁用=降明度+去饱和;已解锁=常态。**四态零新素材**(全部程序化)。
|
||||
|
||||
命中区:七件两两不相交、不越出画面、**不侵入顶栏禁区(y ≤ 48)**。
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
|
||||
## 叠层与开合
|
||||
|
||||
各界面开合走模态栈单口,层序按模态栈契约登记。**承载形态(独立全屏页 vs 单一内页切换)与叠层规则归卡④ §9 代拍板域,本 spec 不预设值**;派生规则:独立全屏页=场景根隐藏/单一内页切换=场景根留底(「缩放虚化」为第三形态,禁批内自选)。ESC 浮窗(返回主菜单/设置/退出游戏)归卡⑤。
|
||||
各界面开合走模态栈单口,层序入 `LAYER_CONTRACT`。**承载形态(独立全屏页 vs 单一内页切换)与叠层规则归卡④ §9 代拍板域,本 spec 不预设值**;派生规则:独立全屏页=场景根隐藏/单一内页切换=场景根留底(「缩放虚化」为第三形态,禁批内自选)。ESC 浮窗(返回主菜单/设置/退出游戏)归卡⑤。
|
||||
|
||||
## 口径
|
||||
|
||||
- 呈现数据源=元进度系统只读投影经组合根喂入;本层不持有系统资源、不算价。
|
||||
- 呈现数据源=MetaProgression 只读投影经组合根喂入;本层不持有系统资源、不算价。
|
||||
- 「最近冒险」条带已撤下(卡④ Q4=甲),逐局历史回看归生涯。
|
||||
- 秘宝匣界面内部呈现(解锁面+同调装配段)保留为附录,待该界面立独立 spec 后迁出。
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **Status**: Complete(核心 8 成文〔2 号已退役留档〕+ 12 目录占位)
|
||||
> **Author**: user + ux-designer
|
||||
> **Last Updated**: 2026-10-29
|
||||
> **Last Updated**: 2026-10-15(简明技术中文用语规范批:词面修正 6 处)
|
||||
> **Template**: Interaction Pattern Library
|
||||
> **来源**: `design/gdd/ux/battle.md`(2026-09-12 /ux-review APPROVED)已拍板内容的成文固化——本库不引入新设计决策
|
||||
|
||||
@@ -29,18 +29,18 @@
|
||||
| 6 | 模态 overlay 层级纪律 | Modal | **成文 ✓** |
|
||||
| 7 | 破坏性确认异位 | Feedback | **成文 ✓** |
|
||||
| 8 | 禁用态即理由 | Feedback | **成文 ✓** |
|
||||
| 9 | 常驻意图徽标 | Data Display | **已实现**(意图徽标呈现件——规格全文待补) |
|
||||
| 9 | 常驻意图徽标 | Data Display | **已实现**(enemy_card_view.gd——规格全文待补) |
|
||||
| 10 | 一次性非模态教学提示 | Feedback | **已实现**(chord 提示——规格全文待补) |
|
||||
| 11 | tooltip 规范 | Feedback | **已实现**(状态/道具悬停——规格全文待补) |
|
||||
| 12 | 单意图帧批次提交 | Input | **已实现**(组合根——规格全文待补) |
|
||||
| 13 | 状态效果槽 | Data Display | **已实现**(状态图标行呈现件——规格全文待补;载体变更留档:C 区四槽已退役,现役载体=B 区站桩伴随件) |
|
||||
| 14 | 步进进度条 | Navigation | **已退役留档**(步进进度条呈现件已删,节点态承载进度) |
|
||||
| 15 | 移动路径预览 | Input | **已实现**(棋盘视图 BFS 蓝点——规格全文待补) |
|
||||
| 16 | 清图/换图演出编排 | Feedback | **已实现·占位级**(棋盘演出呈现件 金粒彩纸——规格随战斗表现 美术批补) |
|
||||
| 17 | 胜利/失败终局编排 | Feedback | **已实现·占位级**(战斗终局覆盖层——规格随战斗表现补) |
|
||||
| 12 | 单意图帧批次提交 | Input | **已实现**(main.gd 组合根——规格全文待补) |
|
||||
| 13 | 状态效果槽 | Data Display | **已实现**(status_slot_row.gd——规格全文待补;载体变更留档:C 区四槽已退役,现役载体=B 区站桩伴随件) |
|
||||
| 14 | 步进进度条 | Navigation | **已退役留档**(level_strip_view 已删,节点态承载进度) |
|
||||
| 15 | 移动路径预览 | Input | **已实现**(board_view.gd BFS 蓝点——规格全文待补) |
|
||||
| 16 | 清图/换图演出编排 | Feedback | **已实现·占位级**(board_fx_view.gd 金粒彩纸——规格随战斗表现 美术批补) |
|
||||
| 17 | 胜利/失败终局编排 | Feedback | **已实现·占位级**(battle_end_overlay.gd——规格随战斗表现补) |
|
||||
| 18 | Boss 遭遇演出 | Feedback | **已实现·占位级**(紫赤影子——规格随战斗表现补) |
|
||||
| 19 | 库存常读列表 | Data Display | **占位失效**(所记载体从未入库;库存面已随秘宝过渡形态退役——C 区现行秘宝槽=装配呈现面、重接归装配面批次,见 battle.md 组件清单) |
|
||||
| 20 | 标准控件组(button/progress bar/list) | Control | **已实现**(标准控件组 直角细线/凸圆角——规格全文待补) |
|
||||
| 19 | 库存常读列表 | Data Display | **占位失效**(所记载体 inventory_panel_view.gd 从未入库〔git 全史零记录,2026-10-09 复核〕;库存面已随秘宝过渡形态退役——C 区现行秘宝槽=装配呈现面、重接归装配面批次,见 battle.md 组件清单) |
|
||||
| 20 | 标准控件组(button/progress bar/list) | Control | **已实现**(ui_kit.gd 直角细线/凸圆角——规格全文待补) |
|
||||
|
||||
MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab bar——战斗屏无此需求;TunePanel slider 为调试专用。
|
||||
|
||||
@@ -53,11 +53,11 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
**Category**: Feedback
|
||||
**Used In**: 战斗屏(棋盘/资源全部意图动作)
|
||||
|
||||
**Description**: 玩家意图被核心拒绝时,反馈必须同时做到:(a) 每次拒绝玩家可感知(防静默拒绝读感欺骗);(b) 来源可区分——棋盘面(排雷玩法判,携细分原因封闭枚举)/资源面(行动经济判,客户端推断)/相位(排雷玩法意图回执)三源各异;(c) 图标+文案双通道,非色相独载。
|
||||
**Description**: 玩家意图被核心拒绝时,反馈必须同时做到:(a) 每次拒绝玩家可感知(防静默拒绝读感欺骗);(b) 来源可区分——棋盘面(排雷玩法判,携 sub_reason 封闭枚举)/资源面(行动经济判,客户端推断)/相位(排雷玩法 ActionOutcome)三源各异;(c) 图标+文案双通道,非色相独载。
|
||||
|
||||
**Specification**:
|
||||
- 触发:意图回执(受理标志 + 拒绝原因 + 细分原因)**返回值驱动**(拒绝无事件外发——排雷玩法发射面封闭,实现层禁止等待拒绝信号)
|
||||
- 反馈映射:棋盘面 → 目标格危险红 `#A8321F` 边框闪(拒绝语义红族——旗朱→封印紫→封印黑 #000000,2026-09-28 用户拍板现行) + toast 具体原因(细分原因→文案映射表:非相邻 / 目标已开格 / 目标未开格 / 该格已有封印 / 该格无封印 / 无可达路径 / 坐标越界);资源面 → 对应资源数字脉冲(AP/RAP)+「AP 不足 · 剩 0 点」式文案;相位 → toast(结算中/非挖掘期)
|
||||
- 触发:`ActionOutcome{accepted=false, reject_reason, sub_reason}` **返回值驱动**(拒绝无事件外发——排雷玩法发射面封闭,实现层禁止等待拒绝信号)
|
||||
- 反馈映射:board_face → 目标格危险红 `#A8321F` 边框闪(拒绝语义红族——旗朱→封印紫→封印黑 #000000,2026-09-28 用户拍板现行) + toast 具体原因(sub_reason→文案映射表:not_adjacent/target_revealed/target_concealed/flag_present/flag_absent/no_path/out_of_catalog);resource_face → 对应资源数字脉冲(AP/RAP)+「AP 不足 · 剩 0 点」式文案;phase → toast(结算中/非挖掘期)
|
||||
- 即时性:拒绝当帧呈现;toast 自动消退 2.5s
|
||||
- **voided 区分**:作废 ≠ 拒绝(零效果零扣费零事件)——须独立文案如「本轮已清图,停手未执行 · 剩余 AP 已作废」,至少 stop 作废可感知
|
||||
- Accessibility:危险红边框闪为形状+运动通道;文案常驻
|
||||
@@ -84,11 +84,11 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
**Description**: 轮末结算逐行流水实时呈现 + 可回看——「扫雷之因逐行兑现为战果」(P2 归因)的承载面。挖掘期收起为 1 行上轮摘要;结算期展开 84px 实时流;点击开完整回看 overlay。
|
||||
|
||||
**Specification**:
|
||||
- 数据源:[战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行封闭协议(现行);公共字段:来源类别 / 来源格 / 轮次 / 显示名 / 数值 / 可空高光标记);**无来源行 = 断言失败**
|
||||
- 数据源:[战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行封闭协议(现行);公共字段 `type/source_class/origin_cell/round_index/display_name/value/highlight?`);**无来源行 = 断言失败**
|
||||
- 行模板:「{行为} {值} → {目标}(来源)」——来源标注(第 N 轮 · 安全格式);行文案最长 token = 来源标签(4 汉字封闭枚举),模板预留 40% 膨胀宽度
|
||||
- 聚合纪律:未生效类行(奖励未生效——现行 9 类行协议唯一未生效型,2026-09-20 收敛)按聚合计数呈现(防逐行惩罚轰炸);衰减行聚合计数;效果行数值 = 单次贡献值、禁与池合成值相加呈现;零值行可见不吞(免伤轮归因不断点)
|
||||
- 高亮:高亮标记(封印标中、清图奖励、完美破除) → 金框强调;完美封印 = 独立高光行 + 全屏喝彩级反馈。「完美破除」的判据句读作「本板首次标错受检」,不等于完美资格已失——专长「完美保险」可在本场首次标错时豁免,实际资格按有效误标(误标总数 − 豁免数)判定
|
||||
- 布局:固定槽高 + 裁剪兜底;正文 ≥14px;数值暗底高对比;未生效类行带 icon/划线形状冗余
|
||||
- 聚合纪律:未生效类行(奖励未生效——现行 9 类行协议唯一未生效型,2026-09-20 收敛)按聚合计数呈现(防逐行惩罚轰炸);衰减行聚合计数;效果行 value=单次贡献值、禁与 pool_value(池合成值)相加呈现;零值行可见不吞(免伤轮归因不断点)
|
||||
- 高亮:highlight 字段 {flag_hit, clear_reward_h2, perfect_broken} → 金框强调;完美封印 = 独立高光行 + 全屏喝彩级反馈。`perfect_broken` 的判据句读作「本板首次标错受检」,不等于完美资格已失——专长「完美保险」可在本场首次标错时豁免,实际资格按有效误标(误标总数 − 豁免数)判定
|
||||
- 布局:固定槽高 + clip_contents;正文 ≥14px;数值暗底高对比;未生效类行带 icon/划线形状冗余
|
||||
- 击杀标记呈现(H3 数据源 = 战斗结算流水击杀结果字段)
|
||||
|
||||
**When to Use**: 任何「因果可归因」的逐行流水呈现
|
||||
@@ -101,7 +101,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
### 4. 悬停预承诺光标(hover pre-commitment cursor)
|
||||
|
||||
**Category**: Input
|
||||
**Used In**: 扫雷图(棋盘视图)
|
||||
**Used In**: 扫雷图 BoardView
|
||||
|
||||
**Description**: 左键双义(已开格=移动 / 未开相邻格=挖)的消歧完全依赖格态一瞥可辨 + 悬停光标区分——**误挖不可逆**(1 AP + 可能触雷)的感知保险。
|
||||
|
||||
@@ -130,7 +130,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
**Specification**:
|
||||
- 形态:`●●●●●○○○` + 「5/8」;直角细线数据框(信息=直线直角,art-bible §3.3)
|
||||
- 更新触发:组合根每次调用返回后重查(**行动经济无推送信号**——实现层禁止等待资源变更事件)
|
||||
- 拒绝反馈:资源不足时数字脉冲(pattern 1 的资源面腿)
|
||||
- 拒绝反馈:资源不足时数字脉冲(pattern 1 的 resource_face 腿)
|
||||
- Accessibility:点阵=形状通道、数字=文本通道;对比 ≥4.5:1
|
||||
|
||||
**When to Use**: 小整数离散资源(≤16 量级)
|
||||
@@ -150,7 +150,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
**Specification**:
|
||||
- 打开:遮挡物隐藏或禁用 + 输入锁定;单一模态栈(无叠模态)
|
||||
- 关闭:恢复被遮挡物;关闭按钮/再点入口切换
|
||||
- 内容:固定槽高 + 裁剪兜底(缺陷①——悬停文案换行禁止推挤布局)
|
||||
- 内容:固定槽高 + clip_contents(缺陷①——悬停文案换行禁止推挤布局)
|
||||
- 验收:**场景级断言「打开时遮挡物隐藏/输入锁定」为每个模态 overlay 的强制 AC**(battle.md 场景级测试节)
|
||||
|
||||
**When to Use**: 全屏打断级信息、只读回看、仪式性终局
|
||||
@@ -170,7 +170,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
**Specification**:
|
||||
- 弃图刷新:确认微交互显式呈现全部代价(RAP−8 · **旧板封印印记随旧板作废**提示);确认交互位置与常规确认不同位
|
||||
- 双通道:图标 + 文案冗余
|
||||
- 拒绝路径:RAP<8 → pattern 1 的资源面(EC13 合法拒绝可见)
|
||||
- 拒绝路径:RAP<8 → pattern 1 resource_face(EC13 合法拒绝可见)
|
||||
|
||||
**When to Use**: 任何消耗资源/不可逆的操作确认
|
||||
**When NOT to Use**: 无代价操作(直接执行 + 直接反馈)
|
||||
@@ -189,7 +189,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
**Specification**:
|
||||
- 形态:灰置 + tooltip「HP 已满 · 禁选」;点击无效 + 原因 toast 兜底
|
||||
- 语义区分:满血 = 零收益守卫(禁选、不烧包)≠ 缺血不足(超量 clamp 部分回复,**不**禁选)
|
||||
- 「当前可用」标记由战斗结算组装进窗口载荷(地图战斗资源零跨系统读)——呈现层只消费不推断
|
||||
- usable_now 由战斗结算组装进窗口载荷(地图战斗资源零跨系统读)——呈现层只消费不推断
|
||||
|
||||
**When to Use**: 任何可见但不可交互的元素
|
||||
**When NOT to Use**: 完全隐藏的不可用功能(不存在的东西无需解释)
|
||||
@@ -201,7 +201,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab
|
||||
## Gaps & Patterns Needed
|
||||
|
||||
- **目录 #9–#20 已全部实现**(2026-09-12 战斗屏实现批,冒烟 149/149 + 三探针全绿);规格全文回写 = HUD框架正式化批义务
|
||||
- 实现期新增技术件(不单独立 pattern,规格归并):去饱和+金橙状态切换 = 逐格共享 ShaderMaterial(明度不变,兼容渲染器下安全);敌人死亡残位 = 卡体灰化+碎裂禁瞬消(归入 #17 终局编排规格)
|
||||
- 实现期新增技术件(不单独立 pattern,规格归并):去饱和+金橙状态切换 = 逐格共享 ShaderMaterial(明度不变,gl_compatibility 安全);敌人死亡残位 = 卡体灰化+碎裂禁瞬消(归入 #17 终局编排规格)
|
||||
- **MVP 未使用标准控件**:toggle / dropdown / input field / tab bar(无需求不设占位);TunePanel slider 为调试专用不入库
|
||||
- **实现偏差规则**:pattern 近似但不完全适配时,实现层禁止静默变体——登记偏差交 ux-designer 复核后回写
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# UX Spec: 关卡结算屏(Level Clear)——提升三选一选择面
|
||||
|
||||
> **Status**: v2 义务锁定版
|
||||
> **Status**: v2 义务锁定版(2026-10-01 迭代 10 奖励重构批重写——三件套快照展示退役,改三选一选择交互;呈现形态随实装批定,视觉终稿以表现层样张为前置,见 P1/OQ4;**本批渲染层验证冻结——目检清单顺带交付、实机目检待用户批准**)
|
||||
> **Author**: user + ZCode(UX 文档欠账处置批;迭代 10 重写)
|
||||
> **Last Updated**: 2026-10-29
|
||||
> **Last Updated**: 2026-10-15(简明技术中文用语规范批:词面修正 4 处;原标 2026-10-01 滞后于 2026-10-09 两条修订记录,本批一并对齐)
|
||||
> **Platform Target**: PC (Steam)——Keyboard/Mouse 主,全部操作纯鼠标可完成(同 battle.md)
|
||||
> **Template**: UX Spec
|
||||
> **来源**: battle.md OQ8 欠账处置(2026-09-27 用户拍板建档)+ 迭代 10 奖励重构批(2026-09-30 用户拍板案丙——三选一/部分回血/钥石挪转,计划书 m3-iter10-loop-plan-2026-09-30.md)
|
||||
@@ -28,13 +28,13 @@
|
||||
| 时刻 | 载体(目标形态,迭代 10 实装) | 呈现内容 |
|
||||
|---|---|---|
|
||||
| Boss 战胜利(非末关) | 战斗总结结算([settlement-summary.md](settlement-summary.md))→ 确认后进**本屏** | 战利品行含钥石增量行 → 本屏:部分回血反馈 + 三选一三卡 |
|
||||
| 非末关完成(本屏默认态) | 三选一覆盖层(与奖励节点共用面) | 部分回血兑付行 + 三张专长选项卡(点选+确认+兑付反馈) |
|
||||
| 非末关完成(本屏默认态) | 三选一覆盖层(curio_pick_overlay——与奖励节点共用面) | 部分回血兑付行 + 三张专长选项卡(点选+确认+兑付反馈) |
|
||||
| 末关完成 / 失败 / 放弃 | 冒险结算(复用战斗终局 overlay) | 冒险摘要五件事 + 钥石入账明细——**相邻域**(冒险落幕面,非本屏职责) |
|
||||
|
||||
## Navigation Position
|
||||
|
||||
```
|
||||
战斗屏 ──胜利(末节点 Boss)──▶ 战斗总结结算(GP/钥石增量行)──确认──▶ 【关卡结算(关卡完成)】
|
||||
战斗屏 ──胜利(末节点 Boss)──▶ 战斗总结结算(GP/钥石增量行)──确认──▶ 【关卡结算(level_clear)】
|
||||
├─ 非末关:回血反馈 + 三选一点选兑付 → 下一关开始(→ 关卡画面选路)
|
||||
└─ 末关完成:直通冒险结算(相邻域)→ 返回存档/营地
|
||||
失败不经本屏(战斗屏失败分支直达冒险落幕)。
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
| 方向 | 触发 | 携带语境 |
|
||||
|---|---|---|
|
||||
| 进入 | 战斗总结结算确认 → 关卡收束(先清库后宣布)→ 非末关兑付部分回血 → 三选一候选呈现(奖励三选一拉起信号) | 三候选(件 id + 名称 + 效果行值);部分回血前后生命读数;GP 账本余额(跨关延续) |
|
||||
| 进入 | 战斗总结结算确认 → 关卡收束(先清库后宣布)→ 非末关兑付部分回血 → 三选一候选呈现(bonus_pick 信号) | 三候选(件 id + 名称 + 效果行值);部分回血前后生命读数;GP 账本余额(跨关延续) |
|
||||
| 离开 | 三选一确认兑付 → 继续钮(唯一出口) | 兑付反馈载荷 → 下一关开始 |
|
||||
|
||||
零自动推进(冒险结构 契约 4):三选一呈现后必须玩家点选才兑付,确认前玩家不被推着走;重复兑付被拒。选择停点可中断:断点附随件扩「奖励选择态」,续玩回到本屏同一候选(不重抽)。
|
||||
@@ -70,7 +70,7 @@
|
||||
| 三选一选择态(默认) | 非末关完成,候选已抽定 | 三卡呈现(零自动推进)→ 点选 → 确认 → 兑付反馈 → 继续 |
|
||||
| ~~同调位替换子态~~ | ~~点选秘宝件且库存满位~~ | 已随渠道退役(秘宝件出池、关卡完成候选 = 纯专长——本屏无道具件候选) |
|
||||
| 兑付反馈态 | 确认兑付后 | 选中件效果一行 + 丢弃提示 → 继续钮点亮 |
|
||||
| 末关完成 | 关卡完成且末关 | 直通冒险结算——不发三选一与回血(奖励只朝下一战生效);本屏不出现 |
|
||||
| 末关完成 | level_clear 且末关 | 直通冒险结算——不发三选一与回血(奖励只朝下一战生效);本屏不出现 |
|
||||
| Boss 入口语境 | 击杀 Boss(恒为本屏入口前置) | 入口演出归战斗屏;钥石增量行归战斗总结结算——本屏不另设 |
|
||||
|
||||
## Interaction Map
|
||||
@@ -78,23 +78,23 @@
|
||||
| 组件 | 动作 | 输入 | 即时反馈 | 结果(经组合根) |
|
||||
|---|---|---|---|---|
|
||||
| 提升选项卡 ×3 | 点选(单选高亮) | 左键 | 选中卡高亮、确认钮点亮 | 选中态暂存(未确认可改选) |
|
||||
| 确认钮 | 兑付选中件 | 左键 | 兑付反馈(效果一行) | 冒险编排兑付恰一件(重复兑付被拒);另两件丢弃不可反悔 |
|
||||
| 继续钮 | 接受结算、推进 | 左键 | 按钮下压 | 下一关开始(推进到下一关——兑付后受理) |
|
||||
| 确认钮 | 兑付选中件 | 左键 | 兑付反馈(效果一行) | AdventureRunner 兑付恰一件(重复兑付被拒);另两件丢弃不可反悔 |
|
||||
| 继续钮 | 接受结算、推进 | 左键 | 按钮下压 | 下一关开始(AdventureRunner.continue_to_next_level——兑付后受理) |
|
||||
| ~~替换子面板钮~~ | —— | —— | —— | 已随渠道退役(本屏无道具件候选) |
|
||||
|
||||
复用既有交互范式,零新增原语:三卡点选 = 奖励节点 选择框 按钮数组同族(由节点覆盖层展示奖励三选一 先例)+ 选路覆盖层点选确认两段式(关卡地图屏 先例);覆盖层容器 = 中场确认覆盖层位置复用。
|
||||
复用既有交互范式,零新增原语:三卡点选 = 奖励节点 choice_box 按钮数组同族(node_overlay.show_reward_items 先例)+ 选路覆盖层点选确认两段式(level_map_screen 先例);覆盖层容器 = 中场确认覆盖层位置复用。
|
||||
|
||||
## Data Requirements
|
||||
|
||||
| Data | Source System | Read / Write | Notes |
|
||||
|---|---|---|---|
|
||||
| 三候选(件 id/名称/效果行值) | 冒险结构 奖励三选一拉起信号(令牌池洗牌不放回抽 3〔同 kind 去重——v0.14 令牌池换代口径,原「加权洗牌」退役〕,奖励抽取封闭流) | Read | 载荷自包含、销毁前捕获;同种子同三候选(可复放) |
|
||||
| 三候选(件 id/名称/效果行值) | 冒险结构 bonus_pick 信号(令牌池洗牌不放回抽 3〔同 kind 去重——v0.14 令牌池换代口径,原「加权洗牌」退役〕,reward_pick 封闭流) | Read | 载荷自包含、despawn 前捕获;同种子同三候选(可复放) |
|
||||
| 部分回血读数(回血前后生命) | 冒险结构生命账本(clear_heal_pct 兑付) | Read | 满血回 0 合法态文案化 |
|
||||
| 兑付反馈载荷 | 冒险结构 奖励兑付完成信号 | Read | 选中件 id + 生效值 |
|
||||
| 兑付反馈载荷 | 冒险结构 bonus_resolved 信号 | Read | 选中件 id + 生效值 |
|
||||
| ~~同调位库存~~ | —— | —— | 替换子态随渠道退役;过渡键 transitional_sync_slots 已退役(迭代 11① T7——同调位现行事实源 = attunement_growth.tres 谓词表实时求值) |
|
||||
| 冒险摘要(五件事) | 冒险结构的冒险收束载荷 | Read | 末关分支数据锚(相邻域冒险结算屏消费) |
|
||||
| 冒险摘要(五件事) | 冒险结构 adventure_finished 载荷 | Read | 末关分支数据锚(相邻域冒险结算屏消费) |
|
||||
| GP 账本 | 冒险结构 GP 冒险账本 | — | 不进本屏(维持 2026-09-27 拍板) |
|
||||
| 钥石入账 | 元进度 冒险结算入账 | Write(相邻域) | 唯一写档点不变;**本屏零钥石元素**(迭代 10 起,增量行迁战斗总结结算) |
|
||||
| 钥石入账 | 元进度 settle_adventure | Write(相邻域) | 唯一写档点不变;**本屏零钥石元素**(迭代 10 起,增量行迁战斗总结结算) |
|
||||
|
||||
## Accessibility
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] 非末关完成必经本屏:三选一恰呈现一次(零自动推进)、点选后恰兑付一件(重复兑付被拒)、未选项零生效
|
||||
- [ ] 三候选读数可见且与奖励三选一拉起载荷一致(件名称 + 效果行值);同种子同三候选
|
||||
- [ ] 三候选读数可见且与 bonus_pick 载荷一致(件名称 + 效果行值);同种子同三候选
|
||||
- [ ] 部分回血兑付行可见且封顶上限;满血回 0 呈合法态文案
|
||||
- [ ] ~~同调位替换子交互~~(已随渠道退役——本屏无道具件候选,见 Information Hierarchy 第 4 条注)
|
||||
- [ ] 末关完成分支正确直通冒险结算(不发三选一与回血),冒险摘要五件事完整
|
||||
|
||||
+27
-27
@@ -1,8 +1,8 @@
|
||||
# UX Spec: 关卡画面(选路枢纽,Level Map)
|
||||
|
||||
> **Status**: 定稿版(现行——三项设计提案已拍板:底栏状态展示 / 图上点击选路·候选按钮退役 / 放弃二次确认;形态为独立屏;视觉终稿已冻结)
|
||||
> **Status**: 定稿版——三项设计提案已拍板完成(2026-09-27:底栏状态展示 / 图上点击选路·候选按钮退役 / 放弃二次确认);**形态已升格独立屏(2026-09-28 用户裁决:独立存在为最终形态)**;**视觉终稿已冻结(2026-09-28 关卡画面样张 v1 机检 11/11 全绿,闸形 A——冻结值见 Layout/组件清单与样张机检报告,迭代 4)**
|
||||
> **Author**: user + ZCode(关卡画面 UX 批)
|
||||
> **Last Updated**: 2026-10-29
|
||||
> **Last Updated**: 2026-10-25(迭代 35 生成图换代:呈现面随动登记)
|
||||
> **Platform Target**: PC (Steam)——Keyboard/Mouse 主,全部操作纯鼠标可完成(同 [battle.md](battle.md))
|
||||
> **Template**: UX Spec
|
||||
> **覆盖范围**: 独立屏形态(关卡停点全景)· 入口停点 · 岔路停点 · 单链停点 · 放弃冒险入口
|
||||
@@ -61,24 +61,24 @@
|
||||
|
||||
### Layout Zones
|
||||
|
||||
按 1280×800 基座(2026-09-12 定)。本屏为独立屏独占呈现:屏底(深底背景色 + 石纹底噪〔迭代 2 框材组冻结件,缺位纯色回退〕)铺满,内容居中三段。
|
||||
按 1280×800 基座(2026-09-12 定)。本屏为独立屏独占呈现:屏底(深底 `BG_ROOT` + 石纹底噪〔迭代 2 框材组冻结件,缺位纯色回退〕)铺满,内容居中三段。
|
||||
|
||||
| 区 | 位置与尺寸 | 内容 |
|
||||
|---|---|---|
|
||||
| **顶栏语境** | 居中横排,图区上方,高约 32px | 左:关卡名(关卡表 `display_name` 行值,如「第二层 · 幽暗地域」);右:GP 常驻徽章(GP 图标+数字,直角细线数据框——GP 值域超点阵适用档,走 pattern 5 的 When-NOT-to-Use 路线);HP 归底部状态栏(2026-09-27 拍板完成) |
|
||||
| **节点图区** | 居中 | 整幅节点图自绘:节点方块 + 通道折线 + 节点态着色 + Boss 紫赤描边。画布随图自适应(**冻结公式**:宽 = 70+层深×122+44.5、高 = 52+槽位×58+25+24,下限 620×256——路线缺陷根修后定值);通道折线**冻结 2/3/4px**(未点亮石灰 STONE/候选亮金 GOLD_LIT/悬停加粗);节点方块 52×36 内**节点图标 20px 烘焙 1:1**(♻ kenney 五键:战=弓/赏=桂冠/疗=篝火/王=王冠/商=钱袋,WARM 单色、当前金底转深墨——双色墨制)+ 编号(图内句柄 id)10px 右上角 |
|
||||
| **顶栏语境** | 居中横排,图区上方,高约 32px | 左:关卡名(`level_row.display_name`,如「第二层 · 幽暗地域」);右:GP 常驻徽章(GP 图标+数字,直角细线数据框——GP 值域超点阵适用档,走 pattern 5 的 When-NOT-to-Use 路线);HP 归底部状态栏(2026-09-27 拍板完成) |
|
||||
| **节点图区** | 居中 | 整幅节点图自绘:节点方块 + 通道折线 + 节点态着色 + Boss 紫赤描边。画布随图自适应(**冻结公式**:宽 = 70+层深×122+44.5、高 = 52+槽位×58+25+24,下限 620×256——routebug 83c11a1 根修件);通道折线**冻结 2/3/4px**(未点亮石灰 STONE/候选亮金 GOLD_LIT/悬停加粗);节点方块 52×36 内**节点图标 20px 烘焙 1:1**(♻ kenney 五键:战=弓/赏=桂冠/疗=篝火/王=王冠/商=钱袋,WARM 单色、当前金底转深墨——双色墨制)+ 编号(图内句柄 id)10px 右上角 |
|
||||
| **底部状态栏** | 图区下方横排,高约 48px | 左-中:状态数据框组(直角细线,pattern 5 族)——生命(当前/上限 + 迷你血条)、属性(攻击 / 护甲 AC,有效值 + 加成角标)、本关加成(攻+X · 上限+Y · AC+Z,零加成隐藏);右端:放弃冒险按钮(危险红族文字,与状态数据框保持间距——破坏性确认异位,pattern 7) |
|
||||
|
||||
### Component Inventory
|
||||
|
||||
| 组件 | 类型 | 内容 | 交互 | 现有实现锚 |
|
||||
|---|---|---|---|---|
|
||||
| 关卡名标签 | 文本 | 关卡表 `display_name` 行值(关卡表行读数) | 只读 | 新建(现行标题位升级) |
|
||||
| GP 常驻徽章 | 直角细线数据框 | GP 图标 + 数字(冒险钱包读数;刷新经钱包变动信号投影〔gain/buy/clear 三事件〕或写路径回执后重查) | 只读 | 新建(GP 去向拍板落地面) |
|
||||
| 节点图画布 | 自绘 Control | 节点图标(五键 20px 烘焙,双色墨制)+ 编号(图内句柄 id)、通道折线、节点态着色、Boss 紫赤描边+深墨环(BOSS_PURPLE——2026-09-26 封印紫批语义:紫赤本色) | 悬停预承诺 / 点击提交选路(唯一通道) | ✅ 已实装(视觉终稿已落码——迭代 4 T2/T3) |
|
||||
| 关卡名标签 | 文本 | `level_row.display_name`(关卡表行读数) | 只读 | 新建(现行标题位升级) |
|
||||
| GP 常驻徽章 | 直角细线数据框 | GP 图标 + 数字(`runner.gp`,冒险钱包读数;刷新经 `wallet_changed` 信号投影〔gain/buy/clear 三事件〕或写路径回执后重查) | 只读 | 新建(GP 去向拍板落地面) |
|
||||
| 节点图画布 | 自绘 Control | 节点图标(五键 20px 烘焙,双色墨制)+ 编号(图内句柄 id)、通道折线、节点态着色、Boss 紫赤描边+深墨环(BOSS_PURPLE——2026-09-26 封印紫批语义:紫赤本色) | 悬停预承诺 / 点击提交选路(唯一通道) | ✅ level_map_screen.gd `_draw_graph`(视觉终稿已落码——迭代 4 T2/T3) |
|
||||
| 状态数据框组 | 直角细线数据框 ×3 | 生命(当前/上限 + 迷你血条)、属性(攻击 / 护甲 AC 有效值 + 加成角标)、本关加成(加算区增量列表,零加成隐藏) | 只读 | 新建(2026-09-27 拍板:底栏状态展示) |
|
||||
| 放弃冒险按钮 | 按钮(危险红族) | 「放弃冒险(同失败结算——已获大奖励保留)」;二次确认态已拍板(见布局决策 3) | 点击(首击转确认态、二击提交) | ✅ 已实装(可见性归组合根,仅冒险模式开) |
|
||||
| 标题行 | 文本 | 停点语境提示(见布局决策 1 三停点标题) | 只读 | ✅ 已实装(措辞已按布局决策 1 改稿) |
|
||||
| 放弃冒险按钮 | 按钮(危险红族) | 「放弃冒险(同失败结算——已获大奖励保留)」;二次确认态已拍板(见布局决策 3) | 点击(首击转确认态、二击提交) | ✅ level_map_screen.gd(可见性归组合根,仅冒险模式开) |
|
||||
| 标题行 | 文本 | 停点语境提示(见布局决策 1 三停点标题) | 只读 | ✅ level_map_screen.gd `_title`(措辞已按布局决策 1 改稿) |
|
||||
|
||||
**布局决策 1 —— 停点标题措辞修正(清偿状态记录 143 遗留)**:现行入口停点标题沿用「继续前进(战斗房)」,与「尚未走出第一步」的语境矛盾。三停点标题定稿:
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
| 单链停点 | 1 | 「继续前进」 |
|
||||
| 岔路停点 | ≥2 | 「选择下一节点」 |
|
||||
|
||||
**布局决策 2 —— 图上直接点击选路(2026-09-27 拍板)**:候选节点的亮金描边本身是可点目标,悬停预承诺(pattern 4)后点击即提交——**候选按钮整列退役,图上点击为唯一提交通道**。
|
||||
**布局决策 2 —— 图上直接点击选路(2026-09-27 拍板)**:候选节点的亮金描边本身是可点目标,悬停预承诺(pattern 4)后点击即提交——**候选按钮整列退役,图上点击为唯一提交通道**。实装注记:route_overlay.gd 现行候选按钮列与 `press_candidate` 探针入口随实装批拆除改造(图上命中换整图公式族命中),ui_click_probe 选路段同步改写。
|
||||
|
||||
**布局决策 3 —— 放弃冒险二次确认(2026-09-27 拍板)**:放弃 = 整局冒险落幕,不可逆(pattern 7 破坏性确认)。首击转入确认态(按钮文案变「再点一次确认放弃——不可逆」,危险红边框脉冲约 3 秒,超时回落),二击才提交。代价语义(已获大奖励保留、同失败结算)常驻按钮文案。
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
| **单链停点** | 兑付确认后、恰 1 个下一跳 | 标题「继续前进」;单候选节点图上点击提交(候选按钮已退役——图上点击为唯一通道) |
|
||||
| **岔路停点** | 兑付确认后、≥2 个下一跳 | 标题「选择下一节点」;候选节点图上点击提交(候选按钮已退役——图上点击为唯一通道);亮金通道与候选描边逐一分叉可辨 |
|
||||
| **悬停预承诺** | 悬停候选节点 | 该节点亮金描边加粗 + 所属通道增亮 + 光标切指针态;移出即回落(仅预承诺,点击才提交) |
|
||||
| **放弃确认态** | 首击放弃按钮 | 文案转确认语 + 危险红边框脉冲约 3 秒;超时或移出回落;二击提交放弃请求 |
|
||||
| **放弃确认态** | 首击放弃按钮 | 文案转确认语 + 危险红边框脉冲约 3 秒;超时或移出回落;二击提交 `abandon_requested` |
|
||||
| **换层进入** | 上一关结算确认 → 新关开始 | 本屏以新关卡数据淡入;屏底世界侧随层进换挡(**换层色板渐变挂点**——§2.7 切片档:只动色相/饱和、明度带归一,level_index→tint 表候选值 = art-bible §6.3 三关方向,终值归色板样张批;M-2 迭代 4 落挂点) |
|
||||
| **减动效** | 设置开关(设置面——迭代 8 卡④已转正,TunePanel 已退役) | 淡入、描边脉冲等全部 tween 时长减半或跳终态(UiKit.motion 单点包装,同 battle.md 通道) |
|
||||
|
||||
@@ -135,8 +135,8 @@
|
||||
|
||||
| 组件 | 动作 | 输入 | 即时反馈 | 结果(经组合根) |
|
||||
|---|---|---|---|---|
|
||||
| 候选节点(图上,唯一通道) | 提交选路 | 左键 | 悬停预承诺(描边加粗 + 通道增亮 + 指针)→ 点击本屏关闭 | 选路提交 → 关卡推进方受理——到达即兑付,无进入前确认步 |
|
||||
| 放弃冒险按钮 | 终结整局冒险 | 左键(二击提交——首击转确认态,2026-09-27 布局决策 3) | 危险红族反馈 | 放弃请求 → 组合根走冒险落幕(同失败结算——已获大奖励保留) |
|
||||
| 候选节点(图上,唯一通道) | 提交选路 | 左键 | 悬停预承诺(描边加粗 + 通道增亮 + 指针)→ 点击本屏关闭 | `route_chosen(node_id)` → `LevelRunner.pick_next_node`——到达即兑付,无进入前确认步 |
|
||||
| 放弃冒险按钮 | 终结整局冒险 | 左键(二击提交——首击转确认态,2026-09-27 布局决策 3) | 危险红族反馈 | `abandon_requested` → 组合根走冒险落幕(同失败结算——已获大奖励保留) |
|
||||
|
||||
**零自动推进纪律**(关卡节点地图 定稿):本屏是唯一的行进发起口——不选就停在图上;没有任何定时、默认或顺延的自动前进路径。兑付后确认挂各兑付面(战斗总结结算〔settlement-summary.md〕/ 节点覆盖层 / 商店覆盖层离开动作),本屏不重复确认步。
|
||||
|
||||
@@ -146,13 +146,13 @@
|
||||
|
||||
| Data | Source System | Read / Write | Notes |
|
||||
|---|---|---|---|
|
||||
| 节点图结构 / 当前节点 / 已到序列 / 候选集 | 关卡推进方只读成文出口:全节点集 / 当前节点 / 已到序列 / 候选集 / 节点编号 / 节点出边 | Read | 呈现只读(关卡节点地图 验收「呈现只读」条);节点态四色直接读图 |
|
||||
| GP 常驻总量 | 冒险钱包读数 | Read | 刷新经钱包变动信号投影(gain/buy/clear 三事件)或写路径回执后重查;冒险收束清零后本屏不可达(收束即离屏) |
|
||||
| 关卡名 | 关卡表 `display_name` 行值(关卡表行) | Read | 字段名实现期核对(level.tres 行键 `display_name` 在案) |
|
||||
| 生命读数 | 主角当前生命 / 有效生命上限(跨战斗生命携带) | Read | 已拍板(2026-09-27):底栏状态栏承载 |
|
||||
| 属性与本关加成 | 有效攻击 / 有效护甲 / 有效生命上限,以及统一冒险加算区(锻造/大奖励/商店购买/节点奖励同账) | Read | 已拍板:底栏承载;无推送信号——组合根打开本屏 / 兑付确认回执后重查(命令式刷新纪律,同行动经济) |
|
||||
| 选路提交 | 关卡推进方 | **Write** | 唯一写路径 = 选路提交 → 组合根 → 关卡推进方受理;本屏零其他写面 |
|
||||
| 放弃请求 | 组合根 | **Write** | 放弃意图 → 冒险落幕流程(归冒险结构) |
|
||||
| 节点图结构 / 当前节点 / 已到序列 / 候选集 | LevelRunner 只读成文出口:`nodes()` / `current_node_id()` / `visited_ids()` / `next_candidate_ids()` / `node_id_of()` / `node_out_ids()` | Read | 呈现只读(关卡节点地图 验收「呈现只读」条);节点态四色直接读图 |
|
||||
| GP 常驻总量 | `runner.gp`(冒险钱包) | Read | 刷新经 `wallet_changed` 信号投影(gain/buy/clear 三事件)或写路径回执后重查;冒险收束清零后本屏不可达(收束即离屏) |
|
||||
| 关卡名 | `level_row.display_name`(关卡表行) | Read | 字段名实现期核对(level.tres 行键 `display_name` 在案) |
|
||||
| 生命读数 | `runner.hero_hp` / `runner.effective_max_hp()`(跨战斗生命携带) | Read | 已拍板(2026-09-27):底栏状态栏承载 |
|
||||
| 属性与本关加成 | `runner.effective_atk() / effective_ac() / effective_max_hp()` 与 `bonus` 统一冒险加算区(锻造/大奖励/商店购买/节点奖励同账) | Read | 已拍板:底栏承载;无推送信号——组合根打开本屏 / 兑付确认回执后重查(命令式刷新纪律,同行动经济) |
|
||||
| 选路提交 | LevelRunner | **Write** | 唯一写路径 = `route_chosen` → 组合根 → `pick_next_node`;本屏零其他写面 |
|
||||
| 放弃请求 | 组合根 | **Write** | `abandon_requested` → 冒险落幕流程(归冒险结构) |
|
||||
|
||||
**架构注记**:与 battle.md 同族——UI 不拥有任何游戏状态,全部读经核心只读面,全部写经组合根;呈现层直接订阅的推进信号属 HUD框架 已锁两线之一(战斗结算明细流水 + 关卡节点地图推进信号)。
|
||||
|
||||
@@ -197,21 +197,21 @@
|
||||
- [ ] 关卡开始即出图(停点前移语义),入口节点不自动进入;每次兑付确认后回到本屏
|
||||
- [ ] 1280×800 与 16:9 全屏下顶栏/图区/动作栏无遮挡、无重叠、无内容裁切;节点图完整可见(含 Boss)
|
||||
- [ ] 节点四态(已过/当前/候选/未来)+ Boss 描边在灰度截图下可分类;色值对 art-bible §4.1 色板在案
|
||||
- [ ] 顶栏关卡名与 GP 常驻徽章可见、读数与关卡推进方现值一致(GP 经 gain/buy/clear 事件刷新)
|
||||
- [ ] 顶栏关卡名与 GP 常驻徽章可见、读数与 `runner` 现值一致(GP 经 gain/buy/clear 事件刷新)
|
||||
|
||||
**交互与流程**
|
||||
|
||||
- [ ] 三停点标题按布局决策 1 呈现(入口停点不再出现「继续前进(战斗房)」措辞——状态记录 143 遗留清偿)
|
||||
- [ ] 候选提交经组合根唯一写路径(选路提交 → 关卡推进方受理),到达即兑付;零自动推进(无任何不选而行的路径)
|
||||
- [ ] 图上点击为唯一选路提交通道(候选按钮退役,2026-09-27 拍板);悬停预承诺反馈可见;图上选路段随实装批改造后复核通过
|
||||
- [ ] 底部状态栏三组读数可见且与关卡推进方现值一致(生命当前/上限、攻击/AC 有效值、本关加成增量——零加成隐藏);兑付确认返回后读数刷新
|
||||
- [ ] 候选提交经组合根唯一写路径(`route_chosen` → `pick_next_node`),到达即兑付;零自动推进(无任何不选而行的路径)
|
||||
- [ ] 图上点击为唯一选路提交通道(候选按钮退役,2026-09-27 拍板);悬停预承诺反馈可见;ui_click_probe 选路段随实装批改造后全绿
|
||||
- [ ] 底部状态栏三组读数可见且与 runner 现值一致(生命当前/上限、攻击/AC 有效值、本关加成增量——零加成隐藏);兑付确认返回后读数刷新
|
||||
- [ ] 放弃按钮仅冒险模式可见(调试两层不可达);单击不提交、确认态超时回落、二击才终结(已拍板)
|
||||
- [ ] 放弃后走冒险落幕(同失败结算),已获大奖励保留语义可见
|
||||
|
||||
**模态与测试**
|
||||
|
||||
- [ ] **独立性断言**:本屏激活期战斗屏宿主整体隐藏(整屏隐藏级互斥,零透出);选路提交至战斗节点后战斗屏恢复;兑付覆盖层(节点/商店)关闭后本屏恢复——场景级断言
|
||||
- [ ] 场景级 headless 测试:真实实例化本屏 + 驱动选路全程 + 断言零脚本错误(场景探针家族扩展)
|
||||
- [ ] **独立性断言**:本屏激活期战斗屏宿主整体隐藏(`visible=false` 级互斥,零透出);选路提交至战斗节点后战斗屏恢复;兑付覆盖层(节点/商店)关闭后本屏恢复——场景级断言
|
||||
- [ ] 场景级 headless 测试:真实实例化本屏 + 驱动选路全程 + 断言零脚本错误(ui_probe 家族扩展)
|
||||
- [ ] 中文渲染无豆腐块;像素字体整数倍缩放;全部操作纯鼠标可完成
|
||||
|
||||
---
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
# 节点奖励屏 UX spec(node-reward)
|
||||
|
||||
> 状态:v2.9(现行)
|
||||
> 事实源:本 spec(呈现)+ 三选一覆盖层(共用呈现件)+ 头部行文案(旁白条目)
|
||||
> 状态:v2.9(池与交互形态同 v2.4;档名对齐四级档位框架、配额对齐现行结构锚)
|
||||
> 事实源:`game/presentation/views/curio_pick_overlay.gd`(三选一覆盖层共用面)+ `main.gd`(奖励节点分支——`adventure.node_bonus_candidates/apply_node_bonus`)+ `battle_narrator.gd`(node_bonus_header)
|
||||
> 相邻:[level-clear](level-clear.md)(关卡完成三选一面——同一覆盖层的另一上下文)/ [level-map](level-map.md)(关卡画面)/ [秘宝](../systems/跨局循环/秘宝.md)(道具件内容权威——本批起为局外同调件,不再入三选一牌库)/ [冒险结构](../systems/冒险循环/冒险结构.md)(共享池令牌库账本)
|
||||
|
||||
## 定位
|
||||
|
||||
奖励节点(reward node)到达即开的**提升三选一选择面**:**七种×档位**令牌池(攻击/生命上限/护甲/GP 袋/行动点件/恢复件/刷新件 × 普通/优秀/稀有(+传说头奖位留空)——v2.2 起秘宝件随同调批退役出池;v2.4 起=固定配额令牌池;刷新件随迭代15② T6 入池〔优秀档 2,恢复件同批挤占收窄——冒险表的令牌类型闭集第七类〕),与商店货架同库同账(v2.3)、同池耗语义、同奖励抽取封闭流。**关卡完成三选一自迭代 15② 渠道分离起候选 = 纯专长,与本面不再同池**;与关卡完成面的差异另在上下文:无部分回血、无钥石增量行,兑付后「继续」回图选路(不推进关卡)。
|
||||
奖励节点(reward node)到达即开的**提升三选一选择面**:**七种×档位**令牌池(攻击/生命上限/护甲/GP 袋/行动点件/恢复件/刷新件 × 普通/优秀/稀有(+传说头奖位留空)——v2.2 起秘宝件随同调批退役出池;v2.4 起=固定配额令牌池;刷新件随迭代15② T6 入池〔优秀档 2,恢复件同批挤占收窄——adventure_table CURIO_KINDS 第七类〕),与商店货架同库同账(v2.3)、同池耗语义、同 reward_pick 封闭流。**关卡完成三选一自迭代 15② 渠道分离起候选 = 纯专长,与本面不再同池**;与关卡完成面的差异另在上下文:无部分回血、无钥石增量行,兑付后「继续」回图选路(不推进关卡)。
|
||||
|
||||
## 布局与交互
|
||||
|
||||
- 载体 = 提升三选一覆盖层(与 [level-clear](level-clear.md) 共用组件——零新增交互原语)。
|
||||
- 头部行:「关卡奖励点 / 从冒险牌库抽三选一(属性值提升与补给;与通关专长三选一同库分流):选择一件带走:」(旁白条目)。
|
||||
- 载体 = 提升三选一覆盖层(CurioPickOverlay——curio_pick_overlay.gd,与 [level-clear](level-clear.md) 共用组件——零新增交互原语)。
|
||||
- 头部行:「关卡奖励点 / 从冒险牌库抽三选一(属性值提升与补给;与通关专长三选一同库分流):选择一件带走:」(Narrator.node_bonus_header)。
|
||||
- 三卡点选(✓ 高亮,确认前可改选)→「确认选择」→ 兑付反馈(选中件效果 + 丢弃提示)→「继续」→ 回图选路(零自动推进同款)。
|
||||
- ~~秘宝件直显/满位替换~~(v2.1 两面随池种退役——迭代 11 第①批 T7;秘宝改走营地同调装配面,见[秘宝](../systems/跨局循环/秘宝.md))。
|
||||
- **三选一刷新**(v2.2 新增——P1 甲 X/Y 双源;机制现行事实源=[秘宝](../systems/跨局循环/秘宝.md)「三选一刷新双源」节,X 源承载件已随新目录批换代〔旧目录「三选一刷新件」退役→新目录「刷新练习」〕):装配「三选一刷新件」给 X 次(每次碰三选一重给、优先消耗、不结转)+ 营地「刷新升级」给 Y 次(每冒险开局注入冒险周期池、用完即无);刷新钮余量 >0 时现形,点按重抽三候选(奖励抽取既有洗牌流,池规则全保留:不放回/达上限剔牌/掷定前置直显/停点可中断)。自动演示默认不刷(钓鱼归玩家)。
|
||||
- **三选一刷新**(v2.2 新增——P1 甲 X/Y 双源;机制现行事实源=[秘宝](../systems/跨局循环/秘宝.md)「三选一刷新双源」节,X 源承载件已随新目录批换代〔旧目录「三选一刷新件」退役→新目录「刷新练习」〕):装配「三选一刷新件」给 X 次(每次碰三选一重给、优先消耗、不结转)+ 营地「刷新升级」给 Y 次(每冒险开局注入冒险周期池、用完即无);刷新钮余量 >0 时现形,点按重抽三候选(reward_pick 既有洗牌流,池规则全保留:不放回/达上限剔牌/掷定前置直显/停点可中断)。autoplay 默认不刷(钓鱼归玩家)。
|
||||
|
||||
## 口径
|
||||
|
||||
- **同库同池耗(v2.4)**:池=固定配额令牌库(档位=四级框架 普通/优秀/稀有/传说,传说=头奖位留空〔稀有档现投放为行动点件〕;各 kind 现行配额读 `game/data/tables/adventure.tres`——「道具件 2」原列稀有档,随 aux_item 池种退役〔迭代 11 第①批 T7,落地晚于追认 b〕收窄——状态记录自决披露项);洗牌不放回抽 3(**同 kind 去重每 kind 至多一枚**——「三种不同选项」体验延续,kind 出现率∝剩余令牌数)、选中踢池未选回池、池耗即枯竭(余库不足出齐剩余,空库=零候选合法态直通);**种类次数上限退役**(池消耗即上限)。数值对:小GP 20/大GP 50、小增伤 +1/大 +2、小护甲 +1/大 +2、小生命 +5/大 +10、恢复 +6 当即回血(封顶生效上限)、AP +1。**MC 策略 316-f**:1 级优先度=最稀有(legendary>rare>excellent>common,头奖位现行留空)、2 级=最左(并列同档取最左)。配额结构锚与档位构成读冒险表(结构校验归实现侧)。**v2.3 第三渠道并账维持**:商店货架=同库付费渠道(令牌级货架,买一件=奖励面少一件),库存=剩余令牌数,账本语义与切边注记归[冒险结构](../systems/冒险循环/冒险结构.md)共享池账本节。
|
||||
- **同库同池耗(v2.4)**:池=固定配额令牌库(档位=四级框架 普通/优秀/稀有/传说,传说=头奖位留空〔稀有档现投放为行动点件〕;各 kind 现行配额读 `game/data/tables/adventure.tres`——「道具件 2」原列稀有档,随 aux_item 池种退役〔迭代 11 第①批 T7,落地晚于追认 b〕收窄——状态记录自决披露项);洗牌不放回抽 3(**同 kind 去重每 kind 至多一枚**——「三种不同选项」体验延续,kind 出现率∝剩余令牌数)、选中踢池未选回池、池耗即枯竭(余库不足出齐剩余,空库=零候选合法态直通);**种类次数上限退役**(池消耗即上限)。数值对:小GP 20/大GP 50、小增伤 +1/大 +2、小护甲 +1/大 +2、小生命 +5/大 +10、恢复 +6 当即回血(封顶生效上限)、AP +1。**MC 策略 316-f**:1 级优先度=最稀有(legendary>rare>excellent>common,头奖位现行留空)、2 级=最左(并列同档取最左)。配额结构锚与档位构成读冒险表(schema 硬断言配额结构锚——见 `data/schemas/adventure_table.gd`)。**v2.3 第三渠道并账维持**:商店货架=同库付费渠道(令牌级货架,买一件=奖励面少一件),库存=剩余令牌数,账本语义与切边注记归[冒险结构](../systems/冒险循环/冒险结构.md)共享池账本节。
|
||||
- ~~道具件入本关库存~~(v2.2 退役——秘宝局内不掉落机制道具,三轴 doctrine 锁死)。
|
||||
- ~~「池空直通」合法态~~(v2.4 随令牌池换代退役又回归异形:旧口径=GP 无上限保证牌库恒非空;现口径=固定配额池(现行值读冒险表)真可耗尽,空库=零候选直通合法态——池耗即枯竭既定后果)。
|
||||
@@ -1,7 +1,7 @@
|
||||
# 结算总结 UX spec(settlement-summary)
|
||||
|
||||
> 状态:v1.4(现行)
|
||||
> 事实源:本 spec(呈现)+ 战斗终局覆盖层(胜利金蜡封 / 失败暮蓝双形态)
|
||||
> 状态:v1.4(2026-10-26 迭代 37 结项:事实源行号引用改指拆件后现址,呈现设计与规则零变化;承 v1.3(2026-10-15 简明技术中文用语规范(用户令)批:词面修正 8 处——两面分节、纯呈现轻量 spec 不变;无新概念))
|
||||
> 事实源:`game/presentation/views/battle_end_overlay.gd`(胜利金蜡封 / 失败暮蓝双形态载体)+ `main.gd`(胜利接线:调试 `main.gd:455-461`、冒险主路径 `main_adventure_flow.gd:165`;冒险终局接线:`main_adventure_flow.gd:19` 的 `adventure_finished.connect`)
|
||||
> 相邻:[battle.md](battle.md)(战斗屏出口锚与信息归属两原则)/ [level-clear.md](level-clear.md)(关卡结算屏——Boss 胜利走大奖励面,非本 spec)/ [level-map.md](level-map.md)(GP 常驻徽章)
|
||||
|
||||
## 定位
|
||||
@@ -15,17 +15,17 @@
|
||||
|
||||
## 战斗总结结算(战斗胜利面)
|
||||
|
||||
- 触发:冒险模式战斗胜利(判胜)含 Boss 胜利——迭代 10 起 Boss 胜利也经本面(钥石逐杀掉落增量在此呈现,确认后进[关卡结算屏](level-clear.md)三选一面;原「Boss 胜利走大奖励面不经本面」口径随大奖励重构退役)。非 Boss 接线 2026-09-29 迭代 8 卡⑥。
|
||||
- 载体:战斗结束覆盖层胜利形态(金蜡封)。
|
||||
- 触发:冒险模式战斗胜利(verdict=win)含 Boss 胜利——迭代 10 起 Boss 胜利也经本面(钥石逐杀掉落增量在此呈现,确认后进[关卡结算屏](level-clear.md)三选一面;原「Boss 胜利走大奖励面不经本面」口径随大奖励重构退役)。非 Boss 接线 2026-09-29 迭代 8 卡⑥。
|
||||
- 载体:battle_end_overlay 胜利形态(金蜡封)。
|
||||
- 呈现内容(2026-09-27 拍板面 + 迭代 10 扩):金蜡封 + 判定行 + 战利品行(GP 增量 + 总量;Boss/精英击杀追加**钥石增量行**——首杀/复杀档位读 meta.tres boss_keystone)+「下一节点」钮(明细回看入口已随 2026-10-04 P-C7 退役——冒险中回看归「生涯」)。
|
||||
- 数据锚:增量 = 战斗结束信号的掉落载荷;总量 = 关卡推进方 GP 现值(关卡推进方入账先于呈现连接——次序依赖在案,M-1 迭代 2 T5 接线)。
|
||||
- 数据锚:增量 = `battle_finished` 载荷 `gp_dropped`;总量 = runner.gp 现值(LevelRunner 入账先于呈现连接——次序依赖在案,M-1 迭代 2 T5 接线)。
|
||||
- 出口:「下一节点」→ 关卡画面选路(零自动推进)。
|
||||
|
||||
## 冒险总结结算(冒险落幕面)
|
||||
|
||||
- 触发:主角倒下(判负)/ 末关完成 / 玩家放弃——三结局同面(由冒险收束信号统一触发)。
|
||||
- 载体:与战斗面同一个战斗结束覆盖层(2026-09-29 迭代 6 T7 接线)——末关通关走胜利态开屏(金蜡封 +「本局 GP 入账 · 合计 N」行,GP 收束清零前的呈现侧影子账);倒下 / 放弃走失败态开屏(暮蓝)。无独立「冒险终局面板」实体,待办清单状态记录旧称随本条完成。
|
||||
- 呈现内容:冒险摘要五件事(定义归[冒险结构](../systems/冒险循环/冒险结构.md))+ 钥石写入明细(= 本局逐杀 Boss 掉落合计;消费归[元进度](../systems/跨局循环/元进度.md) 的冒险结算入账——迭代 10 起大奖励面不再产钥石)+ GP 合计行。
|
||||
- 触发:主角倒下(verdict=lose)/ 末关完成 / 玩家放弃——三结局同面(`adventure_finished` 收束)。
|
||||
- 载体:与战斗面同一个 battle_end_overlay(2026-09-29 迭代 6 T7 接线)——末关通关走 `open_victory`(金蜡封 +「本局 GP 入账 · 合计 N」行,GP 收束清零前的呈现侧影子账);倒下 / 放弃走 `open_defeat`(暮蓝)。无独立「冒险终局面板」实体,待办清单状态记录旧称随本条完成。
|
||||
- 呈现内容:冒险摘要五件事(定义归[冒险结构](../systems/冒险循环/冒险结构.md))+ 钥石写入明细(= 本局逐杀 Boss 掉落合计;消费归[元进度](../systems/跨局循环/元进度.md) settle_adventure——迭代 10 起大奖励面不再产钥石)+ GP 合计行。
|
||||
- 出口:确认 → 回存档首页。
|
||||
|
||||
## 口径
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 商店覆盖层 UX spec(shop)
|
||||
|
||||
> 状态:v1.1(现行)
|
||||
> 事实源:本 spec(呈现)+ 商店覆盖层(呈现件)
|
||||
> 状态:v1.1(2026-09-30 审计拍板点 4B 用户裁决写入文档——甲+乙并行:编排面小节落关卡节点地图、呈现面独立成文)
|
||||
> 事实源:`game/presentation/views/shop_overlay_view.gd`(ShopOverlay)
|
||||
> 机制权威:[关卡节点地图](../systems/冒险循环/关卡节点地图.md)(商店房编排:每关恰 1/Boss 前一位必经/兑付触发);定价数值归[难度曲线与Boss](../systems/冒险循环/难度曲线与Boss.md)(shop.tres,provisional)
|
||||
|
||||
## 定位
|
||||
@@ -11,7 +11,7 @@
|
||||
## 布局与交互
|
||||
|
||||
- 模态覆盖层(dim + 居中):标题「商店」/ GP 余额读数/ 令牌级货架卡(进店自共享池抽 3 张:显示名·效果·现价——六行池面含回复与专长凭证;买一件 = 池少一件、货架随即全架重抽)/ 购买按钮(余额不足禁用置灰——pattern 8 禁用态即理由)/ 刷新按钮(GP 付费刷新,价 = ceil(20×1.8^本次进店已付费刷) provisional,余额不足禁用)/ 离开按钮。
|
||||
- 购买意图经组合根转发(pool 模式载荷 = kind_id);成功后货架整架重建(买 1 全重抽反馈)。刷新意图经组合根转交商店呈现件受理。
|
||||
- 购买意图 `buy_requested` 经组合根转发 runner(pool 模式载荷 = kind_id);成功后货架整架重建(买 1 全重抽反馈)。刷新意图 `refresh_requested` 经组合根转发 presenter。
|
||||
- 离开 → 关卡画面兑付确认回选路(零自动推进)。
|
||||
- 刷新与货架口径(2026-10-04 P-C2+Q2 裁决,SR-1 落码):基础免费 0 次 + GP 付费刷新 + 池源同源(与三选一同一令牌库本)——原「无独立刷新、全陈列」裁决随该批被推翻;天赋侧「刷新次数」增益预留 free_count 位(待办清单登记条在册)。
|
||||
|
||||
|
||||
+11
-11
@@ -1,7 +1,7 @@
|
||||
# 术语表
|
||||
|
||||
> 全库专用术语的唯一对照表(2026-10-11 用户令建立)。规矩:新术语先登记本表、再在文档使用;退役词见文末对照表,文档正文一律使用现行词。文档中遇到看不懂的词,查本表。用词纪律(禁用词、替换值、豁免范围)见「用语规范」节。
|
||||
> 状态:**现行 v1.25**——2026-10-11 建立;历次升版明细见 git 提交史。
|
||||
> 状态:**现行 v1.24**——2026-10-11 建立;历次升版明细见 git 提交史。
|
||||
|
||||
## 格与棋盘
|
||||
|
||||
@@ -12,18 +12,18 @@
|
||||
| 安全格 | 没有惩罚的格子——挖开安全并获得其上信息与收益 |
|
||||
| 整图 | 单张棋盘(的整个范围)——原「整图」退役(2026-10-11 用户裁)。例:整图叠加层、整图作用域 |
|
||||
| 叠加层(整图叠加层) | 秘宝产生的信息的自持容器:按效果分类的格集,随图消亡、不回写棋盘(见[秘宝](systems/跨局循环/秘宝.md)) |
|
||||
| 封印 / 控制 | 封印动作的机制名/玩家名:封印印记落在危险格上为「标中」(危险格被控制、化险为利),封错为「标空」(原「旗 / 控制」,2026-10-18 用户裁:「旗」概念不存在——动作=封印、印记=封印印记),板面单字字形=「封」 |
|
||||
| 封印 / 控制 | 封印动作的机制名/玩家名:封印印记落在危险格上为「标中」(危险格被控制、化险为利),封错为「标空」(原「旗 / 控制」,2026-10-18 用户裁:「旗」概念不存在——动作=封印、印记=封印印记);代码契约键与标识符统一用 `seal_*`(原 `flag_*` 全族换代),板面单字字形=「封」 |
|
||||
| 真视 | 直接告诉玩家某范围内哪些格是危险格的效果(秘宝承重契约:一次最多 3×3,见[秘宝](systems/跨局循环/秘宝.md)核心规则) |
|
||||
| 类型微光 | 棋盘上按格子类型显示的提示光效(视野参数控制其显示范围) |
|
||||
| 换图 / 弃图刷新 | 清完一图进入下一图 / 花储备放弃当前图重开一张(代价见[行动经济](systems/排雷循环/行动经济.md)) |
|
||||
| 装板(装板期) | 把地图战斗资源摇定的类型身份铺设到棋盘格子上的布置动作(阶段);由战斗结算的布置段执行,随机取数标签为 `variant_place` |
|
||||
| 摇号 / 摇定 | 按池配置用随机数决定结果(资源身份、遭遇抽取、货架抽签);随机服务为全库单点(流标签为既有事实,归属见架构文档) |
|
||||
| 摇号 / 摇定 | 按池配置用随机数决定结果(资源身份、遭遇抽取、货架抽签);随机服务实现见 `game/core/rng_service.gd`(流标签为代码事实) |
|
||||
|
||||
## 关卡与地图
|
||||
|
||||
| 术语 | 定义 |
|
||||
|---|---|
|
||||
| 信息迷雾 | 关卡节点图上按邻近层数隐藏节点类型的可见性机制——只隐藏类型,结构(节点、连线、入口、终点位置)恒可见;与「视野迷雾」(战斗棋盘按英雄曼哈顿半径遮挡格子)同词根易混。参数 N=信息可见层数(`level.tres` 的 `info_visible_layers`),机制见[关卡节点地图](systems/冒险循环/关卡节点地图.md) |
|
||||
| 信息迷雾 | 关卡节点图上按邻近层数隐藏节点类型的可见性机制——只隐藏类型,结构(节点、连线、入口、终点位置)恒可见;与「视野迷雾」(战斗棋盘按英雄曼哈顿半径遮挡格子)同词根易混,代码标识符一律不用 `fog_` 前缀。参数 N=信息可见层数(`level.tres` 的 `info_visible_layers`),机制见[关卡节点地图](systems/冒险循环/关卡节点地图.md) |
|
||||
|
||||
## 系统资源与经济
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
| 魔法护甲 | 三型甲之一(= 现役甲域 ward,基础 AC 最低、被普通攻击克);「魔法甲」系笔误、非别名,不单独登记 |
|
||||
| 并联双通道 | 待解锁路线的解锁结构:练满前一档 **OR** 一次性解锁价,两通道互不影响、玩家自选其一、不设串联门槛 |
|
||||
| 出场选择 | 一次冒险 = 一个武器类型 + 一个甲型;营地内免费切换、冒险开始后锁死 |
|
||||
| 路线 id / 存档域键名 | 锻造工坊实现层词汇(非玩家可见,2026-10-13 迭代 23 反哺落文登记):六路线 id = sword/spear/staff/light/heavy/ward(甲路线 id = 甲型值本身);存档域 `forge_routes = {levels〔六路线等级〕, unlocked〔直购解锁清单〕, weapon/armor〔当前选中〕}`——初始持有与练满前一档为派生解锁不落档(派生单点 = 解锁判定) |
|
||||
| 路线 id / 存档域键名 | 锻造工坊实现层词汇(非玩家可见,2026-10-13 迭代 23 反哺落文登记):六路线 id = sword/spear/staff/light/heavy/ward(甲路线 id = 甲型值本身);存档域 `forge_routes = {levels〔六路线等级〕, unlocked〔直购解锁清单〕, weapon/armor〔当前选中〕}`——初始持有与练满前一档为派生解锁不落档(派生单点 = forge_route_unlocked) |
|
||||
|
||||
## 道具体系
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
| 术语 | 定义 |
|
||||
|---|---|
|
||||
| `seal_missed` | 封印落空事件(旧名已换代):封印动作落在安全格上时发出,订阅面据此做限次与豁免判定(迭代 31 卡② 落地) |
|
||||
| `seal_missed` | 封印落空事件(原 `flag_missed` 换代):封印动作落在安全格上时发出,订阅面据此做限次与豁免判定(迭代 31 卡② 落地) |
|
||||
| `forgive_seal_miss` | 本场首次封印落空豁免——专长「完美保险」的效果类型,`domain=battle` 首例;有效误标=误标总数 − 豁免数,豁免不改写误标账(迭代 31 卡② 落地) |
|
||||
|
||||
## 美术表现
|
||||
@@ -120,9 +120,9 @@
|
||||
|
||||
## 用语规范(2026-10-15 用户令立)
|
||||
|
||||
词面纪律的登记处。通用禁用词与选词以**简明技术中文(STC)词表**为权威:外部同名词表,约 170 条,配检查脚本。
|
||||
词面纪律的登记处。通用禁用词与选词以**简明技术中文(STC)词表**为权威:外部技能文件 `C:\Users\DK\.zcode\skills\simplified-technical-chinese\词表.md`,约 170 条,配检查脚本 check.py。
|
||||
|
||||
本仓库的机器闸 = 用语审计(闸件清单唯一出处=process-conventions 运行与验证节),已吸收本节项目裁项。**词表冻结**:本节与该闸的禁用词表不再扩充,扩表唯一入口=用户实读反馈并经用户裁决(由工程/文档设计改动批写入,agent 禁自行增词)。本节只登记两类裁项:A 已裁替换、B 豁免条款。历史退役词(雷格/正主/落籍等 7 组)见下方「退役词对照」节,不与 A 表重复。
|
||||
本仓库的机器闸 = `tools/doc_term_audit.py`,已吸收本节项目裁项。**词表冻结**:本节与该闸的禁用词表不再扩充,扩表唯一入口=用户实读反馈并经用户裁决(由工程/文档设计改动批写入,agent 禁自行增词)。本节只登记两类裁项:A 已裁替换、B 豁免条款。历史退役词(雷格/正主/落籍等 7 组)见下方「退役词对照」节,不与 A 表重复。
|
||||
|
||||
### A. 已裁替换(写新文本必须用「用」列)
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
1. **历史文本**:git 提交说明、裁决记录中引用用户原话的句子——保留原用词,不按 A 表追改。
|
||||
2. **对照性文本**:「退役词对照」表本身、「原 ××」式更名记载、禁令引举句——旧词在这些位置是内容本身,不是残留。
|
||||
3. **玩家可见专名与机制词**:按「对外命名纪律」节与各系统文档现行用语使用(标中/踩雷等机制词在文档内部照常用)。
|
||||
4. **被检查的禁字不算使用**:守卫里作为检查对象的禁字字面量——核心层检字断言所检查的禁字本身、呈现层字形集负探针、`game/data/tables/feats.tres` 头注的「desc 禁『雷/旗』字面」、用语审计闸的退役词表定义行——不属换代范围:被检查的字不是对该字的使用,改写等于自毁守卫。术语清扫的复扫口径按 **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 表换代。
|
||||
|
||||
@@ -168,11 +168,11 @@
|
||||
| 插旗 | 封印(2026-10-18 用户裁:封印=正式动作名,全库统一,非比喻非「对外表达」别名) |
|
||||
| 旗(游戏概念语境) | 封印印记(2026-10-18 用户裁:「旗」概念不存在——封印动作落下的印记称封印印记) |
|
||||
| flag_*(代码契约键/标识符) | seal_*(2026-10-18 用户裁全族换代;迭代 31 卡① 已清零) |
|
||||
| 系统级断言套件 / 冒烟全量 | 系统测试(2026-10-22 用户裁——标准四级测试层之一:启动真实工程走真实玩法路径的断言面;依据=提案正文 §二)(《提案-测试术语与层级重构方案》已退役,考古=git 历史——删除批与删除前全稿均可在其中查得) |
|
||||
| 系统级断言套件 / 冒烟全量 | 系统测试(2026-10-22 用户裁——标准四级测试层之一:启动真实工程走真实玩法路径的断言面;依据=提案正文 §二)(《提案-测试术语与层级重构方案》已退役,考古=git 历史——删除批 53075baa,删除前全稿见历史版本 b4da36a8) |
|
||||
| 单元套件 | 单元测试(2026-10-22 用户裁——标准四级测试层之一,「套件」单独成词非必要) |
|
||||
| 启动探针 / 秒级冒烟探针 / L0–L3 | 冒烟测试(2026-10-22 用户裁——极小启动场景:能否启动、能否加载表、能否进主屏,零逻辑判定) |
|
||||
| 轻闸 / 重闸 / 三查 | (随 2026-10-22 频率规则消亡,无替代词——检出工作区零测试;卡内只测自己改的东西;全量只在收尾与合回两个时机。机制词「去重闸」含「重闸」二字但与此无关,不在退役之列) |
|
||||
| 魔法道具 | 秘宝(2026-10-26 用户裁入表:秘宝系统旧中文规范名,2026-10-05 已更名) |
|
||||
| 魔法道具 | 秘宝(2026-10-26 用户裁入表:AUXILIARY_ITEMS 旧中文规范名,2026-10-05 已更名) |
|
||||
| 罕见(档位名) | 稀有(2026-10-26 用户裁入表:旧三档档位名,现行四级第三档=稀有;散文形容词义不受限) |
|
||||
| 通关 | 关卡完成(单关)/冒险成功(整局)——2026-10-26 用户裁:主体明确短语族替代歧义单义词 |
|
||||
| 冒险终结 | 冒险落幕——2026-10-26 通关口径统一批 |
|
||||
|
||||
@@ -36,10 +36,10 @@ const SOURCE_EXEMPT_CLASSES := ["hero_attack", "enemy_action", "clear_reward", "
|
||||
|
||||
var db: ConfigDb
|
||||
var rng: RngServiceCore
|
||||
# E1 封装收口:协作对象 enemy_system/status_effects/reward_economy 私有化——跨层读取一律经 presentation_snapshot()/diagnostic_snapshot() 成文出口。
|
||||
# E1 封装收口:协作对象 board_generator/enemy_system/status_effects/reward_economy 私有化——跨层读取一律经 presentation_snapshot()/diagnostic_snapshot() 成文出口。
|
||||
# minesweeper/action_economy 保持公有 = 架构文档 API Boundaries 的 HUD框架消费面(意图提交 settle_batch + compute_move_path
|
||||
# 只读;ap/rap/相位读取)——非本文档登记的契约面,勿增新用途。
|
||||
# 装板域(BoardGenerator+装板六函数族)已拆 BoardInstaller——生成器实例随件自建,宿主零成员。
|
||||
var _board_generator: BoardGenerator
|
||||
var minesweeper: MinesweeperRules
|
||||
var action_economy: ActionEconomy
|
||||
var _enemy_system: UnitContainer
|
||||
@@ -230,12 +230,13 @@ var _hero_atk := 0 # 主角攻击基值快照(encounte
|
||||
func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void:
|
||||
db = db_ref
|
||||
rng = rng_ref
|
||||
_board_generator = BoardGenerator.new()
|
||||
action_economy = ActionEconomy.new(db)
|
||||
minesweeper = MinesweeperRules.new(db, action_economy)
|
||||
_enemy_system = UnitContainer.new(db)
|
||||
_status_effects = StatusContainer.new(db)
|
||||
_reward_economy = RewardEconomy.new(db, rng)
|
||||
_reward_economy.fatal_handler = _fatal # 协作件违约→本类 _fatal 封印(单点接线)
|
||||
_board_generator.fatal_handler = _fatal; _reward_economy.fatal_handler = _fatal # 协作件违约→本类 _fatal 封印(单点接线)
|
||||
_damage = DamageController.new(db, rng, _enemy_system, _status_effects)
|
||||
_damage.emit_row_cb = _emit_row # 行协议归属本类(9 类行协议 + 来源断言不外泄)
|
||||
_fx_host = BattleFxHost.new({"db": db, "rng": rng, "minesweeper": minesweeper, "action_economy": action_economy,
|
||||
@@ -267,7 +268,7 @@ func begin_battle(enc: Dictionary) -> bool:
|
||||
return false
|
||||
if not _begin_battle_accept(enc):
|
||||
return false
|
||||
if not _install_and_reset():
|
||||
if not _install_new_board():
|
||||
return false
|
||||
_reset_round_facts() # 首板 install 的初始展开事件不入轮 facts(resource 恒 false 的双保险)
|
||||
_begin_battle_fx_state(enc)
|
||||
@@ -410,14 +411,34 @@ func _begin_battle_preview_economy(enc: Dictionary) -> void:
|
||||
action_economy.grant_reserve_ap(voucher_rap)
|
||||
|
||||
|
||||
# ---- 装板受理薄壳(BoardInstaller 拆件后的宿主承接面——begin_battle/中途刷新/轮内刷新三调用点唯一入口)----
|
||||
# 件内装板(生成→全局变异决议→装板受理→资源摇号→变异布置)成功后执行宿主态复位:五处计数清零+
|
||||
# 板序推进+board_changed 发射+秘宝叠加层退役——时序逐字;复位职责留宿主(成员单点),不随件。
|
||||
func _install_and_reset(during_round := false) -> bool:
|
||||
var installer := BoardInstaller.new({"db": db, "rng": rng, "minesweeper": minesweeper,
|
||||
"reward_economy": _reward_economy, "encounter": encounter, "fatal_cb": _fatal})
|
||||
if not installer.install(during_round):
|
||||
func _install_new_board(during_round := false) -> bool:
|
||||
var stream: RandomNumberGenerator = rng.open_stream("board_gen")
|
||||
var board: BoardData = _board_generator.generate(int(encounter.level_index), int(encounter.node_depth), stream, db)
|
||||
if board == null:
|
||||
return false
|
||||
# 全局作用域变异决议(装板序内前置于 roll_board:图级偏斜旋钮须在资源摇号前定型——详见 _resolve_global_variant)
|
||||
_resolve_global_variant(board)
|
||||
var res: Dictionary[Variant, Variant] = minesweeper.install_board(board, during_round)
|
||||
if not res.accepted:
|
||||
_fatal("排雷玩法 install 拒绝(不变式违例): %s" % str(res))
|
||||
return false
|
||||
# 地图战斗资源 义务⑥:roll_board 恰一次(install 后、挖掘前);资格格 = 全部非封锁格(安全格 + 危险格,雷安同池)
|
||||
var r0 := {}
|
||||
for c in board.compute_r0():
|
||||
r0[c] = true
|
||||
var eligible: Array[Dictionary] = []
|
||||
for c in board.safe_cells():
|
||||
if not r0.has(c):
|
||||
eligible.append({"cell": c})
|
||||
for c in board.mines.keys():
|
||||
if not r0.has(c):
|
||||
eligible.append({"cell": c})
|
||||
if not _reward_economy.roll_board(eligible):
|
||||
_fatal("地图战斗资源 roll_board 被拒")
|
||||
return false
|
||||
# 地形变异 布置段(棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 →
|
||||
# 战斗资源格设置 → 变异格设置)——布置在初始展开与资源格之后,变异天然不落已开区
|
||||
_place_variants(board)
|
||||
_seal_consumed.clear() # 换图新雷 = 新实例,资格自然重置(行动经济 Rule 8)
|
||||
_seal_miss_seen.clear()
|
||||
_perfect_hit_true = 0 # 整图完美计数随 install 重置
|
||||
@@ -431,6 +452,103 @@ func _install_and_reset(during_round := false) -> bool:
|
||||
return true
|
||||
|
||||
|
||||
# ---- 全局作用域变异 决议(装板序内 roll_board 之前)----
|
||||
# boss/elite 图命中全局型:写整图 board_variants(恰一行)+ 注入资源面偏斜旋钮(图级投影在
|
||||
# RewardEconomy.roll_board 消费);不消费 variant_place 流(全局取用确定性——零取号合法态)。
|
||||
# 全局池空(含 L1 Boss 免疫/unlock 门控未达):字段留空、旋钮归零——_place_variants 原路走
|
||||
# region 布置 = 兜底回落合法态(防配置缺行静默裸奔——provisional)。
|
||||
func _resolve_global_variant(board: BoardData) -> void:
|
||||
board.board_variants.clear()
|
||||
_reward_economy.board_skew = 0
|
||||
var row: Dictionary[Variant, Variant] = db.combat.variation.global_variant_row(int(encounter.level_index), String(board.board_type),
|
||||
String(encounter.get("node_type", "")))
|
||||
if row.is_empty():
|
||||
return
|
||||
board.board_variants = [String(row.variant_id)]
|
||||
_reward_economy.board_skew = int(row.get("effect_value", 0))
|
||||
|
||||
|
||||
# ---- 地形变异 布置段(棋盘设置顺序第 4 步)----
|
||||
# 候选池门控(unlock_level ≤ 关卡序号 + board_types 与本地形交集,∅ 通配)经 config_db.variant_pool;
|
||||
# 池空 = 合法态,静默零布置(框架 P0 口径不变)。零特判:本段只写格子变异数据快照,不改扫雷规则本体。
|
||||
# 候选格域 = 安全格 − 初始展开区(伤害型 placement=closed_only 的结构保障——布置发生在初始展开之后,
|
||||
# 已开格天然排除);危险格不吃变异(挖雷一层惩罚 + 变异伤害双层叠罚污染逐行归因,首版排除——provisional)。
|
||||
# 每图至多一种类型(候选池内均匀选一);数量 = round(候选池格数×percent) +
|
||||
# (关卡序号−1)×per_level_bonus——基数为候选池而非总格数(percent 语义 = 占可挖格比例,
|
||||
# 关卡递增由 per_level_bonus 绝对格数承载);连通片生长(8 邻),单片 ≤ pack_max。
|
||||
# 替换制:整图 board_variants 非空 = 本图已带全局型,跳过 region 布置(详见 _resolve_global_variant)。
|
||||
func _place_variants(board: BoardData) -> void:
|
||||
if not board.board_variants.is_empty():
|
||||
return
|
||||
var pool: Array[Variant] = db.combat.variation.variant_pool(int(encounter.level_index), String(board.board_type))
|
||||
if pool.is_empty():
|
||||
return
|
||||
var r0 := {}
|
||||
for c in board.compute_r0():
|
||||
r0[c] = true
|
||||
var candidates: Array[Vector2i] = []
|
||||
for c in board.safe_cells():
|
||||
if not r0.has(c):
|
||||
candidates.append(c)
|
||||
if candidates.is_empty():
|
||||
return
|
||||
var stream: RandomNumberGenerator = rng.open_stream("variant_place") # 一板恰一 scope(换图/刷新图各取号一次)
|
||||
var vrow: Dictionary[Variant, Variant] = pool[stream.randi_range(0, pool.size() - 1)]
|
||||
var total: int = int(round(float(candidates.size()) * float(db.combat.variation.percent_of_cells) / 100.0)) \
|
||||
+ (int(encounter.level_index) - 1) * int(db.combat.variation.per_level_bonus)
|
||||
total = mini(total, candidates.size())
|
||||
_place_variants_apply(board, candidates, stream, vrow, total)
|
||||
|
||||
|
||||
# 变异片生长施加面(布置域=候选格,数量=total,vrow 单型贯穿;取号序=stream 顺序消费)
|
||||
func _place_variants_apply(board: BoardData, candidates: Array[Vector2i], stream: RandomNumberGenerator, vrow: Dictionary, total: int) -> void:
|
||||
var placed := {}
|
||||
while placed.size() < total:
|
||||
var pack_size: int = mini(total - placed.size(), stream.randi_range(2, int(db.combat.variation.pack_max)))
|
||||
var free: Array[Vector2i] = []
|
||||
for c in candidates:
|
||||
# 新片种子/生长格禁与其他已布片 8 邻贴接——否则两片粘连成一个超 pack_max 的连通分量
|
||||
# (R3 随机流下实测暴露:独立生长的相邻片合流击穿单片上限断言)
|
||||
if placed.has(c) or _adjacent_to_packs(board, placed, c):
|
||||
continue
|
||||
free.append(c)
|
||||
if free.is_empty():
|
||||
break # 生长域耗尽——该片就地收束(数量不足总目标为合法态,候选域碎片化时触发)
|
||||
var seed_c: Vector2i = free[stream.randi_range(0, free.size() - 1)]
|
||||
placed[seed_c] = true
|
||||
var pack: Array[Variant] = [seed_c]
|
||||
var pack_set := {seed_c: true}
|
||||
while pack.size() < pack_size:
|
||||
var fringe := _variants_fringe(board, pack, candidates, placed, pack_set)
|
||||
if fringe.is_empty():
|
||||
break # 生长域耗尽——该片就地收束(数量不足总目标为合法态,候选域碎片化时触发)
|
||||
var nxt: Vector2i = fringe[stream.randi_range(0, fringe.size() - 1)]
|
||||
placed[nxt] = true
|
||||
pack_set[nxt] = true
|
||||
pack.append(nxt)
|
||||
for c in placed.keys():
|
||||
board.variants[c] = [String(vrow.variant_id)]
|
||||
|
||||
|
||||
# 片生长待选格收集(本片内各生长格的 8 邻候选并集——未布置、未在途、不与他片贴接)
|
||||
func _variants_fringe(board: BoardData, pack: Array, candidates: Array[Vector2i], placed: Dictionary, pack_set: Dictionary) -> Array[Vector2i]:
|
||||
var fringe: Array[Vector2i] = []
|
||||
for c in pack:
|
||||
for n in board.neighbors8(c):
|
||||
if candidates.has(n) and not placed.has(n) and not fringe.has(n) \
|
||||
and not _adjacent_to_packs(board, placed, n, pack_set):
|
||||
fringe.append(n)
|
||||
return fringe
|
||||
|
||||
|
||||
# 候选格是否与其他已布片(own_pack 之外的 placed 格)8 邻贴接——片间隔离保证连通分量 = 单片 ≤ pack_max
|
||||
func _adjacent_to_packs(board: BoardData, placed: Dictionary, c: Vector2i, own_pack: Dictionary = {}) -> bool:
|
||||
for m in board.neighbors8(c):
|
||||
if placed.has(m) and not own_pack.has(m):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
# ---- 事件缓冲(轮 facts 收集;结算触发 = Waiting 相位编排点,不依赖到达序)----
|
||||
|
||||
func _on_cell_revealed(evt: Dictionary) -> void:
|
||||
@@ -680,7 +798,7 @@ func _exit_distribution() -> void:
|
||||
if mode == "new_board":
|
||||
_reward_economy.retire_mapping()
|
||||
minesweeper.retire_board()
|
||||
if not _install_and_reset():
|
||||
if not _install_new_board():
|
||||
_fatal("换图编排失败")
|
||||
return
|
||||
# 工兵晨令续队直调拆除(内容数据驱动扩展批 T4——round_start 订阅行承载,见 begin_battle 注)
|
||||
@@ -714,7 +832,7 @@ func player_request_refresh() -> bool:
|
||||
_refresh_used_this_round += 1
|
||||
_reward_economy.retire_mapping() # 旧图批次退役(地图战斗资源 Ready→retired;E6 新批重置前提)
|
||||
minesweeper.retire_board(true) # 旧板退役(轮内通道)
|
||||
return _install_and_reset(true) # 当场换图——失败即编排违例 fail-fast
|
||||
return _install_new_board(true) # 当场换图——失败即编排违例 fail-fast
|
||||
|
||||
|
||||
func _battle_over(result: String) -> void:
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
## 棋盘安装与变异布置域件(B1 域·BoardInstaller):生成受理、全局作用域变异决议、装板受理、
|
||||
## 资源摇号资格域组装(roll_board 恰一次——install 后、挖掘前)、region 变异决议与连通片布置。
|
||||
## 棋盘设置顺序 = 生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置(布置在初始展开与
|
||||
## 资源格之后,变异天然不落已开区)。宿主侧装板后状态复位(封印/完美计数清零、板序推进、
|
||||
## board_changed 发射、秘宝叠加层退役)留宿主薄壳——本件零复位职责。零 UI 零 await;
|
||||
## 随机只经注入 RngServiceCore 的 board_gen/variant_place 两封闭流(流名与开流时点不变,
|
||||
## 生成器只消费传入流——同种子同输入逐位复现)。
|
||||
class_name BoardInstaller
|
||||
extends RefCounted
|
||||
|
||||
var db: ConfigDb
|
||||
var rng: RngServiceCore
|
||||
var minesweeper: MinesweeperRules
|
||||
var reward_economy: RewardEconomy
|
||||
var encounter: Dictionary[String, Variant] # 宿主 encounter 同对象引用(assign 原地变异——跨战活引用)
|
||||
var fatal_cb: Callable # 协作件违约→宿主 _fatal 封印(单点接线——BoardGenerator 同款)
|
||||
var generator: BoardGenerator # 件内自建自接线(原宿主 _board_generator 成员随件迁移)
|
||||
|
||||
|
||||
func _init(bundle: Dictionary) -> void:
|
||||
for k in ["db", "rng", "minesweeper", "reward_economy", "encounter", "fatal_cb"]:
|
||||
assert(bundle.has(k), "[装板域件] 引用束缺键: %s" % k)
|
||||
db = bundle.db
|
||||
rng = bundle.rng
|
||||
minesweeper = bundle.minesweeper
|
||||
reward_economy = bundle.reward_economy
|
||||
encounter = bundle.encounter
|
||||
fatal_cb = bundle.fatal_cb
|
||||
generator = BoardGenerator.new()
|
||||
generator.fatal_handler = fatal_cb # 协作件违约→宿主 _fatal 封印(单点接线)
|
||||
|
||||
|
||||
func _fatal(msg: String) -> void:
|
||||
if fatal_cb.is_valid():
|
||||
fatal_cb.call(msg) # 组装层注入 orchestrator._fatal(封印传导,不绕第二中止通道)
|
||||
else:
|
||||
push_error(msg)
|
||||
assert(false, msg)
|
||||
|
||||
|
||||
# 装板单入口(生成 → 全局变异决议 → 装板受理 → 资源摇号 → 变异布置);
|
||||
# 宿主态复位归宿主薄壳(_install_and_reset)——本件返回即装板完成、复位未行。
|
||||
func install(during_round := false) -> bool:
|
||||
var stream: RandomNumberGenerator = rng.open_stream("board_gen")
|
||||
var board: BoardData = generator.generate(int(encounter.level_index), int(encounter.node_depth), stream, db)
|
||||
if board == null:
|
||||
return false
|
||||
# 全局作用域变异决议(装板序内前置于 roll_board:图级偏斜旋钮须在资源摇号前定型——详见 _resolve_global_variant)
|
||||
_resolve_global_variant(board)
|
||||
var res: Dictionary[Variant, Variant] = minesweeper.install_board(board, during_round)
|
||||
if not res.accepted:
|
||||
_fatal("排雷玩法 install 拒绝(不变式违例): %s" % str(res))
|
||||
return false
|
||||
# 地图战斗资源 义务⑥:roll_board 恰一次(install 后、挖掘前);资格格 = 全部非封锁格(安全格 + 危险格,雷安同池)
|
||||
var r0 := {}
|
||||
for c in board.compute_r0():
|
||||
r0[c] = true
|
||||
var eligible: Array[Dictionary] = []
|
||||
for c in board.safe_cells():
|
||||
if not r0.has(c):
|
||||
eligible.append({"cell": c})
|
||||
for c in board.mines.keys():
|
||||
if not r0.has(c):
|
||||
eligible.append({"cell": c})
|
||||
if not reward_economy.roll_board(eligible):
|
||||
_fatal("地图战斗资源 roll_board 被拒")
|
||||
return false
|
||||
# 地形变异 布置段(棋盘设置顺序第 4 步)——布置在初始展开与资源格之后,变异天然不落已开区
|
||||
_place_variants(board)
|
||||
return true
|
||||
|
||||
|
||||
# ---- 全局作用域变异 决议(装板序内 roll_board 之前)----
|
||||
# boss/elite 图命中全局型:写整图 board_variants(恰一行)+ 注入资源面偏斜旋钮(图级投影在
|
||||
# RewardEconomy.roll_board 消费);不消费 variant_place 流(全局取用确定性——零取号合法态)。
|
||||
# 全局池空(含 L1 Boss 免疫/unlock 门控未达):字段留空、旋钮归零——_place_variants 原路走
|
||||
# region 布置 = 兜底回落合法态(防配置缺行静默裸奔——provisional)。
|
||||
func _resolve_global_variant(board: BoardData) -> void:
|
||||
board.board_variants.clear()
|
||||
reward_economy.board_skew = 0
|
||||
var row: Dictionary[Variant, Variant] = db.combat.variation.global_variant_row(int(encounter.level_index), String(board.board_type),
|
||||
String(encounter.get("node_type", "")))
|
||||
if row.is_empty():
|
||||
return
|
||||
board.board_variants = [String(row.variant_id)]
|
||||
reward_economy.board_skew = int(row.get("effect_value", 0))
|
||||
|
||||
|
||||
# ---- 地形变异 布置段(棋盘设置顺序第 4 步)----
|
||||
# 候选池门控(unlock_level ≤ 关卡序号 + board_types 与本地形交集,∅ 通配)经 config_db.variant_pool;
|
||||
# 池空 = 合法态,静默零布置(框架 P0 口径不变)。零特判:本段只写格子变异数据快照,不改扫雷规则本体。
|
||||
# 候选格域 = 安全格 − 初始展开区(伤害型 placement=closed_only 的结构保障——布置发生在初始展开之后,
|
||||
# 已开格天然排除);危险格不吃变异(挖雷一层惩罚 + 变异伤害双层叠罚污染逐行归因,首版排除——provisional)。
|
||||
# 每图至多一种类型(候选池内均匀选一);数量 = round(候选池格数×percent) +
|
||||
# (关卡序号−1)×per_level_bonus——基数为候选池而非总格数(percent 语义 = 占可挖格比例,
|
||||
# 关卡递增由 per_level_bonus 绝对格数承载);连通片生长(8 邻),单片 ≤ pack_max。
|
||||
# 替换制:整图 board_variants 非空 = 本图已带全局型,跳过 region 布置(详见 _resolve_global_variant)。
|
||||
func _place_variants(board: BoardData) -> void:
|
||||
if not board.board_variants.is_empty():
|
||||
return
|
||||
var pool: Array[Variant] = db.combat.variation.variant_pool(int(encounter.level_index), String(board.board_type))
|
||||
if pool.is_empty():
|
||||
return
|
||||
var r0 := {}
|
||||
for c in board.compute_r0():
|
||||
r0[c] = true
|
||||
var candidates: Array[Vector2i] = []
|
||||
for c in board.safe_cells():
|
||||
if not r0.has(c):
|
||||
candidates.append(c)
|
||||
if candidates.is_empty():
|
||||
return
|
||||
var stream: RandomNumberGenerator = rng.open_stream("variant_place") # 一板恰一 scope(换图/刷新图各取号一次)
|
||||
var vrow: Dictionary[Variant, Variant] = pool[stream.randi_range(0, pool.size() - 1)]
|
||||
var total: int = int(round(float(candidates.size()) * float(db.combat.variation.percent_of_cells) / 100.0)) \
|
||||
+ (int(encounter.level_index) - 1) * int(db.combat.variation.per_level_bonus)
|
||||
total = mini(total, candidates.size())
|
||||
_place_variants_apply(board, candidates, stream, vrow, total)
|
||||
|
||||
|
||||
# 变异片生长施加面(布置域=候选格,数量=total,vrow 单型贯穿;取号序=stream 顺序消费)
|
||||
func _place_variants_apply(board: BoardData, candidates: Array[Vector2i], stream: RandomNumberGenerator, vrow: Dictionary, total: int) -> void:
|
||||
var placed := {}
|
||||
while placed.size() < total:
|
||||
var pack_size: int = mini(total - placed.size(), stream.randi_range(2, int(db.combat.variation.pack_max)))
|
||||
var free: Array[Vector2i] = []
|
||||
for c in candidates:
|
||||
# 新片种子/生长格禁与其他已布片 8 邻贴接——否则两片粘连成一个超 pack_max 的连通分量
|
||||
# (R3 随机流下实测暴露:独立生长的相邻片合流击穿单片上限断言)
|
||||
if placed.has(c) or _adjacent_to_packs(board, placed, c):
|
||||
continue
|
||||
free.append(c)
|
||||
if free.is_empty():
|
||||
break # 生长域耗尽——该片就地收束(数量不足总目标为合法态,候选域碎片化时触发)
|
||||
var seed_c: Vector2i = free[stream.randi_range(0, free.size() - 1)]
|
||||
placed[seed_c] = true
|
||||
var pack: Array[Variant] = [seed_c]
|
||||
var pack_set := {seed_c: true}
|
||||
while pack.size() < pack_size:
|
||||
var fringe := _variants_fringe(board, pack, candidates, placed, pack_set)
|
||||
if fringe.is_empty():
|
||||
break # 生长域耗尽——该片就地收束(数量不足总目标为合法态,候选域碎片化时触发)
|
||||
var nxt: Vector2i = fringe[stream.randi_range(0, fringe.size() - 1)]
|
||||
placed[nxt] = true
|
||||
pack_set[nxt] = true
|
||||
pack.append(nxt)
|
||||
for c in placed.keys():
|
||||
board.variants[c] = [String(vrow.variant_id)]
|
||||
|
||||
|
||||
# 片生长待选格收集(本片内各生长格的 8 邻候选并集——未布置、未在途、不与他片贴接)
|
||||
func _variants_fringe(board: BoardData, pack: Array, candidates: Array[Vector2i], placed: Dictionary, pack_set: Dictionary) -> Array[Vector2i]:
|
||||
var fringe: Array[Vector2i] = []
|
||||
for c in pack:
|
||||
for n in board.neighbors8(c):
|
||||
if candidates.has(n) and not placed.has(n) and not fringe.has(n) \
|
||||
and not _adjacent_to_packs(board, placed, n, pack_set):
|
||||
fringe.append(n)
|
||||
return fringe
|
||||
|
||||
|
||||
# 候选格是否与其他已布片(own_pack 之外的 placed 格)8 邻贴接——片间隔离保证连通分量 = 单片 ≤ pack_max
|
||||
func _adjacent_to_packs(board: BoardData, placed: Dictionary, c: Vector2i, own_pack: Dictionary = {}) -> bool:
|
||||
for m in board.neighbors8(c):
|
||||
if placed.has(m) and not own_pack.has(m):
|
||||
return true
|
||||
return false
|
||||
@@ -1 +0,0 @@
|
||||
uid://di6u170vqf8ae
|
||||
+94
-14
@@ -41,7 +41,7 @@ var hero_hp: int:
|
||||
var gp: int: # GP 冒险钱包(局内货币——冒险开始 = 0、收束清零;不入存档不入摘要)
|
||||
get: return _wallet.gp
|
||||
set(v): _wallet.gp = v
|
||||
var shop: ShopSession = null # 商店件(_init 建;双模式货架/定价/购买/刷新唯一宿主)
|
||||
var _shop: ShopSession = null # 商店件(_init 建;双模式货架/定价/购买/刷新唯一宿主)
|
||||
# 协作对象私有(E1/E3 封装收口):settlement 读取经 current_battle() 成文出口
|
||||
var _settlement: BattleOrchestrator = null # 当前战斗编排器(关卡结束置 null)
|
||||
var treasure_inventory: TreasureItems = null # 秘宝 关卡域库存(TreasureItems;跨战斗延续,
|
||||
@@ -96,10 +96,10 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore, ctx: Dictionary = {}) -> v
|
||||
_hero_armor_type = String(ctx.get("hero_armor_type", ""))
|
||||
_voucher_rap = maxi(0, int(ctx.get("voucher_rap", 0)))
|
||||
_voucher_time_sand = maxi(0, int(ctx.get("voucher_time_sand", 0)))
|
||||
shop = ShopSession.new(db, rng)
|
||||
_shop = ShopSession.new(db, rng)
|
||||
var pool: Dictionary[Variant, Variant] = ctx.get("pool_wiring", {}) as Dictionary
|
||||
if String(ctx.get("shop_mode", "")) == "pool" and not pool.is_empty():
|
||||
shop.set_shop_pool(pool.get("deck", []) as Array, pool.get("consume", Callable()) as Callable,
|
||||
_shop.set_shop_pool(pool.get("deck", []) as Array, pool.get("consume", Callable()) as Callable,
|
||||
pool.get("ticket", Callable()) as Callable, pool.get("cap", Callable()) as Callable)
|
||||
_bind_shop()
|
||||
|
||||
@@ -302,8 +302,8 @@ func breakpoint_fragment() -> Dictionary[Variant, Variant]:
|
||||
"node_id": current_node_id(),
|
||||
"visited_ids": visited_ids(),
|
||||
"aux_items": treasure_snapshot,
|
||||
"shop_shelf": shop.shop_bp_shelf(),
|
||||
"shop_visit_buys": shop.shop_bp_visit_buys(),
|
||||
"shop_shelf": _shop.shop_bp_shelf(),
|
||||
"shop_visit_buys": _shop.shop_bp_visit_buys(),
|
||||
}
|
||||
|
||||
|
||||
@@ -503,11 +503,11 @@ func _enter_node(node: Dictionary) -> bool:
|
||||
"shop":
|
||||
# 商店房兑付:到达即开店(覆盖层归呈现层),购买出账/
|
||||
# 离开归玩家意图——零自动推进;离开确认经 continue_after_node 回选路口
|
||||
var payload := {"gp": gp} # legacy 固定三件(off 对照承载——零 RNG 零池消费)
|
||||
if shop.pool_mode:
|
||||
shop.open_pool() # 进店抽 3(恰一 shop_draw scope;买后全重抽同签)
|
||||
payload = {"gp": gp, "shelf": true}
|
||||
node_entered.emit(node, payload)
|
||||
if _shop.pool_mode:
|
||||
_shop.open_pool() # 进店抽 3(恰一 shop_draw scope;买后全重抽同签)
|
||||
node_entered.emit(node, {"gp": gp, "shelf": true})
|
||||
return true
|
||||
node_entered.emit(node, {"gp": gp}) # legacy 固定三件(off 对照承载——零 RNG 零池消费)
|
||||
return true
|
||||
push_error("[关卡节点地图] 未知节点类型: %s" % str(node))
|
||||
return false
|
||||
@@ -701,7 +701,7 @@ func continue_after_node() -> bool:
|
||||
if t != "reward" and t != "rest" and t != "shop":
|
||||
return false
|
||||
if t == "shop":
|
||||
shop.leave() # 离开店面货架态清零(断点快照 shop_shelf 键随离开落空架合法态)
|
||||
_shop.leave() # 离开店面货架态清零(断点快照 shop_shelf 键随离开落空架合法态)
|
||||
return _present_choices()
|
||||
|
||||
|
||||
@@ -721,12 +721,12 @@ func close_wallet() -> void:
|
||||
|
||||
|
||||
# ---- 商店房兑付(GP+商店房实施批:呈现层只读投影 + 购买出账)----
|
||||
# 实装归 ShopSession 件(双模式货架/定价/购买/刷新唯一宿主);外部调用面=调用方经宿主公开
|
||||
# 成员 shop 直连(调用直连不留委托壳——2026-10-26 Middle Man 裁定)。
|
||||
# 实装归 ShopSession 件(双模式货架/定价/购买/刷新唯一宿主);本类保留同签名委托与件注入/
|
||||
# 白盒入口——外部调用面与断点取数面零变化。
|
||||
|
||||
# 件注入(建件与宿主引用换代时调用——钱包/主角账三件/图行/装配集为共享引用,出账直接落同一引用)
|
||||
func _bind_shop() -> void:
|
||||
shop.bind({
|
||||
_shop.bind({
|
||||
"wallet": _wallet,
|
||||
"journal": _journal,
|
||||
"level_row": level_row,
|
||||
@@ -746,3 +746,83 @@ func _emit_wallet_event(event: String, gp_now: int, extra: Dictionary) -> void:
|
||||
# 购血(商店 max_hp 商品——当前生命 +Δ 并封顶新上限,与账本置满/关卡完成回血同式)
|
||||
func _gain_max_hp_flat(flat: int) -> void:
|
||||
_stats.hero_hp = mini(_stats.hero_hp + flat, _stats.effective_max_hp())
|
||||
|
||||
|
||||
func shop_products() -> Array:
|
||||
return _shop.shop_products()
|
||||
|
||||
|
||||
func current_price(prow: Dictionary) -> int:
|
||||
return _shop.current_price(prow)
|
||||
|
||||
|
||||
func purchased_tier(product_id: String) -> int:
|
||||
return _shop.purchased_tier(product_id)
|
||||
|
||||
|
||||
func buy_product(product_id: String) -> bool:
|
||||
return _shop.buy_product(product_id)
|
||||
|
||||
|
||||
func player_request_refresh() -> bool:
|
||||
return _shop.player_request_refresh()
|
||||
|
||||
|
||||
# 散折价单点(测试取数面沿用本类调用名)
|
||||
func _spend_discounted(price: int) -> int:
|
||||
return _shop._spend_discounted(price)
|
||||
|
||||
|
||||
# 注入(AdventureRunner._start_current_level 唯一调用方——pool 模式专用):令牌库共享引用 +
|
||||
# 池消费 handler + 专长凭证判定 + cap 检查回调(cap 满 kind 剔出货架候选视图)。
|
||||
func set_shop_pool(deck_ref: Array, consume_handler: Callable, ticket_consider: Callable = Callable(), cap_check: Callable = Callable()) -> void:
|
||||
_shop.set_shop_pool(deck_ref, consume_handler, ticket_consider, cap_check)
|
||||
|
||||
|
||||
# 货架抽签白盒入口(测试取数面沿用本类调用名)
|
||||
func _shop_draw_shelf() -> void:
|
||||
_shop._draw_shelf()
|
||||
|
||||
|
||||
func pool_stock(kind: String) -> int:
|
||||
return _shop.pool_stock(kind)
|
||||
|
||||
|
||||
func pool_price(kind: String) -> int:
|
||||
return _shop.pool_price(kind)
|
||||
|
||||
|
||||
func shop_shelf() -> Array:
|
||||
return _shop.shop_shelf()
|
||||
|
||||
|
||||
func shop_refresh_free_left() -> int:
|
||||
return _shop.shop_refresh_free_left()
|
||||
|
||||
|
||||
func shop_refresh_cost() -> int:
|
||||
return _shop.shop_refresh_cost()
|
||||
|
||||
|
||||
func shop_refresh() -> bool:
|
||||
return _shop.shop_refresh()
|
||||
|
||||
|
||||
func spend_gp(amount: int) -> bool:
|
||||
return _shop.spend_gp(amount)
|
||||
|
||||
|
||||
func buy_pool_item(kind: String) -> bool:
|
||||
return _shop.buy_pool_item(kind)
|
||||
|
||||
|
||||
func is_shop_pool() -> bool:
|
||||
return _shop.is_shop_pool()
|
||||
|
||||
|
||||
func shop_bp_shelf() -> Array:
|
||||
return _shop.shop_bp_shelf()
|
||||
|
||||
|
||||
func shop_bp_visit_buys() -> int:
|
||||
return _shop.shop_bp_visit_buys()
|
||||
@@ -1,7 +1,7 @@
|
||||
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
## 商店会话件:关卡商店双模式(legacy 固定三件加定价/pool 共享令牌池)的货架、定价、购买与刷新唯一宿主。
|
||||
## 钱包/主角账/装配集归宿主(GpWallet/GainJournal 共享引用经 bind 注入——GP 读写走钱包、购买加算走日记单点);
|
||||
## Core 层零 UI 依赖;外部调用面=调用方经宿主 LevelRunner 公开成员 shop 直连(调用直连不留委托壳);
|
||||
## Core 层零 UI 依赖;公开面由 LevelRunner 同签名委托承载(外部调用面零变化);
|
||||
## legacy 模式零 RNG 零池消费(off 对照承载)。
|
||||
class_name ShopSession
|
||||
extends RefCounted
|
||||
|
||||
@@ -170,37 +170,37 @@ func on_shop_buy(product_id: String) -> void:
|
||||
var runner = _runner_get.call()
|
||||
if runner == null:
|
||||
return
|
||||
if runner.shop.is_shop_pool():
|
||||
if runner.is_shop_pool():
|
||||
# pool 面:买 1 → 核心全重抽——货架整架重投喂(重抽反馈;余额不足核心拒绝零副作用)
|
||||
if not runner.shop.buy_pool_item(product_id):
|
||||
if not runner.buy_pool_item(product_id):
|
||||
logger.log_ux("ux_reject", {"source": "wallet", "sub_reason": "insufficient_gp"})
|
||||
toast.show_toast("GP不足——买不起这件商品", "warn")
|
||||
return
|
||||
shop_overlay.open_shelf(runner.shop.shop_shelf(), int(runner.gp))
|
||||
shop_overlay.set_visit_info(int(runner.shop.shop_bp_visit_buys()), float(db.run.shop.price_a)) # T6 爬价规则行
|
||||
shop_overlay.set_refresh_display(runner.shop.shop_refresh_free_left(), runner.shop.shop_refresh_cost(), int(runner.gp) >= runner.shop.shop_refresh_cost())
|
||||
shop_overlay.open_shelf(runner.shop_shelf(), int(runner.gp))
|
||||
shop_overlay.set_visit_info(int(runner.shop_bp_visit_buys()), float(db.run.shop.price_a)) # T6 爬价规则行
|
||||
shop_overlay.set_refresh_display(runner.shop_refresh_free_left(), runner.shop_refresh_cost(), int(runner.gp) >= runner.shop_refresh_cost())
|
||||
_refresh_presentations.call()
|
||||
return
|
||||
if not runner.shop.buy_product(product_id):
|
||||
if not runner.buy_product(product_id):
|
||||
# 余额不足(按钮禁用为常态防线——兜底拒绝可见,pattern 1)
|
||||
logger.log_ux("ux_reject", {"source": "wallet", "sub_reason": "insufficient_gp"})
|
||||
toast.show_toast("GP不足——买不起这件商品", "warn")
|
||||
return
|
||||
shop_overlay.refresh_state(runner.shop.shop_products(), int(runner.gp))
|
||||
shop_overlay.refresh_state(runner.shop_products(), int(runner.gp))
|
||||
_refresh_presentations.call()
|
||||
|
||||
|
||||
# MC-1:刷新意图(shop_overlay.refresh_requested——核心 shop_refresh 受理后整架重投喂=重抽反馈)
|
||||
func on_shop_refresh() -> void:
|
||||
var runner = _runner_get.call()
|
||||
if runner == null or not runner.shop.is_shop_pool():
|
||||
if runner == null or not runner.is_shop_pool():
|
||||
return
|
||||
if not runner.shop.shop_refresh():
|
||||
if not runner.shop_refresh():
|
||||
toast.show_toast("GP不足——刷新失败", "warn")
|
||||
return
|
||||
shop_overlay.open_shelf(runner.shop.shop_shelf(), int(runner.gp))
|
||||
shop_overlay.set_visit_info(int(runner.shop.shop_bp_visit_buys()), float(db.run.shop.price_a)) # T6 爬价规则行
|
||||
shop_overlay.set_refresh_display(runner.shop.shop_refresh_free_left(), runner.shop.shop_refresh_cost(), int(runner.gp) >= runner.shop.shop_refresh_cost())
|
||||
shop_overlay.open_shelf(runner.shop_shelf(), int(runner.gp))
|
||||
shop_overlay.set_visit_info(int(runner.shop_bp_visit_buys()), float(db.run.shop.price_a)) # T6 爬价规则行
|
||||
shop_overlay.set_refresh_display(runner.shop_refresh_free_left(), runner.shop_refresh_cost(), int(runner.gp) >= runner.shop_refresh_cost())
|
||||
_refresh_presentations.call()
|
||||
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ func on_refresh() -> void:
|
||||
if not refreshed:
|
||||
# 免费位(X/Y)已穷——GP 付费档(先扣钱包后重抽,余额不足拒绝零副作用)
|
||||
var cost: int = adventure.refresh_bank().gp_cost()
|
||||
if runner == null or not runner.shop.spend_gp(cost):
|
||||
if runner == null or not runner.spend_gp(cost):
|
||||
ctx.views.toast.show_toast("GP不足——刷新失败", "warn")
|
||||
return
|
||||
refreshed = adventure.stop().refresh_curio_paid()
|
||||
|
||||
@@ -770,7 +770,7 @@ func _on_refresh_confirmed() -> void:
|
||||
return
|
||||
var ok: bool = false
|
||||
if run_scope.level_active and run_scope.runner != null:
|
||||
ok = run_scope.runner.shop.player_request_refresh()
|
||||
ok = run_scope.runner.player_request_refresh()
|
||||
elif run_scope.settlement != null:
|
||||
ok = run_scope.settlement.player_request_refresh()
|
||||
logger.log_action("refresh", Vector2i(-1, -1), ok)
|
||||
|
||||
@@ -78,12 +78,12 @@ static func _on_runner_node(root: Variant, node: Dictionary, info: Dictionary) -
|
||||
# 购买/离开归玩家意图(buy_requested/leave_pressed 接线),零自动推进。
|
||||
# pool 面 = 共享池货架三选一同构卡;legacy 面 = 固定三件(off 对照承载)
|
||||
root._open_modal(root.shop_overlay)
|
||||
if root.run_scope.runner.shop.is_shop_pool():
|
||||
root.shop_overlay.open_shelf(root.run_scope.runner.shop.shop_shelf(), int(root.run_scope.runner.gp))
|
||||
root.shop_overlay.set_visit_info(int(root.run_scope.runner.shop.shop_bp_visit_buys()), float(root.db.run.shop.price_a)) # 爬价规则行
|
||||
root.shop_overlay.set_refresh_display(root.run_scope.runner.shop.shop_refresh_free_left(), root.run_scope.runner.shop.shop_refresh_cost(), int(root.run_scope.runner.gp) >= root.run_scope.runner.shop.shop_refresh_cost()) # MC-1
|
||||
if root.run_scope.runner.is_shop_pool():
|
||||
root.shop_overlay.open_shelf(root.run_scope.runner.shop_shelf(), int(root.run_scope.runner.gp))
|
||||
root.shop_overlay.set_visit_info(int(root.run_scope.runner.shop_bp_visit_buys()), float(root.db.run.shop.price_a)) # 爬价规则行
|
||||
root.shop_overlay.set_refresh_display(root.run_scope.runner.shop_refresh_free_left(), root.run_scope.runner.shop_refresh_cost(), int(root.run_scope.runner.gp) >= root.run_scope.runner.shop_refresh_cost()) # MC-1
|
||||
else:
|
||||
root.shop_overlay.open_shop(root.run_scope.runner.shop.shop_products(), int(root.run_scope.runner.gp))
|
||||
root.shop_overlay.open_shop(root.run_scope.runner.shop_products(), int(root.run_scope.runner.gp))
|
||||
root.shop_overlay.set_visit_info(-1, 1.0) # legacy 面无爬价行(off 对照承载)
|
||||
root.log_view.append_bb(root.Narrator.shop_line(int(root.run_scope.runner.gp)))
|
||||
root.logger.log_node(node, info, root.run_scope.runner.node_index)
|
||||
|
||||
@@ -132,10 +132,10 @@ static func _on_wallet_changed(root: Variant, event: String, gp: int, extra: Dic
|
||||
if String(event) == "gain":
|
||||
root.run_scope.last_gain_amount = int(extra.get("amount", 0)) # GP 增量取数(每战恰一笔 gain)
|
||||
if root.shop_overlay.visible and root.run_scope.runner != null:
|
||||
if root.run_scope.runner.shop.is_shop_pool():
|
||||
if root.run_scope.runner.is_shop_pool():
|
||||
root.shop_overlay.refresh_shelf_state(int(root.run_scope.runner.gp)) # pool 面余额联动(货架内容仅买后重抽变)
|
||||
else:
|
||||
root.shop_overlay.refresh_state(root.run_scope.runner.shop.shop_products(), int(root.run_scope.runner.gp))
|
||||
root.shop_overlay.refresh_state(root.run_scope.runner.shop_products(), int(root.run_scope.runner.gp))
|
||||
root._refresh_presentations()
|
||||
|
||||
|
||||
|
||||
@@ -246,30 +246,25 @@ func rebuild(board: BoardData, minesweeper: MinesweeperRules) -> void:
|
||||
for y in _board.height:
|
||||
for x in _board.width:
|
||||
var c := Vector2i(x, y)
|
||||
_cells[c] = _build_cell_unit(c, stride)
|
||||
var u: Node2D = _CELL_UNIT.new()
|
||||
u.st.cell = c
|
||||
u.st.edge = _cell
|
||||
u.position = Vector2(c) * stride
|
||||
u.st.bevel = DEPTH_BEVEL # 新建格单元继承
|
||||
u.use_parent_material = true # 去饱和材质挂 BoardWorld——单元随世界材质灰化
|
||||
if _palette.tiles_ok:
|
||||
# NEAREST 采样(32×32 源 × 45/36px 格边非整数缩放接受档,
|
||||
# 与英雄小人 1.5× 豁免同级(圣经 §8.2);只在瓦片
|
||||
# 模式启用——程序化回退路径渲染零扰动(含格面文字采样不回退不变化)
|
||||
u.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
u.st.font = _world.board_font
|
||||
_world.add_child(u)
|
||||
_cells[c] = u
|
||||
set_cell_area(size)
|
||||
_install_entrance_fx()
|
||||
refresh()
|
||||
|
||||
|
||||
# 逐格构建器(rebuild 建格循环唯一出函面):.new() 与属性装配逐字迁入,循环体只调构建器
|
||||
func _build_cell_unit(c: Vector2i, stride: float) -> Node2D:
|
||||
var u: Node2D = _CELL_UNIT.new()
|
||||
u.st.cell = c
|
||||
u.st.edge = _cell
|
||||
u.position = Vector2(c) * stride
|
||||
u.st.bevel = DEPTH_BEVEL # 新建格单元继承
|
||||
u.use_parent_material = true # 去饱和材质挂 BoardWorld——单元随世界材质灰化
|
||||
if _palette.tiles_ok:
|
||||
# NEAREST 采样(32×32 源 × 45/36px 格边非整数缩放接受档,
|
||||
# 与英雄小人 1.5× 豁免同级(圣经 §8.2);只在瓦片
|
||||
# 模式启用——程序化回退路径渲染零扰动(含格面文字采样不回退不变化)
|
||||
u.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
u.st.font = _world.board_font
|
||||
_world.add_child(u)
|
||||
return u
|
||||
|
||||
|
||||
# 逐格重绘(挖掘/结算后调用)
|
||||
func refresh() -> void:
|
||||
if _board == null or _minesweeper == null:
|
||||
@@ -611,6 +606,9 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void:
|
||||
var seal: bool = _minesweeper.has_seal(c)
|
||||
var removed: bool = _minesweeper.is_removed(c) # 中立移除格(退色降档)
|
||||
var is_hero: bool = c == hero
|
||||
var glyph := ""
|
||||
var bg: Color
|
||||
var digit_col := COL_DIGIT
|
||||
# 封印槽统一维护:封印格=封印印记纹理;其余格清 null(封印格挖开后残留在 tex_seal
|
||||
# 会让 _draw 无条件把封印印画在已开格上——tex_seal 绘制无 revealed 条件)。缺盘走字形回退。
|
||||
u.st.tex_seal = _palette.seal_tex if (seal and not revealed and _palette.seal_tex != null) else null
|
||||
@@ -618,23 +616,6 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void:
|
||||
revealed = false # 移除格固定未开呈现基座(退色暗幕层承载;危险格本无数字,周边数字冻结)
|
||||
seal = false
|
||||
u.st.tex_seal = null
|
||||
# 绘制层五段(字形与色牌→基底瓦片→立面投影→秘宝/变异叠加→迷雾)——段间交换经单元状态面
|
||||
#(u.st/u.glyph/u.glyph_color),唯一例外=基底色 bg 经 ink 段返回值交 base 段(无单元场域承载)
|
||||
var bg: Color = _paint_cell_ink(c, u, revealed, seal)
|
||||
_paint_cell_base(c, u, revealed, is_hero, bg)
|
||||
_paint_cell_facade(c, u, revealed)
|
||||
_paint_cell_overlays(c, u, revealed)
|
||||
_paint_cell_fog(c, u, revealed, hero)
|
||||
u.st.removed_dim = removed
|
||||
u.queue_redraw()
|
||||
|
||||
|
||||
# 字形与色牌段:reveal 记录→字形/墨色判定+u.glyph/u.glyph_color 终写+双峰纹理板落牌;
|
||||
# 返回基底色 bg(平色回退 sb 构建的唯一消费方在基底段)
|
||||
func _paint_cell_ink(c: Vector2i, u: Node2D, revealed: bool, seal: bool) -> Color:
|
||||
var glyph := ""
|
||||
var bg: Color
|
||||
var digit_col := COL_DIGIT
|
||||
if revealed:
|
||||
var rec: Dictionary[Variant, Variant] = _minesweeper.reveal_record(c) # 已开记录经查询面
|
||||
if rec.get("kind", "") == "mine":
|
||||
@@ -658,21 +639,6 @@ func _paint_cell_ink(c: Vector2i, u: Node2D, revealed: bool, seal: bool) -> Colo
|
||||
digit_col = COL_SEAL
|
||||
else:
|
||||
bg = COL_BRICK
|
||||
u.glyph = glyph
|
||||
u.glyph_color = digit_col
|
||||
# 色牌后备(数字直画退牌;「危」/「?」维持牌载保读性)+ v3.4:双峰纹理板
|
||||
#(_palette.digit_plate——underdark 系亮白筋+近黑斑并存的直画不可救纹理)数字落牌,牌上深墨 12:1
|
||||
var plate_digit: bool = _palette.digit_plate and glyph != "" and glyph != "危" and glyph != "?" and glyph != "封" and glyph != "人"
|
||||
if plate_digit:
|
||||
digit_col = COL_DIGIT # 牌上深墨族(素牌 12:1——双峰纹理免疫)
|
||||
u.glyph_color = digit_col
|
||||
u.plate = revealed and (glyph == "危" or glyph == "?" or plate_digit)
|
||||
return bg
|
||||
|
||||
|
||||
# 基底瓦片段:瓦片查表/平色回退 sb+英雄蓝框载体;英雄贴图缺位回退字形「人」在此段落
|
||||
# u.glyph(先于叠加段消费,结果与原函数字形累计局部量逐字同值)
|
||||
func _paint_cell_base(c: Vector2i, u: Node2D, revealed: bool, is_hero: bool, bg: Color) -> void:
|
||||
# 瓦片模式:tex_base = 查表瓦片(未开=墙瓦片/已开=地面瓦片),
|
||||
# bg_sb 降级为透明描边载体——只承载呼吸微光/主角蓝框(CellUnit 瓦片态画在瓦片之上),
|
||||
# 瓦片分配=格坐标哈希,初始化落定后逐拍稳定(禁逐轮重掷——圣经原则三)
|
||||
@@ -692,16 +658,21 @@ func _paint_cell_base(c: Vector2i, u: Node2D, revealed: bool, is_hero: bool, bg:
|
||||
sb = UiKit.panel_flat(Color.TRANSPARENT, Color.TRANSPARENT,UiKit.RADIUS_OBJECT, 0)
|
||||
sb.set_border_width_all(3)
|
||||
sb.border_color = COL_HERO
|
||||
if u.glyph == "" and _hero_sprite.tex_idle == null:
|
||||
if glyph == "" and _hero_sprite.tex_idle == null:
|
||||
# 贴图缺位回退字形「人」(项目纹理槽惯例——贴图在位=格内字形退役,单位本体由独立精灵承载)
|
||||
u.glyph = "人"
|
||||
u.glyph_color = COL_HERO
|
||||
glyph = "人"
|
||||
digit_col = COL_HERO
|
||||
u.st.tex_base = tile
|
||||
u.st.bg_sb = sb
|
||||
|
||||
|
||||
# 立面投影段:未开墙格南缘立面/轮廓描边码;已开格北缘投影暗带/E 格高墙面——段内重置与赋值同序
|
||||
func _paint_cell_facade(c: Vector2i, u: Node2D, revealed: bool) -> void:
|
||||
u.glyph = glyph
|
||||
u.glyph_color = digit_col
|
||||
# 色牌后备(数字直画退牌;「危」/「?」维持牌载保读性)+ v3.4:双峰纹理板
|
||||
#(_palette.digit_plate——underdark 系亮白筋+近黑斑并存的直画不可救纹理)数字落牌,牌上深墨 12:1
|
||||
var plate_digit: bool = _palette.digit_plate and glyph != "" and glyph != "危" and glyph != "?" and glyph != "封" and glyph != "人"
|
||||
if plate_digit:
|
||||
digit_col = COL_DIGIT # 牌上深墨族(素牌 12:1——双峰纹理免疫)
|
||||
u.glyph_color = digit_col
|
||||
u.plate = revealed and (glyph == "危" or glyph == "?" or plate_digit)
|
||||
u.st.outline_sides.assign([]) # typed Array[int](assign 保持引用语义)
|
||||
u.st.facade_south = false
|
||||
u.st.proj_band = 0.0
|
||||
@@ -736,15 +707,8 @@ func _paint_cell_facade(c: Vector2i, u: Node2D, revealed: bool) -> void:
|
||||
if south_in and not _minesweeper.is_revealed(south_n) and _palette.tiles_ok:
|
||||
u.st.facade_strip = true
|
||||
u.st.tex_facade = _palette.tiles.get("wall_center")
|
||||
|
||||
|
||||
# 秘宝/变异叠加段:真视红框/预读徽章/变异角标/奖励徽章/类型微光组号——glyph/digit_col 局部镜像
|
||||
# 自 u.glyph/u.glyph_color(原函数字形累计局部量的段内重建,预读徽章分支的无效局部写入逐字保留)
|
||||
func _paint_cell_overlays(c: Vector2i, u: Node2D, revealed: bool) -> void:
|
||||
# ②( 秘宝叠加层:真视格=红内缩框;预读格=奖励身份徽章(identity_resolver 既有
|
||||
# 只读面取字形——零数据复制,badge 位复用);已开格标记自然退位(refresh 逐拍重算)
|
||||
var glyph: String = u.glyph
|
||||
var digit_col: Color = u.glyph_color
|
||||
if not revealed:
|
||||
u.st.treasure_mark = "mine_reveal" if _treasure_reveal.has(c) else ""
|
||||
if _treasure_preview.has(c) and glyph == "":
|
||||
@@ -761,10 +725,6 @@ func _paint_cell_overlays(c: Vector2i, u: Node2D, revealed: bool) -> void:
|
||||
u.st.mutation_mark = ""
|
||||
u.st.badge_glyph = _update_badge(c)
|
||||
u.st.glow_group = int(_glow.get(c, UiKit.GLOW_NONE))
|
||||
|
||||
|
||||
# 迷雾段:灯光区外未开格全黑/已开格记忆态灰显——纯呈现零逻辑(🔴 契约 1)
|
||||
func _paint_cell_fog(c: Vector2i, u: Node2D, revealed: bool, hero: Vector2i) -> void:
|
||||
# 视野迷雾呈态:曼哈顿距离 > 半径 → 区外——未开格全黑(现行事实源照抄)/
|
||||
# 已开格记忆态(灰显可读);以英雄格为心逐格重算,refresh()/notify_hero_move() 既有重绘驱动=移动实时跟随。
|
||||
# 纯呈现零逻辑——格态/数字真值/清图判定零触碰(🔴 契约 1);结算期去饱和叠加互斥由 CellUnit 记忆态终态档承载。
|
||||
@@ -774,6 +734,8 @@ func _paint_cell_fog(c: Vector2i, u: Node2D, revealed: bool, hero: Vector2i) ->
|
||||
u.fog_state = (2 if revealed else 1) if fogged else 0
|
||||
else:
|
||||
u.fog_state = 0
|
||||
u.st.removed_dim = removed
|
||||
u.queue_redraw()
|
||||
|
||||
|
||||
# ---- 可挖域接触带呼吸微光(挖掘期唯一在动元素——§3.2 v2.8 画法:光画英雄格周界空间侧,
|
||||
|
||||
@@ -85,7 +85,7 @@ func _xnum(v: float) -> String:
|
||||
return "×%d" % int(round(v)) if absf(v - roundf(v)) < 0.005 else "×%.2f" % v
|
||||
|
||||
|
||||
# 打开商店(products = runner.shop.shop_products() 投影——[{product_id, display_name, attr, flat_value, price, purchased}])
|
||||
# 打开商店(products = runner.shop_products() 投影——[{product_id, display_name, attr, flat_value, price, purchased}])
|
||||
func open_shop(products: Array, gp: int) -> void:
|
||||
for child in _cards_box.get_children():
|
||||
child.queue_free()
|
||||
@@ -149,7 +149,7 @@ func _emit_buy_requested(p: Dictionary) -> void:
|
||||
|
||||
# ---- 共享池货架面(M-4 迭代 11 第②批 T4——P3 甲程序占位,三选一同构卡;UiKit 既有件)----
|
||||
|
||||
# 打开/重刷货架(cards = runner.shop.shop_shelf() 投影——[{kind_id, display_name, value, price, stock_left}])。
|
||||
# 打开/重刷货架(cards = runner.shop_shelf() 投影——[{kind_id, display_name, value, price, stock_left}])。
|
||||
# 买后组合根重投喂新货架 = 整架重建呈现(三件全重抽反馈——未买不保留);空架 = 池空硬闸合法态。
|
||||
func open_shelf(cards: Array, gp: int) -> void:
|
||||
for child in _cards_box.get_children():
|
||||
|
||||
@@ -332,13 +332,13 @@ static func _on_adventure_curio_resolved(result: Dictionary, st: Dictionary, adr
|
||||
|
||||
# 商店贪心买齐:GP 局内死钱——买得起就买( affordable 集里挑最便宜的
|
||||
# 反复买到达不上任何商品为止,guard 防死循环)。确定性(零随机流);购买出账/加算区入账全走
|
||||
# runner.shop.buy_product 核心编排(与呈现层购买同一出账路径,wallet_changed 信号照常采集)。
|
||||
# runner.buy_product 核心编排(与呈现层购买同一出账路径,wallet_changed 信号照常采集)。
|
||||
static func _autoplay_shop(r, st: Dictionary) -> void:
|
||||
var guard := 30
|
||||
while guard > 0:
|
||||
guard -= 1
|
||||
var affordable: Array = []
|
||||
for p in r.shop.shop_products():
|
||||
for p in r.shop_products():
|
||||
if r.gp >= int(p.get("price", 1 << 30)):
|
||||
affordable.append(p)
|
||||
if affordable.is_empty():
|
||||
@@ -347,20 +347,20 @@ static func _autoplay_shop(r, st: Dictionary) -> void:
|
||||
for p in affordable:
|
||||
if int(p.get("price", 1 << 30)) < int(pick.get("price", 1 << 30)):
|
||||
pick = p
|
||||
if not r.shop.buy_product(String(pick.get("product_id", ""))):
|
||||
if not r.buy_product(String(pick.get("product_id", ""))):
|
||||
return
|
||||
st.shop_buys = int(st.get("shop_buys", 0)) + 1
|
||||
|
||||
|
||||
# 商店共享池贪心:货架三选一同构面贪心买齐——affordable 集挑最便宜反复买
|
||||
# (每次买后全重抽、货架随买随换,枯竭/不可负担即止,guard 防死循环)。购买走 runner.shop.buy_pool_item
|
||||
# (每次买后全重抽、货架随买随换,枯竭/不可负担即止,guard 防死循环)。购买走 runner.buy_pool_item
|
||||
# 核心编排(与呈现层购买同一出账+池消费路径,wallet_changed 信号照常采集)。确定性(零随机流)。
|
||||
static func _autoplay_shop_pool(r, st: Dictionary) -> void:
|
||||
var guard := 30
|
||||
while guard > 0:
|
||||
guard -= 1
|
||||
var affordable: Array = []
|
||||
for c in r.shop.shop_shelf():
|
||||
for c in r.shop_shelf():
|
||||
if r.gp >= int(c.get("price", 1 << 30)):
|
||||
affordable.append(c)
|
||||
if affordable.is_empty():
|
||||
@@ -369,7 +369,7 @@ static func _autoplay_shop_pool(r, st: Dictionary) -> void:
|
||||
for c in affordable:
|
||||
if int(c.get("price", 1 << 30)) < int(pick.get("price", 1 << 30)):
|
||||
pick = c
|
||||
if not r.shop.buy_pool_item(String(pick.get("kind_id", ""))):
|
||||
if not r.buy_pool_item(String(pick.get("kind_id", ""))):
|
||||
return
|
||||
st.shop_buys = int(st.get("shop_buys", 0)) + 1
|
||||
|
||||
@@ -415,10 +415,10 @@ static func _route_pick(runner, route: String, st: Dictionary) -> int:
|
||||
s = 10.0
|
||||
var cheapest := 1 << 30
|
||||
if String(st.get("shop_mode", "legacy")) == "pool":
|
||||
for c in runner.shop.shop_shelf(): # pool 面:货架现价
|
||||
for c in runner.shop_shelf(): # pool 面:货架现价
|
||||
cheapest = mini(cheapest, int(c.get("price", 1 << 30)))
|
||||
else:
|
||||
for p in runner.shop.shop_products():
|
||||
for p in runner.shop_products():
|
||||
cheapest = mini(cheapest, int(p.get("price", 1 << 30)))
|
||||
if cheapest < (1 << 30) and runner.gp >= cheapest:
|
||||
s = 80.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"note": "存量基线·首次自动生成;闸况变化时本脚本会判红,需人工确认后重生成;2026-10-17 人工确认重生成 06 条目:af94ce97 把 gdd_lint 记为存量红(01 篇 R5),该红已由 fcb8c3f8 补流程图消除,实测 --docs 域 06 exit=0,故基线改回绿。2026-10-18 新增闸件 08c 流水线闸(tools/pipeline_gate.py 注册上电),手工加入绿记录(roadmap 压缩批实测 --docs 域 exit=0),其余条目原样保留。2026-10-22 测试术语与层级重构批 A 改键:01 冒烟全量→01 系统测试(同一断言面 smoke_all.gd,运行器换 tools/run_system_test.py,过渡期判定口径不变)、02 单元套件→02 单元与集成测试(同一 run_all.gd 入口,名从实)、新增 00 冒烟测试(tools/run_smoke.py+game/tests/smoke_boot.tscn,重写后单跑实测 17 项 0 失败 PASS);09 静态扫描基线 exit=1(fp=4354b2aa72a7)系滞后红,本批单跑实测 exit=0(与 2026-10-22 16:20 回执一致),基线改回绿;其余条目原样保留。;2026-10-23 主会话记 07 doc_link 为存量红(用户令忽略:锻造工坊.md 死链的修复在另一会话未合入,合回闸豁免;外部修复合入后应重生成基线归绿);2026-10-26 用户特批带红合并(迭代 38 收口):09 静态扫描记存量红——gdstyle 恶化 2 条(battle_orchestrator.gd max-file-length 1314>1302=卡④头注必载内容、level_map_screen.gd max-class-variables 22>21=卡①缓存成员,均为卡片义务的记账漂移非缺陷,压缩还债经计算不可行),用户裁「不管引入的恶化直接提交、特许免测试重跑」;后续批次若触及两文件可顺带还债或经批准重生成基线归绿;2026-10-27 用户裁「标准是尺、不以现状为尺」:09 存量红照实记(exit=1+现行红项指纹,两条恶化各自点名可核),gdstyle 基线登记值回退 1302/21(波 0 的 18 条陈旧键清理保留),gdstyle_gate 逐条违规行加 FAIL 前缀并加「refresh 禁抬高登记值」守卫——存量红期间任何新增违规或进一步恶化都会改指纹被拦;阈值口径不变=gdstyle 默认值(文件 1000 行/类变量 15 等),还债归迭代 40 卡①(battle_orchestrator 1314→≤1000)与迭代 41 卡③(level_map_screen 22→≤15),还清后重新生成基线归绿;2026-10-27 用户特批带红合并(迭代39 拆件批):02 记存量红(fp f74b9a48ef4a=round_flow EV 锚 goblin 0.9148∉[1.00,1.20],触发器批有意行为改动,旧带宽锚触发器前设计,重锚归后续数值批待用户发起);08d 记存量红(red-nokeys=生涯.md:55 引 adventure_runner.gd:814 行号漂移,B1 拆分后 660 行,另 :50/:60 与 元进度.md:70 建议级,修复归合并后文档批,反哺点在册);07 doc_link 基线红→现绿改善随下次基线重生成记账;09 指纹经 S9 注解修复(f96632de)回归登记值 91d45583cf6d;2026-10-28 迭代40 收口记账(用户裁「刷」):卡① 拆件还债——battle_orchestrator 行数红项消失(实测 1036≤登记 1302;契约2 残余 36 行系合并适配带入 master 迭代39 内容,用户裁登记残余债归待办清单),09 红项由两条收敛为一条(level_map_screen 类变量 22>21=迭代38 存量,还债归迭代41 卡③),指纹 91d45583cf6d → 8467b4588a20(收口会话按闸壳同款算法对用户探跑日志实算,全量闸复验);02 存量红已随 master 侧 EV 重锚批(ba5105aa)归绿并入本合并;2026-10-28 EV 锚重锚批(工程改动·worktree ev-anchor-remeasure-20261028,用户特许会话内执行):02 基线红→现绿归绿——round_flow EV 锚 goblin 带宽按无情境口径(模拟器不过滤 trigger 行)重锚 [0.82,1.02](迭代39触发器批孤注守势入池稀释,实测 0.9148,重锚注记 enemy.tres 与测试注释;旧带 [1.00,1.20] 随池构成换代作废),撤销证明=带宽回退 [1.00,1.20] 断言复红;08d 存量红不变(生涯.md:55 行号漂移,修复归文档批);2026-10-29 文档清理批(批 5)实测 --docs 域 07/08d 皆绿,两条目归绿;2026-10-29 能力审计闸上电(tools/capability_audit.py 注册文档域 08e,查 GDD 纯度+能力清单与覆盖域表结构):手工加入绿记录(批 5 纯度红项清零后孤立实测 exit=0),其余条目原样保留;2026-10-29 合回闸关联档批实测重生成 02/09 两键(人工确认凭据=待办清单「迭代 41 测试债修复」条 2026-10-29 用户裁带红合并、代码域现存红全部由该条目承接):02 记存量红 fp f9865f1a5a44=9 套件失败(config_db 解析错 cattr/config_db_fatal_oob 退出码 2≠1/table_structure_guard 缺 meta_state/treasure_items 缺 crossrun/standee_fx_sweep set_trans 空引用/forge_workbench 120s 超时挂死/tree_requires_level 空基址/save_manager_domain 缺 _Line truncated
|
||||
"note": "存量基线·首次自动生成;闸况变化时本脚本会判红,需人工确认后重生成;2026-10-17 人工确认重生成 06 条目:af94ce97 把 gdd_lint 记为存量红(01 篇 R5),该红已由 fcb8c3f8 补流程图消除,实测 --docs 域 06 exit=0,故基线改回绿。2026-10-18 新增闸件 08c 流水线闸(tools/pipeline_gate.py 注册上电),手工加入绿记录(roadmap 压缩批实测 --docs 域 exit=0),其余条目原样保留。2026-10-22 测试术语与层级重构批 A 改键:01 冒烟全量→01 系统测试(同一断言面 smoke_all.gd,运行器换 tools/run_system_test.py,过渡期判定口径不变)、02 单元套件→02 单元与集成测试(同一 run_all.gd 入口,名从实)、新增 00 冒烟测试(tools/run_smoke.py+game/tests/smoke_boot.tscn,重写后单跑实测 17 项 0 失败 PASS);09 静态扫描基线 exit=1(fp=4354b2aa72a7)系滞后红,本批单跑实测 exit=0(与 2026-10-22 16:20 回执一致),基线改回绿;其余条目原样保留。;2026-10-23 主会话记 07 doc_link 为存量红(用户令忽略:锻造工坊.md 死链的修复在另一会话未合入,合回闸豁免;外部修复合入后应重生成基线归绿);2026-10-26 用户特批带红合并(迭代 38 收口):09 静态扫描记存量红——gdstyle 恶化 2 条(battle_orchestrator.gd max-file-length 1314>1302=卡④头注必载内容、level_map_screen.gd max-class-variables 22>21=卡①缓存成员,均为卡片义务的记账漂移非缺陷,压缩还债经计算不可行),用户裁「不管引入的恶化直接提交、特许免测试重跑」;后续批次若触及两文件可顺带还债或经批准重生成基线归绿;2026-10-27 用户裁「标准是尺、不以现状为尺」:09 存量红照实记(exit=1+现行红项指纹,两条恶化各自点名可核),gdstyle 基线登记值回退 1302/21(波 0 的 18 条陈旧键清理保留),gdstyle_gate 逐条违规行加 FAIL 前缀并加「refresh 禁抬高登记值」守卫——存量红期间任何新增违规或进一步恶化都会改指纹被拦;阈值口径不变=gdstyle 默认值(文件 1000 行/类变量 15 等),还债归迭代 40 卡①(battle_orchestrator 1314→≤1000)与迭代 41 卡③(level_map_screen 22→≤15),还清后重新生成基线归绿;2026-10-27 用户特批带红合并(迭代39 拆件批):02 记存量红(fp f74b9a48ef4a=round_flow EV 锚 goblin 0.9148∉[1.00,1.20],触发器批有意行为改动,旧带宽锚触发器前设计,重锚归后续数值批待用户发起);08d 记存量红(red-nokeys=生涯.md:55 引 adventure_runner.gd:814 行号漂移,B1 拆分后 660 行,另 :50/:60 与 元进度.md:70 建议级,修复归合并后文档批,反哺点在册);07 doc_link 基线红→现绿改善随下次基线重生成记账;09 指纹经 S9 注解修复(f96632de)回归登记值 91d45583cf6d;2026-10-28 迭代40 收口记账(用户裁「刷」):卡① 拆件还债——battle_orchestrator 行数红项消失(实测 1036≤登记 1302;契约2 残余 36 行系合并适配带入 master 迭代39 内容,用户裁登记残余债归待办清单),09 红项由两条收敛为一条(level_map_screen 类变量 22>21=迭代38 存量,还债归迭代41 卡③),指纹 91d45583cf6d → 8467b4588a20(收口会话按闸壳同款算法对用户探跑日志实算,全量闸复验);02 存量红已随 master 侧 EV 重锚批(ba5105aa)归绿并入本合并;2026-10-28 EV 锚重锚批(工程改动·worktree ev-anchor-remeasure-20261028,用户特许会话内执行):02 基线红→现绿归绿——round_flow EV 锚 goblin 带宽按无情境口径(模拟器不过滤 trigger 行)重锚 [0.82,1.02](迭代39触发器批孤注守势入池稀释,实测 0.9148,重锚注记 enemy.tres 与测试注释;旧带 [1.00,1.20] 随池构成换代作废),撤销证明=带宽回退 [1.00,1.20] 断言复红;08d 存量红不变(生涯.md:55 行号漂移,修复归文档批)",
|
||||
"gates": {
|
||||
"00 冒烟测试": {
|
||||
"exit": "0",
|
||||
@@ -10,8 +10,8 @@
|
||||
"fp": "green"
|
||||
},
|
||||
"02 单元与集成测试": {
|
||||
"exit": "1",
|
||||
"fp": "f9865f1a5a44"
|
||||
"exit": "0",
|
||||
"fp": "green"
|
||||
},
|
||||
"03 探针 --click": {
|
||||
"exit": "0",
|
||||
@@ -34,8 +34,8 @@
|
||||
"fp": "green"
|
||||
},
|
||||
"07 doc_link": {
|
||||
"exit": "0",
|
||||
"fp": "green"
|
||||
"exit": "1",
|
||||
"fp": "red-nokeys"
|
||||
},
|
||||
"08 doc_term": {
|
||||
"exit": "0",
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
"09 静态扫描": {
|
||||
"exit": "1",
|
||||
"fp": "1a9ad773489f"
|
||||
"fp": "8467b4588a20"
|
||||
},
|
||||
"10 熵增闸": {
|
||||
"exit": "0",
|
||||
@@ -58,12 +58,8 @@
|
||||
"fp": "skip"
|
||||
},
|
||||
"08d 引用可核": {
|
||||
"exit": "0",
|
||||
"fp": "green"
|
||||
},
|
||||
"08e 能力审计": {
|
||||
"exit": "0",
|
||||
"fp": "green"
|
||||
"exit": "1",
|
||||
"fp": "red-nokeys"
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
-128
@@ -2,7 +2,7 @@
|
||||
|
||||
**Engine**: Godot 4.7.2-stable(GDScript 单语言)
|
||||
**Test Framework**: 标准四级测试层(冒烟/单元/集成/系统)+ headless 场景探针与渲染 golden;gdUnit4 **deferred**(D2 OQ1 关闭形态——本仓库不引第三方测试框架,需求见下「门禁」节)
|
||||
**门禁**: 本地闸——`tools/run_all_gates.sh`(收口唯一验收入口,按改动域选档 `--code`/`--docs`,跨两域或改闸件本身不带参数=全量;代码域 02 按关联档选套件,算法与套件族映射表只在脚本内定义)。本仓库**无远端、无 CI**(`.github/workflows/` 已删除,不建不留不参考);闸清单与域划分只在本脚本定义,文档不另列
|
||||
**门禁**: 本地闸——`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/probe/`(场景探针族)· `game/sim/`(测量/诊断/模拟驱动件)(场景探针族——正式工程的活样板;系统测试断言面过渡宿主 `smoke_all.gd` 亦在此,迁移归断言迁移批)
|
||||
|
||||
@@ -43,145 +43,72 @@ tests/
|
||||
> **分层判据**:能不能在 `--script` 模式下不加载 autoload 就验完?能 = 单元测试;
|
||||
> 需要两个以上真实系统协同并走落盘/落库 = 集成测试;需要完整项目引导与场景树 = 冒烟/系统/UI 探针。
|
||||
|
||||
**能力清单**(2026-10-28 立,2026-10-29 改版定稿——验证与清单体系整改的能力义务清单:一行=一个玩家或系统可观测的能力,只宣布「要验证什么」,不记「是否已验证/是否跑过」;定位=实现指导+阅读导航+义务声明,代表用例只给指针、不复制断言细节;原「集成旅程清单」五条跨系统旅程已并入本表。七段=核心四域+排雷循环+表现与支撑+数据配置与跨系统契约,行数随清单生长不在此记账;系统文档逐篇对照见下方「覆盖域表」):
|
||||
**能力清单 v1**(2026-10-28 立——验证与清单体系整改阶段 1 的覆盖索引:一行=一个玩家或系统可观测的能力,代表用例只给指针、不复制断言细节;原「集成旅程清单」五条跨系统旅程已并入本表。首期覆盖核心四域(29 行)+跨域条件闸 1 行,共 30 行;其余域按同一形态扩面):
|
||||
|
||||
> **与验证集清单的关系**:`tests/验证集清单.md` 已于「存量断言精简」阶段完成后删除(对账基准与结果留 git 历史)。本表是该清单退役后的唯一能力义务清单(维护锚=test-conventions §8.3 清单归属+§8.9 三层模型)。本表不是闸,不替代改动—验收对照表、体验验证清单与静态纪律;已落地行的唯一事实源是 `game/tests/` 下的测试代码,计划中的行由需求卡片锚定(见维护规则)。
|
||||
> **与验证集清单的关系**:`tests/验证集清单.md` 已于阶段 2「存量断言精简」完成后删除——冻结对账基准(基点 `b9260138`/1587 条)与精简对账结果(33 站点并为 7、1587→1561,合回 `87d241c1`)留 git 历史。本表是该清单退役后的唯一覆盖索引(维护锚=test-conventions §8.3)。本表不是闸,不替代改动—验收对照表、体验验证清单与静态纪律;每行的唯一事实源仍是 `game/tests/` 下的测试代码。
|
||||
>
|
||||
> **代表用例口径**:写 `文件:函数`,每行 1–3 个;函数内可含 `Kit.check_quiet` 静默通道(逐断言提取器口径外,test-conventions §5.2 已备案)——本表以函数为锚,不受该工具局限影响。计划中的用例=卡内定死的测试名,实现落地后转为代码实锚(机检双通道:代码在或卡在,test-conventions §8.9)。
|
||||
> **代表用例口径**:写 `文件:函数`,每行 2–3 个;函数内可含 `Kit.check_quiet` 静默通道(逐断言提取器口径外,test-conventions §5.2 已备案)——本表以函数为锚,不受该工具局限影响。
|
||||
>
|
||||
> **维护规则(写卡段维护,实现批禁写本表)**:写需求卡片时当场入表——本批新增能力当场增行(真实入口取自设计文档已定的入口;代表用例=卡内定死的计划测试 `文件:函数`,实现照单落名,名实不符=卡片没写清=停卡退回);受影响存量行(入口/用例名变更)同批更新;能力退役删行。批末收尾只核对表上名字与实际落地一致(改名则回表),不刷任何批次字段(test-conventions §8.3/§8.9)。
|
||||
> **维护规则(每批收口核对本批受影响行)**:本批改到哪个能力,收口时核对该行代表用例可 grep、在本批真实跑批中执行、真实入口未绕过改动点,并把「最后验证批次」刷新为本批回执;新增能力加行,能力退役删行。全表核对频率与抽样规则归阶段 3。首期未覆盖:排雷循环(棋盘生成/排雷玩法/行动经济)、表现与支撑(HUD/主题/字体/地形瓦片/模态)、数据配置与跨系统契约——按同一形态后续扩面。
|
||||
>
|
||||
> **旅程补录方法**:新旅程=加一行,「系统」列写涉及边界;源=architecture「API 边界」表+「数据流」存档/读档路径+各 GDD 登记的 deferral 集成用例。
|
||||
>
|
||||
> 「最后验证批次」列记回执 commit;多数行初值 `20c13c3a`=存量断言精简 A+B 首批的全量域闸回执,RNG 行随 C 档批刷新为 `fd6cf968`。
|
||||
|
||||
**旅程段一:开机与存档**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 存档写盘⇄读回往返保真 | 存档序列化 | `SaveManagerCore.write_to_disk()`/`load_from_disk()` | `save_manager_domain_test.gd:_smoke_save` |
|
||||
| 三槽位隔离与激活失败回滚 | 存档序列化 | `SaveManagerCore.activate_slot()`/`create_slot()`/`delete_slot()` | `save_slot_isolation_test.gd:_test_three_slot_roundtrip_and_isolation`;`save_slot_isolation_test.gd:_test_activate_failure_restores_previous_slot` |
|
||||
| 槽位摘要窥视与坏槽三态 | 存档序列化 | `SaveManagerCore.peek_slot_summary()` | `save_slot_summary_test.gd:_test_peek_three_slots_distinct_values`;`save_slot_summary_test.gd:_test_peek_empty_and_unreadable_states`;`save_slot_summary_test.gd:_test_peek_zero_side_effect` |
|
||||
| 启动态无激活不写盘 | 存档序列化 | `SaveManagerCore.has_write_target()`/`write_to_disk()` | `save_boot_no_activate_test.gd:_test_write_rejected_without_target`;`save_boot_no_activate_test.gd:_test_out_of_range_slots_rejected` |
|
||||
| 旧档迁移链与断点续玩零跳号(集成) | 存档序列化×冒险结构 | `SaveManagerCore.load_from_disk()`(内置迁移链)× `AdventureRunner.resume_adventure()` | `save_rng_roundtrip_test.gd:_test_old_version_save_migrates_and_resumes` |
|
||||
| 存档⇄RNG 快照往返保真(集成) | 存档序列化×RNG 服务×冒险结构 | `AdventureRunner.start_adventure()` → `SaveManagerCore.write_to_disk()`/`load_from_disk()` | `save_rng_roundtrip_test.gd:_test_disk_roundtrip_preserves_breakpoint` |
|
||||
| RNG 统一流派生与取号账本 | RNG 服务 | `RngServiceCore.derive_at()`/`open_stream()`/`counter()` | `rng_service_test.gd:_test_derive_determinism`;`rng_service_test.gd:_test_stream_draw_determinism`;`rng_stream_boot_test.gd:_smoke_initialize` |
|
||||
| 断点片段往返与续玩幂等 | 冒险结构×关卡节点地图 | `LevelRunner.breakpoint_fragment()`/`restore_fragment()`;`AdventureRunner.resume_adventure()` | `breakpoint_resume_test.gd:_init` |
|
||||
| 跨系统附随面:事件日志落盘与断点附随件(集成) | RNG 服务×存档序列化×冒险结构 | `RngServiceCore.new_adventure()`(开事件日志会话);`SaveManagerCore.breakpoint_snapshot()`(断点附随键) | `cross_system_flow_test.gd:_rng_event_log_session`;`cross_system_flow_test.gd:_feats_breakpoint_roundtrip` |
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) | 最后验证批次 | 缺口 |
|
||||
|---|---|---|---|---|---|
|
||||
| 存档写盘⇄读回往返保真 | 存档序列化 | `SaveManagerCore.write_to_disk()`/`load_from_disk()` | `save_manager_domain_test.gd:_smoke_save` | `20c13c3a` | — |
|
||||
| 三槽位隔离与激活失败回滚 | 存档序列化 | `SaveManagerCore.activate_slot()`/`create_slot()`/`delete_slot()` | `save_slot_isolation_test.gd:_test_three_slot_roundtrip_and_isolation`;`save_slot_isolation_test.gd:_test_activate_failure_restores_previous_slot` | `20c13c3a` | — |
|
||||
| 槽位摘要窥视与坏槽三态 | 存档序列化 | `SaveManagerCore.peek_slot_summary()` | `save_slot_summary_test.gd:_test_peek_three_slots_distinct_values`;`save_slot_summary_test.gd:_test_peek_empty_and_unreadable_states`;`save_slot_summary_test.gd:_test_peek_zero_side_effect` | `20c13c3a` | — |
|
||||
| 启动态无激活不写盘 | 存档序列化 | `SaveManagerCore.has_write_target()`/`write_to_disk()` | `save_boot_no_activate_test.gd:_test_write_rejected_without_target`;`save_boot_no_activate_test.gd:_test_out_of_range_slots_rejected` | `20c13c3a` | — |
|
||||
| 旧档迁移链与断点续玩零跳号(集成) | 存档序列化×冒险结构 | `SaveManagerCore.load_from_disk()`(内置迁移链)× `AdventureRunner.resume_adventure()` | `save_rng_roundtrip_test.gd:_test_old_version_save_migrates_and_resumes` | `20c13c3a` | — |
|
||||
| 存档⇄RNG 快照往返保真(集成) | 存档序列化×RNG 服务×冒险结构 | `AdventureRunner.start_adventure()` → `SaveManagerCore.write_to_disk()`/`load_from_disk()` | `save_rng_roundtrip_test.gd:_test_disk_roundtrip_preserves_breakpoint` | `20c13c3a` | — |
|
||||
| RNG 统一流派生与取号账本 | RNG 服务 | `RngServiceCore.derive_at()`/`open_stream()`/`counter()` | `rng_service_test.gd:_test_derive_determinism`;`rng_service_test.gd:_test_stream_draw_determinism`;`rng_stream_boot_test.gd:_smoke_initialize` | `fd6cf968` | — |
|
||||
| 断点片段往返与续玩幂等 | 冒险结构×关卡节点地图 | `LevelRunner.breakpoint_fragment()`/`restore_fragment()`;`AdventureRunner.resume_adventure()` | `breakpoint_resume_test.gd:_init` | `20c13c3a` | — |
|
||||
| 跨系统附随面:事件日志落盘与断点附随件(集成) | RNG 服务×存档序列化×冒险结构 | `RngServiceCore.new_adventure()`(开事件日志会话);`SaveManagerCore.breakpoint_snapshot()`(断点附随键) | `cross_system_flow_test.gd:_rng_event_log_session`;`cross_system_flow_test.gd:_feats_breakpoint_roundtrip` | `20c13c3a` | 日志面仅此一条会话覆盖 |
|
||||
|
||||
**旅程段二:冒险开局与选路**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 冒险生命周期:开局受理/三关序列/败北线 | 冒险结构 | `AdventureRunner.start_adventure()`/`continue_to_next_level()` | `adventure_feats_test.gd:_smoke_adventure_api`;`adventure_feats_test.gd:_smoke_adventure` |
|
||||
| 专长(奇物)授予与凭证保底 | 奇物 | `AdventureRunner.present_node_curio()`/`feats_held()` × 效果引擎兑付 | `adventure_feats_test.gd:_smoke_feats`;`feat_vouchers_test.gd:_init` |
|
||||
| 节点图生成合法性与同种子复现 | 关卡节点图生成 | `NodeMapGenerator.generate()`/`validate_output()` | `node_map_generator_test.gd:_test_output_ok`;`node_map_generator_test.gd:_test_reproducible`;`node_map_generator_test.gd:_test_exit_structure` |
|
||||
| 节点图生长递增与无解 fail-fast | 关卡节点图生成 | `NodeMapGenerator.generate()`/`is_fatal()` | `node_map_growth_test.gd:_test_growth`;`node_map_growth_test.gd:_test_fatal_subprocess` |
|
||||
| 起关/选路/断点重生成同图(集成) | 关卡节点地图×关卡节点图生成×冒险结构 | `LevelRunner.start_level()`/`start_level_external()`/`pick_next_node()`;`AdventureRunner.resume_adventure()` | `node_map_determinism_test.gd:_smoke_generated_map_determinism` |
|
||||
| 信息迷雾类型可见性 | 关卡节点地图 | `LevelRunner.type_visible_ids()` | `level_map_type_vis_test.gd:_test_layer_distance`;`level_map_type_vis_test.gd:_test_boss_exempt`;`level_map_type_vis_test.gd:_test_resume_rebuild` |
|
||||
| 关卡表消费侧校验与关卡推进 | 关卡节点地图×数据配置 | `LevelTable.validate_graph()`;`LevelRunner.start_level()` | `level_table_validate_test.gd:_test_positive`;`level_table_validate_test.gd:_test_negative`;`level_shop_economy_test.gd:_smoke_level` |
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) | 最后验证批次 | 缺口 |
|
||||
|---|---|---|---|---|---|
|
||||
| 冒险生命周期:开局受理/三关序列/败北线 | 冒险结构 | `AdventureRunner.start_adventure()`/`continue_to_next_level()` | `adventure_feats_test.gd:_smoke_adventure_api`;`adventure_feats_test.gd:_smoke_adventure` | `20c13c3a` | — |
|
||||
| 专长(奇物)授予与凭证保底 | 奇物 | `AdventureRunner.present_node_curio()`/`feats_held()` × 效果引擎兑付 | `adventure_feats_test.gd:_smoke_feats`;`feat_vouchers_test.gd:_init` | `20c13c3a` | — |
|
||||
| 节点图生成合法性与同种子复现 | 关卡节点图生成 | `NodeMapGenerator.generate()`/`validate_output()` | `node_map_generator_test.gd:_test_output_ok`;`node_map_generator_test.gd:_test_reproducible`;`node_map_generator_test.gd:_test_exit_structure` | `20c13c3a` | — |
|
||||
| 节点图生长递增与无解 fail-fast | 关卡节点图生成 | `NodeMapGenerator.generate()`/`is_fatal()` | `node_map_growth_test.gd:_test_growth`;`node_map_growth_test.gd:_test_fatal_subprocess` | `20c13c3a` | — |
|
||||
| 起关/选路/断点重生成同图(集成) | 关卡节点地图×关卡节点图生成×冒险结构 | `LevelRunner.start_level()`/`start_level_external()`/`pick_next_node()`;`AdventureRunner.resume_adventure()` | `node_map_determinism_test.gd:_smoke_generated_map_determinism` | `20c13c3a` | — |
|
||||
| 信息迷雾类型可见性 | 关卡节点地图 | `LevelRunner.type_visible_ids()` | `level_map_type_vis_test.gd:_test_layer_distance`;`level_map_type_vis_test.gd:_test_boss_exempt`;`level_map_type_vis_test.gd:_test_resume_rebuild` | `20c13c3a` | — |
|
||||
| 关卡表消费侧校验与关卡推进 | 关卡节点地图×数据配置 | `LevelTable.validate_graph()`;`LevelRunner.start_level()` | `level_table_validate_test.gd:_test_positive`;`level_table_validate_test.gd:_test_negative`;`level_shop_economy_test.gd:_smoke_level` | `20c13c3a` | — |
|
||||
|
||||
**旅程段三:战斗结算**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 伤害公式与掷点乘区 | 战斗结算 | `DamageMath.pool_damage()`/`roll_discount_percent()`/`rolled_component()` | `damage_math_test.gd:_test_pool_damage`;`damage_math_test.gd:_test_roll_discount_percent`;`roll_multiplier_test.gd:_smoke_armor_roll` |
|
||||
| 伤害单据编排与回放 | 战斗结算 | `DamageController.submit()`/`open_ticket()`/`flush()` | `damage_controller_test.gd:_run_recipe_sequence`;`damage_controller_test.gd:_test_five_recipes_and_replay` |
|
||||
| 轮内流与结算五段全序 | 战斗结算 | `BattleOrchestrator.begin_battle()` | `round_flow_skill_pool_test.gd:_smoke_full_battle`;`round_flow_skill_pool_test.gd:_smoke_settlement_segments` |
|
||||
| 技能池数据面与回放独立 | 敌人系统 | `BattleOrchestrator.begin_battle()`(技能池抽号/校验) | `round_flow_skill_pool_test.gd:_smoke_skill_pool_data`;`round_flow_skill_pool_test.gd:_smoke_skill_pool_replay_independence` |
|
||||
| Boss 半血解锁技门控 | 敌人系统 | `BattleOrchestrator.begin_battle()`(Boss 行) | `skill_unlock_test.gd:_test_gate_predicate`;`skill_unlock_test.gd:_test_latch_irreversible` |
|
||||
| 封印与极性路由/不可逆 | 地图战斗资源×战斗结算 | 效果引擎 × `BattleOrchestrator.begin_battle()` | `seal_polarity_test.gd:_smoke_seal_ap_exhausted`;`seal_polarity_test.gd:_smoke_seal_irreversible_quadrants`;`seal_polarity_test.gd:_smoke_polarity_routing` |
|
||||
| 变异布置门控 | 地形变异 | `BattleOrchestrator.begin_battle()`(变异布置段) | `variant_placement_test.gd:_smoke_variant_placement`;`variant_placement_test.gd:_smoke_global_variant` |
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) | 最后验证批次 | 缺口 |
|
||||
|---|---|---|---|---|---|
|
||||
| 伤害公式与掷点乘区 | 战斗结算 | `DamageMath.pool_damage()`/`roll_discount_percent()`/`rolled_component()` | `damage_math_test.gd:_test_pool_damage`;`damage_math_test.gd:_test_roll_discount_percent`;`roll_multiplier_test.gd:_smoke_armor_roll` | `20c13c3a` | — |
|
||||
| 伤害单据编排与回放 | 战斗结算 | `DamageController.submit()`/`open_ticket()`/`flush()` | `damage_controller_test.gd:_run_recipe_sequence`;`damage_controller_test.gd:_test_five_recipes_and_replay` | `20c13c3a` | — |
|
||||
| 轮内流与结算五段全序 | 战斗结算 | `BattleOrchestrator.begin_battle()` | `round_flow_skill_pool_test.gd:_smoke_full_battle`;`round_flow_skill_pool_test.gd:_smoke_settlement_segments` | `20c13c3a` | — |
|
||||
| 技能池数据面与回放独立 | 敌人系统 | `BattleOrchestrator.begin_battle()`(技能池抽号/校验) | `round_flow_skill_pool_test.gd:_smoke_skill_pool_data`;`round_flow_skill_pool_test.gd:_smoke_skill_pool_replay_independence` | `20c13c3a` | — |
|
||||
| Boss 半血解锁技门控 | 敌人系统 | `BattleOrchestrator.begin_battle()`(Boss 行) | `skill_unlock_test.gd:_test_gate_predicate`;`skill_unlock_test.gd:_test_latch_irreversible` | `20c13c3a` | — |
|
||||
| 封印与极性路由/不可逆 | 地图战斗资源×战斗结算 | 效果引擎 × `BattleOrchestrator.begin_battle()` | `seal_polarity_test.gd:_smoke_seal_ap_exhausted`;`seal_polarity_test.gd:_smoke_seal_irreversible_quadrants`;`seal_polarity_test.gd:_smoke_polarity_routing` | `20c13c3a` | — |
|
||||
| 变异布置门控 | 地形变异 | `BattleOrchestrator.begin_battle()`(变异布置段) | `variant_placement_test.gd:_smoke_variant_placement`;`variant_placement_test.gd:_smoke_global_variant` | `20c13c3a` | — |
|
||||
|
||||
**旅程段四:奖励、经济与局外成长**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 清图奖励双份与零路径 | 地图战斗资源 | `BattleOrchestrator.begin_battle()` → 步骤流行(`source_class=clear_reward`) | `seal_polarity_test.gd:_smoke_clear_reward_chain`;`seal_polarity_test.gd:_smoke_clear_reward_zero_paths` |
|
||||
| 奖励三选一候选/刷新付费/呈现 | 奇物×节点奖励屏 | `AdventureRunner.present_node_curio()`(数据面);奖励节点覆盖层场景(呈现面) | `curio_refresh_paid_test.gd:_init`;`reward_overlay_test.gd:_run` |
|
||||
| GP 钱包/escrow/商店收口/共享池 | 地图战斗资源×商店 | `LevelRunner.shop.buy_product()`/`shop.player_request_refresh()`/`LevelRunner.close_wallet()`/`shop.set_shop_pool()` | `level_shop_economy_test.gd:_smoke_gp_wallet`;`level_shop_economy_test.gd:_smoke_shop_room`;`level_shop_economy_test.gd:_smoke_shop_pool` |
|
||||
| 元进度入账与锻造两轴 | 元进度×锻造工坊 | `MetaStateStore.apply_adventure_summary()`/`MetaStateStore.spend_keystone()`/`MetaStateStore.set_forge_route_level()` | `meta_progression_forge_test.gd:_meta_pricing_and_buy`;`meta_progression_forge_test.gd:_smoke_forge_axes` |
|
||||
| 天赋树购买与六键合成 | 天赋树 | `MetaProgression.tree_buy()`/`MetaStateStore.tree_state()`/`MetaStateStore.set_tree_level()` | `meta_progression_forge_test.gd:_smoke_tree`;`meta_progression_forge_test.gd:_smoke_tree_rules`;`tree_rules_v11_test.gd:_init` |
|
||||
| 秘宝结构冻结与 12 件效果 | 秘宝 | `TreasureItems.add_item()`/`query_inventory()`/`validate_use()` | `treasure_items_test.gd:_init`;`treasure_effects_test.gd:_init` |
|
||||
|
||||
**旅程段五:排雷循环**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 棋盘按参数行出图、数字恒真 | 棋盘生成 | `BoardGenerator.generate()` | `board_generator_test.gd:_test_generate_shape_and_mines`;`board_generator_test.gd:_test_digits_equal_neighbor_mine_count` |
|
||||
| 同参数同种子逐位复现、异种子不退化 | 棋盘生成 | `BoardGenerator.generate()` | `board_generator_test.gd:_test_same_seed_bit_identical`;`board_gen_reward_test.gd:_smoke_board_generator` |
|
||||
| 可推理率与清图可达(合法性先于质量分)、重试有界、降级诚实 | 棋盘生成 | `BoardGenerator.measure_inferability()`/`BoardGenerator.is_clearable()` | `board_generator_test.gd:_test_clearable_and_inferability_selfconsistent`;`board_generator_test.gd:_test_target_mine_count_single_source`;`board_gen_reward_test.gd:_smoke_board_generator` |
|
||||
| 装板与开局免费展开(封锁格无资源、计入清图) | 排雷玩法 | `MinesweeperRules.install_board()` | `minesweeper_rules_test.gd:_test_install_invariants`;`seal_polarity_test.gd:_smoke_resource_surface` |
|
||||
| 挖/封印合法性与可辨拒绝(拒绝零副作用) | 排雷玩法 | `MinesweeperRules.settle_batch()` | `minesweeper_rules_test.gd:_test_dig_face_rules`;`minesweeper_rules_test.gd:_test_seal_place`;`minesweeper_rules_test.gd:_test_reject_out_of_catalog` |
|
||||
| 封印不可逆与挖开封印格放行(兑付改判四情况) | 排雷玩法 | `MinesweeperRules.settle_batch()` | `seal_polarity_test.gd:_smoke_seal_irreversible_quadrants`;`minesweeper_rules_test.gd:_test_seal_place` |
|
||||
| AP 扣费、末点耗尽即收轮与战斗收束清零 | 行动经济 | `MinesweeperRules.settle_batch()`(→`ActionEconomy.try_spend()`/`ActionEconomy.notify_combat_end()`) | `seal_polarity_test.gd:_smoke_seal_ap_exhausted`;`round_flow_skill_pool_test.gd:_smoke_full_battle`;`round_flow_skill_pool_test.gd:_smoke_active_refresh` |
|
||||
| 停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) | 行动经济 | `BattleOrchestrator.player_request_refresh()`/`MinesweeperRules.settle_batch()` | `round_flow_skill_pool_test.gd:_smoke_active_refresh`;`seal_polarity_test.gd:_smoke_refresh_provenance_guard` |
|
||||
| 下轮行动点修正排队与兑现 | 行动经济 | `ActionEconomy.pending_ap_delta()`(排队经 `ActionEconomy.queue_ap_delta()`,写入方为效果引擎) | `seal_polarity_test.gd:_smoke_negative_dictionary`;`feat_vouchers_test.gd:_init` |
|
||||
|
||||
**旅程段六:表现与支撑**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 拒绝反馈分面可辨与未知兜底文案 | HUD框架 | `HudPresenter.outcome_text()` | `hud_presenter_test.gd:_test_reject_text_by_reason`;`hud_presenter_test.gd:_test_unknown_reason_fallback`;`hud_presenter_test.gd:_test_accepted_text` |
|
||||
| 结算明细带逐行呈现与排播节奏 | HUD框架 | `BattleLogView.append_row()`/`RowPacer.pace_delay_for()` | `theme_projection_test.gd:_smoke_battle_log_view`;`player_copy_sweep_test.gd:_sweep_source_names`;`pacing_queue_test.gd:_init` |
|
||||
| 模态覆盖层编排与输入锁 | HUD框架 | `ModalFlow.locks_input()`/`ModalFlow.open_after_playback()` | `modal_flow_test.gd:_init`;`reward_overlay_test.gd:_run` |
|
||||
| 未开格类型微光(8 邻作用集/五组色相/零玩法写入) | HUD框架 | `BoardView.type_glow_probe()`/`UiKit.glow_group_for_cell_type()` | `theme_projection_test.gd:_smoke_type_glow`;`type_glow_test.gd:_test_grouping_closed`;`type_glow_test.gd:_test_frozen_hue_face` |
|
||||
| 棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) | HUD框架 | `ui_input_probe` 合成鼠标事件→`BoardView._gui_input()`;读面 `BoardView.hover_probe()` | `ui_input_probe.gd:_ready`(case①到达②禁入③路径预览三语义) |
|
||||
| UI 全局主题与按钮五态(含对比度锚) | HUD框架 | `UiKit.button()`/`UiKit.primary_button()` | `theme_projection_test.gd:_smoke_global_theme`;`theme_projection_test.gd:_smoke_button_five_states`;`theme_projection_test.gd:_smoke_contrast_inks` |
|
||||
| 中文字体随包与字形覆盖 | HUD框架 | `UiKit.load_font()` | `ui_font_asset_test.gd:_init`;`theme_projection_test.gd:_smoke_global_theme` |
|
||||
| 地形瓦片套与格面数字可读 | HUD框架 | `TilePalette.digit_ink_mode()`/`TilePalette.normalize_floor_luma()` | `terrain_tile_sets_test.gd:_test_set_completeness`;`terrain_tile_sets_test.gd:_test_hue_domains`;`terrain_tile_sets_test.gd:_test_digit_ink_modes` |
|
||||
| 站桩敌人呈现与结算演出落点 | 战斗表现 | `BattleStageView.enemy_standee_center()`/`BattleEndOverlay.open_victory()` | `standee_fx_sweep_test.gd:_init`;`pacing_queue_test.gd:_init` |
|
||||
| 战斗叙述与终局文案(数值带入/胜负互异) | HUD框架 | `BattleNarrator.battle_end_text()`/`BattleNarrator.boss_name()` | `battle_narrator_test.gd:_test_numeric_lines_carry_values`;`battle_narrator_test.gd:_test_end_text_differs_by_result`;`battle_narrator_test.gd:_test_boss_name_uses_boss_rowset` |
|
||||
| 玩家面文案与危险格格面字形 | HUD框架 | `BoardView.rebuild()`/`StatusSlotRow.set_effects()` | `player_copy_sweep_test.gd:_sweep_board_glyph`;`player_copy_sweep_test.gd:_sweep_legend`;`player_copy_sweep_test.gd:_sweep_hero_panel` |
|
||||
|
||||
**旅程段七:数据配置与跨系统契约**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) |
|
||||
|---|---|---|---|
|
||||
| 全表装载、就绪态与表清单目录对账 | 数据配置 | `ConfigDB.load_tables()`/`ConfigDB.diagnostics_count()` | `config_db_test.gd:_test_manifest_dir_sync`;`rng_stream_boot_test.gd:_smoke_initialize` |
|
||||
| 进度坐标查行:精确命中/向上取整/封顶/警告去重 | 数据配置 | `BoardGenTable.resolve_row()`/`ConfigDbResolver.resolve_enemy_rowset()` | `config_db_test.gd:_test_progress_resolution`;`config_db_resolver_test.gd:_test_band_hit`;`config_db_resolver_test.gd:_test_top_band_clamp` |
|
||||
| 行集寻址、行序保序与难度乘数 clamp | 数据配置×难度曲线与Boss | `ConfigDbResolver.resolve_enemy_rowset()`/`ConfigDbResolver.resolve_difficulty_modifiers()` | `config_db_resolver_test.gd:_test_rowset_order_preserved`;`config_db_resolver_test.gd:_test_row_kind_routing`;`config_db_resolver_test.gd:_test_difficulty_clamp` |
|
||||
| 运行期越域致命与进程非 0 退出 | 数据配置 | `BoardGenTable.resolve_row()`/`ConfigDbResolver.resolve_enemy_rowset()` | `config_db_fatal_oob_test.gd:_trigger_oob`;`config_db_resolver_test.gd:_test_request_oob` |
|
||||
| 加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域 | 数据配置×秘宝×奇物 | `ConfigDB.load_tables()` | `reward_dangling_treasure_test.gd:_init`;`counter_prefix_fatal_test.gd:_assert_rejected`;`treasure_target_violation_test.gd:_init` |
|
||||
| 表结构守卫:域校验/行序键/跨字段互锁/配额锚 | 数据配置×敌人系统×地形变异×冒险结构 | `EnemyTable.validate()`/`VariationTable.variant_pool()`/`AdventureTable.validate()` | `table_structure_guard_test.gd:_smoke_enemy_bands`;`table_structure_guard_test.gd:_smoke_variation_framework`;`table_structure_guard_test.gd:_smoke_adventure_table` |
|
||||
| 难度修饰套乘:空表零行为/套乘生效/越域 clamp | 难度曲线与Boss | `UnitContainer.spawn()`/`ConfigDbResolver.resolve_difficulty_modifiers()` | `table_structure_guard_test.gd:_smoke_difficulty_table`;`config_db_resolver_test.gd:_test_difficulty_clamp` |
|
||||
| 锻造表 schema 正反与几何价格梯 | 锻造工坊 | `ForgeTable.level_price()`/`ForgeTable.route_rows()` | `forge_table_test.gd:_test_production_rows`;`forge_table_test.gd:_test_price_ladder`;`forge_table_test.gd:_test_negative_cases` |
|
||||
| 系统间契约词表与受理口径:五配方互异/掷点标签成员性/增益布尔受理 | 战斗结算×数据配置×增益状态 | `DamageController.open_ticket()`/`StatusContainer.apply_effect()` | `system_contracts_test.gd:_test_damage_controller_vocabularies`;`system_contracts_test.gd:_test_rng_tag_closure`;`system_contracts_test.gd:_test_status_boolean_acceptance` |
|
||||
| 敌人技能池跨表链接校验 | 数据配置×敌人系统 | `ConfigDbCrossValidator.validate_skill_pool_links()` | `config_db_cross_validator_test.gd:_test_all_links_valid`;`config_db_cross_validator_test.gd:_test_dangling_skill_id`;`config_db_cross_validator_test.gd:_test_cast_side_mismatch` |
|
||||
| 能力 | 系统 | 真实入口 | 代表用例(文件:函数) | 最后验证批次 | 缺口 |
|
||||
|---|---|---|---|---|---|
|
||||
| 清图奖励双份与零路径 | 地图战斗资源 | `BattleOrchestrator.begin_battle()` → 步骤流行(`source_class=clear_reward`) | `seal_polarity_test.gd:_smoke_clear_reward_chain`;`seal_polarity_test.gd:_smoke_clear_reward_zero_paths` | `20c13c3a` | — |
|
||||
| 奖励三选一候选/刷新付费/呈现 | 奇物×节点奖励屏 | `AdventureRunner.present_node_curio()`(数据面);奖励节点覆盖层场景(呈现面) | `curio_refresh_paid_test.gd:_init`;`reward_overlay_test.gd:_run` | `20c13c3a` | — |
|
||||
| GP 钱包/escrow/商店收口/共享池 | 地图战斗资源×商店 | `LevelRunner.buy_product()`/`player_request_refresh()`/`close_wallet()`/`set_shop_pool()` | `level_shop_economy_test.gd:_smoke_gp_wallet`;`level_shop_economy_test.gd:_smoke_shop_room`;`level_shop_economy_test.gd:_smoke_shop_pool` | `20c13c3a` | — |
|
||||
| 元进度入账与锻造两轴 | 元进度×锻造工坊 | `SaveManagerCore.add_keystone()`/`spend_keystone()`/`set_forge_route_level()` | `meta_progression_forge_test.gd:_meta_pricing_and_buy`;`meta_progression_forge_test.gd:_smoke_forge_axes` | `20c13c3a` | — |
|
||||
| 天赋树购买与六键合成 | 天赋树 | `SaveManagerCore.tree_nodes()`/`set_tree_level()` | `meta_progression_forge_test.gd:_smoke_tree`;`meta_progression_forge_test.gd:_smoke_tree_rules`;`tree_rules_v11_test.gd:_init` | `20c13c3a` | — |
|
||||
| 秘宝结构冻结与 12 件效果 | 秘宝 | `TreasureItems.add_item()`/`query_inventory()`/`validate_use()` | `treasure_items_test.gd:_init`;`treasure_effects_test.gd:_init` | `20c13c3a` | — |
|
||||
|
||||
**跨域条件闸**
|
||||
|
||||
| 能力 | 系统 | 真实入口 | 代表用例 |
|
||||
|---|---|---|---|
|
||||
| 回放确定性(同种子三变体逐位) | 全玩法链 | `tools/parity_anchor.py`(闸 11 条件闸,按批发起) | `tools/parity_anchor.py`(整件为条件闸) |
|
||||
|
||||
**覆盖域表**(`design/gdd/systems/` 逐篇对照——状态三档:已覆盖/部分覆盖/未覆盖;部分与未覆盖行的缺口指待办清单条目,覆盖面提升时同批改本表):
|
||||
|
||||
| 域 | 系统文档 | 能力行 | 状态 | 缺口 |
|
||||
|---|---|---|---|---|
|
||||
| 冒险循环 | 冒险结构.md | 冒险生命周期:开局受理/三关序列/败北线;断点片段往返与续玩幂等;起关/选路/断点重生成同图(集成) | 已覆盖 | — |
|
||||
| 冒险循环 | 关卡节点图生成.md | 节点图生成合法性与同种子复现;节点图生长递增与无解 fail-fast | 已覆盖 | — |
|
||||
| 冒险循环 | 关卡节点地图.md | 起关/选路/断点重生成同图(集成);信息迷雾类型可见性;关卡表消费侧校验与关卡推进 | 已覆盖 | — |
|
||||
| 冒险循环 | 奇物.md | 专长(奇物)授予与凭证保底;奖励三选一候选/刷新付费/呈现 | 已覆盖 | — |
|
||||
| 冒险循环 | 难度曲线与Boss.md | Boss 半血解锁技门控;行集寻址、行序保序与难度乘数 clamp;难度修饰套乘:空表零行为/套乘生效/越域 clamp | 部分覆盖 | 难度曲线整链与 Boss 出场门控无专项断言;见待办清单「能力清单覆盖缺口补齐」条 |
|
||||
| 战斗循环 | 地图战斗资源.md | 清图奖励双份与零路径;GP 钱包/escrow/商店收口/共享池;封印与极性路由/不可逆 | 已覆盖 | — |
|
||||
| 战斗循环 | 增益状态.md | 系统间契约词表与受理口径:五配方互异/掷点标签成员性/增益布尔受理;封印与极性路由/不可逆 | 部分覆盖 | 增益叠层/衰减/清除结算链无断言;见待办清单「能力清单覆盖缺口补齐」条 |
|
||||
| 战斗循环 | 战斗结算.md | 伤害公式与掷点乘区;伤害单据编排与回放;轮内流与结算五段全序 | 已覆盖 | — |
|
||||
| 战斗循环 | 战斗表现.md | 站桩敌人呈现与结算演出落点 | 部分覆盖 | 死亡灰化与减动效演出档仅探针与人工目检;见待办清单「能力清单覆盖缺口补齐」条 |
|
||||
| 战斗循环 | 敌人系统.md | 技能池数据面与回放独立;Boss 半血解锁技门控;敌人技能池跨表链接校验 | 已覆盖 | — |
|
||||
| 排雷循环 | 地形变异.md | 变异布置门控;表结构守卫:域校验/行序键/跨字段互锁/配额锚 | 已覆盖 | — |
|
||||
| 排雷循环 | 排雷玩法.md | 装板与开局免费展开(封锁格无资源、计入清图);挖/封印合法性与可辨拒绝(拒绝零副作用);封印不可逆与挖开封印格放行(兑付改判四情况) | 已覆盖 | — |
|
||||
| 排雷循环 | 棋盘生成.md | 棋盘按参数行出图、数字恒真;同参数同种子逐位复现、异种子不退化;可推理率与清图可达(合法性先于质量分)、重试有界、降级诚实 | 已覆盖 | — |
|
||||
| 排雷循环 | 行动经济.md | AP 扣费、末点耗尽即收轮与战斗收束清零;停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励);下轮行动点修正排队与兑现 | 已覆盖 | — |
|
||||
| 表现与支撑 | HUD框架.md | 拒绝反馈分面可辨与未知兜底文案;结算明细带逐行呈现与排播节奏;模态覆盖层编排与输入锁;未开格类型微光(8 邻作用集/五组色相/零玩法写入);UI 全局主题与按钮五态(含对比度锚);中文字体随包与字形覆盖;地形瓦片套与格面数字可读;战斗叙述与终局文案(数值带入/胜负互异);玩家面文案与危险格格面字形 | 已覆盖 | — |
|
||||
| 表现与支撑 | 存档序列化.md | 存档写盘⇄读回往返保真;三槽位隔离与激活失败回滚;槽位摘要窥视与坏槽三态;启动态无激活不写盘;旧档迁移链与断点续玩零跳号(集成);存档⇄RNG 快照往返保真(集成) | 已覆盖 | — |
|
||||
| 表现与支撑 | 教学引导.md | — | 未覆盖 | 教学形态与首遇时机待设计;见待办清单「教学形态未定」条 |
|
||||
| 表现与支撑 | 数据配置.md | 全表装载、就绪态与表清单目录对账;进度坐标查行:精确命中/向上取整/封顶/警告去重;运行期越域致命与进程非 0 退出;加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域;表结构守卫:域校验/行序键/跨字段互锁/配额锚 | 已覆盖 | — |
|
||||
| 表现与支撑 | 设置与本地化.md | — | 未覆盖 | 减动效开关本体仅系统测试与冒烟覆盖、无单元/集成断言,多语言切换面未建;见待办清单「能力清单覆盖缺口补齐」条 |
|
||||
| 表现与支撑 | 音频.md | — | 未覆盖 | MVP 无音频(P1 后置,无断言面);见待办清单「能力清单覆盖缺口补齐」条 |
|
||||
| 跨局循环 | 元进度.md | 元进度入账与锻造两轴 | 已覆盖 | — |
|
||||
| 跨局循环 | 天赋树.md | 天赋树购买与六键合成 | 已覆盖 | — |
|
||||
| 跨局循环 | 生涯.md | — | 未覆盖 | P6 后置未实装;见待办清单「「生涯」界面——冒险中数据回看的唯一承接处」条 |
|
||||
| 跨局循环 | 秘宝.md | 秘宝结构冻结与 12 件效果;加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域 | 已覆盖 | — |
|
||||
| 跨局循环 | 锻造工坊.md | 锻造表 schema 正反与几何价格梯;元进度入账与锻造两轴 | 部分覆盖 | 价格梯仅长剑路线逐级验,GDD 无验收标准节(机检豁免在册);见待办清单「能力清单覆盖缺口补齐」条 |
|
||||
| 能力 | 系统 | 真实入口 | 代表用例 | 最后验证批次 | 缺口 |
|
||||
|---|---|---|---|---|---|
|
||||
| 回放确定性(同种子三变体逐位) | 全玩法链 | `tools/parity_anchor.py`(闸 11 条件闸,按批发起) | `tools/parity_anchor.py`(整件为条件闸) | —(条件闸) | 条件闸未随本批执行 |
|
||||
|
||||
## 断言计数双口径(2026-10-08 迭代 19 卡① T4 订正)
|
||||
|
||||
@@ -198,7 +125,7 @@ tests/
|
||||
|---|---|---|---|
|
||||
| `tools/run_smoke.py`(冒烟测试) | 这版能否启动、能否加载表、能否进主屏——零逻辑判定 | 退出码+脚本错误扫描 | 开机路径/表加载改动后的快速自检;收口由闸编排 |
|
||||
| `tools/run_system_test.py`(系统测试) | 真实玩法路径的行为断言面(推理→战斗→结算→进度推进) | 退出码+脚本错误扫描 | 玩法链路改动的调试期确认 |
|
||||
| `tests/run_all.gd`(单元与集成) | 公式/状态机/契约/跨系统闭环(65 套件 manifest) | 退出码+三硬闸(见下);每套件子进程带截止时间守护——超时先 taskkill /T 整树回收再判该套件 FAIL、批继续(默认 120s,环境变量 `RUN_ALL_SUITE_TIMEOUT_SEC` 可覆盖);连续 3 个套件超时=红树整批挂死,第 3 个即中止整轮、汇总已见失败与超时清单后非 0 退出(阈值=可调常量,不连续的超时照旧逐个回收) | 新套件单跑调试;逻辑改动的最小单元复跑;开发期选跑——追加 `-- --only=<词[,词…]>` 只跑路径命中词的套件(零命中=用法错 exit 2;此形态仅供开发期最窄确认,不产闸回执、不作验收凭据);闸机关联档选跑——同一过滤机制加 `-- --only-source=gates`,由 `tools/run_all_gates.sh` 在 02 闸传入(回执 scope=related,是验收跑批本体) |
|
||||
| `tests/run_all.gd`(单元与集成) | 公式/状态机/契约/跨系统闭环(64 套件 manifest) | 退出码+三硬闸(见下);每套件子进程带截止时间守护——超时先 taskkill /T 整树回收再判该套件 FAIL、批继续(默认 120s,环境变量 `RUN_ALL_SUITE_TIMEOUT_SEC` 可覆盖) | 新套件单跑调试;逻辑改动的最小单元复跑;开发期选跑——追加 `-- --only=<词[,词…]>` 只跑路径命中词的套件(零命中=用法错 exit 2;选跑态仅供开发期最窄确认,不产闸回执、不作验收凭据) |
|
||||
| `tools/probe_gate.sh`(场景探针,`--click`/`--full` 两模式) | UI 可达性、可见性、状态——真实实例化场景+真实输入路径 | 探针自检+退出码 | 新增 UI 区域的配套探针直跑与断言复核 |
|
||||
| `tools/render_gate.sh`(渲染 golden) | 画面基线——截图与基线图逐像素容差比对 | golden 比对脚本(依赖 PIL) | 主题/素材/排版类改动;窗口化运行,需开显示器 |
|
||||
| `game/tests/static_scan.sh`(S 域) | 项目纪律+第三方质量规则:RNG 单点/core 纯度/类型标注/文件头/注释禁词/旧符号残留;S13=gdstyle 质量规则(重复 load、循环内 await、循环内分配、不可达代码等真缺陷类;基线键=文件|规则|函数名(类/文件级=文件|规则,无数字条目带消息),数字漂移不假红,同键指标恶化超基线登记值即红) | 退出码(逐规则 FAIL 行) | 改产品码前后的快速自检;新增纪律先补扫描规则再修码 |
|
||||
@@ -226,12 +153,10 @@ godot --headless --path . res://probe/<probe>.tscn
|
||||
|
||||
# 挂死防护内建于 run_all.gd(引擎无死锁探测,超时靠外部判):每套件子进程带截止时间——
|
||||
# 默认 120s,环境变量 RUN_ALL_SUITE_TIMEOUT_SEC 可覆盖;超时先 taskkill /T 整树回收
|
||||
#(cmd wrapper 连引擎孙进程一起杀,不留孤儿),该套件判 FAIL、批继续——单套件挂死不拖死整闸;
|
||||
# 连续 3 个套件超时=红树整批挂死,第 3 个即中止整轮(汇总已见失败与超时清单、退出码非 0),
|
||||
# 不连续的超时照旧逐个回收;阈值是 run_all.gd 内可调常量
|
||||
#(cmd wrapper 连引擎孙进程一起杀,不留孤儿),该套件判 FAIL、批继续——单套件挂死不拖死整闸
|
||||
```
|
||||
|
||||
> 套件 manifest 现况:`_suites()` 登记 **65 条**(62 单元+3 集成,2026-10-29 实数;口径=manifest 条目数,
|
||||
> 套件 manifest 现况:`_suites()` 登记 **64 条**(61 单元+3 集成,2026-10-28 实数;口径=manifest 条目数,
|
||||
> 随套件增减浮动)——data_config(ConfigDB 加载/进度坐标 ceil 解析/fatal 退出码/统一随机流)、core(秘宝结构冻结/断点续玩/存档槽位/结算五段等)、battle_settlement(DamageMath 纯函数/DamageController 伤害单据五配方)、contracts(系统间接口契约断言)、presentation(节奏队列/奖励浮层/字体资产/地形瓦片集/模态编排等);集成 3 条存 `tests/integration/`。致命类独立进程 `expect=1`;负面套件 `negative=true` 只豁免错误扫描一闸。期望值一律由表读值推导(零玩法数值字面量)、随机只经 RngService 统一流。
|
||||
|
||||
**协议要点**(D2 冒烟协议):
|
||||
@@ -300,9 +225,9 @@ S12 效果引擎无状态化旧件零残留:扫描 game/ 全域 `.gd` 与 `gam
|
||||
|
||||
## 本地闸(唯一验收门禁)
|
||||
|
||||
本仓库无远端、无 CI——**验收只在本地发生**,跑 `tools/run_all_gates.sh` 是收口唯一入口,按本批改动域选档(`--code`/`--docs`/跨两域或改闸件本身=不带参数全量;代码域 02 按关联档选套件,回执 `scope` 字段记 full|related),
|
||||
跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 与 `scope` 字段),合回 master 由 worktree-guard 按 diff 文件性质推域校验回执(`game/` 内 `.md` 归文档域)。
|
||||
闸清单与域划分(含选闸算法与套件族映射表)的唯一定义处就是那个脚本,本文档不另列清单(清单散落多份文档正是历史漏跑闸的成因)。
|
||||
本仓库无远端、无 CI——**验收只在本地发生**,跑 `tools/run_all_gates.sh` 是收口唯一入口,按本批改动域选档(`--code`/`--docs`/跨两域或改闸件本身=不带参数全量),
|
||||
跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回 master 由 worktree-guard 按 diff 文件性质推域校验回执(`game/` 内 `.md` 归文档域)。
|
||||
闸清单与域划分的唯一定义处就是那个脚本,本文档不另列清单(清单散落多份文档正是历史漏跑闸的成因)。
|
||||
|
||||
**判定三硬闸**(各闸一律适用,缺一即判定有洞):
|
||||
①**退出码为唯一权威判据**——日志里的 PASS 串只是日志,不作判据;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
比对判据与工具见 `tools/golden_compare.py`
|
||||
(逐像素灰度差 >16 的像素占比 ≤2%)。
|
||||
|
||||
**未建锚面备案(2026-10-29 迭代 41 收尾登记)**:营地/设置/战斗三屏与战末结算/三选一/图例/调试浮窗四浮层无改前 golden 锚——迭代 41 测试特许移交(2026-10-28 用户裁,码先行动)致改前帧无法补建;这些呈现面的等价证据承载=现役探针/单元测试断言面+实机目检(体验验证清单 ㊵ 节)。
|
||||
|
||||
## 时效判定纪律(迭代 29 T7 立)
|
||||
|
||||
基线冻结于 2026-09-30(v3.5 视觉落码后)。**判定先于动作**:每代换代面(视觉/素材/布局改动)
|
||||
|
||||
+18
-61
@@ -1,9 +1,8 @@
|
||||
# tests/run_all.gd — 单元测试统一入口(双载体的逻辑测试调用点,套件 manifest 协议 D2 AC-2b)
|
||||
# 用法:godot --headless --path game --script res://tests/run_all.gd
|
||||
# 选跑态:追加 `-- --only=<词[,词…]>` ——对套件 res:// 路径做子串匹配,只跑命中套件;
|
||||
# 零命中/空值=用法错 quit(2)。两个来源分开定性——开发期直跑(默认)仅供最窄确认,不产闸回执、
|
||||
# 不作验收凭据;闸机关联档选跑(--only-source=gates,由 tools/run_all_gates.sh 在 02 闸传入)
|
||||
# 是收口验收跑批本体,回执 scope=related。无任何选跑参数=全量态,行为与全量口径完全一致。
|
||||
# 选跑态(开发期直跑专用):追加 `-- --only=<词[,词…]>` ——对套件 res:// 路径做子串匹配,只跑命中套件;
|
||||
# 零命中/空值=用法错 quit(2)。选跑态仅供开发期最窄确认,不产闸回执、不作验收凭据;
|
||||
# 批末全量闸不带参数不经选跑分支。
|
||||
# 协议:套件清单逐条"套件 → 期望退出码";致命类独立进程(expect=1)。
|
||||
# 执行形态:逐套件起独立 Godot 子进程实跑
|
||||
#(OS.get_executable_path() 解析本引擎二进制——--script 模式无 autoload/全局标识符,
|
||||
@@ -12,9 +11,6 @@
|
||||
# 套件挂死(_init 在 quit() 前中断,子进程永不退出)=超时先 taskkill /T 整树回收
|
||||
#(连 cmd wrapper 带引擎孙进程一起杀,只杀 wrapper 会留孤儿殃及后续全部 Godot 启动)
|
||||
# 再判该套件 FAIL 继续下一套件——单套件挂死不拖死整批;正常退出路径判定形态不变。
|
||||
# 快速失败:连续 N 个套件超时=红树正在整批挂死(如公共件解析错让每个套件都起不来),
|
||||
# 继续逐个回收只剩烧钟——第 N 个超时即中止整轮,汇总已见失败与超时清单后非 0 退出;
|
||||
# 不连续的超时仍逐个回收照旧。
|
||||
# 场景探针(.tscn 载体)由本地闸(probe_gate.sh)单独步骤调用,不经本入口。
|
||||
extends SceneTree
|
||||
|
||||
@@ -27,27 +23,21 @@ const ERROR_MARKERS: Array[String] = ["SCRIPT ERROR", "Parse Error"]
|
||||
const SUITE_TIMEOUT_ENV := "RUN_ALL_SUITE_TIMEOUT_SEC"
|
||||
const SUITE_TIMEOUT_DEFAULT_SEC := 120
|
||||
|
||||
# 快速失败阈值(可调常量,初值 3):连续 N 个套件超时即中止整轮。
|
||||
const CONSECUTIVE_TIMEOUT_ABORT := 3
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
# 选跑态解析:--only=<词[,词…]>(经 -- 分隔的 user args)——对套件 res:// 路径做子串匹配;
|
||||
# --only-source=gates=来源标记:由闸脚本传入的关联档选跑(验收跑批本体),缺省=开发期直跑。
|
||||
# 空值/零命中=用法错 quit(2)(fail-closed:禁把零套件当绿)。
|
||||
# 选跑态解析:--only=<词[,词…]>(经 -- 分隔的 user args)——对套件 res:// 路径做子串匹配。
|
||||
# 空值/零命中=用法错 quit(2)(fail-closed:禁把零套件当绿);选跑态仅供开发期最窄确认,
|
||||
# 不产闸回执、不作验收凭据;批末全量闸不带参数,不走此分支。
|
||||
var only_terms := PackedStringArray()
|
||||
var has_only := false
|
||||
var only_from_gates := false
|
||||
for a in OS.get_cmdline_user_args():
|
||||
if a.begins_with("--only="):
|
||||
has_only = true
|
||||
var term := a.trim_prefix("--only=").strip_edges()
|
||||
if term != "":
|
||||
only_terms.append(term)
|
||||
elif a == "--only-source=gates":
|
||||
only_from_gates = true
|
||||
if has_only and only_terms.is_empty():
|
||||
push_error("[run_all] --only= 空值——用法错(选跑禁把零套件当全量)")
|
||||
push_error("[run_all] --only= 空值——用法错(选跑态禁把零套件当全量)")
|
||||
quit(2)
|
||||
return
|
||||
var manifest := _suites()
|
||||
@@ -60,37 +50,15 @@ func _init() -> void:
|
||||
quit(2)
|
||||
return
|
||||
filtered = true
|
||||
if only_from_gates:
|
||||
print("[run_all] GATE FILTERED RUN — 闸机关联档选跑 %d/%d 套件(--only=%s)" % [suites.size(), manifest.size(), ",".join(only_terms)])
|
||||
else:
|
||||
print("[run_all] FILTERED RUN — 选跑 %d/%d 套件(--only=%s)——仅供开发期最窄确认,不产闸回执、不作验收凭据" % [suites.size(), manifest.size(), ",".join(only_terms)])
|
||||
print("[run_all] FILTERED RUN — 选跑 %d/%d 套件(--only=%s)——仅供开发期最窄确认,不产闸回执、不作验收凭据" % [suites.size(), manifest.size(), ",".join(only_terms)])
|
||||
print("[run_all] unit/contract suite entry — %d suites" % suites.size())
|
||||
if DisplayServer.get_name() != "headless":
|
||||
push_warning("[run_all] 建议以 --headless 运行(D2 冒烟协议)")
|
||||
var failures := 0
|
||||
var ran := 0
|
||||
var consecutive_timeouts := 0
|
||||
var failed_paths := PackedStringArray()
|
||||
var timed_out_paths := PackedStringArray()
|
||||
for suite in suites:
|
||||
var outcome := _run_suite(suite, ran, filtered)
|
||||
var suite_fail: int = outcome["fail"]
|
||||
var suite_timed_out: bool = outcome["timed_out"]
|
||||
failures += suite_fail
|
||||
failures += _run_suite(suite, ran, filtered)
|
||||
ran += 1
|
||||
var spath: String = suite.get("path", "")
|
||||
if suite_timed_out:
|
||||
consecutive_timeouts += 1
|
||||
timed_out_paths.append(spath)
|
||||
if consecutive_timeouts >= CONSECUTIVE_TIMEOUT_ABORT:
|
||||
push_error("[run_all] ABORT — 连续 %d 个套件超时(阈值 %d),中止整轮" % [consecutive_timeouts, CONSECUTIVE_TIMEOUT_ABORT])
|
||||
_report_abort(failed_paths, timed_out_paths, ran, suites.size())
|
||||
quit(1)
|
||||
return
|
||||
else:
|
||||
consecutive_timeouts = 0
|
||||
if suite_fail > 0:
|
||||
failed_paths.append(spath)
|
||||
# 实跑套件数校验:清单有条目却被静默跳过(早退/continue)必须判红,不能只凭 failures。
|
||||
# 选跑态对过滤后清单校验;全量态与原 manifest 条目数同一。
|
||||
if ran != suites.size():
|
||||
@@ -183,19 +151,17 @@ func _suites() -> Array:
|
||||
]
|
||||
|
||||
|
||||
# 返回 {"fail": int(该套件失败计 1/过 0), "timed_out": bool(是否超时挂死)}——
|
||||
# timed_out 供编排层做连续超时快速失败判定,fail 照旧累计。
|
||||
func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> Dictionary:
|
||||
func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> int:
|
||||
var path: String = suite.get("path", "")
|
||||
var expect: int = int(suite.get("expect", 0))
|
||||
if path.is_empty():
|
||||
push_error("[run_all] suite missing path")
|
||||
return {"fail": 1, "timed_out": false}
|
||||
return 1
|
||||
var bin := _engine_bin()
|
||||
if bin == "":
|
||||
push_error("[run_all] 未找到 console 版引擎二进制(设 GODOT_BIN 指向 *_console.exe)——"
|
||||
+ "非 console 版是 GUI 子系统,子进程 stdout/stderr 句柄无效,脚本错误扫描无从落地")
|
||||
return {"fail": 1, "timed_out": false}
|
||||
return 1
|
||||
# 子进程输出只能落盘再读:OS.execute 的 output 管道在本机 Godot/Windows 组合下恒为空
|
||||
#(实测 0 行),故整条命令交给 cmd 并重定向到日志。退出码同样走文件通道——
|
||||
# 阻塞式 execute 无超时能力(套件挂死时整批陪葬),换 create_process 非阻塞起进程
|
||||
@@ -214,7 +180,7 @@ func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> Dictiona
|
||||
var pid: int = OS.create_process("cmd.exe", PackedStringArray(["/V:ON", "/C", cmd]))
|
||||
if pid < 0:
|
||||
push_error("[run_all] FAIL %s — cmd 子进程启动失败(pid=%d)" % [path, pid])
|
||||
return {"fail": 1, "timed_out": false}
|
||||
return 1
|
||||
# 轮询先查存活再查截止:进程在轮询间隙自然退出时按正常路径判,截止临界不误杀。
|
||||
var timed_out := false
|
||||
var deadline_ms := Time.get_ticks_msec() + _suite_timeout_sec() * 1000
|
||||
@@ -247,7 +213,7 @@ func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> Dictiona
|
||||
push_error("[run_all] FAIL %s — 超时挂死(%ds),进程树已整树回收(pid=%d)" % [path, _suite_timeout_sec(), pid])
|
||||
else:
|
||||
push_error("[run_all] FAIL %s — 超时挂死(%ds),进程树回收未确认(pid=%d,需手工清杀残留)" % [path, _suite_timeout_sec(), pid])
|
||||
return {"fail": 1, "timed_out": true}
|
||||
return 1
|
||||
# 负面套件(坏表/违规输入是它的测试目标)全文折叠,只回显结论行——
|
||||
# 它输出里的 Parse Error 是预期产物,回显出去会让编排层的日志扫描误判成真实脚本错误。
|
||||
if negative:
|
||||
@@ -257,26 +223,17 @@ func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> Dictiona
|
||||
var code_txt := FileAccess.get_file_as_string(codefile).strip_edges() if FileAccess.file_exists(codefile) else ""
|
||||
if code_txt == "" or not code_txt.is_valid_int():
|
||||
push_error("[run_all] FAIL %s — 退出码文件缺失或非数字(%s)——子进程未走到退出码落盘即死,判红" % [path, codefile])
|
||||
return {"fail": 1, "timed_out": false}
|
||||
return 1
|
||||
var code: int = int(code_txt)
|
||||
DirAccess.remove_absolute(codefile) # 用毕即删:退出码经文件通道但不落 residuum(.gates 只留 *.log)
|
||||
if not negative and _has_script_error(text):
|
||||
push_error("[run_all] FAIL %s — 输出含脚本错误标记:%s" % [path, _script_error_line(text)])
|
||||
return {"fail": 1, "timed_out": false}
|
||||
return 1
|
||||
if code != expect:
|
||||
push_error("[run_all] FAIL %s — 退出码 %d ≠ 期望 %d" % [path, code, expect])
|
||||
return {"fail": 1, "timed_out": false}
|
||||
return 1
|
||||
print("[run_all] PASS %s (exit=%d)" % [path, code])
|
||||
return {"fail": 0, "timed_out": false}
|
||||
|
||||
|
||||
# 快速失败中止时的汇总:已见失败与超时清单+中止时进度——红树几分钟出结论,不磨完整轮。
|
||||
func _report_abort(failed: PackedStringArray, timed_out: PackedStringArray, ran: int, total: int) -> void:
|
||||
var timed_out_txt := "、".join(timed_out) if timed_out.size() > 0 else "(无)"
|
||||
var failed_txt := "、".join(failed) if failed.size() > 0 else "(无)"
|
||||
push_error("[run_all] 已见超时 %d 件:%s" % [timed_out.size(), timed_out_txt])
|
||||
push_error("[run_all] 已见失败(非超时)%d 件:%s" % [failed.size(), failed_txt])
|
||||
push_error("[run_all] 中止时进度:%d/%d 套件(余下未跑)" % [ran, total])
|
||||
return 0
|
||||
|
||||
|
||||
# 选跑过滤:对套件 res:// 路径做子串匹配,任一词命中即选入,词序无关。
|
||||
|
||||
@@ -308,13 +308,13 @@ fi
|
||||
# 可回放纯逻辑步骤流(同种子同输入逐位复现),await 会打断确定性——「模块归属」B1 行已写明
|
||||
# 「禁 await——切片 88 冒烟实证」。本闸为防回归防线(2026-10-24 人工 grep 盘面干净)。
|
||||
# 扫描面:B1 域文件集(与 architecture.md「模块归属」B1 行同口径)=battle_orchestrator.gd
|
||||
# + battle_fx_host.gd + reward_grant.gd + board_installer.gd 三拆件 + settlement/ 五段段类 + damage_controller.gd,共 10 文件,显式清单见 S8_FILES。
|
||||
# + battle_fx_host.gd + reward_grant.gd 两拆件 + settlement/ 五段段类 + damage_controller.gd,共 9 文件,显式清单见 S8_FILES。
|
||||
# 执行侧字面值豁免:脚本必须带字面值才能工作;文件集与架构文档冲突时以 B1 域文件集为准。
|
||||
# 判据:文件集内出现 await 关键字即红(词边界 \bawait\b,任何形态——await 信号/协程/
|
||||
# get_tree());排除注释行(行首 #/##)与字符串字面量(双引号包裹段内的 await 非代码),
|
||||
# 口径仿 S1/S2 的 grep 排除手法。
|
||||
# 自检:清单内文件缺位(路径写错/被改名)即判红——防扫面为空静默绿。
|
||||
S8_FILES="game/core/battle_orchestrator.gd game/core/battle_fx_host.gd game/core/reward_grant.gd game/core/board_installer.gd game/core/settlement/aura_segment.gd game/core/settlement/combat_segment.gd game/core/settlement/decay_segment.gd game/core/settlement/grant_segment.gd game/core/settlement/verdict_segment.gd game/core/damage_controller.gd"
|
||||
S8_FILES="game/core/battle_orchestrator.gd game/core/battle_fx_host.gd game/core/reward_grant.gd game/core/settlement/aura_segment.gd game/core/settlement/combat_segment.gd game/core/settlement/decay_segment.gd game/core/settlement/grant_segment.gd game/core/settlement/verdict_segment.gd game/core/damage_controller.gd"
|
||||
S8_MISS=0
|
||||
for f in $S8_FILES; do
|
||||
if [ ! -f "$f" ]; then
|
||||
@@ -356,7 +356,7 @@ fi
|
||||
# 自检:扫描面为空即判红(require_scan_face);B1 文件集与三族自家文件缺位即判红
|
||||
# (文件被改名=豁免名单失效,宁可红不可静默放行)。
|
||||
if require_scan_face "S7" "$DIR_CORE"; then
|
||||
S7_B1_SET="game/core/battle_orchestrator.gd game/core/battle_fx_host.gd game/core/reward_grant.gd game/core/board_installer.gd game/core/settlement/aura_segment.gd game/core/settlement/combat_segment.gd game/core/settlement/decay_segment.gd game/core/settlement/grant_segment.gd game/core/settlement/verdict_segment.gd game/core/damage_controller.gd"
|
||||
S7_B1_SET="game/core/battle_orchestrator.gd game/core/battle_fx_host.gd game/core/reward_grant.gd game/core/settlement/aura_segment.gd game/core/settlement/combat_segment.gd game/core/settlement/decay_segment.gd game/core/settlement/grant_segment.gd game/core/settlement/verdict_segment.gd game/core/damage_controller.gd"
|
||||
S7_MISS=0
|
||||
for f in $S7_B1_SET game/core/unit_container.gd game/core/status_container.gd game/core/reward_economy.gd; do
|
||||
if [ ! -f "$f" ]; then
|
||||
|
||||
@@ -361,7 +361,7 @@ func _smoke_adventure() -> void:
|
||||
if int(pb.get("level_index", -1)) == 2:
|
||||
l2_price_bonus = int(pb.get("bonus", 0))
|
||||
Kit.check("进店余额 ≥ hp_up L2 首价(%d = 基价 %d + 关卡加成 %d——配置推导)" % [hp_price + l2_price_bonus, hp_price, l2_price_bonus], gp0 >= hp_price + l2_price_bonus)
|
||||
Kit.check("购买 hp_up 受理(出账 + 加算区)", r8.shop.buy_product("hp_up"))
|
||||
Kit.check("购买 hp_up 受理(出账 + 加算区)", r8.buy_product("hp_up"))
|
||||
var acc_shop: int = a8.journal().bonus_total("max_hp") # L1 三选一后 + 商店 3(首件随种子)
|
||||
Kit.check("统一冒险加算区含商店值(max_hp=%d ≥ 商店 3——L1 三选一件值另计)" % acc_shop, acc_shop >= 3)
|
||||
var l2_cap := {"payload": {}} # 公开信号面采集(curio_choice_presented 停点载荷——容器写回规避 lambda 按值捕获)
|
||||
|
||||
@@ -49,9 +49,9 @@ func _init() -> void:
|
||||
# ---- ⑤ 钱包单口支出 spend_gp(LevelRunner——三选一付费档与商店刷新共用同一冒险钱包)----
|
||||
var lr = load("res://core/level_runner.gd").new(db, load("res://core/rng_service.gd").new())
|
||||
lr.gp = 30
|
||||
Kit.check_quiet(lr.shop.spend_gp(0) == false and int(lr.gp) == 30, "零额支出拒绝零副作用")
|
||||
Kit.check_quiet(lr.shop.spend_gp(31) == false and int(lr.gp) == 30, "余额不足拒绝零副作用")
|
||||
Kit.check_quiet(lr.shop.spend_gp(20) == true and int(lr.gp) == 10, "足额支出扣账(30→10)")
|
||||
Kit.check_quiet(lr.spend_gp(0) == false and int(lr.gp) == 30, "零额支出拒绝零副作用")
|
||||
Kit.check_quiet(lr.spend_gp(31) == false and int(lr.gp) == 30, "余额不足拒绝零副作用")
|
||||
Kit.check_quiet(lr.spend_gp(20) == true and int(lr.gp) == 10, "足额支出扣账(30→10)")
|
||||
|
||||
# ---- ⑥ Y 断点随存(缺陷锚:续玩自参数面整额重注入=用完 Y 退菜单再续玩满血复活)----
|
||||
var bp_y := {"level_index": 1, "hero_hp": 10, "attune_refresh_y": 2, "graph_gen_v2": 1}
|
||||
|
||||
@@ -57,13 +57,13 @@ func _init() -> void:
|
||||
|
||||
# ---- hr1-s:商店属性商品加算走日记单写原语(购买后 bonus_total 与旧径同值)----
|
||||
runner._gain_wallet(1000) # 钱包注入(测试直调写口——测试构造惯例)
|
||||
var products: Array = runner.shop.shop_products()
|
||||
var products: Array = runner.shop_products()
|
||||
var bought := false
|
||||
for p in products:
|
||||
if int(p.get("price", 1 << 30)) <= 1000 and String(p.get("attr", "")) != "":
|
||||
var attr := String(p.get("attr", ""))
|
||||
var before: int = runner.journal().bonus_total(attr)
|
||||
bought = runner.shop.buy_product(String(p.get("product_id", "")))
|
||||
bought = runner.buy_product(String(p.get("product_id", "")))
|
||||
if bought:
|
||||
Kit.check_quiet(runner.journal().bonus_total(attr) == before + int(p.get("flat_value", 0)),
|
||||
"hr1-s 商店购买后 bonus_total 增量 = 商品 flat(加算走 gain_bonus 单写原语——同值承载)")
|
||||
|
||||
@@ -251,7 +251,6 @@ func _init() -> void:
|
||||
_smoke_shop_graph()
|
||||
_smoke_multi_terminal_settlement()
|
||||
_smoke_shop_pool()
|
||||
_test_shop_node_entered_payload()
|
||||
_smoke_generated_coverage()
|
||||
quit(Kit.finish("level_shop_economy_test"))
|
||||
|
||||
@@ -1025,17 +1024,17 @@ func _smoke_shop_room() -> void:
|
||||
return
|
||||
Kit.check("到店开店态(覆盖层数据源就位——离开前不出选路口,零自动推进)", not runner.awaiting_choice() and runner.next_candidate_ids().is_empty())
|
||||
# 现价 = 基价 + price_level_bonus(L2)=2 + 步长 × 已购档数
|
||||
var prods: Array = runner.shop.shop_products()
|
||||
var prods: Array = runner.shop_products()
|
||||
Kit.check("三商品全陈列(atk_up/hp_up/armor_up——无刷新无摇号)", prods.size() == 3)
|
||||
var by_id := _shop_products_by_id(prods)
|
||||
Kit.check("L2 首购现价 = 基价 + 关级加值 2(atk_up 6 / hp_up 4 / armor_up 6)", int(by_id["atk_up"]["price"]) == 6 and int(by_id["hp_up"]["price"]) == 4 and int(by_id["armor_up"]["price"]) == 6)
|
||||
# 购买 atk_up:钱包 −6 · 加算区 atk +1 · 二购现价 8
|
||||
var gp0: int = runner.gp
|
||||
Kit.check("购买 atk_up 受理(现价 6)", runner.shop.buy_product("atk_up"))
|
||||
Kit.check("购买 atk_up 受理(现价 6)", runner.buy_product("atk_up"))
|
||||
Kit.check("钱包扣现价 6(%d → %d)" % [gp0, runner.gp], runner.gp == gp0 - 6)
|
||||
# 加算区住加算日记
|
||||
Kit.check("统一冒险加算区 atk +1(加算区住加算日记)", runner.journal().bonus_total("atk") == 1 and runner.journal().bonus_total("max_hp") == 0 and runner.journal().bonus_total("armor_class") == 0)
|
||||
by_id = _shop_products_by_id(runner.shop.shop_products())
|
||||
by_id = _shop_products_by_id(runner.shop_products())
|
||||
Kit.check("atk_up 二购现价 = 4+2+2=8(步长 2 × 已购 1 档,现价现算)", int(by_id["atk_up"]["price"]) == 8 and int(by_id["atk_up"]["purchased"]) == 1)
|
||||
# 行进段百分比归零(购买/生效断言按加算区裸值口径——调试浮窗百分比后乘;hp 快照钳到新口径上限防 spawn 越界,测试通道)
|
||||
runner.set_hero_override(0, 0)
|
||||
@@ -1043,28 +1042,28 @@ func _smoke_shop_room() -> void:
|
||||
# hp_up:上限与当前生命同步 +3(封顶新上限)
|
||||
var hp_before: int = runner.hero_hp
|
||||
var mhp_before: int = runner.effective_max_hp()
|
||||
Kit.check("购买 hp_up 受理(现价 4)", runner.shop.buy_product("hp_up"))
|
||||
Kit.check("购买 hp_up 受理(现价 4)", runner.buy_product("hp_up"))
|
||||
Kit.check("钱包扣 4(%d)" % runner.gp, runner.gp == gp0 - 6 - 4)
|
||||
Kit.check("生命上限 +3(%d → %d——加算区 max_hp 轴)" % [mhp_before, runner.effective_max_hp()], runner.effective_max_hp() == mhp_before + 3)
|
||||
Kit.check("当前生命同步 +3 封顶新上限(%d → %d)" % [hp_before, runner.hero_hp], runner.hero_hp == mini(hp_before + 3, runner.effective_max_hp()))
|
||||
# armor_up:AC 10+1
|
||||
Kit.check("购买 armor_up 受理(现价 6)", runner.shop.buy_product("armor_up"))
|
||||
Kit.check("购买 armor_up 受理(现价 6)", runner.buy_product("armor_up"))
|
||||
Kit.check("AC = 10+1(armor_class 加算区轴,无百分比通道)", runner.effective_ac() == int(_db.combat.hero.armor_class) + 1)
|
||||
# 余额不足购买被拒(零副作用):hp_up 连购至不可负担后兜底拒绝
|
||||
var guard_drain := 20
|
||||
var hp_buys := 1 # 夹具前段已购 1 笔(购买 hp_up 受理断言)——总数 = 前段 + 本循环
|
||||
while guard_drain > 0:
|
||||
guard_drain -= 1
|
||||
var hp_price: int = int(_shop_products_by_id(runner.shop.shop_products())["hp_up"]["price"])
|
||||
var hp_price: int = int(_shop_products_by_id(runner.shop_products())["hp_up"]["price"])
|
||||
if runner.gp < hp_price:
|
||||
break
|
||||
if not runner.shop.buy_product("hp_up"):
|
||||
if not runner.buy_product("hp_up"):
|
||||
break
|
||||
hp_buys += 1
|
||||
var gp_dry: int = runner.gp
|
||||
var tier_dry: int = runner.shop.purchased_tier("hp_up")
|
||||
var hp_dry: int = int(_shop_products_by_id(runner.shop.shop_products())["hp_up"]["price"])
|
||||
Kit.check("余额不足购买被拒(gp=%d < 现价 %d——零扣费零档位变动)" % [gp_dry, hp_dry], not runner.shop.buy_product("hp_up") and runner.gp == gp_dry and runner.shop.purchased_tier("hp_up") == tier_dry)
|
||||
var tier_dry: int = runner.purchased_tier("hp_up")
|
||||
var hp_dry: int = int(_shop_products_by_id(runner.shop_products())["hp_up"]["price"])
|
||||
Kit.check("余额不足购买被拒(gp=%d < 现价 %d——零扣费零档位变动)" % [gp_dry, hp_dry], not runner.buy_product("hp_up") and runner.gp == gp_dry and runner.purchased_tier("hp_up") == tier_dry)
|
||||
# 离开 → 回选路口(候选 = 该店出边——恰一条,指向终点 Boss)
|
||||
Kit.check("离开商店 → 回选路口(候选 = 店出边 %s——零自动推进收口)" % str(shop_outs),
|
||||
runner.continue_after_node() and runner.awaiting_choice() and _sorted_ids(runner.next_candidate_ids()) == _sorted_ids(shop_outs))
|
||||
@@ -1253,7 +1252,7 @@ func _smoke_shop_pool() -> void:
|
||||
if not _adv_drive_to_shop(a8, _adv_st(), autoplay):
|
||||
continue
|
||||
scen = {"a": a8, "s": s, "r": a8.runner()}
|
||||
first_shelf_a = (a8.runner().shop.shop_shelf() as Array).duplicate(true)
|
||||
first_shelf_a = (a8.runner().shop_shelf() as Array).duplicate(true)
|
||||
break
|
||||
Kit.check("池模式商店房场景可达(seed=%s)" % str(scen.get("s", -1)), not scen.is_empty())
|
||||
if not scen.is_empty():
|
||||
@@ -1262,19 +1261,19 @@ func _smoke_shop_pool() -> void:
|
||||
a8b.set_hero_override(900, 400)
|
||||
if a8b.start_adventure(int(scen["s"]), {"shop_mode": "pool"}) \
|
||||
and _adv_drive_to_shop(a8b, _adv_st(), autoplay):
|
||||
first_shelf_b = (a8b.runner().shop.shop_shelf() as Array).duplicate(true)
|
||||
first_shelf_b = (a8b.runner().shop_shelf() as Array).duplicate(true)
|
||||
Kit.check("进店抽 3(货架 %d 卡——同构交互)" % first_shelf_a.size(), first_shelf_a.size() == 3)
|
||||
# MC-1 商店独立刷新(P-C2+Q2 裁——基础免费 0;GP 刷新 ceil(20×1.8^n) provisional;重抽同源)
|
||||
if not scen.is_empty():
|
||||
var r8 = scen["r"]
|
||||
var gp0: int = int(r8.gp)
|
||||
var cost0: int = r8.shop.shop_refresh_cost()
|
||||
var cost0: int = r8.shop_refresh_cost()
|
||||
Kit.check("刷新首价=基价(%d)" % cost0, cost0 == int(_db.run.adventure.shop_refresh_cost_base))
|
||||
Kit.check("基础免费 0 次(Q2——天赋增益位后续添加)", r8.shop.shop_refresh_free_left() == 0)
|
||||
var shelf_pre: Array = (r8.shop.shop_shelf() as Array).duplicate(true)
|
||||
Kit.check("GP 刷新受理(gp=%d cost=%d)" % [gp0, cost0], r8.shop.shop_refresh())
|
||||
Kit.check("基础免费 0 次(Q2——天赋增益位后续添加)", r8.shop_refresh_free_left() == 0)
|
||||
var shelf_pre: Array = (r8.shop_shelf() as Array).duplicate(true)
|
||||
Kit.check("GP 刷新受理(gp=%d cost=%d)" % [gp0, cost0], r8.shop_refresh())
|
||||
Kit.check("GP 刷新扣费(%d→%d)" % [gp0, int(r8.gp)], int(r8.gp) == gp0 - cost0)
|
||||
Kit.check("刷新爬价 ×curve(%d)" % int(r8.shop.shop_refresh_cost()), int(r8.shop.shop_refresh_cost()) == int(ceil(float(cost0) * float(_db.run.adventure.shop_refresh_cost_curve))))
|
||||
Kit.check("刷新爬价 ×curve(%d)" % int(r8.shop_refresh_cost()), int(r8.shop_refresh_cost()) == int(ceil(float(cost0) * float(_db.run.adventure.shop_refresh_cost_curve))))
|
||||
var same_shelf := first_shelf_a.size() == first_shelf_b.size()
|
||||
if same_shelf:
|
||||
for i in first_shelf_a.size():
|
||||
@@ -1290,10 +1289,10 @@ func _smoke_shop_pool() -> void:
|
||||
# ② 货架投影形制:kind 词表封闭 + 现价公式推导(ceil(base×b^(关序−1)×A^0)——核心现算,呈现零复算)
|
||||
var l2 := int(r8.level_row.level_index)
|
||||
# 现价等价证明(d11——消费端读表推导 vs 迁移前硬编码字面量推导:同输入逐位一致)
|
||||
var relic_price_now: int = r8.shop.pool_price("relic")
|
||||
var relic_price_now: int = r8.pool_price("relic")
|
||||
var relic_price_pre: int = int(ceil(15.0 * pow(_db.run.shop.price_b, float(l2 - 1)) * 1.0))
|
||||
Kit.check("relic 现价 = ceil(15.0×b^(关序−1))(读表与迁移前字面量逐位一致,%d)〔wd11〕" % relic_price_now, relic_price_now == relic_price_pre)
|
||||
for c in r8.shop.shop_shelf():
|
||||
for c in r8.shop_shelf():
|
||||
# T6 商店保底后 relic 卡合法入架(保底占位)——词表断言放行 relic;价格断言分叉
|
||||
# (数值卡走 shop_pool_row 推导 / relic 卡走表 knob relic_base_price——同公式不同基价)
|
||||
var ckind := String(c.get("kind_id", ""))
|
||||
@@ -1308,7 +1307,7 @@ func _smoke_shop_pool() -> void:
|
||||
Kit.check("首购现价 = ceil(基价×b^(关序−1))(%s: %d = %d 推导)" % [ckind, int(c.get("price", -1)), expect_p], int(c.get("price", -1)) == expect_p)
|
||||
# ③ 买 1 全重抽:出账+加算区+账本三落点 + 现价 A 链递增(买后 visit 计数=1;TP0——消费在架令牌本体)
|
||||
var buy_c: Dictionary = {}
|
||||
for c in r8.shop.shop_shelf():
|
||||
for c in r8.shop_shelf():
|
||||
if int(c.get("price", 1 << 30)) <= int(r8.gp):
|
||||
buy_c = c
|
||||
break
|
||||
@@ -1320,7 +1319,7 @@ func _smoke_shop_pool() -> void:
|
||||
var gp0: int = int(r8.gp)
|
||||
var taken0: int = int(a8._curio.taken.get(kind, 0))
|
||||
var val0: int = a8.journal().bonus_total(String(val_map[kind]))
|
||||
Kit.check("购买受理(pool 口——%s|%s)" % [kind, tier], r8.shop.buy_pool_item(kind))
|
||||
Kit.check("购买受理(pool 口——%s|%s)" % [kind, tier], r8.buy_pool_item(kind))
|
||||
Kit.check("钱包扣现价(%d → %d)" % [gp0, int(r8.gp)], int(r8.gp) == gp0 - int(buy_c.get("price", 0)))
|
||||
Kit.check("加算区 +令牌档位件值(池件=奖励件本体——%s|%s %+d)" % [kind, tier, int(_db.run.adventure.curio_value(kind, tier))], a8.journal().bonus_total(String(val_map[kind])) == val0 + int(_db.run.adventure.curio_value(kind, tier)))
|
||||
Kit.check("共享池账本 -1(跨渠道单点——taken %d → %d)" % [taken0, int(a8.deck().taken.get(kind, 0))], int(a8.deck().taken.get(kind, 0)) == taken0 + 1)
|
||||
@@ -1328,7 +1327,7 @@ func _smoke_shop_pool() -> void:
|
||||
# A 链:白盒抬 GP 保证第二购场景确定构造(直改测试基建——非生产行为)
|
||||
r8.gp = int(r8.gp) + 64
|
||||
var second: Dictionary = {}
|
||||
for c in r8.shop.shop_shelf():
|
||||
for c in r8.shop_shelf():
|
||||
if int(c.get("price", 1 << 30)) <= int(r8.gp):
|
||||
second = c
|
||||
break
|
||||
@@ -1336,14 +1335,14 @@ func _smoke_shop_pool() -> void:
|
||||
var prow2: Dictionary = _db.run.shop.pool_row(String(second.get("kind_id", "")))
|
||||
var expect_p2: int = int(ceil(float(int(prow2.get("base_price", 0))) * pow(_db.run.shop.price_b, float(l2 - 1)) * _db.run.shop.price_a))
|
||||
Kit.check("A 链爬价 = ceil(base×b^(关序−1)×A^1)(进店第 2 购——%d)" % expect_p2, int(second.get("price", -1)) == expect_p2)
|
||||
Kit.check("同 visit 第二购受理(A 链软闸在价不在限)", r8.shop.buy_pool_item(String(second.get("kind_id", ""))))
|
||||
Kit.check("同 visit 第二购受理(A 链软闸在价不在限)", r8.buy_pool_item(String(second.get("kind_id", ""))))
|
||||
else:
|
||||
Kit.check("A 链爬价场景未构造(抬 GP 后货架仍无可购第二卡)——场景绑定失败", false)
|
||||
# ④ 切边零入店(白-box 重抽 40 次——GP 袋/规则改写型特性永不在架;重抽消费 shop_draw 签,场景尾不回写主时间线)
|
||||
var cut_seen := false
|
||||
for i in 40:
|
||||
r8.shop._draw_shelf()
|
||||
for c in r8.shop.shop_shelf():
|
||||
r8._shop_draw_shelf()
|
||||
for c in r8.shop_shelf():
|
||||
if String(c.get("kind_id", "")) == "gp" or String(c.get("kind_id", "")) == "treasure_item":
|
||||
cut_seen = true
|
||||
Kit.check("切边件零入店(40 次重抽零 gp/aux——负交易切边+三轴 doctrine)", not cut_seen)
|
||||
@@ -1353,8 +1352,8 @@ func _smoke_shop_pool() -> void:
|
||||
a8._curio.deck.remove_at(di8)
|
||||
var attack_seen := false
|
||||
for i in 40:
|
||||
r8.shop._draw_shelf()
|
||||
if (r8.shop.shop_shelf() as Array).any(func(c): return String(c.get("kind_id", "")) == "attack"):
|
||||
r8._shop_draw_shelf()
|
||||
if (r8.shop_shelf() as Array).any(func(c): return String(c.get("kind_id", "")) == "attack"):
|
||||
attack_seen = true
|
||||
break
|
||||
Kit.check("库存尽剔牌库(attack 令牌耗尽——池消耗即上限跨渠道共库 reward→shop 向)", not attack_seen)
|
||||
@@ -1392,74 +1391,6 @@ func _smoke_shop_pool() -> void:
|
||||
Kit.check("终局池余量在域 [0,配额](%s)" % str(ps), ps_ok)
|
||||
|
||||
|
||||
# ---- 商店房 node_entered 载荷(尾波 V1——_enter_node pool/legacy 双发射路径归一后的行为保持断言)----
|
||||
|
||||
func _test_shop_node_entered_payload() -> void:
|
||||
print("--- 商店房 node_entered 载荷(pool 含 shelf:true+gp 现值/legacy 无 shelf 键)---")
|
||||
var autoplay = load("res://sim/level_autoplay.gd")
|
||||
# pool 态:载荷字典经信号闭包当场取样(字典为引用累积器——lambda 按值捕获标量的绕行惯例)
|
||||
var cap_pool := {"payload": {}, "gp": -1}
|
||||
var pool_ok := false
|
||||
for s in range(42, 92):
|
||||
var pr = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(s))
|
||||
pr.set_hero_override(900, 400)
|
||||
if not pr.start_adventure(s, {"shop_mode": "pool"}):
|
||||
continue
|
||||
var rp = pr.runner()
|
||||
rp.node_entered.connect(func(node, payload):
|
||||
if String(node.get("type", "")) == "shop":
|
||||
cap_pool["payload"] = payload
|
||||
cap_pool["gp"] = int(rp.gp))
|
||||
if not _adv_drive_to_shop(pr, _adv_st(), autoplay):
|
||||
continue
|
||||
pool_ok = not (cap_pool["payload"] as Dictionary).is_empty()
|
||||
if pool_ok:
|
||||
break
|
||||
Kit.check("pool 态进店信号可达(seed 扫描 42–91)", pool_ok)
|
||||
Kit.check("pool 态 node_entered 载荷含 shelf:true〔尾波 V1〕", pool_ok and bool((cap_pool["payload"] as Dictionary).get("shelf", false)))
|
||||
Kit.check("pool 态载荷 gp = 进店钱包现值(%d)〔尾波 V1〕" % int(cap_pool["gp"]), pool_ok and int((cap_pool["payload"] as Dictionary).get("gp", -1)) == int(cap_pool["gp"]))
|
||||
# legacy 态:载荷无 shelf 键(两 payload 字典逐字保持的另一半——直构 LevelRunner 链)
|
||||
var cap_leg := {"payload": {}, "gp": -1}
|
||||
var leg_ok := false
|
||||
for s in range(42, 92):
|
||||
var lr = load("res://core/level_runner.gd").new(_db, _fresh_rng(s))
|
||||
lr.set_hero_override(900, 400)
|
||||
lr.start_level(2, s)
|
||||
lr.node_entered.connect(func(node, payload):
|
||||
if String(node.get("type", "")) == "shop":
|
||||
cap_leg["payload"] = payload
|
||||
cap_leg["gp"] = int(lr.gp))
|
||||
var st := _battle_st("normal")
|
||||
var guard := 60
|
||||
while String(lr.level_result) == "" and String(lr.current_node().get("type", "")) != "shop" and guard > 0:
|
||||
guard -= 1
|
||||
if lr.awaiting_choice():
|
||||
var ids: Array = lr.next_candidate_ids()
|
||||
ids.sort()
|
||||
lr.pick_next_node(int(ids[0]))
|
||||
continue
|
||||
var t := String(lr.current_node().get("type", ""))
|
||||
if t == "reward" or t == "rest":
|
||||
lr.continue_after_node()
|
||||
continue
|
||||
var b = lr.current_battle()
|
||||
if b == null:
|
||||
break
|
||||
var fin := {}
|
||||
b.battle_finished.connect(func(p): fin["p"] = p)
|
||||
var g2 := 80
|
||||
while lr.current_battle() == b and not fin.has("p") and g2 > 0:
|
||||
g2 -= 1
|
||||
autoplay._autoplay_battle(lr, b, st, null)
|
||||
if String(lr.level_result) == "" and String(lr.current_node().get("type", "")) == "shop":
|
||||
leg_ok = not (cap_leg["payload"] as Dictionary).is_empty()
|
||||
if leg_ok:
|
||||
break
|
||||
Kit.check("legacy 态进店信号可达(seed 扫描 42–91)", leg_ok)
|
||||
Kit.check("legacy 态 node_entered 载荷无 shelf 键〔尾波 V1〕", leg_ok and not (cap_leg["payload"] as Dictionary).has("shelf"))
|
||||
Kit.check("legacy 态载荷 gp = 进店钱包现值(%d)〔尾波 V1〕" % int(cap_leg["gp"]), leg_ok and int((cap_leg["payload"] as Dictionary).get("gp", -1)) == int(cap_leg["gp"]))
|
||||
|
||||
|
||||
# 入口→Boss 全路径枚举(DFS 迭代栈——图合法性校验保证单入口无环,路径有限)
|
||||
|
||||
|
||||
|
||||
@@ -732,12 +732,12 @@ func _smoke_tree_rules() -> void:
|
||||
var lr = load("res://core/level_runner.gd").new(_db, _fresh_rng(777004),
|
||||
{"tree_rules": []}) # 构造注入(拆件批 T3——setter 群退役)
|
||||
Kit.check("散未激活:商品标价原价(无 economy_spend 键)",
|
||||
int(lr.shop.current_price({"base_price": 100, "price_increment": 0})) == 100 + int(_db.run.shop.price_level_bonus_at(0)))
|
||||
int(lr.current_price({"base_price": 100, "price_increment": 0})) == 100 + int(_db.run.shop.price_level_bonus_at(0)))
|
||||
lr = load("res://core/level_runner.gd").new(_db, _fresh_rng(777005),
|
||||
{"tree_rules": ["economy_spend"]}) # 构造注入(拆件批 T3——setter 群退役)
|
||||
Kit.check("散激活:商品购买价 ×80%(provisional 折率——floor 偏向玩家、下限 1;刷新价不折=另一计价点零触碰)",
|
||||
int(lr.shop.current_price({"base_price": 100, "price_increment": 0})) == maxi(1, int(floor(float(100 + int(_db.run.shop.price_level_bonus_at(0))) * float(_db.run.shop.spend_discount))))
|
||||
and int(lr.shop.current_price({"base_price": 1, "price_increment": 0})) == maxi(1, int(floor(float(1 + int(_db.run.shop.price_level_bonus_at(0))) * float(_db.run.shop.spend_discount)))))
|
||||
int(lr.current_price({"base_price": 100, "price_increment": 0})) == maxi(1, int(floor(float(100 + int(_db.run.shop.price_level_bonus_at(0))) * float(_db.run.shop.spend_discount))))
|
||||
and int(lr.current_price({"base_price": 1, "price_increment": 0})) == maxi(1, int(floor(float(1 + int(_db.run.shop.price_level_bonus_at(0))) * float(_db.run.shop.spend_discount)))))
|
||||
# 财富之道·聚:战斗掉落乘算·入账前(编排 _roll_gp_drop——同种子配对对拍 1.5×)
|
||||
var orch3 = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(777005))
|
||||
Kit.check("聚 rig:基线编排启动(无增益侧)",
|
||||
|
||||
@@ -42,9 +42,9 @@ func _init() -> void:
|
||||
Kit.check_quiet(not e.stop().skip_empty_curio(),
|
||||
"空配置闸反例:非空停点拒绝跳过(零自动推进契约不破)〔专长批 T10〕")
|
||||
var lr = load("res://core/level_runner.gd").new(db, load("res://core/rng_service.gd").new())
|
||||
lr.shop.set_shop_pool([], Callable(), Callable(), Callable())
|
||||
lr.shop._draw_shelf()
|
||||
Kit.check_quiet((lr.shop.shop_bp_shelf() as Array).is_empty(),
|
||||
lr.set_shop_pool([], Callable(), Callable(), Callable())
|
||||
lr._shop_draw_shelf()
|
||||
Kit.check_quiet((lr.shop_bp_shelf() as Array).is_empty(),
|
||||
"空配置闸:商店空货架=合法态(牌库空=零扰动不崩)〔专长批 T10〕")
|
||||
|
||||
quit(Kit.finish("pool_case_d"))
|
||||
|
||||
@@ -14,7 +14,6 @@ const RngScript := preload("res://core/rng_service.gd")
|
||||
const BoardGeneratorScript := preload("res://core/board_generator.gd")
|
||||
const RewardEconomyScript := preload("res://core/reward_economy.gd")
|
||||
const OrchestratorScript := preload("res://core/battle_orchestrator.gd")
|
||||
const BoardInstallerScript := preload("res://core/board_installer.gd")
|
||||
|
||||
const TAG_OK := "board_gen" # 在册合法标签(PURPOSE_TAGS 含;wr7 必须用合法标签——未知标签检查排在播种检查之前)
|
||||
|
||||
@@ -65,15 +64,11 @@ func _default_form(db) -> bool:
|
||||
|
||||
|
||||
# ①wr5(p5):两协作件违约经组装点接线传导 → orchestrator.battle_result 落 "fatal_error"
|
||||
# (棋盘生成半边:装板域拆件后生成器随 BoardInstaller 件内自建——组装点=引用束 fatal_cb 接线,
|
||||
# 经新组装点构建后触发生成器违约,封印传导断言不变)
|
||||
func _seal_propagation(db) -> bool:
|
||||
var rng_a = RngScript.new()
|
||||
rng_a.set_master_seed(5)
|
||||
var oc_bg = OrchestratorScript.new(db, rng_a)
|
||||
var bi_bg = BoardInstallerScript.new({"db": db, "rng": rng_a, "minesweeper": oc_bg.minesweeper,
|
||||
"reward_economy": oc_bg._reward_economy, "encounter": oc_bg.encounter, "fatal_cb": oc_bg._fatal})
|
||||
bi_bg.generator._fatal("测试违约①棋盘生成")
|
||||
oc_bg._board_generator._fatal("测试违约①棋盘生成")
|
||||
if oc_bg.battle_result != "fatal_error":
|
||||
push_error("[run_time_fatal_test/wr5] 棋盘生成违约未传导封印(battle_result=%s)" % str(oc_bg.battle_result))
|
||||
return false
|
||||
|
||||
@@ -226,11 +226,11 @@ func _init() -> void:
|
||||
|
||||
# ⑩ 刷新执照(商店免费刷新 +2/店——读数叠加)
|
||||
var lv10 = load("res://core/level_runner.gd").new(db, load("res://core/rng_service.gd").new())
|
||||
Kit.check_quiet(int(lv10.shop.shop_refresh_free_left()) == int(db.run.adventure.shop_refresh_free),
|
||||
Kit.check_quiet(int(lv10.shop_refresh_free_left()) == int(db.run.adventure.shop_refresh_free),
|
||||
"刷新执照基线:未装配=表值(%d)" % int(db.run.adventure.shop_refresh_free))
|
||||
lv10 = load("res://core/level_runner.gd").new(db, load("res://core/rng_service.gd").new(),
|
||||
{"attunement": ["refresh_license"]}) # 构造注入(拆件批 T3——setter 群退役)
|
||||
Kit.check_quiet(int(lv10.shop.shop_refresh_free_left()) == int(db.run.adventure.shop_refresh_free) + 2,
|
||||
Kit.check_quiet(int(lv10.shop_refresh_free_left()) == int(db.run.adventure.shop_refresh_free) + 2,
|
||||
"刷新执照正常:免费刷新 +2/店(读数即本店可用——进店重置生命周期同 knob)")
|
||||
|
||||
# ⑪ 天眼(3×3 真视+安全格直开/危险格不开/封印格跳过)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# 在册词表组合;本测试直构 rebuild 同构合成行(与 effect_engine.gd rebuild 树规则段逐字段同源)
|
||||
# 调 validate_trigger_row 断零违例。实现侧扩闭集未呈报时,本断言以在册词表为准转红。
|
||||
# 聚散两键(economy_hoard/economy_spend)不入事件面:消费点=tree_rules 成员判定
|
||||
# (battle_orchestrator._roll_gp_drop GP 掉落乘算 / shop_session._spend_discounted 商品折价),
|
||||
# (battle_orchestrator._roll_gp_drop GP 掉落乘算 / level_runner._spend_discounted 商品折价),
|
||||
# rebuild 树规则段对两键零合成行——此状态在此被显式断言(旧版对两键取空夹具静默跳过=假绿):
|
||||
# rebuild 实装面行数对照——四键逐键与夹具同行数(rebuild 分支被删/漂移即转红),
|
||||
# 两键断零行(将来被加合成行即转红,提示先复核效果闭集再同步夹具与实现)。
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# 迭代 41 反哺点清单——两卡(核心数据面结构收敛批+呈现层结构收敛批)
|
||||
|
||||
> 每条=哪个文件哪一节、改成什么、依据。落文归文档批(doc-design),本清单只是申请单。
|
||||
|
||||
## A. architecture.md(v1.22)——定稿注记的现状改写(卡① §6 ③)
|
||||
|
||||
依据:卡① 全清裁决四项已实现,v1.19 定稿注记的「实现批后」表述全部过期;现行行号按 v1.22 实查(2026-10-28)。
|
||||
|
||||
1. **:88 ConfigDB 行**——「分组建档于实现卡,消费方改址随该批」改现状:三容器已建(`config_domain_combat/run/crossrun.gd`,类型化成员 7/7/5),公开面收敛至 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload),类变量 9;resolver 经 load_tables 装配段注入三表(board_gen.resolve_row/enemy.resolve_rowset/difficulty.resolve_modifiers),resolver 文件与键零搬移。红线句「唯一加载与持有单点……经其持有的表对象」原样保留。
|
||||
2. **:89 SlotStore 行**——「实现批建件」改现状:已建件,槽位族 10 公开/类变量 4;save_manager 组装持有,消费方经 `save.slots.` 直连;_rename_overwrite 留 save_manager(IO 原语单点)。
|
||||
3. **:90 MetaStateStore 行**——「实现批建件」改现状:已建件,写口原语 13+只读投影 6(tree_state/forge_state/attune_state/career_state 四投影+keystone_balance/item_unlocked)=19 公开,add_keystone 私有 _add_keystone;零 _data 副本零缓存;消费方经 `save.meta_state.` 直连。
|
||||
4. **:126 meta_progression 行**——「随件退役」改现状:公开面 20 定稿(buy_treasure_unlock/refresh_treasure_unlocks/treasure_shop_status/forge_buy_level/forge_buy_unlock/forge_select/hero_type_axes/forge_shop_status/settle_adventure/hero_override/tree_can_buy/tree_buy/tree_toggle_fork/tree_buy_fork/tree_rule_keys/tree_camp_status/toggle_attunement/attune_camp_status/attune_refresh_charges/buy_attune_refresh);纯转发读已退役(消费方直连 meta_state);hero_override 内联锻造加值与树淬炼 flat;并组三组(forge_select(kind,route_id)/hero_type_axes()→{attack,armor}/tree_camp_status()→{rows,fork_groups});补 meta_state 成员装配。
|
||||
5. **:104 minesweeper_rules 行**——消费依赖列「A3 try_spend / last_round_end / 相位」补形态注记:last_round_end 已由属性改方法(迭代 41 K5,消费方 minesweeper_rules :495 一处改方法调用)。
|
||||
6. **其余在册行零改动注记**(卡① §6 原列 :90/:92/:93/:103/:104 为 v1.19 行号,v1.22 现行=:92 action_economy/:93 variation/:94 status_container/:103 board_generator/:105 unit_container/:106 reward_economy):公开 API 语义零变化,仅内部拆分/束化/私有化——注记「迭代 41 零改动」即可,不逐行改写。
|
||||
|
||||
## B. GDD 行号随动(卡① §6 ①②,陈述本体零变化)
|
||||
|
||||
7. **design/gdd/systems/战斗循环/地图战斗资源.md :83**——代码引用行行号换代:`_rollable_rows()` 「第 207-213 行」→「第 325 行起」(reward_economy 拆分后漂移);「循环第 65-67 行」→「第 59-61 行」(roll_board 身份批循环现行位置;规范化段已提 `_normalize_eligible`)。同池同权重一视同仁的陈述本体不变。
|
||||
8. **design/gdd/systems/冒险循环/冒险结构.md 调参表**——落点列改指段路径(K4′ 拆段后标量槽随段件嵌套,单 .tres 保持):
|
||||
- :268「adventure_table curio_value_*」→「adventure_table value_segment.curio_value_*」;
|
||||
- :270「adventure_table token_* 配额列族」→「adventure_table quota_segment.curio_quota_*」;
|
||||
- :271 clear_heal_pct 不动(knob 留置宿主,:267 同理不动)。
|
||||
9. **同表 :267 疑似先行漂移发现(非本批造成,归文档批核实裁决)**:落点列「adventure_table bonus_attack_flat / bonus_max_hp_flat / bonus_armor_flat」——全库 grep 零命中(.gd 与 .tres 均无),疑指已退役槽名;现行承载疑为 value_segment.curio_value_{attack,max_hp,armor}_{common,excellent} 六槽。本批未改该行(不属两卡清单),提请文档批核现行值源后换代。
|
||||
|
||||
## C. 卡② 同步面核对记录(architecture 预期零修订)
|
||||
|
||||
10. **architecture.md 零改动核对**:两豁免段在位(:183 组合根句柄面豁免、:311 测量面豁免);模块归属表零行变化(零新件、ui_kit 无独立行、flow context/状态件均为宿主内形态);组合根句柄面条款不受影响。**落文动作=无,仅登记核对结论。**
|
||||
11. **待办清单状态核对注记(卡① §6 ④)**:来源条目「gdstyle 存量债全量清偿——216 键按病根分波整改」两卡对应键账已清(卡① 85/85+卡② 67 清 2 豁免 2 改善,见实现报告 §2);条目状态推进与残余键(三宿主 12 键归迭代 39 主卡)的去向,归主会话/batch-closure 统一回写,本批未触碰该清单。
|
||||
|
||||
## D. game/ 内文档(批内机械同步,非反哺)
|
||||
|
||||
12. game/tests/验证集清单.md——已机器重生成对账(68 源文件 1587 调用点;断言数与 master 侧一致,地址形态随改址换代),随批入库,无落文义务。
|
||||
13. game/tests/golden/README.md——未动(乙组建锚与甲组判读属测试动作,随特许移交;让步声明见实现报告 §八.2)。
|
||||
@@ -0,0 +1,91 @@
|
||||
# 迭代 41 实现报告——gdstyle 存量债清偿两卡(核心数据面 85 键+呈现层 71 键)
|
||||
|
||||
- 批次:迭代 41(卡① 需求卡片-核心数据面结构收敛批-2026-10-27 v1.2;卡② 需求卡片-呈现层结构收敛批-2026-10-27 v1.2)
|
||||
- 工作区:worktree `D:\code\g-plan2-iter41`(分支 iter41,基 7f49a8c2);卡① 提交 c56b816f→070a5340 九笔,卡② 提交 98ac923f→9bef58f9 十笔(含 T2a 修与 u14 补做),并 master 38c9a0eb
|
||||
- **测试执行声明(2026-10-28 用户特许)**:「不用做任何测试……测试相关动作全部交给我来运行」——本批全部套件停跑、闸停跑(gdstyle 结构闸除外,为开发期读数反馈在跑);验收断言、golden 对拍、撤销证明复现、独立验收审计全部移交用户执行,清单见 §7。因此本报告的「验收」栏记的是**移交状态**,不是已验证状态。
|
||||
|
||||
## 一、各卡状态
|
||||
|
||||
| 卡 | 状态 | 读数 |
|
||||
|---|---|---|
|
||||
| 卡① 核心数据面结构收敛批 | T0–T9 完成(T10=本报告+反哺点清单) | 在册 85/85 键全消失;8 新件键账逐件在阈(§3);契约 1 行为零变化六款按拆分逐字执行(提交信息逐笔留痕) |
|
||||
| 卡② 呈现层结构收敛批 | T0–T5 完成(u1–u25 全落地;u14 补做) | 71 键=67 清+2 豁免在册+2 在案改善未消(§2);u23/u25 豁免申报见 §4 |
|
||||
|
||||
偏差两笔(都在 §6 立案):①卡② u14 在 T2b(525529ad)提交信息有记、实际漏改——已补做(9bef58f9);②卡①完成定义写「下降 86 键」,波 0 刷新基线中卡①范围在册实为 85 键(config_db_cross_validator `validate_skill_pool_links 局部` 键在刷新时已不在册)——按在册口径 85/85 清零。
|
||||
|
||||
## 二、S13 键账终局对拍
|
||||
|
||||
**开工(波 0 刷新基线 d219dd3d)168 键 → 终局 16 键在册(全部基线内,NEW=0、WORSENED=0)→ 消失 152 键。**
|
||||
|
||||
基线 168 键构成与终局去向(逐键归类实测,脚本对拍 2026-10-28):
|
||||
|
||||
| 范围 | 基线在册 | 终局去向 |
|
||||
|---|---|---|
|
||||
| 卡① 26 文件 | 85 | **85 全消失** |
|
||||
| 卡② 25 文件 | 71 | 67 消失;main 类变量 49、tune_sim await 2 键豁免在册;board_cell_unit 类变量 31→30、standee_body 类变量 29→19 两键**改善未消**(成因见 §6-B) |
|
||||
| 两卡之外(board_view 6/level_runner 3/battle_orchestrator 2/adventure_runner 1) | 12 | 12 全在册(禁触面——board_view/level_runner/adventure_runner 结构拆件归迭代 39 主卡,battle_orchestrator 类变量为 v1.22 豁免第三条;battle_orchestrator 文件长度 1037→1035 随卡① spawn 调用点改址顺带改善) |
|
||||
|
||||
卡② 71 键逐单元对账(卡面 §8.4 账目 vs 实绩):69 清承诺中 66 键消失;u3 类变量键、u4 类变量键两键未消(展平计数,§6-B);u14 一键补做后消失。卡① 85 键逐 T 对账:T1 17+T2 23+T3 17+T4 8=65 拆分清偿;T5 存档拆件(save 52→7+_peek_summary_at 7→6+load_from_disk 8→6)+T6 meta 31→20 与 status/treasure+T7 config_db 44→8、25→9+T8 adventure 44→12+T9 action_economy 18→15、spawn 参数 10→1 等结构收敛清偿。
|
||||
|
||||
## 三、新件键账表(卡① 8 新件,实测 vs 卡面预演值)
|
||||
|
||||
| 新件 | 公开方法 | 类变量 | 卡面预演 | 判定 |
|
||||
|---|---|---|---|---|
|
||||
| `core/slot_store.gd` | 10 | 4 | 10/4 | 在阈 |
|
||||
| `core/meta_state_store.gd` | 19(写口 13+读投影 6,_add_keystone 私有) | 1 | 19/1 | 在阈 |
|
||||
| `core/config_domain_combat.gd` | 0 | 7 | 7 | 在阈 |
|
||||
| `core/config_domain_run.gd` | 0 | 7 | 7 | 在阈 |
|
||||
| `core/config_domain_crossrun.gd` | 0 | 5 | 5 | 在阈 |
|
||||
| `schemas/adventure_quota_segment.gd` | 0 | 13 | 13 | 在阈 |
|
||||
| `schemas/adventure_value_segment.gd` | 0 | 13 | 13 | 在阈 |
|
||||
| `schemas/adventure_cap_segment.gd` | 0 | 9 | 9 | 在阈 |
|
||||
|
||||
## 四、豁免申报(卡② u23/u25,零重构零键清偿动作)
|
||||
|
||||
1. **u25 组合根类变量**:`game/presentation/main.gd|max-class-variables = 49`(登记 49,持平)——依据 architecture「呈现层装配与会话生命周期·三屏壳与组合根句柄面」节 S13 豁免登记在册(v1.22 :183:组合根类变量面=探针契约面,约 46 句柄被探针挂载假设钉死,键永久基线内、禁再恶化)。u25 零改动;本批 main.gd 的其他改动均为卡① 改址与 u6/u19 消费点随动,S10 句柄面零增删。
|
||||
2. **u23 测速循环 await**:`game/presentation/tune_sim_controller.gd|await-in-loop`(裸键,在册持平)——依据 architecture「测试与质量域·S13 测量面豁免登记」段在册(v1.22 :311:逐帧让出=调参测量 wall-clock 步进承载语义,禁重构)。同件 print 与 run 局部两键已清;playtest_logger print×2 已删。
|
||||
|
||||
## 五、并 master 与合并期处置(2026-10-28,合并提交 38c9a0eb)
|
||||
|
||||
迭代期间 master 前进(断言归位专项批 94 处、断言精简 A+B 档 19 处、单元闸挂死守护、undo_proof 退役)。合并冲突 6 文件,处置原则=**master 的断言改钉/删并+本批的容器/拆件改址,两者语义正交逐处并案**(adventure_feats×2/config_db_resolver/level_shop_economy/save_boot_no_activate/roll_multiplier);另发现两批改址的系统性盲区互补——master 新写行带旧表地址 5 处、**本批 T7 扫荡漏「无点形态」(空值守卫/赋值/传参位的裸表引用)17 处+访问器迁移漏网 3 处**,合并期全数修复(action_economy._cost、effect_engine feats 守卫、hud_presenter 两守卫、测试 14 处;终扫 PCRE 负向前瞻零残留,冻结标签字面量未动)。验证集清单机器重生成对账(68 源文件 1587 调用点,与 master 侧计数一致——本批改址零断言数变化)。
|
||||
|
||||
## 六、实现决定记录
|
||||
|
||||
**A. 事故与补做**
|
||||
1. 卡① T7 首轮改址扫荡漏容器表名(`db.combat.rows` 形)→ 整树 `git checkout -- game/` 回滚、修正替换规则后重跑,净效果零(a9a163f9 提交信息在案)。撤销方式:无需(事故已消解于当卡)。
|
||||
2. 卡② u14 漏做(T2b 提交信息有记、diff 未含该文件)→ 合并前补做(9bef58f9),装配序逐行原序保持,S7 源锚句逐字在位。撤销方式:回退 9bef58f9 即回键在册态。
|
||||
|
||||
**B. 键以「在案改善」收口(卡面承诺键消失不可达)**
|
||||
- u3 board_cell_unit 类变量(31→30)、u4 standee_body 类变量(29→19):gdstyle 0.4.0 对宿主内 inner class 状态件成员按宿主**展平计数**(开工探针实测),键值含状态件成员后必 >15;卡面契约 6 定死 inner class 单形态(零新文件),独立状态类形态被禁。处置=按闸口径收口(改善绿非恶化红),键留基线。代价:两键继续在册。撤销方式:后续批若改 gdstyle 计数口径(类级键排除 inner class)可自然消失;否则随键主文件的下一次结构批裁决。
|
||||
- 与卡面「71=69 清+2 豁免」的差额即此两键:实绩 67 清+2 豁免+2 改善。
|
||||
|
||||
**C. 白名单内等价微调(一行备案)**
|
||||
1. legend_overlay 循环提函数时尾段成孤儿代码(不可达 NEW 键)→ 尾段归还原调用方。
|
||||
2. camp_shop_presenter 束读落地改构造期成员拷贝形态(ctx 键集不变)。
|
||||
3. main.gd 战末账行束提 `_end_victory_opts` 装配单点(u6 opts 形随动,键构成不变)。
|
||||
4. board_fx 循环按实际 `for i in 2` 形态提函数;battle_log `_fmt_damage` 宿主成员 `_db` 不进状态件。
|
||||
5. spawn 束化扫荡加引号奇偶守卫(@@SPAWN_SKIP@@),断言字符串字面量零触碰。
|
||||
|
||||
## 七、测试移交清单(用户运行——特许移交,全部未跑)
|
||||
|
||||
**交付前验收唯一入口**:worktree 内跑 `python tools/run_all_gates.sh`(本批含 game/ 代码面+reports/ 文档面 → 不带参数全量档;worktree 冷检出注意素材齐盘预检——art 素材与 *.import 边车不入 git)。
|
||||
|
||||
按卡重点套件(闸绿之外的建议抽查面):
|
||||
- 卡①:data_config 八套件+core 直引;board_generator/board_gen_reward+node_map 三件(同种子逐位一致);效果面六套件;save 断言面全套(save_manager_domain/save_slot_isolation/save_slot_summary/save_boot_no_activate/breakpoint_resume/save_rng_roundtrip+integration);tree_requires_level/meta_progression_forge;seal_polarity/roll_multiplier/damage_controller/system_contracts/treasure_items_test;minesweeper_rules_test/round_flow_skill_pool;level_shop_economy;adventure_feats/pool_case_d/feat_vouchers/table_structure_guard(**deck_total()=102 结构锚**)。
|
||||
- 卡②:probe_gate 全段+system_test;theme_projection/ui_struct/ui_contrast/ui_tune/ui_click/ui_probe;player_copy_sweep/standee_fx_sweep/reward_overlay/battle_narrator/level_map_info_fog/hud_presenter;render_gate(甲组在库五张 golden 改后对拍——**乙组三帧与丙组四态改前锚因码先行动未建,此义务让步**,见 §8)。
|
||||
- 撤销证明:两卡 §8.1 末列手法(读数型/迁移型/grep 型)——移交抽查执行。
|
||||
- 独立验收审计:两卡 §8.3 抽查重点(卡① ⑪ 项含契约 7 职责语句抽检;卡② ⑨ 项含 u1 子域分组与 board_view 随动改址抽 5 行)——未过不得合并。
|
||||
- 批后可裁事项:`tools/gdstyle_baseline.txt --refresh`(152 死键清账,只降不升纪律,人工专用)——用户裁决时机。
|
||||
|
||||
## 八、实机目检总清单(登记不阻塞,判读口径全部=「与改前一致」)
|
||||
|
||||
1. 启动冒烟实机一屏(卡① 行为零变化批总入口)。
|
||||
2. 乙组三屏开合观感:营地/设置/战斗。
|
||||
3. 丙组四态开合观感:战末结算/三选一/图例/调试浮窗。
|
||||
4. 营地三柜台(树淬炼/锻造工坊/秘宝匣)与同调交互回归。
|
||||
|
||||
## 九、遗留读数义务
|
||||
|
||||
1. MC/对拍锚:本批零数值零 RNG 改动 → 零 MC 零对拍补跑(卡① §0 纪律),无遗留。
|
||||
2. golden 乙组三帧(camp/settings/battle)与丙组四态改前锚未建(特许时序:码先行动)——改后无法补建改前帧,唯一在库对拍面=甲组五张;呈现等价的其余证据承载=现役探针/单测断言面。
|
||||
3. gdstyle 基线 152 死键在册(闸绿不受影响)——refresh 时机归用户(§7 末条)。
|
||||
@@ -1,24 +0,0 @@
|
||||
# 迭代 42 反哺点清单(2026-10-29)
|
||||
|
||||
要写进 `design/` 的点逐条列全:哪个文件哪一节、改成什么、依据是什么。用户在会话中裁决后归文档批落文,落文后本条清掉(不登记待办清单)。
|
||||
|
||||
## 反哺点 1:architecture.md:109 ShopSession 行——委托承载句失效+公开面格重写(卡② §6)
|
||||
|
||||
- **位置**:`design/engineering/architecture/architecture.md` 功能层表 ShopSession 行(:109)「对外暴露」格。
|
||||
- **失效陈述**:「外部调用面由 LevelRunner 同签名委托承载(外部零变化)」——委托壳已随迭代 42 卡② 全量拆除(19 委托+2 死壳归零)。
|
||||
- **改写内容全文(建议落文)**:该格末句改为——「外部调用面=调用方经宿主 LevelRunner 公开成员 `shop` 直连(调用直连不留委托壳,2026-10-26 Middle Man 裁定;迭代 42 拆除);直连消费的方法=shop_products/current_price/purchased_tier/buy_product/player_request_refresh/set_shop_pool/pool_price/shop_shelf/shop_refresh_free_left/shop_refresh_cost/shop_refresh/spend_gp/buy_pool_item/is_shop_pool/shop_bp_shelf/shop_bp_visit_buys(+白盒两入口仅测试侧:_draw_shelf/_spend_discounted)」。
|
||||
- **set_shop_pool 调用面改述**:pool 注入经 LevelRunner 构造 ctx 供给(level_runner.gd:101–102 内部直调 ShopSession.set_shop_pool);原委托块注释「AdventureRunner._start_current_level 唯一调用方」系陈旧表述(全仓 grep 证实产品码零其他调用方),随壳删除作废;测试面直连 `shop.set_shop_pool`。
|
||||
- **依据**:迭代 42 卡② v1.1 §2–§6(拆除形态权威=architecture.md:154「调用直连:不留中间人委托壳」);实测残留扫描零真残留(实现报告 §7)。
|
||||
|
||||
## 反哺点 2:architecture.md「测试与质量域」S13 豁免登记段——本批 5 键+既有讨论 5 键按实测值落文(卡① D5/§14.5)
|
||||
|
||||
- **位置**:`design/engineering/architecture/architecture.md`「测试与质量域」S13 豁免登记段(先例=battle_orchestrator 第三条形态:键永久基线内、禁再恶化、豁免不等于了结)。
|
||||
- **落文内容(批末实测值,2026-10-29 全量扫描)**:
|
||||
- board_view.gd max-class-variables = 32(D2 裁悬停域不拆——类变量无拆分动作可归绿,残留面全为契约承载)
|
||||
- board_view.gd max-public-methods = 27(同 D2——27 个逐类核对全为探针契约面与依赖单向纪律承载面)
|
||||
- level_runner.gd max-public-methods = 33(D3/D6——委托壳拆除后终值,直连形态下无再降空间)
|
||||
- level_runner.gd max-class-variables = 30(D3——`shop` 公开成员留宿主,非无效成员)
|
||||
- adventure_runner.gd max-class-variables = 28(D4 裁断点域不拆——断点协议住冒险生命周期 owner 内本身内聚)
|
||||
- 既有讨论 5 键同段合并落文:main.gd max-class-variables = 49/tune_sim_controller.gd await-in-loop/board_cell_unit.gd max-class-variables = 30/standee_body.gd max-class-variables = 19/battle_orchestrator.gd max-class-variables = 37(随装板域拆件 38→37 只降,替代原登记值 38)。
|
||||
- **依据**:卡① §6 D5 裁决(2026-10-29 用户裁)+§14.5;实测值见实现报告 §3 键账对账表。
|
||||
- **配套**:S13 基线重锚由用户发令 `python tools/gdstyle_gate.py --refresh --force`(16→10 键,降幅逾 10%)——重锚后归绿 6 键自然消失,豁免 10 键以新登记值留基线。
|
||||
@@ -1,92 +0,0 @@
|
||||
# 迭代 42 实现报告(2026-10-29)
|
||||
|
||||
批次=gdstyle 尾波清偿批(卡① v2.0)+ level_runner 商店委托层拆除(卡② v1.1)并排编队。执行形态=整迭代单工作区 `g-plan2-iter42`(两卡均未声明并行工作区,D6 裁「同迭代并排编队、先后皆可」=串行任一序),卡序 gdstyle 先(编排既定)、level_runner 后;卡① T6 批末对账与卡② T2 收口合并为迭代总收口一次执行。定义面(roadmap/待办清单/两卡)已随编排提交 14a10e5e 入库,本批无定义面搬运提交。
|
||||
|
||||
## 1. 各卡状态
|
||||
|
||||
| 卡 | 任务 | 状态 | 分支提交 |
|
||||
|---|---|---|---|
|
||||
| 卡① gdstyle 尾波清偿 | T0 读数复核与对账 | 完成(16 键现值与基线登记值逐键全数对上,零漂移;行位订正 7 处就地落卡) | 509f41f5(随 T1 同笔) |
|
||||
| 卡① | T1 board_view 拆分 | 完成(键 1–4 归绿) | 509f41f5 |
|
||||
| 卡① | T2 _enter_node 载荷合并 | 完成(键 9 归绿) | c47a032d |
|
||||
| 卡① | T3 装板域拆件 BoardInstaller | 完成(键 10 归绿,类变量 38→37) | adff0772 |
|
||||
| 卡② level_runner 委托拆除 | T0 调用面直连(中间态) | 完成(改址六件产品码+sim+七件测试,壳在位全绿) | f7e898be |
|
||||
| 卡② | T1 壳拆除与完整性证明 | 完成(键 7 实测 50→33,残留扫描零真残留) | ae3bd5fc |
|
||||
| 两卡 | T6/T2 迭代总收口 | 本报告+反哺点清单+全量域闸+独立验收审计+合回呈报 | 见 git log |
|
||||
|
||||
## 2. 实际改动—验收对照表(承两卡 §13/§11 需求侧对照表;结果列为本批实测)
|
||||
|
||||
| 行 | 需求点 | 改动(文件:行) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 结果 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V1 | 键 1/2/3/4——_paint_cell 拆五段+rebuild 构建器 | board_view.gd `_paint_cell` 拆 `_paint_cell_ink/_paint_cell_base/_paint_cell_facade/_paint_cell_overlays/_paint_cell_fog` 五段+`_build_cell_unit` 出函 | 复用 type_glow_test(48 checks 绿)/theme_projection_test._smoke_type_glow(163 checks 绿)/player_copy_sweep_test(22 checks 绿);render_gate 棋盘 golden 三张 | 单元+探针+golden | BoardView.rebuild()→refresh()→type_glow_probe();board_shot_probe 真实场景帧 | 既有断言面+golden 逐像素 | 绿——三套件全绿(theme_projection 的 163 checks 全过;该套件 FAIL=存量红,见 §6-①,与本改动无涉);golden 有 diff 与 stash 对照逐位同值(L2/L3 0.00%、L1 2.74% 双侧同值——见 §6-③) |
|
||||
| V3 | 键 9——_enter_node 载荷合并 | level_runner.gd shop 分支双 return 并单 return(payload 变量,两字典逐字保持) | 新增 level_shop_economy_test.gd:_test_shop_node_entered_payload〔尾波 V1〕四断言 | 单元 | LevelRunner.start_level(_external)→pick_next_node 进 shop 节点 | node_entered 信号载荷(pool 含 shelf:true 且 gp=进店钱包现值 27;legacy 无 shelf 键且 gp=现值 30) | 绿——套件 192 checks 全绿(exit 0) |
|
||||
| V4 | 键 10——装板域拆件 | board_installer.gd 新建;battle_orchestrator 六函数迁出、复位块留薄壳 `_install_and_reset`、三调用点改址、`_board_generator` 成员退役 | 复用 variant_placement_test(49 checks)/round_flow_skill_pool_test(129 checks)/seal_polarity_test(70 checks)/run_time_fatal_test(负套件 exit=1,wr5 棋盘生成半边随拆件改指 BoardInstaller 新组装点——见 §5-7)+run_smoke(15 项) | 单元+集成 | BattleOrchestrator.begin_battle()/player_request_refresh() | 同种子变异布置逐位断言面+全战斗步骤流逐行回放断言(board_gen/variant_place 取号序零漂移由同种子断言钉住)+违约封印传导链(wr5 双半边) | 绿——三套件+负套件+冒烟全绿;键 10 归绿(文件长 916≤1000 键消失)、类变量实测 37 |
|
||||
| R1 | 调用面直连改址(非行为改动) | 产品码 6 件+sim 1 件+测试 7 件全部调用点 `<表达式>.shop.<方法>` | 既有套件回归两轮全绿:T0 中间态轮(壳在位)+T1 壳删后轮(level_shop_economy 192/hero_ledger/adventure_feats/pool_case_d/treasure_effects/curio_refresh_paid/meta_progression_forge 全套+冒烟) | 单元+接口 | 各套件既有真实入口 | 既有断言逐位不变+壳删后编译通过 | 绿——两轮全绿(全量 65 套件两轮失败清单逐一同值=10 存量红,见 §6-②;七件相关套件两轮全绿) |
|
||||
| R2 | 壳块拆除(非行为改动) | level_runner.gd :723–725 区块涉委托两句+:751–828 十九委托全量删除(含死壳 2 枚) | 残留扫描零命中(19 方法名全仓 grep,输出留 §7)+T1 套件绿 | 静态+单元 | grep 全仓+套件真实入口 | 扫描面>0(19 名单命中 34 行逐一判类归属)+壳删后零引用可编译 | 绿——34 行全数为他类定义与调用/字典键名/宿主内部 shop. 直连点,零真残留 |
|
||||
| R3 | 宿主成员公开化(非行为改动) | level_runner.gd:44 `_shop`→`shop`+内部引用 28 处随更名 | 随 R1 两轮套件绿 | 单元 | 套件真实入口 | 内部使用点行为不变 | 绿——词级 `_shop` 全仓 .gd 零残留(件核) |
|
||||
| R4 | 注释同步六处(非行为改动) | shop_session.gd:4/level_runner.gd 区块句/level_autoplay.gd:335/:356/shop_overlay_view.gd:88/152/tree_rules_v11_test.gd:6 | 随批代码域闸绿(静态扫描覆盖文件头纪律面) | 静态 | —(静态判据) | 静态扫描+评审注记(观测面局限申报:注释无运行时提交面) | 绿——六处已同步,闸 09 见全量域闸回执 |
|
||||
|
||||
反向核对:diff 中行为改动仅 V3 一处(载荷合并,行为保持——载荷字典逐字);其余均为非行为改动(结构整改,判据=零漂移证明如上)。孤儿断言:无(新增断言仅 V3 行四条〔尾波 V1〕,已挂行)。
|
||||
|
||||
## 3. 键账对账(S13——11 键终值对照卡① §7 预期)
|
||||
|
||||
| 键 | 预期(卡① §7) | 批末实测 | 判定 |
|
||||
|---|---|---|---|
|
||||
| 1 board_view _paint_cell 长度 | ≤50 归绿 | 键消失(函数已拆五段,新函数无超标键) | 归绿 ✓ |
|
||||
| 2 board_view _paint_cell 分支 | ≤8 归绿 | 键消失 | 归绿 ✓ |
|
||||
| 3 board_view _paint_cell 局部变量 | ≤10 归绿 | 键消失 | 归绿 ✓ |
|
||||
| 4 board_view allocation-in-loop | 消除归绿 | 键消失(.new() 迁入 _build_cell_unit) | 归绿 ✓ |
|
||||
| 5 board_view 类变量 | 32 维持豁免终局 | 32 持平 | 豁免终局 ✓ |
|
||||
| 6 board_view 公开方法 | 27 维持豁免终局 | 27 持平 | 豁免终局 ✓ |
|
||||
| 7 level_runner 公开方法 | 约 33 降值后豁免终局 | 33(50→33,并排卡兑现,与卡面预测精确一致) | 豁免终局 ✓ |
|
||||
| 8 level_runner 类变量 | 30 维持豁免终局 | 30 持平 | 豁免终局 ✓ |
|
||||
| 9 _enter_node 返回数 | 6 归绿 | 键消失 | 归绿 ✓ |
|
||||
| 10 battle_orchestrator 文件长 | 约 910–920 归绿 | 键消失(实测 916 行) | 归绿 ✓ |
|
||||
| 11 adventure_runner 类变量 | 28 维持豁免终局 | 28 持平(本批零触碰) | 豁免终局 ✓ |
|
||||
|
||||
豁免通道既有键随批只降核对:battle_orchestrator 类变量 38→37(D1 修正二兑现,登记值不抬)。**零新增键**(全扫描现值 10 键=基线 16−归绿 6,EXTRA 清单为空)。基线重锚=用户发令人工 `python tools/gdstyle_gate.py --refresh --force`(降幅 6/16≈37.5% 逾 10% 须 --force,卡① §14.4)。
|
||||
|
||||
## 4. 逐拆出单元职责语句(拆分边界纪律①,逐件一行)
|
||||
|
||||
- **BoardInstaller**(新件,board_installer.gd):棋盘安装与变异布置域唯一承载——生成受理→全局作用域变异决议→装板受理→资源摇号资格域组装(roll_board 恰一次)→region 变异决议与连通片布置;单一变化原因=棋盘设置顺序与变异布置算法。
|
||||
- **_paint_cell_ink**(board_view 私有段):字形与色牌层——reveal 记录→字形/墨色判定+u.glyph/u.glyph_color 终写+双峰纹理板落牌。
|
||||
- **_paint_cell_base**:基底瓦片层——瓦片查表/平色回退 sb+英雄蓝框载体与贴图缺位回退字形。
|
||||
- **_paint_cell_facade**:立面投影层——未开墙格南缘立面/轮廓描边码;已开格北缘投影暗带/E 格高墙面。
|
||||
- **_paint_cell_overlays**:秘宝/变异叠加层——真视红框/预读徽章/变异角标/奖励徽章/类型微光组号。
|
||||
- **_paint_cell_fog**:迷雾层——灯光区外未开格全黑/已开格记忆态灰显。
|
||||
- **_build_cell_unit**:逐格构建器——CellUnit 实例化与属性装配(allocation 出循环唯一出函面)。
|
||||
- **_install_and_reset**(battle_orchestrator 宿主薄壳):装板受理承接+宿主态复位单点(五处计数清零+板序推进+board_changed 发射+秘宝叠加层退役)。
|
||||
- **LevelRunner.shop**(公开成员,非新件):商店件取件唯一形态(委托壳拆除后的直连承载,零新增职责)。
|
||||
|
||||
## 5. 实现决定记录(代拍板白名单外事项备案)
|
||||
|
||||
1. **run_all.gd `--only` 逗号形态工具缺陷**(卡① T1/T3、卡② T0 验证命令形态适配):`game/tests/run_all.gd` 的 `--only` 解析自 6caf56b5 起把整串 `--only=a,b,c` 当单个词(不按逗号拆分),与文件头注「词[,词…]」文档形态及 `tools/run_all_gates.sh:331` 的逗号拼接传参形态均不符——本批改用逐词重复 `--only=` 形态(语义等价)。批末全量闸不受影响(本批触 battle_orchestrator=PARITY 触面表→横切→02 回落全部套件,不经选跑分支);**建议登记工程改动**:run_all.gd 补逗号拆分(或闸脚本改多旗标传参)。
|
||||
2. **BoardInstaller 宿主持有形态**:薄壳 `_install_and_reset` 内逐调用构建 installer(非宿主成员)——T3 验收项「类变量实测 37」要求宿主不新增成员;BoardGenerator 唯一成员 fatal_handler、零跨 generate 调用状态,逐调用构建观察等价(装板取号序由同种子断言钉住,实测全绿)。
|
||||
3. **ink→base 段间 bg 传值**:卡① §7 键 1 限「段间只经 u.st/glyph/digit_col 传值」;bg(基底色)无单元场域可承载、其唯一消费方在 base 段回退分支——经 ink 段返回值交 base 段(唯一例外,函数体逐字搬运不受影响)。
|
||||
4. **两卡里程碑全量闸并入迭代总收口**:卡① T6 与卡② T1 的「里程碑出口 run_all_gates --code」按 iter 技能闸序列「全量域闸每迭代一次」铁律合并为收口单次跑闸(重塑后)——卡面两处闸义务由同一次跑闸兑付。
|
||||
5. **worktree 冷检出 `--editor --quit` 首跑 `--path` 误指仓库根**(未建 .godot 类缓存致首跑解析红)——改指 game 切片目录重刷后正常(106 类)。坑速查条目候选,登记建议随工程批。
|
||||
6. **信号契约注释陈旧发现**(不属本批改动面):level_runner.gd:14 node_entered 信号注释 `shop={gp}` 与 pool 态实际载荷 `{gp, shelf:true}` 不符——改动前即如此(本批未触载荷),随本报告呈报,归文档批/后续批处置。
|
||||
7. **run_time_fatal_test wr5 改指新组装点(L1 就地修复)**:T3 删宿主 `_board_generator` 成员后,该负面套件 :71 的白盒取数 `oc._board_generator._fatal(...)` 断链(脚本错误中断断言函数→零断言退出 2)=**本批新增红**。卡面 §3 现状考证只查了 battle_orchestrator.gd 全文件(四处使用属实)漏查跨文件测试取数点;§16 L1「探针断言调用面改址漏改——就地修复重跑最窄确认」通道处置:wr5 棋盘生成半边改经新组装点(BoardInstaller 引用束 fatal_cb 接线)构建后触发,断言目标(违约→封印传导)不变、断言零增删(§17 四不违);卡 §9 文件结构图就地补行;复跑 exit=1(负套件期望码)绿。**勘误**:本报告先前稿曾将该套件误列存量红——彼次 stash 对照时工作树处于卡①完成态(HEAD 已含 T3)而非 master 原态,对照被污染;更正后 02 存量红=9 套件与基线登记清单逐项一致。
|
||||
|
||||
## 6. 存量红清单(master 原状同值复现,非本批新增——stash 对照法逐组取证)
|
||||
|
||||
1. **theme_projection_test**:`_recent_list` 断链(test:805 访问 `camp._recent_list`——成员已随迭代 41 卡② 拆入内嵌类 `_SideState`;iter41 特许移交合回未跑遗留)。该套件 163 checks 本体全绿,FAIL=脚本错误扫描命中。
|
||||
2. **全量轮 9 套件红**(T0/T1 两轮与 master 原状逐一同值,与基线登记清单及待办清单「迭代 41 测试债修复」条目逐项一致):config_db_test(cattr 解析)/config_db_fatal_oob_test(退出码 2≠1)/table_structure_guard_test(meta_state)/treasure_items_test(crossrun)/standee_fx_sweep_test(set_trans)/forge_workbench_test(120s 挂死)/tree_requires_level_test(row_by_id Nil)/save_manager_domain_test(_migrate_legacy_save)/theme_projection_test(同①)——形态与迭代 41 卡①(核心数据面结构收敛)卡②(呈现层结构收敛)改动特征吻合;已随基线 80b49c0f 记账(用户 2026-10-29 裁带红合并承接)。初稿曾多列 run_time_fatal_test 一项,经 §5-7 勘误更正为本批新增红(已修)。
|
||||
3. **probe_gate --click 三红**:ui_input_probe 超时挂死(exit 124)/ui_struct_probe resume 断言/ui_click_probe 16 行 set_trans 空值(battle_end_overlay 等未触文件)——master 原状同值复现(连错误行数都一致)。
|
||||
4. **render_gate golden L1_dungeon 2.74% 超容差**:master 原状同值(L2/L3 双侧 0.00%)——golden 锚落后于 master 现状,重锚须用户批准(本批禁自行换锚)。
|
||||
|
||||
## 7. 残留扫描输出留痕(卡② T1/R2 判据)
|
||||
|
||||
19 方法名全仓 grep(game/ 下 .gd)命中 34 行,逐行判接收方类归属**零真残留**:字典键名(adventure_runner:505/546/591/600、breakpoint_resume_test:196、level_shop_economy_test:1378/1383、sim 两文件共 4 行);他类定义与调用(battle_orchestrator.player_request_refresh 定义 :709+settlement 侧 8 处调用、CurioDeck.pool_stock 经 deck() 9 处、GpWallet.spend_gp 定义 :15);宿主内部直连使用点(level_runner.gd:102/305/306/704 shop. 形态)。产品码与测试面零旧委托调用。
|
||||
|
||||
## 8. 实机目检总清单
|
||||
|
||||
本批零玩家可观测改动(结构整改+调用面直连)——**无新增目检项**。既有在册提醒(不阻塞):迭代 41 移交的四项实机目检在体验验证清单㊵。
|
||||
|
||||
## 9. 遗留读数义务与登记建议
|
||||
|
||||
1. S13 基线重锚:用户发令 `python tools/gdstyle_gate.py --refresh --force`(§3)。
|
||||
2. MC 对拍:不补跑(零数值零数据表零 RNG 流词表改动,卡① §15)。
|
||||
3. PARITY gate 11(回放确定性对拍):本批触 PARITY_TOUCH_FACES(battle_orchestrator.gd)——闸记 NEED-APPROVAL,实跑或跳过由用户裁决(卡① §15,卡内不定案);批准实跑=`PARITY_APPROVED=1` 重跑闸。
|
||||
4. 工程改动登记建议:§5-1(--only 逗号拆分)+§5-5(坑速查补条)。
|
||||
5. 独立验收审计:报告落 `reports/iter42-验收审计-2026-10-29.md`(未参与实现的子代理执行,test-conventions §8.7 四事),结论见该件。
|
||||
@@ -1,61 +0,0 @@
|
||||
# 工程改动报告——合回闸关联档+闸机编排快速失败(2026-10-29)
|
||||
|
||||
**接收方**:待办清单原「合回闸关联档——收口跑批按改动关联面选测」「闸机编排快速失败——连续套件超时中止整轮」两条目(两 entry 已随本批完成整条删除,本报告为其收尾凭据与算法说明存放处)。
|
||||
**改动面**:工具代码+游戏代码(run_all.gd 属代码面,走 worktree 批)+文档(规则同步)。
|
||||
**执行**:worktree `gaterel-20261029`(自 master 6abaf67d 分出),合并提交 8bb3541c,回执树校验通过后工作区与分支已删除。
|
||||
|
||||
## 一、改动文件清单
|
||||
|
||||
| 文件 | 改动 | 提交 |
|
||||
|---|---|---|
|
||||
| tools/run_all_gates.sh | 关联档选闸(三件保险恒跑+02 选套件+横切回落)+回执 scope/scope_terms 字段+红项指纹 pid 归一化 | 9f94c9e1、117a37e2 |
|
||||
| game/tests/run_all.gd | 连续超时快速失败+--only-source=gates 闸机来源标记 | 9f94c9e1 |
|
||||
| AGENTS.md | 「交付前验收」句与硬性红线改关联档口径;规范导航行「全量验证」→「提交前验证」 | 9f94c9e1 |
|
||||
| design/engineering/process-conventions.md | §3 第 8 条合回闸细则同步(选测算法句+scope 字段+全量回归由用户自发) | 9f94c9e1 |
|
||||
| design/engineering/test-conventions.md | §4 标题改「提交前验证」,正文同步关联档口径 | 9f94c9e1 |
|
||||
| design/engineering/code-conventions.md | §3 主题行「提交前全量验证」→「提交前验证」 | 9f94c9e1 |
|
||||
| game/tests/README.md | 工具速查 run_all.gd 行(快速失败+闸机关联档选跑+manifest 实数 65)、挂死防护注、门禁与本地闸回执字段句 | 9f94c9e1 |
|
||||
| 待办清单.md | 上述两条目整条删除 | 9f94c9e1 |
|
||||
| game/tests/.gates/baseline.json | 02/09 两键存量红按实测重生成(记账见第五节) | 80b49c0f |
|
||||
|
||||
## 二、关联档选闸算法(定义处=tools/run_all_gates.sh 脚本中部,文档不另列)
|
||||
|
||||
1. **三件保险恒跑不降**:00 冒烟、01 系统测试、09 静态扫描在代码域恒实跑(测量面批不再免 00);10 熵增闸照旧两域都跑;11 回放确定性触面判定照旧。
|
||||
2. **03/04 探针、05 渲染闸**:维持原影响面口径——本批 game/ 改动全在测量面(game/tests/、game/sim/)时记 SKIP。
|
||||
3. **02 单元与集成改「选套件跑」**:套件集=**申报 ∪ 推导**取并集。
|
||||
- 申报:在册需求卡片(本批 diff 触及的 reports/需求卡片*.md ∪ roadmap「进行中」迭代行登记的卡片)对照表「验收测试」列提到的测试文件名,逐名作为 --only 子串词;找不到在册卡片则申报集为空并在跑批输出注明。
|
||||
- 推导:脚本内 `suite_terms_for()` 映射表(game/ 文件前缀 → 套件族词,族=测试目录名 data_config/core/battle_settlement/contracts/presentation/integration)按本批 diff(merge-base master..HEAD 的 game/ 非 .md 文件,剔除测量面)归族;一个文件可映射多族(如 minesweeper_rules.gd → core+battle_settlement)。
|
||||
- 横切回落全量:命中 game/data/tables/**、公共件前缀(config_db*/rng_service*/save_manager*/meta_progression*/main*)、autoload 注册面(game/project.godot)、PARITY 触面表(gate 11 现行清单,已上移与横切判定共用单点定义)任一,或映射不到 → 02 跑全部套件。
|
||||
- 测量面批:02 照旧全套件跑,不加过滤。
|
||||
4. **回执加 scope 字段**:full|related(02 跑子集=related),随带 scope_terms 记选跑词清单;worktree-guard 校验逻辑不动(只验域覆盖与全绿)。
|
||||
5. **闸机传参**:02 闸经 `-- --only=<词表逗号串> --only-source=gates` 传入;无选跑参数时 run_all.gd 行为与现状完全一致。
|
||||
|
||||
## 三、快速失败行为(game/tests/run_all.gd)
|
||||
|
||||
- 连续 **3** 个套件超时(可调常量 `CONSECUTIVE_TIMEOUT_ABORT`,初值 3)=判定红树整批挂死,**中止整轮**:打印「已见超时/已见失败(非超时)」两清单+中止时进度,退出码非 0。
|
||||
- 不连续的超时照旧逐个回收(taskkill /T 整树回收+10 秒等死确认不变);任何非超时结局(通过或快速失败)重置连续计数。
|
||||
- `_run_suite` 返回值从裸失败数改为 `{"fail": int, "timed_out": bool}`,编排层据此计连击;判定三硬闸(退出码/脚本错误扫描/断言数下限)口径不变。
|
||||
|
||||
## 四、孤立验证证据(闸机轮次纪律第 1 条,先最小试车再入闸)
|
||||
|
||||
- 推导沙箱七场景(对脚本 scope 段原文+mock git 实测):行为面两文件归族 → related[--only=core presentation];damage_math 触面 → 横切 full;测量面批 → 03/04/05 SKIP+02 全量;main* 组合根拆件 → 横切;project.godot → 横切;申报卡片并集 → [--only=core damage_math_test.gd hud_presenter_test.gd system_test.gd];横切优先于申报 → full。
|
||||
- run_all.gd 闸源选跑:`--only=battle_settlement --only-source=gates` 实跑 9/65 套件全绿 exit 0,横幅「GATE FILTERED RUN」不带开发期免责句。
|
||||
- 快速失败机制:`RUN_ALL_SUITE_TIMEOUT_SEC=2` 下首个套件 2 秒内跑完(连续计数归零),随后 3 套件连击超时 → 第 3 个即 ABORT,汇总清单+「中止时进度 4/9」,exit 1。
|
||||
|
||||
## 五、闸机证据与存量债记账(重要)
|
||||
|
||||
收口全量闸(不带参数,域=full)共跑四轮,前两轮红均**非本批新增**:
|
||||
|
||||
1. **首轮(9f94c9e1)**:02 现红 exit 1(9 套件失败)+09 红项指纹变化。逐项核对=待办清单「迭代 41 测试债修复」条在册清单(config_db 解析错 cattr/config_db_fatal_oob 退出码 2≠1/table_structure_guard 缺 meta_state/treasure_items 缺 crossrun/standee_fx_sweep set_trans 空引用/forge_workbench 120 秒超时挂死/tree_requires_level 空基址/save_manager_domain 缺 _migrate_legacy_save/theme_projection 缺 _recent_list;S9 类型闸 24 处+S10 文件头 4 处+S11 adventure_table.gd:55)——全部为迭代 41 遗留债,该条目已载 2026-10-29 用户裁「带红合并,代码域现存红全部由本条目承接」。基线滞后成因=迭代 41 两卡特许直接合回未重跑代码域闸(合回 its 回执为 docs 域),基线 02 键停在绿、09 键停在旧红项构成。
|
||||
2. **指纹修正(117a37e2)**:02 的 forge_workbench 超时行内嵌 pid=NNNN,逐轮变化使存量红指纹不可复现——fingerprint 对 pid 归一化(pid=N)后再入哈希;判定口径(FAIL 行集合)不变。
|
||||
3. **基线记账(80b49c0f)**:02/09 两键按 run A 实测重生成(02 记存量红 fp f9865f1a5a44,09 改记现行指纹 1a9ad773489f),记账注记全文写入 baseline.json note;人工确认凭据=上述用户裁。
|
||||
4. **Run B(80b49c0f)全绿**:存量红·对基线零新增,exit 0。
|
||||
5. **master 推进处置**:收口期间 master 落了 60c1a962(尾波清偿批登记,文档域)。首轮合并未按「先并入分支、重跑全量」流程执行,已作废重做:master reset 回 60c1a962 → 分支并入 master(0f9d1c85)→ Run C 重跑全量全绿 → 再合回。
|
||||
6. **Run C/最终回执(0f9d1c85)**:域=full、scope=full(本批 game/ 改动仅 run_all.gd=测量面批:03/04/05 SKIP、02 全套件 65 跑 56 绿 9 存量红、00/01/09 实跑绿)、dirty_game=false、all_green=true、changed_vs_baseline=[]、tree=284448b47385cff50fe782fdf2ba0c4f77846d69。
|
||||
7. **合回校验**:master^{tree}=284448b4…=回执 tree,一致;合并提交 8bb3541c;合并后主区两件秒级事已做(--editor --quit 刷缓存+冒烟 15 项 0 失败)。
|
||||
|
||||
## 六、边界与移交
|
||||
|
||||
- 本批自身是测量面批,02 过滤路径的端到端闸内形态由沙箱七场景+run_all.gd 直跑证据承载;首个行为面批收口时闸会实际走 related 路径(输出「关联档选闸:02 选套件跑」),如映射表归族与卡片申报有出入,按批修映射表(表只在 run_all_gates.sh 一处)。
|
||||
- 存量债(9 套件+S 域红)归待办清单「迭代 41 测试债修复」条;该批修复实测归绿后需再换代基线 02/09 两键(红→绿走「改善」记账或重生成)。
|
||||
- 全量回归自此由用户自发发起(合入后无自动兜底,2026-10-29 用户裁)。
|
||||
@@ -1,46 +0,0 @@
|
||||
# 工程改动报告——能力清单改版(验证账本改实现指导地图)
|
||||
|
||||
2026-10-29 · 文档设计改动批(用户裁决定稿后发令执行)· worktree 分支 `caplist-20261029` 合回
|
||||
接收方:待办清单.md「能力清单改版——验证账本改实现指导地图」条(本批完成即整条删除,条目内容 git 历史可考)
|
||||
|
||||
## 定位换代(用户裁定,本批不改设计)
|
||||
|
||||
能力清单从「覆盖索引+验证账本」改为**实现指导+阅读导航+义务声明**:只宣布「要验证什么」,不记「是否已验证/是否跑过」;落地账归现行验收闭合链(卡片改动—验收对照表逐条挂断言+合回前独立验收审计),那套机制本批不动。废「滞后一个迭代」:写需求卡片时本批新增能力行当场入表,计划测试文件名与函数名卡里定死;实现照单落名,名实不符=卡片没写清=停卡退回;收尾只核对表上名字与实际落地一致(改名则回表),不刷任何批次字段。
|
||||
|
||||
## 改动面
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `game/tests/README.md` | 八张能力表(七旅程段+跨域条件闸)瘦身四列:能力|系统|真实入口|代表用例(文件:函数)——删「最后验证批次」「缺口」两列,存量行内容保留、不回溯验证;引区块改写(义务清单定位、维护规则、代表用例口径),删「最后验证批次」整段说明;覆盖域表(含其「缺口」列)按用户裁保留现状不动 |
|
||||
| `design/engineering/test-conventions.md` | §8.3「能力清单维护锚」整段改写(新定位+四列+写卡当场入表+实现照单落名+收尾核对);§8.9 三层模型中层「覆盖索引」改「义务清单」,法则 3「覆盖守恒」改「承接守恒」并同步措辞,维护时序段删滞后与批次刷新表述,机器闸句改四列+双通道口径 |
|
||||
| `tools/capability_audit.py` | CAP_COLS 收窄四列(「系统」列纳入非空机检);删「最后验证批次=真实 commit」检查(check_hash/commit_ok/HASH_RE 随删,subprocess 导入随之移除);代表用例与真实入口判据改双通道(见下表);条件闸行豁免保留(按「代表用例」含「条件闸」字样);头部判据清单同步 |
|
||||
| `tools/pipeline_gate.py` | 对照表「能力行」判据收紧:「新增:<能力名>」同样要求该能力行已在 game/tests/README.md 能力表在场(写卡与入表同 commit;改版前仅核「既有:」) |
|
||||
| `.zcode/skills/req-card/SKILL.md`(主区直改,不入 git) | 验证闸节增「能力行当场入表」义务:本批新增能力写卡时增行(真实入口取自设计文档已定入口;代表用例=卡内定死的计划测试 `文件:函数` 名);受影响存量行同批更新;能力退役删行;实现照单落名、收尾核对 |
|
||||
| `.zcode/skills/iter/SKILL.md`(主区直改,不入 git) | 批性质注记更新(能力行增删归写卡段当场入表,「最后验证批次」列已废除);第 5 步账面随批增「能力清单核对」:核对表上名字与实际落地一致、退役能力行已删,名实不符=停卡退回,本批禁代改 README |
|
||||
| `待办清单.md` | 「能力清单改版——验证账本改实现指导地图」条整条删除(完成即删) |
|
||||
|
||||
## 判据变更前后对照
|
||||
|
||||
| 判据点 | 改版前 | 改版后 |
|
||||
|---|---|---|
|
||||
| 能力表列 | 六列(能力|真实入口|代表用例|最后验证批次|缺口;「系统」列不在机检列) | 四列(能力|系统|真实入口|代表用例),四格全非空机检 |
|
||||
| 最后验证批次 | 须为可解析 commit(git cat-file),条件闸行豁免 | 列删除、检查随之删除——清单不记「是否已验证/是否跑过」 |
|
||||
| 代表用例可核 | 单通道:文件在 run_all.gd 套件 manifest 内且文件有 `func 函数名(` | 双通道:代码在(同左)或卡在(文件名或函数名见于 reports/需求卡片*.md——写卡当场入表的计划用例锚);两头都无=红 |
|
||||
| 真实入口可核 | 单通道:产品码有 `func 方法(` | 双通道:产品码有 `func 方法(` 或方法名见于需求卡片(计划入口锚);两头都无=红。※延伸申报见下 |
|
||||
| 对照表「能力行」 | 仅「既有:<能力名>」须在能力表可查,「新增:」不核 | 「既有:」与「新增:」都须在场——新增不在表=「写卡须同批把能力行写入能力清单」红 |
|
||||
| 维护时序 | 清单滞后一个迭代:本批实现的代表用例与批次由下次写卡补齐 | 写卡时当场入表(新增行+受影响存量行更新+退役删行);收尾只核对名字与落地一致,不刷批次字段 |
|
||||
| 条件闸行豁免 | 「代表用例」或「缺口」含「条件闸」即豁免 | 仅「代表用例」含「条件闸」(缺口列已删) |
|
||||
|
||||
**※延伸申报(超出任务清单原文的一处判据延伸,显式呈报待用户追认)**:任务原文只要求「代表用例」改双通道;「真实入口」按原文保持单通道(产品码 `func` 在场)。但用户裁定 ③「受影响存量行(入口/用例名变更)同批更新」与「新增系统的能力行」都在**写卡 commit 点**生效——彼时入口代码尚未落地,单通道必被闸拦(写卡提交被自家闸机拦死,与裁定 ③ 直接矛盾)。故按同一已裁口径「两头都无=红」把卡片通道延伸到入口列:产品码有定义或需求卡片载名,其一即绿。若裁回退,只需还原 `check_entry` 单通道判断(约两行)。
|
||||
|
||||
## 验证
|
||||
|
||||
- 闸件新判据孤立验证(造红探针,未触库内文件):代表用例双通道两头无=红/卡在=绿/代码在=绿(3/3);对照表「既有:」不在表=红、「新增:」不在表=红(2/2)。
|
||||
- 文档域闸(`tools/run_all_gates.sh --docs`,提交点钩子与收口跑批同判据各一遍):06 gdd_lint/06b 变更记录节/07 doc_link/08 doc_term/08c 流水线闸/08d 引用可核/08e 能力审计/10 熵增闸全绿无新增红;08e 能力审计读数=系统文档 25 篇 · 能力行 59 · 套件 65 · 覆盖域表 25 行 · 红项 0。
|
||||
- 收口回执 `game/tests/.gates/receipt.json`:domain=docs、all_green=true、tree=分支尖内容树(不入 git,合回闸按树哈希校验)。
|
||||
|
||||
## 边界与遗留
|
||||
|
||||
- 本批零游戏代码面改动(未跑代码域闸,符合批令);存量 59 行的代表用例全部经代码通道锚定,行内容未动。
|
||||
- 全库「最后验证批次」引用面已清零(test-conventions/README/iter 技能三处随本批改写);待办清单另一条「验证与清单体系整改」实况中的「最后验证批次」字样为历史叙述留档,不在本批改写面。
|
||||
- 主区两个未跟踪旧报告(reports/工程改动报告-存量断言精简C档-2026-10-28.md、reports/盘点-验证与清单体系-2026-10-28.md)按批令未触碰。
|
||||
@@ -1,150 +0,0 @@
|
||||
# 提案:三关色相 × 五组微光互辨抽测方案(2026-10-29)
|
||||
|
||||
> **性质**:待办清单条目「三关色相 × 五组微光互辨抽测——三关图类型色板终值冻结的前置抽测」的设计段过程稿。**本轮只做设计**:不出素材、不跑抽测、不改 `design/art/art-bible.md`(v3.22 已封提交)与其它权威文档、不改代码。
|
||||
> 上游依据:`art-bible` §6.3(三关图类型色板与终值取值程序,本抽测的登记处)、§4.2(类型微光色带五组,色相+明度双码)、§4.3(图类型四槽与不变槽)、§1.4(格子样张,终值冻结闸)、§2(明度三档带与世界底层两子带)、§4.1(色板分层、第二道门、对比硬指标)、§3.2(装饰变体与微光画法)、§6.5(视野迷雾与记忆态);实现侧在役口径 = `game/presentation/views/ui_kit.gd` 微光明度阶梯头注、`game/tests/unit/presentation/type_glow_test.gd`、`game/probe/type_glow_shot_probe.gd`、`tools/render_sample_sheet_v3.py` 的 `CHECKS` 断言写法。
|
||||
> 所引色值一律转写自 `tools/recolor_terrain_tiles.py` 的 `PALETTES` 与 `art-bible` §4.2 冻结值,**冲突时以 owner 文档/脚本为准**(本提案不复述圣经定值、也不新增色值)。
|
||||
|
||||
---
|
||||
|
||||
## 0. 三件缺口的定值结论(只读这一段也能定)
|
||||
|
||||
| 缺口 | 结论 |
|
||||
|---|---|
|
||||
| **① 取样面** | 取样单元 = **三关格底 × 五组微光 = 15 对**;每对铺 **3 格**(素砖底/装饰变体底 A/装饰变体底 B 各一),另每关每底型 1 格无微光基准格 → 取样格 **45**,基准格 **9**,合计 **54 格**。**装饰变体底带**(两种,与 §1.4 样张清单「含至少两种装饰变体」同数),**迷雾记忆态底不带**(推导见 1.4)。 |
|
||||
| **② 互辨判据** | **目检与机检并用**:目检先行、机检冻结(沿 §1.4 整屏样张闸明文闸形)。目检管「色相吞没」这条机器测不了的观感判据(四条,§2.2);机检管明度与可辨下限(四条,§2.3),阈值全部沿用在役值:**合成对比 ≥1.20**(`type_glow_test.gd`/`type_glow_shot_probe.gd` 的 `GRAY_CR_MIN`)、**三通道差不得全部 <8/255**(§4.1 第二道门量纲)、**样图读数与合成模型差 ≤±2/255**(`ui_contrast_probe.gd` 迷雾行值容差)。**不自造阈值**。 |
|
||||
| **③ 产物形态** | **两者兼有**:一张并列样图(承担目检)+一份逐对读数表(承担机检冻结)。样图是本条目要出的图,落 `artwork/` 在途样张 → **本条改动面须补「美术素材」档**;出图与读数由样张脚本产 → **同时补「工具代码」档**。本轮改动面 = **文档+美术素材+工具代码**。 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 抽测设计:取样面
|
||||
|
||||
### 1.1 取样单元与组合数
|
||||
|
||||
- **取样单元 = 一对(当关格底 × 一组微光)**——§6.3 点名的风险就是「格底与微光同在未开格面,邻近色相有吞没风险」,风险发生在**一对之内**,故以对为单元。 ←机检: 读数表行数 = 45(3 关 × 5 组 × 3 底型),逐行可追溯到唯一一格
|
||||
- **组合数 = 3 × 5 = 15 对**:三关 = `dungeon`/`underdark`/`deep_underdark`(§4.3 词表),五组 = 通用增益芥末黄/治疗黄绿/穿刺青/魔法紫罗兰/群伤绯红(§4.2 冻结五组;绘制取值 = `ui_kit.gd` 的 `TG_GLOW_*` 五个常量,组内不细分)。 ←机检: 样图内五组色块与 `ui_kit.gd` 五个常量逐位一致
|
||||
|
||||
### 1.2 底型三版(素砖底 + 两种装饰变体底)
|
||||
|
||||
- **素砖底版**:该关墙瓦片 `wall_center` 件原图铺底。
|
||||
- **装饰变体底版 A/B**:该关 `wall_center_crack`(裂纹)与 `wall_center_speckle`(碎石斑)两件原图铺底——两者即高墙瓦片词表在册的两种装饰变体件,与 §1.4 样张内容清单「含至少两种装饰变体」同数。 ←机检: 抽测脚本装载的装饰变体件名 ∈ 高墙瓦片词表 16 件名单,且两版件名互不相同
|
||||
- **为什么要带装饰变体底**:微光是画在格**内缘**的带状泛光(§4.2 v2 呈现参数:内缘带状、带宽格边÷8),装饰变体按 §3.2 纪律贴**砖缘**分布——两者同处缘部、空间重叠,装饰纹理会混进微光带的合成值。素砖底上互辨过关不等于变体底上过关,故三版都要铺。 ←方向性
|
||||
- **每对 3 格**:同一对(关 × 组)在三种底型上各铺一格,任一底型不通过即该对不通过。
|
||||
|
||||
### 1.3 排布与格数
|
||||
|
||||
- **排布**:三关各一块,竖排;每块 3 行(素砖/变体 A/变体 B)× 6 列(列 0 = 无微光基准格,列 1–5 = 五组微光,**按明度阶梯序**芥末黄→黄绿→青→紫罗兰→绯红排列)。
|
||||
- **阶梯序即相邻并列**:列 1–5 按阶梯序排,任意相邻两列即一组「两两相邻格微光并列」(§1.4 样张内容清单点名项),每关每底型 4 对,合计 3 × 3 × 4 = **36 对**,无需另铺对照列。 ←机检: 每块列 1–5 的带内合成亮度按列序单调递减
|
||||
- **列 0 基准格**:同关同底型、不画微光的一格,供目检比对「这一关的格底本身长什么样」,也是机检「同格中心素底均值」的取样源。
|
||||
- **格边长 = 45px**(D 区实比,与 §1.4 主样张板同档);每块 6 × 45 = 270px 宽、3 × 45 = 135px 高,加块标题 20px;正图段 465px 高。
|
||||
- **灰度副本段**:正图段整段去色相(§4.5「色弱模拟(去色相)」口径)另出一份,等幅面,紧接正图段下方——色弱通道的目检在副本上做,不要求评测者自己脑补去色。 ←目检: 灰度副本段内零彩色像素(R=G=B)
|
||||
- **画布**:单段 620px 宽(左标注列 170 + 图 270 + 右说明列 180);两段 + 页眉 60 + 段间 30 + 图例 80 → **画布 640 × 1120**,四缘留 10px 净空(过 §1.4 A5 四缘净空断言)。本条为过程件布置,不入 §8.2。 ←机检: 样图四缘 10px 带内零内容像素
|
||||
|
||||
### 1.4 迷雾记忆态底:不带(推导)
|
||||
|
||||
- **不带**。推导:类型微光只画在**未开格**(§4.2/§4.6.3「未开格类型预读」单通道);迷雾记忆态只作用于**区外已开格**(§6.5「区外已开格:暗淡记忆态」);区外**未开格**一律全黑不渲染(§6.5 二值态,零信息)。三者合起来:微光与记忆态**永不同格共存**,不构成取样面。
|
||||
- 邻格关系(记忆态已开格与带微光的未开格在灯光区边界相邻)的可辨性由 §2 明度分层(墙顶受光档 L≥0.30 对记忆态合成底 ≈0.036)与 §6.5 可辨性自查三通道承载,不属本抽测面。 ←机检: 抽测样图内零迷雾灰罩合成底格(记忆态合成底三关行值 `#4C4038`/`#3F4147`/`#3E4048` 零出现)
|
||||
|
||||
### 1.5 铺底值的取法
|
||||
|
||||
- **铺底 = 该关在役墙瓦片素材原图**(`terrain_wall_*_<board_type>.png`,由 `tools/recolor_terrain_tiles.py` 程序换色产;素材不入 git,本地需有现件,缺件即抽测不成立的先决阻塞)。
|
||||
- **铺底代表值 = 该关墙顶受光家族最亮槽(色表 `H2` 槽)**,用于登记与读数比对;若实测未过 §4.1 硬指标门(L≥0.30、饱和 ≤0.55、避 300°–345°),则沿同家族向更亮槽上移直到过门——仍在在役色表内,**零新增色值**。 ←机检: 三关铺底代表值逐一满足 L≥0.30 且饱和 ≤0.55 且色相 ∉ [300°,345°]
|
||||
- **机检用的「格底均值」不取色表槽值,取渲染面**:该关墙瓦片在**内缘带区域**(与 `type_glow_shot_probe.gd` 同口径:`de < 格边 × 0.125`)的像素均值——微光落在缘部,判据必须比对的正是它压着的那一圈底,不是整格平均。
|
||||
|
||||
---
|
||||
|
||||
## 2. 互辨判据
|
||||
|
||||
### 2.1 两段的分工(沿 §1.4 已立闸形,不自造)
|
||||
|
||||
- **闸形 = 目检先行、机检冻结**,直接沿用 §1.4 整屏样张闸明文写法(「方向稿目检先行(防『机检过闸但气质否决』式返工),目检过后机检冻结」)。本抽测是 §1.4 格子样张的前置,与同一闸形对齐。
|
||||
- **分工理由**:本次要判的风险是**色相吞没**——「这一组微光在这块格底上还看不看得出来、会不会看成另一组或看成装饰」。这是观感判据,机器测不了;本作对此已有明训(§4.1「机检≠看得清」,目视验证面 = 渲染帧取证)。机器能测的是明度与可辨下限,故机检只管它能管的那一段。 ←方向性
|
||||
- **冲突处理**:目检不通过的一对,机检即使全绿也判该对**不通过**(目检先行即否决权在前);机检不通过的一对,目检即使看得出也判**不通过**,走 §4 步骤 S5 修法后重跑。 ←机检: 读数表逐行判定 = 目检判定 ∧ 机检 B ∧ 机检 C,三者并列取严
|
||||
|
||||
### 2.2 目检判据(看什么、算过,四条)
|
||||
|
||||
1. **逐对指认**:对 45 个取样格逐格报出「这一格的微光属哪一组」(五选一),与样图答案表逐位比对;**45/45 全中才通过**,指认不出或报错组即该格不通过。 ←目检: 逐格报出的组号与答案表 45/45 一致
|
||||
2. **灰度副本重复一遍**:在同一图的去色相副本上重做第 1 条(色弱通道,§1.4 验收 2「色弱玩家的类型主通道 = 微光」+ §4.5⑨),同样 45/45。 ←目检: 灰度副本上逐格报出的组号 45/45 一致
|
||||
3. **相邻并列可辨**:36 对相邻微光格(1.3 阶梯序相邻列)逐对判「两格是否可分辨」,全对可分才通过(§1.4 样张内容清单「含两两相邻格微光并列」)。 ←目检: 36 对逐对判定全为可分
|
||||
4. **装饰不抢读**:两种装饰变体底上的微光仍可指认,且装饰不构成格内第二焦点(§3.4 焦点预算:微光为底效泛光不作焦点,装饰残缺内凹自然后退)。 ←目检: 30 个变体底取样格(2 变体 × 3 关 × 5 组)内无一处装饰被判为焦点
|
||||
|
||||
### 2.3 机检判据(阈值与出处,四条)
|
||||
|
||||
- **机检 A|五组明度阶梯逐关重算**(沿用 `type_glow_test.gd` ④ 与 `type_glow_shot_probe.gd` V6 在役口径,只把合成底从固定 `BRICK` 换成当关格底均值):五组按阶梯序合成后 Rec.709 亮度**单调递减**,且**任意两组合成对比 ≥1.20**(对比 = WCAG 线性域相对亮度 +0.05 偏移,判据线 `GRAY_CR_MIN = 1.20`,与 `tools/shot_checker.py` WCAG 段同公式)。三关 × 三底型各跑一遍,**30 行读数**。 ←机检: 每关每底型阶梯单调成立且最弱合成对比 ≥1.20
|
||||
- **机检 B|格底-微光可辨底线**(沿用 §4.1 第二道门量纲 8/255):每一对的「微光带内合成均值」与「同格中心素底均值」的 RGB **三通道差不得全部 <8/255**——三通道里至少一通道 ≥8/255 才过。全 <8 即肉眼不可辨,等于微光被格底吞没,直接否决。 ←机检: 45 行读数中三通道差全部 <8/255 的行数 = 0
|
||||
- **机检 C|绘制参数校准**(沿用 `ui_contrast_probe.gd` 迷雾行值 ±2/255 容差):样图带内均值与合成模型(`0.49 × 微光色值 + 0.51 × 格底均值`,`ui_kit.gd` 头注登记口径)逐对差 **≤±2/255**;超差即样图绘制参数与 §4.2 v2 冻结呈现参数(α170、带宽格边÷8、软边 0.55、圆角 2px)不符,须校准后重出图,否则后续读数全部失真。 ←机检: 45 行读数中模型差 >±2/255 的行数 = 0
|
||||
- **机检 D|格底候选值准入**(沿用 §4.1 硬指标与两道门):三关铺底代表值各过 L≥0.30、饱和 ≤0.55、避 300°–345° 禁入带、§4.2 语义检查(环境域,不占红/金/蓝/紫赤/绿语义段)、与既有任一色三通道差不得全部 <8/255。 ←机检: 三关铺底代表值五门全过,逐枚列读数
|
||||
- **说明**:机检 A 的 1.20 与机检 B 的 8/255、机检 C 的 ±2/255 三个数值**全部是本作在役值**,本轮不新拟一个数。色相吞没不设机检阈值——本作没有任何条文给出色相差门槛,自造一个数等于把观感问题伪装成可机检问题。 ←方向性
|
||||
|
||||
### 2.4 谁来判
|
||||
|
||||
- **机检 = 脚本自判**:沿用 `tools/render_sample_sheet_v3.py` 的 `CHECKS` 机制(`:113` 建表/`:117` 登记/`:1033` 汇总/`:1164` 出报告表),逐项打印 PASS/FAIL 并输出机检报告。
|
||||
- **目检 = 用户**:§1.4 闸形定气质终审为用户目检(样张 v3 先例:机检 17/17 全绿后由用户目检验收)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 产物形态与改动面
|
||||
|
||||
- **产物 = 两者兼有**:
|
||||
- **一张并列样图**(正图段 + 灰度副本段 + 图例,54 格,1.3 排布)——承担目检四条;
|
||||
- **一份逐对读数表**——表一「逐对表」45 行(关/底型/微光组/带内合成均值/同格中心素底均值/合成对比/三通道差/模型差/色相差/判定),表二「组间表」30 行(关/底型/组对/合成对比/灰度亮度/判定),承担机检 A–D 与冻结后的回归比对。
|
||||
- **归档位**:样图落 `artwork/` 在途样张(与 §1.4 样张 v3 产物 `artwork/mockups/sample-batch-v3-final-2026-09-30.png` 同归位;图片不入 git,按 §8.3 归档纪律);读数表为过程件,随样图同批输出落 `reports/`。
|
||||
- **改动面结论(本轮)= 文档 + 美术素材 + 工具代码**:
|
||||
- **美术素材**:样图是本条目要出的图,落 `artwork/` 在途样张 → 按 `doc-conventions` §12.1 划线判据(美术素材 = `artwork/` 在途样张与 `game/assets/art/` 终稿)**须补本档**;
|
||||
- **工具代码**:出图与读数由 `tools/` 下样张脚本产(扩既有样张脚本或单立抽测脚本,二选一由执行批定)→ **须补本档**;
|
||||
- **文档**:终值落位改 §6.3 与本待办条目 → 本档原已有;
|
||||
- **不补「游戏代码」**:本轮不改 `game/`(不改探针、不改 `ui_kit` 色值)。若抽测判某组不互辨而需动微光明度档(provisional 域,见步骤 S5),那是下游修法,届时再补该档,本轮不预写。
|
||||
|
||||
---
|
||||
|
||||
## 4. 执行步骤(一步一动 + 一个可核查结果)
|
||||
|
||||
- **S1 取三关铺底值**:从 `tools/recolor_terrain_tiles.py` 的 `PALETTES` 取三关墙顶受光家族最亮槽值各一枚,逐枚跑机检 D。→ **结果**:三关铺底值过门读数表(每枚列 L、饱和、色相、与既有色最小三通道差、语义检查结论)。
|
||||
- **S2 出并列样图**:跑样张脚本产样图(含灰度副本与图例),脚本同步打印机检 A/B/C 逐项结果。→ **结果**:一张 PNG(54 取样格 + 灰度副本 + 图例)+ 脚本断言打印全项 PASS/FAIL。
|
||||
- **S3 目检**:用户在样图上按 §2.2 四条逐项判,逐格/逐对记录。→ **结果**:目检判定表(90 次指认 + 36 对相邻并列,逐项 PASS/FAIL + 不通过项描述)。
|
||||
- **S4 汇总裁定**:目检四条全过 且 机检 A–D 全绿 = 抽测通过。→ **结果**:抽测结论一行(通过/不通过 + 不通过项清单)+ 逐对读数表一(45 行)与组间表二(30 行)。
|
||||
- **S5 修法(仅不通过时)**:先调该组微光的**明度档**——`ui_kit.gd` 头注已写明明度档属 provisional 域、允许域内自调(翻动色相才触 §4.2 冻结面),调明度**零新增色值**;明度档调到域边界仍不过,再换当关格底槽(同家族内换槽,仍在在役色表内,零新增)。改完重跑 S2–S4。→ **结果**:修订后样图 + 重跑读数(目标全绿)。
|
||||
- **S6 终值落位**:抽测通过后,把三关 `tile_closed` 与 `wall_ambient` 终值登记进 §6.3 三关行,并按 §4.1 分层②场景环境子板口径登记(每套 ≤32 色、过两道门)。→ **结果**:§6.3 三关行含两槽终值色值字面量,且该行现行机检断言已同步改写(见 §5 断言翻转)。
|
||||
- **S7 下游冻结**:按 §4.3 现行四槽换色规则重跑 §1.4 格子样张,过闸即砖面形态与色板冻结。→ **结果**:§1.4 样张重跑机检全绿 + 用户目检通过。
|
||||
|
||||
---
|
||||
|
||||
## 5. 终值如何落位
|
||||
|
||||
- **落哪两槽**:§4.3 四槽中的 **`tile_closed`**(未开格底)与 **`wall_ambient`**(墙雾氛围 tint)——即本条目原文点名的两槽。`tile_open` 已由 §1.4 样张 v3 冻结在世界底层档、`variant_tint` 只改色相不改纹形(归地形变异批),两槽不属本条。
|
||||
- **按什么程序**:§6.3 明文两步——**先抽测**(本条),**再按 §4.3 现行规则重跑 §1.4 格子样张冻结**,色值不代填。冻结后落 §6.3 修订。
|
||||
- **断言翻转(易漏,务必同批做)**:§6.3 现行机检断言是「本节三关行无 `tile_closed`/`wall_ambient` 终值色值字面量(终值未冻结前禁填)」。填值那一刻该断言必红,故落位同批必须把它改写为「三关行两槽终值 == 冻结值,且与 §4.1 场景环境子板登记同值」——**禁只填值不改断言**。 ←机检: §6.3 三关行两槽终值与 §4.1 环境子板登记值逐字一致,且该行机检断言已改指冻结值
|
||||
- **两槽终值从哪取(零新增)**:`tile_closed` 取该关在役墙瓦片墙顶受光档槽值;`wall_ambient` 取同关色表内带该关主题色相的槽值(dungeon 暖棕/underdark 冷蓝灰/deep_underdark 铁灰,§6.3 方向候选)。两槽取同关同槽值亦可(同属环境域,不撞 §4.2 语义段,一色两岗在环境域不违例);若要拆成两枚不同值,须走 §4.1 分层②「新增环境色」路径(不占 48 token 额度,但仍属新增),本轮不取、不预写。
|
||||
- **额度账**:两槽终值属 §4.1 分层②**场景环境子板**(环境色 = 地面/石材/背景,随场景走;每屏一套 ≤32 色,**不占 48 token 额度**)。本轮终值全部从在役色表取,**需新增色值 = 0,48 色余量仍为 0,无需压缩任何既有色**。
|
||||
- **wall_ambient 的明度口径注(本轮按此执行)**:tint 只染**色相与饱和**,不改被染面的明度档——被染面明度由该面自身层档定(棋盘墙雾面走墙顶受光档,B 区背景走世界底层档,§6.1)。推导:另一读法(tint 连带明度、把被染面拉到 L≥0.30)会同时撞 §6.1「背景明度走世界底层档」、§2 世界底层两子带(0.014–0.06/0.08–0.14)与 §1.4 整屏②项层间可分三条,是唯一会同时破三条的读法,故不取。§4.3 的 L≥0.30 在此口径下仍作**槽值登记门**(登记值取墙顶受光档槽值即满足)。另:`wall_ambient` 不与微光同面(它是背景/墙雾 tint,微光画在格面),**不进本抽测取样面**,其终值由 S7 的 §1.4 重跑闸判定。
|
||||
|
||||
---
|
||||
|
||||
## 6. 待裁点清单
|
||||
|
||||
**零待裁点。** 三件缺口全部由圣经条文与在役实现推出定值:取样面由 §4.2/§3.2/§6.5 推出(含「迷雾记忆态底不带」的推导),判据阈值全部沿用在役值(1.20/8/255/±2/255)不自造,产物形态与改动面按 `doc-conventions` §12.1 划线判据直接判档,终值取值路径零新增色值(不触 48 额度),wall_ambient 的明度口径按「唯一不破三条的读法」定值。
|
||||
|
||||
---
|
||||
|
||||
## 7. 附:读数表字段定义
|
||||
|
||||
**表一 逐对表(45 行 = 3 关 × 5 组 × 3 底型)**
|
||||
|
||||
| 字段 | 口径 |
|
||||
|---|---|
|
||||
| 关 / 底型 / 微光组 | 取样面坐标,可追溯到样图唯一一格 |
|
||||
| 带内合成均值 RGB | 该格内缘带(`de < 格边 × 0.125`)像素均值,与 `type_glow_shot_probe.gd` 同口径 |
|
||||
| 同格中心素底均值 RGB | 同格中心区(内缩 20%,`CORE_PAD_FRAC`)像素均值 |
|
||||
| 合成对比 | WCAG 线性域相对亮度 +0.05 偏移,供机检 A 判读 |
|
||||
| 三通道差(最大/最小) | 带内合成均值 减 素底均值,供机检 B 判读(判据看最小通道是否 <8) |
|
||||
| 模型差 | 带内合成均值 减 合成模型(0.49 × 微光色值 + 0.51 × 格底均值),供机检 C 判读 |
|
||||
| 色相差(度) | 铺底代表值与微光组色相的差值,**只作读数不设门槛**,供目检与后续定值参考 |
|
||||
| 判定 | 目检 ∧ 机检 B ∧ 机检 C,并列取严 |
|
||||
|
||||
**表二 组间表(30 行 = 3 关 × 3 底型 × 10 组对)**
|
||||
|
||||
| 字段 | 口径 |
|
||||
|---|---|
|
||||
| 关 / 底型 / 组对 | 五组两两全组合(`type_glow_shot_probe.gd` 全对比对口径) |
|
||||
| 合成对比 | 同表一公式,判据 ≥1.20(机检 A) |
|
||||
| 灰度合成亮度 | Rec.709 系数合成亮度,供阶梯单调判读 |
|
||||
| 判定 | 合成对比 ≥1.20 且阶梯单调成立 |
|
||||
@@ -1,322 +0,0 @@
|
||||
# 设计——单格绘制状态件拆分(board_cell_unit 类变量键真实清偿)
|
||||
|
||||
设计讨论段过程稿 v1.0——待主会话汇总裁决。
|
||||
|
||||
结论行:推荐「绘制层域两件案」——状态件按 _draw 既有的层域轴拆成两个独立文件的绘制域件(格面基座层件 12 成员/格面标识与叠加层件 13 成员),几何与微光子件面留宿主(10 成员),绘制命令随入参同件迁移,宿主 _draw 退为六步时序器;三文件各自类变量 10/12/13,全部低于阈值 15 且不依赖任何闸机口径漏洞。
|
||||
|
||||
---
|
||||
|
||||
## 1. 现状与两项关键发现
|
||||
|
||||
### 1.1 键账现状
|
||||
|
||||
- 涉案键:`game/presentation/views/board_cell_unit.gd|quality/max-class-variables = 30`(tools/gdstyle_baseline.txt,2026-10-29 重锚版)。阈值 15(gdstyle 默认值,tools/gdstyle.toml 不设数值阈值)。
|
||||
- 源码实查(2026-10-29):全文件 33 个类级 var 声明=宿主 6+inner 状态件 `_CellPaintState` 27。闸实测 30(本会话对单文件实跑 gdstyle v0.4.0 复核)。
|
||||
- 文件头注在案:状态件职责语句「单格绘制输入集」;探针直读冻结成员(glyph/fog_state/plate/glyph_color)与 `_glow_layer` 住宿主。
|
||||
- 迭代 41 已把 `_draw` 拆成约 20 个分层私有函数——函数级键已清零,本设计只解决类变量 30 这一个键。
|
||||
|
||||
### 1.2 发现一:gdstyle 对 inner class 的计数不是均匀展平,是「首个 setter 截断」
|
||||
|
||||
主会话给的事实是「inner class 成员按宿主展平计数」。本会话实测修正:截断点在 inner class 内**第一个带 setter 的属性**。
|
||||
|
||||
| 文件 | 声明数(宿主+inner) | 闸实测 | 归因 |
|
||||
|---|---|---|---|
|
||||
| board_cell_unit.gd | 6+27=33 | 30 | 宿主 6+inner 第一个 setter(edge,30–35 行)之后的 24 个=30;setter 声明本身及其之前的 3 个(_owner/cell/edge)留在 inner 类一侧不进宿主账 |
|
||||
| standee_body.gd | 6+25=31 | 19 | 宿主 6+inner 第一个 setter(_intent_scale,37–40 行)之后的 13 个=19 |
|
||||
| board_view.gd(无 inner class) | 32 | 32 | 平面文件=声明数逐一全计 |
|
||||
| main.gd(无 inner class) | 49 | 49 | 同上 |
|
||||
|
||||
四点全部精确吻合。推论三条:
|
||||
|
||||
1. 现行登记值 30 是截断口径的**欠估**——若 gdstyle 升级修掉该解析行为,同文件键跳到 33=恶化红。任何「调整 inner class 内成员顺序/把 setter 挪位置」的降数手法都是在利用解析缺陷,工具一升级即翻车,且属「为迎合机检保留无效形态」,禁。
|
||||
2. 主会话「任何 inner class 重新分组都降不了数」的结论在截断口径下依然成立(重排不改总量级),且存在更深的坑——重排确实能改数(把首个 setter 挪到类尾=宿主账只剩 6),但那正是第 1 条禁的手法。
|
||||
3. **唯一稳健出路=拆成独立文件**:平面文件口径=声明数逐一全计(board_view/main 两点实证),预测值即实数,不依赖闸机任何解析行为。
|
||||
|
||||
### 1.3 发现二:ui_input_probe 疑似潜伏红(迭代 41 合并遗留,须 T0 先证)
|
||||
|
||||
ui_input_probe.gd 有四处**绕过 st 直接读格件成员**的断言:case① `u1.hl_visible`/`u1.hl_color`(234–235 行)、case② `.hl_color`(243–244 行)、case③ `.dot_visible`(250 行)、case⑭ `.mutation_mark`(374–379 行)。这四个成员迭代 41 已随状态件迁入 `_CellPaintState`,而 GDScript 外部实例读不到 inner class 的成员(取索引=运行时脚本错误)。
|
||||
|
||||
时间线:探针末次全绿 2026-10-28 05:03(game/tests/.gates/probe_full.log)早于状态件合入 2026-10-29 01:37(三文件同秒 mtime=合并检出);基线注记「迭代 41 两卡特许直接合回未重跑代码域闸」。合入后探针未跑过,潜伏红未经证实也未经证伪。同批 standee(u4)作者对同类问题做了宿主侧出口(fx_sweep_counters 方法返回计数器字典),u3 未处理这四处直读。
|
||||
|
||||
处置(本设计的立场):**无论潜伏红真假,本设计的拆分都把探针直读面显式化**——hl_color/hl_visible/dot_visible/mutation_mark 落入格面标识与叠加层件,探针四处断言改址 `u.face.*`(对照表申报的探针改址,断言条件与期望值零变化);四个头注冻结成员(glyph/fog_state/plate/glyph_color)留宿主不动。T0 用一次 ui_input_probe 实跑证实或证伪潜伏红,结果记实现报告。
|
||||
|
||||
### 1.4 探针/测试直读面全清单(改址与保留的依据)
|
||||
|
||||
| 消费方 | 读什么 | 现路径 | 设计后路径 |
|
||||
|---|---|---|---|
|
||||
| ui_input_probe case④b⑪ | glyph | u.glyph | u.glyph(宿主冻结,不变) |
|
||||
| ui_input_probe case⑮ | fog_state | u.fog_state | u.fog_state(宿主冻结,不变) |
|
||||
| player_copy_sweep_test wa8 | plate/glyph_color | u.plate/u.glyph_color | 不变(宿主冻结) |
|
||||
| ui_input_probe case①②③⑭ | hl_visible/hl_color/dot_visible/mutation_mark | u.X(已断——潜伏红) | u.face.X(探针改址四处) |
|
||||
| board_view.cell_rect_probe:891 | edge | u.st.edge | u.edge(board_view 内部改址) |
|
||||
| board_shot_probe/type_glow_shot_probe | 格矩形 | 经 cell_rect_probe | 不变(间接) |
|
||||
|
||||
其余状态件成员全仓零外部读方(本会话 grep 全量复核)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 现状成员全列(33 个)
|
||||
|
||||
写入方全部在 board_view.gd(唯一写方文件);行号为 2026-10-29 实查,实现批 T0 重核。setter→重绘语义列=该成员 setter 的现行副作用(无 setter=普通赋值不重绘)。
|
||||
|
||||
### 2.1 宿主 6 个
|
||||
|
||||
| 成员 | 类型 | 重绘语义 | 写入方 | 读取方 | 绘制消费层 |
|
||||
|---|---|---|---|---|---|
|
||||
| st | _CellPaintState 聚合 | — | 宿主 _init:147 | 全部绘制函数经 st.X | 载体 |
|
||||
| glyph | String | setter→queue_redraw | _paint_cell:667 | _draw_glyph_layer:200/205、_draw_fog_memory:344 | 字形层+迷雾记忆态(探针冻结) |
|
||||
| glyph_color | Color(UiKit.INK) | setter→queue_redraw | _paint_cell:668/674 | _draw_glyph_layer:205 | 字形层(探针冻结) |
|
||||
| plate | bool | 无 setter | _paint_cell:675 | **绘制侧零消费**(_draw_digit_plate 由 glyph 非空无条件触发,plate 不参与判据);读方仅 player_copy_sweep_test:138 | 无(探针冻结成员,禁删禁接线——接线即行为变化) |
|
||||
| fog_state | int | 守卫 setter→queue_redraw | _paint_cell:734/736 | _draw_fog_layer:247 | 迷雾层(探针冻结) |
|
||||
| _glow_layer | Node2D 子件 | — | _sync_glow_layer:407–412 | edge/badge_glyph 两 setter、_sync_glow_layer | 微光子件(头注在案住宿主) |
|
||||
|
||||
### 2.2 状态件 27 个
|
||||
|
||||
| 成员 | 类型 | 重绘语义 | 写入方(board_view) | 读取方 | 绘制消费层 |
|
||||
|---|---|---|---|---|---|
|
||||
| _owner | Node2D 回引 | — | 宿主 _init:147 | 各 setter 内部 | — |
|
||||
| cell | Vector2i | 无 setter | rebuild:250 | **全仓零读方** | 无(诊断观测面,待裁点 3) |
|
||||
| edge | float | setter→glow setup+queue_redraw | set_cell_area:204、rebuild:251;读 _paint_cell:704、cell_rect_probe:891 | 全部层 | 全层(rect 尺寸基准) |
|
||||
| bg_sb | StyleBoxFlat | 无 setter | _paint_cell:666 | _draw_base_layer:174、_draw_contact_or_fallback:187、_draw_bevel:314 | 基座层 |
|
||||
| contact_bands | Array[int] | 无 setter | _apply_contact_bands:804 | _draw_contact_bands:271 | 接触带 |
|
||||
| contact_corners | Array[int] | 无 setter | :805 | :279 | 接触带 |
|
||||
| contact_col | Color | 无 setter | _process 呼吸:780/787、_apply_contact_bands:810/816 | _draw_contact_or_fallback:183、_draw_contact_bands:278、_draw_contact_corner:293–305 | 接触带 |
|
||||
| outline_sides | Array[int] | 无 setter | _paint_cell:676(assign)/:700(append) | _draw_base_layer:166、_draw_outline_sides:257 | 描边 |
|
||||
| facade_south | bool | setter→queue_redraw | _paint_cell:677/690;读 :696 | _draw_south_facade:352 | 南立面 |
|
||||
| proj_band | float | setter→queue_redraw | _paint_cell:678/704 | _draw_north_projection:367 | 地面投影 |
|
||||
| badge_glyph | String | setter→glow mask+queue_redraw | _paint_cell:719/726 | _draw_glyph_layer:206–210、_sync_glow_layer:413 | 徽章 |
|
||||
| dot_visible | bool | setter→queue_redraw | 路径预览:549/554 | _draw_overlay_layers:230 | 叠加层(探针直读 case③) |
|
||||
| hl_visible | bool | setter→queue_redraw | 悬停:512/517/521/525/534 | :233 | 叠加层(探针直读 case①) |
|
||||
| hl_color | Color | setter→queue_redraw | :513/518/522/526 | :235 | 叠加层(探针直读 case①②) |
|
||||
| font | Font | 无 setter | set_world_font:185、rebuild:260 | _draw_glyph:392、_draw_badge:418 | 字形/徽章/迷雾记忆 |
|
||||
| bevel | float | setter→queue_redraw | rebuild:253 | _draw_bevel:312–321 | 倒角 |
|
||||
| tex_base | Texture2D | 无 setter | _paint_cell:665 | _draw_base_layer:161、_draw_fog_memory:341 | 基座+迷雾记忆 |
|
||||
| tex_mutation | Texture2D | 无 setter | 无(素材槽位恒 null) | _draw_glyph_layer:197 | 纹带槽 |
|
||||
| tex_glyph | Texture2D | 无 setter | 无(槽位) | :202 | 数字槽 |
|
||||
| tex_badge | Texture2D | 无 setter | 无(槽位) | :207 | 徽章槽 |
|
||||
| tex_seal | Texture2D | 守卫 setter→queue_redraw | _paint_cell:614/618 | :212 | 封印槽 |
|
||||
| tex_facade | Texture2D | 无 setter | _paint_cell:679/709 | _draw_e_facade:380–386 | E 格墙面 |
|
||||
| facade_strip | bool | setter→queue_redraw | _paint_cell:680/708 | :380 | E 格墙面 |
|
||||
| treasure_mark | String | 守卫 setter→queue_redraw | _paint_cell:713 | _draw_mutation_marks:326 | 变异标记 |
|
||||
| mutation_mark | String | 守卫 setter→queue_redraw | _paint_cell:723/725 | :330 | 变异标记(探针直读 case⑭) |
|
||||
| glow_group | int | 守卫 setter→_owner._sync_glow_layer() | _paint_cell:727、_sync_glow_to_units:768 | _sync_glow_layer:404/412 | 微光子件 |
|
||||
| removed_dim | bool | setter→queue_redraw | _paint_cell:737 | _draw_overlay_layers:239 | 退色层 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 方案形态——三条路的评估
|
||||
|
||||
### 3.1 路 A:状态件升格独立文件×N(推荐,取「绘制域件」形态)
|
||||
|
||||
按 _draw 已有的层域轴切。迭代 41 拆函数时已经沿这条轴走了(基座/字形/叠加/迷雾/描边/接触带/倒角……),本设计把同一条轴从函数级升到类级:**每个件=一个绘制层的入参+该层的绘制命令**。件有行为(draw 方法族+setter 重绘语义)、有职责语句、单一变化原因=该层的视觉规格(art-bible 对应条款族),满足 code-conventions §1.1 全部五条拆分判据与 §1.2「功能=类」。这是对迭代 41「被动数据袋」否决的正面回答:成员不再是「剩下的装一起」,而是「这一层画什么、怎么画」的完整领域单元。
|
||||
|
||||
细化两个子形态:
|
||||
|
||||
- **A2 绘制命令随迁(推荐)**:件的 draw 方法持有绘制命令本体,宿主 _draw 退为时序器。真内聚(状态+行为同件);宿主从 423 行缩到约 150 行,退离 §1.1 的 400 行审视线。
|
||||
- **A1 纯入参件(淘汰)**:件只装数据,绘制函数留宿主。宿主仍有约 20 个绘制函数经 st 间接取值,件本质=把一个被动数据袋拆成两个被动数据袋,迭代 41 的否决理由原样复活;§1.1-① 立不住。
|
||||
|
||||
### 3.2 路 B:成员真实削减(淘汰为主出路,保留两处微收割)
|
||||
|
||||
要降到 15 需削 18 个成员,而可削的只有:
|
||||
|
||||
- `cell`:全仓零读方(写入仅 rebuild 一处)。可删,零行为变化(待裁点 3)。
|
||||
- `plate`:绘制侧零消费,**但**是探针冻结成员(player_copy_sweep_test wa8 直读)——禁删;给它接上绘制判据反而改变 golden 现状(「人」回退格会少画牌),禁。
|
||||
- tex_mutation/tex_glyph/tex_badge 三槽位:从未被写入但被 _draw 消费(elif 程序化回退路径),是 art-bible §8.2 在册素材槽位——结构承载,非无效成员,留。
|
||||
|
||||
削减上限 1–2 个,差 16 个以上,**单独不可达**。上移 board_view 方向被堵死:board_view 类变量 32 已按尾波卡 D5 裁豁免终局(键永久基线内、禁再恶化),上移任何成员都构成禁再恶化的恶化。
|
||||
|
||||
### 3.3 路 A3:整体搬成一个大状态件文件(淘汰)
|
||||
|
||||
状态件 24–27 个成员整体独立成文件,新文件自身 24–27>15=基线外新键——任务简报预警的陷阱,实测确认。拆是必须的,问题只是切几刀、沿什么轴。
|
||||
|
||||
### 3.4 路 C:重绘回引形态三选(随 A2 定案)
|
||||
|
||||
| 形态 | 判定 |
|
||||
|---|---|
|
||||
| **_owner 直引(推荐,现状形态)** | Node 持 RefCounted 成员、RefCounted 持 Node 回引——Node 引用不参与引用计数,**无环无泄漏**(现行 inner class 同款,先例在役)。setter 语句逐字保形,零新契约。Godot 官方判据下 RefCounted 值对象持宿主回引是常规形态。 |
|
||||
| Callable 注入 | 淘汰。edge/badge_glyph/glow_group 三个 setter 的副作用不止 queue_redraw(glow 层 setup/badge mask/子件同步),一个 Callable 表达不了,得注两三个=每件多 1–2 成员+setter 体改写=语义面重写而非迁移。 |
|
||||
| 信号 | 淘汰。Godot 信号同步派发、时序等价,但守卫式 setter(tex_seal/treasure_mark/mutation_mark/fog_state 的判重)与 glow 副作用都得改写成发射+宿主分发,新增每信号一行的 §2.1 成文义务,换不来任何行为收益。 |
|
||||
| 弱引用 | 淘汰。解的是不存在的环引用问题,白白加 is_instance_valid 守卫复杂度。 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 拆分定案(推荐案 A2 两件案)
|
||||
|
||||
### 4.1 总账
|
||||
|
||||
| 文件 | 类变量(全计) | 构成 |
|
||||
|---|---|---|
|
||||
| board_cell_unit.gd(宿主) | **10** | edge/cell/glow_group/glyph/glyph_color/plate/fog_state/_glow_layer/base/face |
|
||||
| cell_base_layer.gd(新) | **12** | _owner/bg_sb/contact_bands/contact_corners/contact_col/outline_sides/facade_south/proj_band/bevel/tex_base/tex_facade/facade_strip |
|
||||
| cell_mark_overlay.gd(新) | **13** | _owner/badge_glyph/dot_visible/hl_visible/hl_color/font/tex_mutation/tex_glyph/tex_badge/tex_seal/treasure_mark/mutation_mark/removed_dim |
|
||||
|
||||
对账:原 33 声明=新 10+12+13=35;差额 2=每件各持一个 _owner(原仅一个)。edge/cell/glow_group 上收宿主的理由:edge 是格件自身几何且其 setter 驱动宿主自有 _glow_layer(收编后 setter 体少两处跨对象回引);glow_group 驱动微光子件生命周期(加/撤子节点是 Node 职责,RefCounted 件做不了);cell 是格件身份。三者上收后,跨对象回引只剩「件→宿主 queue_redraw/glow mask」这一类,与头注「setter 触发宿主重绘语义经 _owner 回引保持逐字」完全同形。
|
||||
|
||||
### 4.2 件 A:cell_base_layer.gd(格面基座层绘制件)
|
||||
|
||||
- 落点:`game/presentation/views/cell_base_layer.gd`;extends **RefCounted**(godot-master 判据:瞬态逻辑/数据容器用 RefCounted,Resource 是给可序列化、要进 Inspector 的数据——绘制入参每拍重写、永不落盘,Resource 只带来共享默认值陷阱与序列化包袱);无 class_name(类名缓存面纪律,同宿主与 cell_type_glow_layer 先例),经宿主 preload 引用。
|
||||
- 职责语句:格面基座层绘制域——底面/描边/高墙立面/地面投影/接触带微光/顶面倒角的全部绘制入参与绘制命令。
|
||||
- 单一变化原因:art-bible 基座层视觉规格(§1.2 叠层序/§3.2 接触带/§8.5 结构归程序/v3.5 冻结①立面条款族)——瓦片、立面、投影、微光的画法变了改本件,不触字形与迷雾。
|
||||
- 成员:上表 4.1 行所列 12 个;类型与默认值逐字继承,四个 setter(facade_south/proj_band/bevel/facade_strip)体逐字(_owner.queue_redraw())。
|
||||
- 绘制命令:现宿主九个私有函数随迁——_draw_base_layer/_draw_outline_sides/_draw_south_facade/_draw_north_projection/_draw_e_facade/_draw_contact_or_fallback/_draw_contact_bands/_draw_contact_corner/_draw_bevel——逐字搬运,三处机械改写:`st.X`→裸成员名、`draw_X(...)`→`canvas.draw_X(...)`、`st.edge`→`rect.size.x`;公开入口一个 `draw_base(canvas: CanvasItem, rect: Rect2)`,其余私有。九函数现役零超标键(基线无其函数级键),搬运不改行数与分支=零新函数级键。
|
||||
- 常量随迁:FACADE_HIGHLIGHT_PX/FACADE_NEAR_FRAC/FACADE_FAR_FRAC/FACADE_NEAR_COL/FACADE_FAR_COL/PROJECTION_NEAR_COL/PROJECTION_MID_COL/PROJECTION_EDGE_COL/E_FACADE_FRAC 九个 D/E 档常量(本会话 grep 实查全仓零外部引用,宿主头注「绘制侧单点」句随迁改写)。UiKit.E_FACADE_FOOT_COL 是 UiKit 自己的成员,不动。
|
||||
- 素材槽位 tex_base 例外消费:迷雾记忆态画底纹(宿主 _draw_fog_memory)读 base.tex_base——公开成员读,单向、成文于宿主头注。
|
||||
|
||||
### 4.3 件 B:cell_mark_overlay.gd(格面标识与顶层叠加绘制件)
|
||||
|
||||
- 落点:`game/presentation/views/cell_mark_overlay.gd`;extends RefCounted;无 class_name。
|
||||
- 职责语句:格面标识与顶层叠加绘制域——变异标记/数字色牌与字形/奖励徽章/封印/路径点迹/焦点高亮/中立移除退色的全部绘制入参与绘制命令。
|
||||
- 单一变化原因:art-bible 标识与叠加层视觉规格(冻结④色牌/徽章金字/真视红框/悬停高亮/退色降档条款族)——「格面上标什么记号」变了改本件,不触底面与迷雾。
|
||||
- 成员:上表 4.1 行所列 13 个;八个守卫/非守卫 setter 体逐字(含 badge_glyph 的 glow mask 回引 `_owner._glow_layer`——头注在案的回引语义原样保留)。
|
||||
- 绘制命令:现宿主六个私有函数随迁——_draw_mutation_marks/_draw_glyph_layer/_draw_digit_plate/_draw_glyph/_draw_badge+_draw_overlay_layers 的 dot/hl/removed 三段。字形文字与色(glyph/glyph_color)是宿主冻结成员,作**参数**传入(`draw_glyph_layer(canvas, rect, glyph, glyph_color)`,4 参≤5);文字渲染单点化为本件公开方法 `draw_centered_text(canvas, rect, text, color, font_size)`(5 参合规),宿主迷雾记忆态复用它画记忆墨数字——零复制。
|
||||
- 拆出两个绘制入口的原因:迷雾(fog_state 宿主冻结成员)在原 _draw_overlay_layers 内部夹在 hl 与 removed 之间,宿主时序器在两入口之间插雾层——见 §6。
|
||||
|
||||
### 4.4 宿主保留面(10 成员)
|
||||
|
||||
- 职责语句:被动绘制壳——绘制时序器+视野迷雾域(fog_state 冻结成员+记忆态换装)+微光子件生命周期(_glow_layer/glow_group/_sync_glow_layer)+格件几何(edge/cell)+探针冻结面(glyph/glyph_color/plate)。
|
||||
- 单一变化原因:迷雾规格(art-bible §6.5)与格件节点生命周期。迷雾居基座与标识两件之上、又读件 A 的 tex_base 与件 B 的字体渲染——把它留在宿主是三域中唯一不产生跨件回引的落点。
|
||||
- 头注改写要点(S10 口径 ≤8 行、无日期、无链接):状态件句改为两件句;「探针直读冻结成员」清单照旧(glyph/fog_state/plate/glyph_color+_glow_layer);新增一句「hl_color/hl_visible/dot_visible/mutation_mark 探针读 u.face.*」。
|
||||
|
||||
### 4.5 宿主 _init 与建件
|
||||
|
||||
```
|
||||
const _BASE_LAYER := preload("res://presentation/views/cell_base_layer.gd")
|
||||
const _MARK_OVERLAY := preload("res://presentation/views/cell_mark_overlay.gd")
|
||||
|
||||
func _init() -> void:
|
||||
base = _BASE_LAYER.new(self)
|
||||
face = _MARK_OVERLAY.new(self)
|
||||
```
|
||||
|
||||
件侧 `func _init(owner: Node2D) -> void: _owner = owner`(S9 R3 对 _init 参数豁免——构造注入面形态自由)。每格三对象(Node2D+两 RefCounted)与现状每格两对象同量级;尾波卡 T1 的 `_build_cell_unit` 构建器里仍只有一处 `_CELL_UNIT.new()`,件在宿主 _init 内自建,不触发 allocation-in-loop 新键(该规则扫循环体内的 .new() 文本,构建器函数体不在循环体内)。
|
||||
|
||||
### 4.6 类型闸与头注义务
|
||||
|
||||
两个新件全量类型标注(S9 R1/R2/R3 同尺度);文件头 `##` 注释 ≤8 行、零日期、零链接、零变更叙事(S10);每件头注写职责语句与 _owner 回引语义(§2.1 精神——回引不是跨类信号,无信号成文义务)。
|
||||
|
||||
---
|
||||
|
||||
## 5. setter→重绘语义零变化论证(写入路径逐点对账)
|
||||
|
||||
原则:全部 setter 体逐字搬家或原位不动;改址只改 board_view 侧赋值表达式的路径段。queue_redraw 本身合帧(同帧多次申请一次重绘),时序逐字=写入点顺序不变。
|
||||
|
||||
### 5.1 board_view 写入面改址对照(行号 2026-10-29,T0 重核)
|
||||
|
||||
| 现写点 | 新写点 | 语义 |
|
||||
|---|---|---|
|
||||
| u.st.edge(:204/:251 写;:704/:891 读) | u.edge | 宿主 setter 体:原 `_owner._glow_layer`→`_glow_layer`、`_owner.queue_redraw()`→`queue_redraw()`——glow setup+重绘的执行序逐字等价(语句同、对象同、时机同) |
|
||||
| u.st.glow_group(:727/:768) | u.glow_group | 守卫 setter 调 _sync_glow_layer()(原经 _owner 转发,现直调——同一函数同一时机) |
|
||||
| u.st.cell(:250) | u.cell(或随待裁点 3 删除) | 无 setter,纯数据 |
|
||||
| u.st.bg_sb(:666) | u.base.bg_sb | 无 setter |
|
||||
| u.st.tex_base(:665) | u.base.tex_base | 无 setter |
|
||||
| u.st.outline_sides(:676 assign/:700 append) | u.base.outline_sides | 无 setter;**assign 保持数组引用语义**——件内成员同为一处 Array[int],引用不变 |
|
||||
| u.st.facade_south(:677/:690 写;:696 读) | u.base.facade_south | setter→queue_redraw 逐字;双写触发两次申请=现状同形 |
|
||||
| u.st.proj_band(:678/:704) | u.base.proj_band | 同上 |
|
||||
| u.st.tex_facade(:679/:709) | u.base.tex_facade | 无 setter |
|
||||
| u.st.facade_strip(:680/:708) | u.base.facade_strip | setter→queue_redraw 逐字 |
|
||||
| u.st.contact_bands/corners(:804/:805) | u.base.contact_* | 无 setter(整组引用换新) |
|
||||
| u.st.contact_col(:780/:787/:810/:816) | u.base.contact_col | 无 setter(_process 逐拍呼吸色) |
|
||||
| u.st.bevel(:253) | u.base.bevel | setter→queue_redraw 逐字 |
|
||||
| u.st.badge_glyph(:719/:726) | u.face.badge_glyph | setter:`_owner._glow_layer` mask+queue_redraw 逐字(回引体原样) |
|
||||
| u.st.dot_visible(:549/:554) | u.face.dot_visible | setter→queue_redraw 逐字 |
|
||||
| u.st.hl_visible/hl_color(:512–526/:534) | u.face.hl_* | setter→queue_redraw 逐字 |
|
||||
| u.st.tex_mutation/tex_glyph/tex_badge | u.face.tex_* | 无 setter |
|
||||
| u.st.tex_seal(:614/:618) | u.face.tex_seal | 守卫 setter 逐字(判重防覆盖语义是 case④b 回归断言的守护对象,禁动) |
|
||||
| u.st.treasure_mark/mutation_mark(:713/:723/:725) | u.face.*_mark | 守卫 setter 逐字 |
|
||||
| u.st.removed_dim(:737) | u.face.removed_dim | setter→queue_redraw 逐字 |
|
||||
| u.st.font(:185/:260) | u.face.font | 无 setter |
|
||||
| u.glyph/u.glyph_color/u.plate/u.fog_state | 不变 | 宿主冻结面 |
|
||||
| u.queue_redraw()(:738 终写) | 不变 | paint 尾部全格重绘申请原样 |
|
||||
|
||||
### 5.2 宿主内消费改址
|
||||
|
||||
- _sync_glow_layer:st.glow_group→glow_group、st.edge→edge、st.badge_glyph→face.badge_glyph(公开成员读);setup/set_badge_mask 调用序逐字。
|
||||
- _draw_fog_memory:st.tex_base→base.tex_base;字形重画改调 face.draw_centered_text(self, rect, glyph, UiKit.FOG_MEMORY_INK, maxi(18, int(ceil(edge * 0.5))))——同公式同字号(§7.4 冻结式)。
|
||||
- cell_rect_probe:u.st.edge→u.edge。
|
||||
|
||||
---
|
||||
|
||||
## 6. 绘制命令序零变化论证(golden 判据本体)
|
||||
|
||||
新宿主 _draw=六步时序器,命令序与现行四函数调用树**逐命令等价**:
|
||||
|
||||
```
|
||||
func _draw() -> void:
|
||||
var rect := Rect2(Vector2.ZERO, Vector2(edge, edge))
|
||||
base.draw_base(self, rect) # 原青 _draw_base_layer 整树(含描边/立面/投影/接触带/倒角与其补画序)
|
||||
face.draw_marks(self, rect) # 原青 _draw_mutation_marks
|
||||
face.draw_glyph_layer(self, rect, glyph, glyph_color) # 原青 _draw_glyph_layer+_draw_digit_plate+_draw_glyph+_draw_badge
|
||||
face.draw_overlay_under(self, rect) # 原青 _draw_overlay_layers 前两段(点迹+高亮)
|
||||
_draw_fog_layer(rect) # 宿主(原位不变——雾夹在 hl 与 removed 之间)
|
||||
face.draw_removed_dim(self, rect) # 原青 _draw_overlay_layers 末段(退色)
|
||||
```
|
||||
|
||||
等价性来源:①层间顺序=原 _draw 的四调用序+_draw_overlay_layers 内部序,一步未动;②件内顺序=九+六函数逐字搬运,`draw_*` 引擎调用全部经 canvas 参数落到同一 CanvasItem(宿主 self),命令流与命令参数逐位相同;③接触带回退路径(contact_col.a>0 时补画投影/E 墙面/接触带;elif bg_sb 路径补画立面/投影/倒角)整体在件 A 内部,补画序逐字;④浮点面:rect.size.x 与 st.edge 同值同源,推导式零改动。结论:绘制命令流逐位一致 ⇒ golden 三张差异 0.00% 可预期。
|
||||
|
||||
---
|
||||
|
||||
## 7. gdstyle 键账预期(逐文件,平面口径=声明数全计)
|
||||
|
||||
| 文件 | 类变量(阈值 15) | 公开方法(阈值 20) | 函数级键预测 |
|
||||
|---|---|---|---|
|
||||
| board_cell_unit.gd | 10(余量 5) | 6(5 setter+_draw) | 无——_draw 时序器约 10 行;_draw_fog_layer/_draw_fog_memory/_sync_glow_layer 原体(现役零键) |
|
||||
| cell_base_layer.gd | 12(余量 3) | 5(draw_base+4 setter) | 无——九函数逐字搬运,行数/分支/局部/返回不变,现役零键 |
|
||||
| cell_mark_overlay.gd | 13(余量 2) | 13(5 绘制入口+8 setter) | 无——同上;draw_glyph_layer 4 参、draw_centered_text 5 参(max-parameters 5=合规上限内) |
|
||||
|
||||
三件全无 inner class ⇒ 不受 §1.2 截断口径影响,预测值即闸实测值。余量最小 2(件 B)——后续 art-bible 加标记类成员的余量,恶化守卫(WORSENED)在位兜底。
|
||||
|
||||
---
|
||||
|
||||
## 8. 行为零变化风险点
|
||||
|
||||
1. **golden 三张(L1 dungeon/L2 underdark/L3 deep_underdark)**:判据=§6 命令流逐位一致;差异非零即停机呈报,禁换锚。最大实操风险=搬运时手误(常量值、rect 推导式)——对照表逐函数「逐字搬运」核对。
|
||||
2. **探针冻结成员**:glyph/fog_state/plate/glyph_color 宿主保留、名称路径零变化(ui_input case④b⑪⑮+player_copy wa8 断言零改动);hl_*/dot_visible/mutation_mark 探针改址四处(断言条件与期望值零变化,只改路径段——对照表申报行)。
|
||||
3. **绘制调用序**:见 §6——含「平色回退+微光并发的英雄格补画」这种跨层重复绘制路径,必须原样保形(重复无害是现行为的一部分)。
|
||||
4. **setter 双写时序**:_paint_cell 内 facade_south(:677/:690)、badge_glyph(:719/:726)、mutation_mark(:723/:725)的多写多触发序不变。
|
||||
5. **`_glow_layer` 生命周期**:宿主成员不动;glow_group/edge 上收后其 setter 直调宿主自有面——子件 add/free 时机零漂移(type_glow_shot_probe/type_glow_probe 断言面)。
|
||||
6. **潜伏红变量**:T0 先跑 ui_input_probe——若现状已红(§1.3 判定),红因与本设计无关但同批修复(改址四处);若绿(本会话对 GDScript 取索引语义判断有误),改址四处照做(新路径本就不同),结论记实现报告。
|
||||
|
||||
---
|
||||
|
||||
## 9. 验收载体建议(全部既有载体,零新增断言面)
|
||||
|
||||
| 载体 | 钉什么 |
|
||||
|---|---|
|
||||
| render_gate 棋盘 golden 三张 | 绘制命令流逐位一致(本批主判据;对拍差异 0.00%) |
|
||||
| ui_input_probe(probe_gate 默认段) | case①②③④b⑪⑭⑮——悬停/禁入/点迹/封印槽/字形回退/变异角标/迷雾直读面全链路 |
|
||||
| probe_gate --click(ui_click_probe) | dig/seal/chord 输入路径(hl 状态写入面的行为侧) |
|
||||
| probe_gate --full(type_glow_shot_probe/board_shot_probe/fx_probe) | 微光子件与格矩形取证面 |
|
||||
| run_all --only=player_copy,theme_projection,type_glow | u.plate/u.glyph_color 直读面+字形墨族+微光派生 |
|
||||
| run_smoke+run_system_test+static_scan(三件保险恒跑) | 启活面+真实玩法路径+S9/S10/S13 键账对账 |
|
||||
|
||||
批末跑 `tools/run_all_gates.sh --code`(改动全为代码面);改址探针断言与对应表申报同批落地。
|
||||
|
||||
---
|
||||
|
||||
## 10. 估时
|
||||
|
||||
| 段 | 内容 | 估时 |
|
||||
|---|---|---|
|
||||
| T0 | 读数复核(33 声明/30 闸账对账)+ui_input_probe 潜伏红一跑定谳 | 0.25–0.5 日 |
|
||||
| T1 | 建 cell_base_layer.gd(成员+九函数+九常量随迁) | 0.5–0.75 日 |
|
||||
| T2 | 建 cell_mark_overlay.gd(成员+六函数随迁+draw_centered_text 单点化) | 0.5–0.75 日 |
|
||||
| T3 | 宿主瘦身(时序器/雾/glow/edge/glow_group setter 上收)+board_view 写入面约 40 处改址 | 0.5 日 |
|
||||
| T4 | 探针改址四处+孤立验证(run_all 选档+probe_gate --click) | 0.25–0.5 日 |
|
||||
| T5 | 批末代码域全量闸+键账对账(10/12/13 实测核对) | 0.25–0.5 日 |
|
||||
|
||||
合计 2.25–3.5 工作日。出红只跑红件最小单元(闸机轮次纪律)。
|
||||
|
||||
---
|
||||
|
||||
## 11. 待裁点清单(呈主会话)
|
||||
|
||||
1. **潜伏红处置**:ui_input_probe 四处直读疑似已被迭代 41 打断(§1.3)。方案=本设计批内改址 u.face.* 并 T0 实跑定谳;若用户希望不等本批,可先走最小工程批把四处改 u.st.* 恢复(后续本批再改一次)。取哪个时序,裁。
|
||||
2. **与尾波清偿卡的编排关系**:尾波卡 T1 把 _paint_cell 拆五段(传值句写明「经 u.st/glyph/digit_col」)。本设计改变状态件路径名——同批编队时 T1 段函数传值句改指 u.base./u.face.(T0 对账自然兜住);先后皆可,同批省一次 golden 全套。取哪个编队,裁。
|
||||
3. **cell 成员去留**:全仓零读方(写入仅 rebuild:250)。删除=真实削减+§1.1-⑤ 无效成员归零;保留=「诊断观测面」注释语义。本设计倾向删(宿主降为 9),删/留,裁。
|
||||
4. **gdstyle 截断口径的登记**:§1.2 发现属工具行为事实(基线欠估、工具升级可能翻键),建议经反哺点通道在 gdstyle_gate 头注或审计报告补一句注记(工程改动,防后人按「均匀展平」误判键账)。落不落、落哪里,裁。
|
||||
|
||||
---
|
||||
|
||||
## 12. 把握度声明
|
||||
|
||||
把握最低的一点:**潜伏红判定**——它建立在「GDScript 外部实例读不到 inner class 成员」这一语义判断与时间线推断上,本会话禁跑测试无法实证,T0 一次 ui_input_probe 即可证实或证伪;即便误判(现状可读),设计本身不受影响(改址四处照做,冻结四面照留)。次低:gdstyle 截断口径系两点反推(30=6+24、19=6+13 双双精确吻合),未读工具源码;设计不依赖该口径——三文件平面化后预测=实数。
|
||||
@@ -1,183 +0,0 @@
|
||||
# 设计——战斗编排类变量归约(S13 真修复方案)
|
||||
|
||||
> 设计讨论段过程稿 v1.0——待主会话汇总裁决(2026-10-29)。输入=用户裁定「不允许任何豁免:battle_orchestrator.gd 的 max-class-variables 必须真实修复到阈值 15 内,architecture S13 豁免登记第三条注销」。读者=主会话(裁决)与后续写卡段(转需求卡片)。
|
||||
|
||||
## 结论
|
||||
|
||||
宿主 38 个类变量经「BoardInstaller 已定稿退役 1 + 两枚新件收编 19 + 库存注入改址 1 + 攻基线快照转派生读 1」收敛到 **15(=阈值,合规)**。两枚新件:RoundCycle(轮循环驱动件——五段段件持有、段序执行、结算重入门闸、开轮摇号、踩雷计数账)与 BattleFacts(战斗事实件——受理事实、轮 facts 缓冲、封印判定账、装板溯源、条件计数、同调装配快照)。已实装两拆件 BattleFxHost/RewardGrant 与五段段类构造、呈现层、A2 订阅面、封闭流全部零触碰或仅改指。
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标形态——battle_orchestrator 改后保留什么
|
||||
|
||||
宿主保留的是「编排」本身,全部在 architecture「战斗编排域拆件定稿」第 1 款的在册职责面内(attune 一款按本文件第 5 节重裁决为「状态归事实件、行为留宿主」):
|
||||
|
||||
1. **状态机与生命周期**:`begin_battle` 受理四段序列(受理/装板/运行态/预告经济)、`_exit_distribution` 轮间转移、`_battle_over` 终局序列、`battle_result` 与 `_fatal` 唯一写点、`round_index` 轮时钟。
|
||||
2. **A2 三事件订阅与事件处理**:三条 connect 留 `_init`(订阅面逐字);`_on_cell_revealed`(旁路守卫→积点自动兑付触发→身份快照捕获→缓冲追加)、`_on_seal_judged`、`_on_round_end` 三个处理器留宿主——它们是多件协作的编排判断点,不是纯缓冲。
|
||||
3. **行发射基建**:`_emit_row`/`_assert_row_source`/`_fatal`+SOURCE_EXEMPT 两常量词表——协议面单点,零迁移。
|
||||
4. **呈现投影**:`presentation_snapshot`/`diagnostic_snapshot`/`_emit_settlement_snapshot` 三出口——签名与载荷逐字不变,内部读数改指两件投影。
|
||||
5. **刷新面**:`can_refresh`/`player_request_refresh`。
|
||||
6. **attune 编排读数与触发面**(重裁决后):`attune_has`/`attune_param_sum`/`attune_convert_state`/`_attune_charge_safe_row`/`_reseed_attune_charges`/`_hook_attune_consume`/`_attune_safe_seen_read`/积点自动兑付体——读数出口与外部面零改址(见第 5 节)。
|
||||
7. **账本读面**:`_journal`/`_attune_loadout`/`_battle_hooks` 三派生读与回调束。
|
||||
8. **装板薄壳**:`_install_and_reset`(轴丙定稿形态——五处计数清零、板序推进、board_changed 发射、叠加层退役,时序逐字)。
|
||||
9. **B2/B3/B4 协作者持有**:S7「唯一调用方=B1 域文件集」的承载面。
|
||||
|
||||
搬出去的只有两类东西:**轮结算周期的推进机构**(谁持有段件、按什么顺序跑、开轮怎么摇号、重入怎么挡——归 RoundCycle)与**发生过什么与本战是什么的记录**(事实账——归 BattleFacts)。两件的职责语句与单一变化原因见第 3、4 节。
|
||||
|
||||
## 2. 逐成员去向对账表(38 项)
|
||||
|
||||
| # | 成员 | 去向 | 依据(一句话) |
|
||||
|---|---|---|---|
|
||||
| 1 | db | 留宿主 | B1 跨系统调用权的表读取面,宿主级协作者 |
|
||||
| 2 | rng | 留宿主 | encounter/gp_drop 两封闭流在宿主函数体内,behavior_roll 随摇号件经 oc 取用 |
|
||||
| 3 | _board_generator | **随 BoardInstaller 退役** | 轴丙已定稿(v1.24):实例随件自建自接线 |
|
||||
| 4 | minesweeper | 留宿主 | A2 订阅面+HUD 公有消费面(API Boundaries 在册)双锁定 |
|
||||
| 5 | action_economy | 留宿主 | A3 回发面+HUD 公有消费面双锁定 |
|
||||
| 6 | _enemy_system | 留宿主 | B2 生命周期(spawn/despawn)与三快照读源 |
|
||||
| 7 | _status_effects | 留宿主 | B3 开域/闭域与三快照读源 |
|
||||
| 8 | _reward_economy | 留宿主 | B4 恰一次 roll/retire 编排+set_treasure_unlocked/query_reward_identity 两外部代理 |
|
||||
| 9 | treasure_inventory | **退役改址** | 唯一外部注入点 level_runner:520 改经 `reward_grant()` 出口直注(RewardGrant 在册成员);宿主与授予段读面改指 grant |
|
||||
| 10 | _damage | 留宿主 | 单据管线接线(fx_calls/inject)与 AC 基线注入时序锁定在受理段内 |
|
||||
| 11 | _fx_host | 留宿主 | 组件出口 `fx_host()`——定稿在册取件面 |
|
||||
| 12 | _reward_grant | 留宿主 | 组件出口 `reward_grant()`+库存持有者+escrow 读源 |
|
||||
| 13 | encounter | **BattleFacts** | 本战受理事实(打什么、带什么进来)——与过程事实同一记录口径 |
|
||||
| 14 | round_index | 留宿主 | 轮时钟;system_test 等四套件约 15 处 `settlement.round_index` 公有直读面,零改址 |
|
||||
| 15 | battle_result | 留宿主 | 状态机终局态;_fatal/_battle_over 唯一写点归属不变 |
|
||||
| 16 | _facts_reveals | **BattleFacts.reveals** | 轮 facts 缓冲 |
|
||||
| 17 | _facts_seals | **BattleFacts.seals** | 封印判定批缓冲 |
|
||||
| 18 | _facts_path | **BattleFacts.path** | 轮末路径事实 |
|
||||
| 19 | _settling | **RoundCycle._settling** | 结算重入门闸——与段序执行同一单元 |
|
||||
| 20 | _grant_seg | **RoundCycle** | 五段段件持有归驱动件(定稿「段序编排+接线」的代码承载) |
|
||||
| 21 | _aura_seg | **RoundCycle** | 同上 |
|
||||
| 22 | _combat_seg | **RoundCycle** | 同上 |
|
||||
| 23 | _decay_seg | **RoundCycle** | 同上 |
|
||||
| 24 | _verdict_seg | **RoundCycle** | 同上 |
|
||||
| 25 | _refresh_used_this_round | **BattleFacts.refresh_used** | 本轮刷新计数=过程事实(复位点=出口分发,语句随迁) |
|
||||
| 26 | _board_seq | **BattleFacts.board_seq** | 装板溯源事实 |
|
||||
| 27 | _board_from_midround_refresh | **BattleFacts.board_from_midround** | 装板 provenance(清图奖励守卫读源) |
|
||||
| 28 | _seal_consumed | **BattleFacts.seal_consumed** | 封印兑付资格账(install 重置) |
|
||||
| 29 | attunement | **BattleFacts.attunement** | 本战装配集快照=受理事实(enc.attunement 携带) |
|
||||
| 30 | _mines_hits | **RoundCycle.mines_hits** | 摇号条件账——转存语句本就在 `_roll_round_actions` 轮末,随摇号件走 |
|
||||
| 31 | _attune_safe_seen | **BattleFacts.attune_safe_seen** | 积点计数=过程事实 |
|
||||
| 32 | nest_preview_count | 留宿主 | 冻结外部直读面(main.gd×2+treasure_effects_test×1)零变化 |
|
||||
| 33 | _feat_first_dig_used | **BattleFacts.feat_first_dig_used** | 条件事实计数(魔矢每战首次) |
|
||||
| 34 | _seal_miss_seen | **BattleFacts.seal_miss_seen** | 标错去重账 |
|
||||
| 35 | _perfect_hit_true | **BattleFacts.perfect_hit_true** | 完美封印三账(契约 2 写口归件,见第 4 节) |
|
||||
| 36 | _perfect_hit_false | **BattleFacts.perfect_hit_false** | 同上 |
|
||||
| 37 | _perfect_forgiven | **BattleFacts.perfect_forgiven** | 同上 |
|
||||
| 38 | _hero_atk | **退役→派生读函数** | `_hero_atk()` 派生读(`encounter.get("hero_atk", 表值)`)——`_journal()`「读面即引用、无第二账」同款先例;E4 收口语义不变(encounter 受理后只读,派生值恒等) |
|
||||
|
||||
**宿主改后 15 项**:db、rng、minesweeper、action_economy、_enemy_system、_status_effects、_reward_economy、_damage、_fx_host、_reward_grant、round_index、battle_result、nest_preview_count、_rounds、_facts。
|
||||
|
||||
## 3. 新件一:RoundCycle(轮循环驱动件)
|
||||
|
||||
- **文件落点**:`game/core/settlement/round_cycle.gd`(与五段段件同目录——它是段件的序主人)。
|
||||
- **extends**:RefCounted(fx_host/reward_grant/段类同款;随编排器每战新建同灭)。
|
||||
- **职责语句**:每轮结算周期的唯一驱动——结算重入门闸(settling)、五段段序执行(段序骨架冻结于 SettlementTable.segment_order)、开轮摇号(共识点 B:技能选择前置到轮次开始,摇定即本拍结算的选技)、踩雷计数账(转存时点=摇号轮末)。
|
||||
- **单一变化原因**:轮结算周期的推进结构(段序、重入闸、摇号时序)。
|
||||
- **类变量(8 ≤ 15)**:`oc`(宿主,段类同款直调形态)、`_grant_seg`、`_aura_seg`、`_combat_seg`、`_decay_seg`、`_verdict_seg`、`_settling`、`mines_hits`({"total","last","round"} 三读数合一账)。
|
||||
- **公开方法(3 ≤ 20)**:`settle_if_due()`(=原 `_maybe_settle` 三闸+`_settle` 段序体合体)、`roll_round_actions()`(原函数逐字迁入)、`is_settling()`(diagnostic_snapshot 读投影)。
|
||||
- **行数估算**:约 120 行(头注+成员+四函数)。
|
||||
- **耦合边界**:
|
||||
- `_init(host, fx_host, reward_grant)`——3 参不触发 max-parameters,无需引用束;五段构造五行从宿主 `_init` 逐字搬入。
|
||||
- 段类对宿主的直调形态不变(定稿在册:「段类经宿主引用直调,现状形态」);驱动件经 `oc` 取 facts/协作件/行发射/出口分发,与段类同款。
|
||||
- **VerdictSegment 零改动**:`_exit_distribution` 留宿主(轮间转移=宿主生命周期域:换图编排、notify、轮始发射),判定段仍直调 `oc._exit_distribution()`——不产生段类对驱动件的新引用,不新增 RefCounted 引用环。
|
||||
- 随机只经 `oc.rng` 的 behavior_roll 封闭流(流名、开流时点、取号序逐字);零 await。
|
||||
- **宿主侧变化**:`_on_round_end` 末行改调 `_rounds.settle_if_due()`;`begin_battle` 与 `_exit_distribution` 的 `_roll_round_actions()` 改调 `_rounds.roll_round_actions()`;`_maybe_settle`/`_settle`/`_roll_round_actions` 三函数从宿主删除。
|
||||
|
||||
## 4. 新件二:BattleFacts(战斗事实件)
|
||||
|
||||
- **文件落点**:`game/core/battle_facts.gd`。
|
||||
- **extends**:RefCounted。
|
||||
- **职责语句**:战斗事实的唯一记录面——本战受理事实(encounter:打什么、带什么进来)、同调装配事实(attunement)、轮 facts 缓冲(reveals/seals/path)、封印判定账(去重两集+完美三账)、装板溯源(seq/provenance)、条件事实计数(refresh_used、feat_first_dig_used);自带轮复位与完美账写口。
|
||||
- **单一变化原因**:战斗事实的记录与查询口径——内容批新增触发条件事实/判定账只落此一处。实证:`_feat_first_dig_used`(魔能共鸣)、`_seal_miss_seen`(危险直觉)、`_mines_hits`(触发条件面)、enc 的 feats/tree_rules/voucher 携带键,全部由内容批按同一节奏累加。
|
||||
- **类变量(15 ≤ 15,贴顶)**:`encounter`、`reveals`、`seals`、`path`、`refresh_used`、`board_seq`、`board_from_midround`、`seal_consumed`、`seal_miss_seen`、`perfect_hit_true`、`perfect_hit_false`、`perfect_forgiven`、`feat_first_dig_used`、`attunement`、`attune_safe_seen`。
|
||||
- **公开方法(5 ≤ 20)**:`reset_round()`(原 `_reset_round_facts` 逐字——只清 reveals/seals/path 三项,**不碰 refresh_used**:_battle_over 后快照读到的 refresh_used 必须保持末轮值)、`mark_perfect_hit()`/`mark_perfect_miss()`/`mark_perfect_forgiven()`(契约 2 写口:`_perfect_hit_false` 纯净禁回退改写的执行点从段类纪律升级为账本单点)。其余一律公有成员直读写(段类/快照/宿主经 `oc._facts.X` 改指——fx_host._fx_bonus_delta 跨件直读写同款现状形态)。
|
||||
- **行数估算**:约 80 行。
|
||||
- **耦合边界**:**零注入引用、零信号、零协作对象调用**——纯数据+谓词+写口;缓冲写入点在宿主 A2 处理器(订阅面锁宿主),身份快照捕获(query_full_snapshot)留宿主 `_on_cell_revealed`(fact 件不持 B4 引用,防它变成第二编排面)。
|
||||
- **成员冻结义务**:15/15 贴顶——实现期禁增员,增员即停卡。预留扩容阀:下一张要加事实成员的卡,先把封印判定账五成员二次拆出(SealLedger,−5)再落新账,禁硬挤。
|
||||
|
||||
## 5. attune 族重新裁决(architecture「原位保留」句的废止建议)
|
||||
|
||||
**建议:部分改裁——状态两成员归 BattleFacts,行为函数留宿主。** 理由四条:
|
||||
|
||||
1. **原位裁的前提已消失**:该句是迭代 39/40 两批的防冲突临时裁,原文自认「本波残留债归尾波」;两批均已合回,本波即尾波,且用户已裁「不允许任何豁免」打开重裁通道。
|
||||
2. **状态是事实,行为是编排**:`attunement`=本战装配了什么(enc.attunement 受理携带的快照,受理后只读)、`attune_safe_seen`=本战安全开格积点——两者都是战斗事实,归账本件名正言顺。而参数合计(装配集行扫描)、积点自动兑付(何时 grant_ap=编排决策)、充能重置触发、呈现进度读数——这些是 B1 编排面的读数与触发,与 `_fx_host_fact` 同位的宿主读数形态,留在宿主不违职责语句。
|
||||
3. **外部面零改址**:`attune_has`(断点续玩测试×2+表结构守卫×2)、`attune_param_sum`(main.gd 授予段两处+treasure_effects_test)、`attune_convert_state`(treasure_interact_controller 取值回调)全部留宿主公有面——main.gd 与 treasure_interact_controller 本批零改动。若整体拆成 BattleAttune 新件,这三面约 10 处消费点全要改址(组件出口或转发壳),收益只是把 8 个读数函数换个文件——判据③(阈值动机)嫌疑大于内聚收益。
|
||||
4. **不并进 AttuneLoadout**:那是营地/冒险域的充能与装备集物化单源(迭代 39 已闭合契约);把战斗域读数插进去会重开已闭合边界。BattleFacts 持有的只是快照与计数,充能物化仍全归 AttuneLoadout(`_reseed_attune_charges`/`_hook_attune_consume` 经调用点传 loadout/treasure 委派,宿主侧单点不变)。
|
||||
|
||||
## 6. 已否决的方向(为什么不是别的切法)
|
||||
|
||||
1. **协作者引用束归袋**(任务提示①的直译形态):db/rng/units/statuses/reward_economy 等 11 个协作者句柄若收进一个「引用束」对象,宿主 150+ 处 `db.`/`oc._enemy_system.` 全部换名——零内聚收益的纯改名,命不出领域名字=凑计数袋(拆分判据②红)。引用束先例只用于新件 `_init` 防参(本批两新件参数均 ≤3,未触发)。
|
||||
2. **attune 整体拆件(BattleAttune)**:宿主 14 基数+3 句柄=16 不可达;且如第 5 节理由 3,外部三面 10 处改址换不来职责改善。
|
||||
3. **encounter 留宿主**:宿主 16 超阈。备选砍口只剩两处——nest_preview_count 解冻迁 facts(违背任务给定冻结面)或 _reward_economy 经 RewardGrant 中转(B4 mapping 生命周期与代理面挂到授予件名下=所有权失真)。encounter 归事实件是唯一不破冻结面、不失真的砍口;它也是本方案最弱的一格,见待裁点 1。
|
||||
4. **四件以上碎片化**:每多一件付一个宿主句柄;封印判定账、装板溯源单独成件都撑不起独立变化原因,且把宿主推向 16+。
|
||||
5. **_exit_distribution 迁入驱动件**:判定段须改持驱动件引用(RefCounted 环+段类构造变化),换图编排又是宿主生命周期语义——收益不抵风险,否。
|
||||
|
||||
## 7. 随迁键收敛义务
|
||||
|
||||
**基线实证**:`tools/gdstyle_baseline.txt` 中 battle_orchestrator.gd 现仅两条类级键(max-class-variables=38、max-file-length=1035),**零函数级键**——59 个函数全部在默认阈值内(长度≤50/分支≤8/局部≤10/返回≤6/参数≤5)。函数级指标是函数体内在属性,逐字迁移(仅引用改指)不产生新键。据此:
|
||||
|
||||
- **随迁键清单:预计零条**。义务改为「迁移函数逐字纪律」:`roll_round_actions`(45 行/分支≈8 贴线)、`settle_if_due`、`reset_round`、三个 mark 方法——迁移与改指**禁顺手增分支/局部**;确需增条件即停手核对 gdstyle,超线在卡内拆助手函数收敛(先例=迭代 40 卡①的 12 随迁键收敛)。
|
||||
- 新增小函数全部远在阈值内(最长 `roll_round_actions` 45 行;新件 `_init` 参≤3)。
|
||||
- 两新件与改址后的宿主、段类落地后跑 `python tools/gdstyle_gate.py` 预检一次再进批末闸。
|
||||
|
||||
## 8. 行为零变化风险点与对策
|
||||
|
||||
1. **RNG 取号序**:宿主三封闭流——encounter(`_begin_battle_dice`,留宿主)、gp_drop(`_roll_gp_drop`,留宿主)、behavior_roll(随 `roll_round_actions` 迁 RoundCycle——流名与开流时点逐字,只经 `oc.rng`)。fx_reveal(fx_host 内零触碰)、board_gen/variant_place(BoardInstaller 已定稿随件)。对策=同种子完整局对拍(见第 9 节 PARITY)。
|
||||
2. **信号契约**:五信号(step_row/battle_finished/round_started/board_changed/settlement_snapshot)全留宿主;发射语句零迁移——`round_started.emit` 在 begin_battle/`_exit_distribution` 内原位,仅 round_index 读源不变;A2 三 connect 逐字。发射时序零变化。
|
||||
3. **段类接线**:五段构造参数与持有形态不变(grant/combat 三引用、aura/decay/verdict 单引用);verdict 段零改动(`_exit_distribution` 留宿主)。段内约 25 处 `oc._X` 改指 `oc._facts.X`/`reward_grant.treasure_inventory`——调用点改指、禁转发壳(定稿同款纪律)。
|
||||
4. **_fatal 与 battle_result 唯一写点**:留宿主;BoardInstaller(已定稿 fatal Callable)、RoundCycle/段类(经 oc 直调)零改形。
|
||||
5. **结算时序**:`settle_if_due` 三闸顺序(settling→battle_result→phase)与「终局不回置 _settling、_battle_over 接管」早退语义逐字;判定段内 `_exit_distribution`→回置 `_settling` 的先后不变(出口留宿主保证);`reset_round` 不碰 refresh_used(_battle_over 后快照的 refresh_used 必须保持末轮值——这是本轮盘点抓出的一处险点)。
|
||||
6. **重入语义**:`_on_cell_revealed` 不设 settling 守卫(现状——flush_pending_reveals 的 fx_reveal 事件依赖 reveal_busy 旁路闸而非 settling),处理器体零改形;install 初始展开事件「先缓冲后清除」路径(begin/exit 两处 reset_round)保持。
|
||||
7. **快照逐字**:三快照字段名、嵌套结构、值口径逐字——读数改指投影后值恒等(round_index/attune_safe_seen/perfect 三账/hero_atk 派生读均受理后不变量)。
|
||||
8. **装板薄壳时序**:轴丙定稿五处清零→板序推进→board_changed 发射→叠加层退役的顺序逐字(成员改指 facts 不改序);BoardInstaller 闭合设计的 bundle 键「encounter」传 `_facts.encounter`——同一字典引用,零冲突。
|
||||
|
||||
## 9. 验收载体与判据
|
||||
|
||||
改动—验收对照表(卡内落六列)建议主行:
|
||||
|
||||
| 需求点 | 真实入口 | 载体 | 判据绑定面 |
|
||||
|---|---|---|---|
|
||||
| 行为零变化(本批总判据) | 真实局 begin_battle→挖掘→结算→终局 | **PARITY 同种子完整局对拍**(parity_anchor/parity_compare) | step_row/settlement_snapshot 逐位一致;**实跑须用户批准、禁重锚**(battle_orchestrator.gd 触 PARITY_TOUCH_FACES) |
|
||||
| 段序与重入门 | stop→WAITING→settle_if_due | round_flow_skill_pool_test、settle_segments_test(真实一轮走段序,零改址应绿) | 五段裁定行序、settling 闸、终局早退 |
|
||||
| 开轮摇号迁移 | begin_battle/出口分发→roll_round_actions | round_flow_skill_pool_test(技能池/保底/冷却)+trigger_cond_test(mines_hits 账——3 处读改指 _rounds) | 同种子摇定结果逐位、转存读数 |
|
||||
| 封印判定账迁移 | 封印动作→结算 | seal_polarity_test(4 处 perfect 直写改指)、feat_vouchers_test(8 处+_grant_seg 改指)、meta_progression_forge_test(契约 12 守侧) | 完美三账读数、去重闸、契约 2 计数纯净 |
|
||||
| 装板 shell/溯源 | begin/refresh/exit 装板 | variant_placement_test(零改址应绿)+seal_polarity_test provenance 守卫 | 刷新图不发清图奖励、board_seq |
|
||||
| attune 面零改址 | 装配起战→读数/兑付 | treasure_effects_test、breakpoint_resume_test、table_structure_guard_test(**应零改址全绿**——本批最硬的「外部面零变化」证) | attune_has/param_sum/convert_state/积点兑付 |
|
||||
| 受理事实迁移 | begin_battle(enc) | adventure_feats_test、meta_progression_forge_test(encounter 4 处改指) | enc 携带键贯通 |
|
||||
| 快照逐字 | presentation/diagnostic 出口 | system_test+对拍 | 载荷 schema 与值逐字 |
|
||||
| 库存注入改址 | level_runner 建战注入 | treasure_effects_test 秘宝使用链 | use_treasure 受理面 |
|
||||
|
||||
配套义务:①三件保险恒跑(冒烟/系统测试/静态扫描)+上表关联套件(02 关联档);②静态扫描随批增行——RoundCycle 进 S7 B1 域文件集与 S8 await 文件集(经 oc 调 B2/B3/B4 符号落在该文件),BattleFacts 零协作调用不入两清单;③新文件全类型标注(S9)、头注按 §1.4.1;④本批零数值改动,MC 零跑。
|
||||
|
||||
## 10. gdstyle 键账预期
|
||||
|
||||
| 文件 | 类变量 | 公开方法 | 长度 | 预期键 |
|
||||
|---|---|---|---|---|
|
||||
| battle_orchestrator.gd | **15**(38→15) | 14 | ~830 | **两条基线键全消失**(类变量/文件长双双回落阈值内),零新键 |
|
||||
| settlement/round_cycle.gd | 8 | 3 | ~120 | 零键 |
|
||||
| battle_facts.gd | 15(贴顶) | 5 | ~80 | 零键(15=阈值内合法,fx_host「14≤15」同口径) |
|
||||
| settlement/grant_segment.gd | 3(不变) | — | +~2 行改指 | 零键 |
|
||||
| 其余段类/fx_host/reward_grant | 不变 | 不变 | 不变 | 零键、零 diff |
|
||||
|
||||
基线处理:`--refresh` 人工重生成;全基线 16 条消失 2 条(−12.5%>10% 骤降守卫)→ 须 `--force` 显式确认,属正常还债缩基线。architecture S13 豁免登记第三条随批注销(反哺点,实现批禁写 design/)。
|
||||
|
||||
## 11. 改址盘点(触面清单)
|
||||
|
||||
- **产品码**:battle_orchestrator.gd(主改——成员改指+三函数迁出+hero_atk 派生化+头注指址改写);settlement/round_cycle.gd、battle_facts.gd(新建);grant_segment.gd(~25 处改指);combat_segment.gd(2 处);level_runner.gd(1 行——库存注入改经 `reward_grant()` 出口);aura/decay/verdict、battle_fx_host、reward_grant、damage_controller、main.gd、treasure_interact_controller、board_installer(**零改动**)。
|
||||
- **测试**:feat_vouchers_test(~13)、meta_progression_forge_test(~8)、seal_polarity_test(~8)、trigger_cond_test(3)、round_flow_skill_pool_test(1)、adventure_feats_test(1)、treasure_effects_test(1——`ob14.attunement` 改指);settle_segments_test、roll_multiplier_test、system_test、breakpoint_resume_test、table_structure_guard_test(零改址——attune 面与 round_index 面不动的直接受益者)。
|
||||
- **probes/sim**:零触碰(盘点无命中)。
|
||||
- **闸件数据**:gdstyle_baseline.txt(--refresh --force)。
|
||||
|
||||
## 12. 估时
|
||||
|
||||
**2–3 个工作日**:实现(两新件+宿主改址+段类改址+测试改址)1.5–2 日;验收(关联档回归+PARITY 批跑+对照表与审计配合)0.5–1 日。PARITY 实跑须用户在场批准(不占卡估时);基线 refresh 属批内闸步骤。
|
||||
|
||||
## 13. 待裁点清单
|
||||
|
||||
1. **encounter 归战斗事实件**(本方案最弱一格):受理参数与过程记录同件,变化理由按「战斗事实面扩展」归一(第 4 节实证),但确与事实缓冲不同复位节奏(encounter 随战、facts 随轮)。若否决:宿主 16,只剩两条砍路——nest_preview_count 冻结面解锁(外部读面 3 处改址)或 _reward_economy 经授予件中转(所有权失真),两者都更差,届时按判据④停卡呈报。
|
||||
2. **treasure_inventory 注入面改址**:唯一外部产品码触面(level_runner 一行改经组件出口直注),拆件定稿「外部赋值路径零改址」句随本批失效,需追认。
|
||||
3. **attune 重裁决幅度**:推荐「状态归 facts、行为留宿主」(第 5 节);备选「整体拆 BattleAttune」因宿主 16 不可达已被排除——即本条实际是确认推荐案或否决整个方向。
|
||||
4. **完美账写口升级**:grant_segment 三处直写改经 facts 三方法(契约 2 单点执行)——推荐采纳;若求最小 diff 可退直写(现状纪律同款),卡内裁量。
|
||||
5. **PARITY 对拍批准**:battle_orchestrator.gd 触 PARITY_TOUCH_FACES,实跑对拍须用户点头、不重锚。
|
||||
@@ -1,210 +0,0 @@
|
||||
# 设计——测速循环去 await(S13 `tune_sim_controller` await-in-loop 键真实消除)
|
||||
|
||||
状态行:设计讨论段过程稿 v1.0——待主会话汇总裁决(2026-10-29)。
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
用户 2026-10-29 裁定「不允许任何豁免」:S13 静态质量闸(gdstyle)的裸键 `game/presentation/tune_sim_controller.gd|quality/await-in-loop|'await' used inside a loop` 必须真实消除;architecture「测试与质量域」S13 测量面豁免登记(2026-10-27,理由=「循环内 await 是调参测量的 wall-clock 步进承载语义——重构即测量口径漂移」)随之注销(注销落文走反哺点通道,实现批禁直改 architecture)。
|
||||
|
||||
本设计回答一件事:**把「循环内 await 逐帧让出」换成信号驱动形态后,测量语义是否逐点等价**——每步恰占一帧、每步执行相位不变、终止与读数不变、输出逐字不变。结论先行:**可行,推荐 process_frame 信号连接+步进状态机形态**;等价性四判据三条可严格证明并可用双实现对拍执行化验证,一条(脚本错误中断路径)无法严格证明、列为已声明缺口。
|
||||
|
||||
## 2. 现状全解
|
||||
|
||||
### 2.1 测速循环逐句流程
|
||||
|
||||
现码 `run(n)`(`game/presentation/tune_sim_controller.gd:36-52`):
|
||||
|
||||
| 步 | 语句 | 做什么 |
|
||||
|---|---|---|
|
||||
| 1 | `_running = true` | 控制器运行态(组合根 `_start_debug_levels` 互查守卫的判据) |
|
||||
| 2 | `PlaytestLogger.new()`+`start_session(SEED_BASE)` | 开共享 JSONL 会话(一文件多局,`log_run` 行带种子切分局次) |
|
||||
| 3 | `panel.set_sim_running(true)` | 浮窗运行态(`DebugOverlay.st._sim_running`——模拟钮置灰+探针守卫环判据) |
|
||||
| 4 | `set_sim_progress("模拟中:0/n …")` | 进度串 |
|
||||
| 5 | 建 `stats` 六键束、取 autoplay 驱动 | 测量桶与策略驱动 |
|
||||
| 6 | 循环体:`_run_one_level(...)` | 单局全量模拟(`level_autoplay.run_level` 静态同步函数——自建 RngService、种子=SEED_BASE+i,逐局确定可回放)→ 四桶记账 |
|
||||
| 7 | `set_sim_progress("i+1/n")` | 进度串 |
|
||||
| 8 | `await panel.get_tree().process_frame` | 每局恰让出一帧(命中键的语句) |
|
||||
| 9 | 循环尽:`close_session()`+`set_sim_report(...)` | JSONL 收口+报告注入(文案归 `HudPresenter.tune_sim_report`,零触碰) |
|
||||
|
||||
读数本质:`stats` 六键与报告是 **(种子, atk_pct, hp_pct) 的纯函数**——帧时点不进测量值(`run_level` 不读 wall-clock)。豁免登记所保护的「测量语义」是运行姿态:每局之间恰隔一帧 process_frame 发射(进度可见、窗口不僵死),以及 run 全程的运行态语义。本设计保的就是这个姿态。
|
||||
|
||||
### 2.2 读数消费链
|
||||
|
||||
- 报告文案:`tune_sim_report(stats)` → 浮窗 RichTextLabel(`set_sim_report`);探针 ⑤ 断言「关卡完成率/关卡完成剩余 HP 均/败北节点/N=10」四串。
|
||||
- JSONL:`user://logs/playtest_*.jsonl`,由未触碰的 `level_autoplay` 逐行写;`close_session` 时点随收尾帧。
|
||||
- 运行态:`panel.set_sim_running` → 浮窗模拟钮置灰;`_running` → 组合根两层调试入口守卫。
|
||||
|
||||
### 2.3 断言面盘点与一处静态矛盾(潜伏红——本设计的关键发现)
|
||||
|
||||
两个在库断言面钉死了 run 生命周期的语义:
|
||||
|
||||
1. **单元套件 `standee_fx_sweep_test.gd`〔wd8〕**(`game/tests/unit/presentation/standee_fx_sweep_test.gd:126-134`):假驱动在**每一局** `run_level` 回调内读 `ctrl.is_running()`,断言 `drv.seen == [true, true]`(两局读数都真);收尾断言 `is_running()` 假+`panel.running` 假+报告非空;且用 `await ctrl.run(2)` 驱动——**run 必须保持可等待(协程),await 它须挂起到整批完成**。
|
||||
2. **探针 `ui_tune_probe.gd` ⑤**(`game/probe/ui_tune_probe.gd:67-83`):按下模拟钮后以 `while debug_overlay.is_running()` 守卫环逐帧等——**语义=浮窗运行态贯穿整批**,环退出后断言输出含报告四串。
|
||||
|
||||
静态推演现码:`_run_one_level` 尾部两行(`panel.set_sim_running(false)`/`_running = false`,:67-68)**每局执行一次**——首局完成即把两个运行态置假。后果:
|
||||
|
||||
- wd8 首断言实测必得 `[true, false]` → 红;
|
||||
- 探针 ⑤ 守卫环在按下返回后立即退出(首局在按下同一同步段内已跑完)→ 输出停在进度串 → 四条输出断言全红。
|
||||
|
||||
推断:这两行原本在循环**之后**(run 收尾单次执行),是「循环体提函数」(run() 局部变量 11→10 清偿批,2026-10-26 审计在案该键)搬运时被卷入提取体——wd8 写于 d8 批且当时必绿,可反证。两断言面均不在近期批次的关联档选测覆盖内(套件名与文件名无字面关联、probe_gate --full 非恒跑三保险),潜伏红未暴露。**T0 义务:实跑 standee_fx_sweep 单套件+probe_gate --full 复核现状**(本设计零测试执行,此判断待实跑确认)。
|
||||
|
||||
推论:本批若逐字保留现行为,wd8 与探针 ⑤ 必红、批不可绿。**本设计按「run 收尾单次置 false」的还原语义设计**(两断言面共同钉住的语义),该还原作为已申报行为改动进卡(待裁点 1)。
|
||||
|
||||
## 3. 方案形态评估
|
||||
|
||||
判定轴:帧相位(步进体在帧循环中的执行时点是否与 await 恢复点相同)、步进节律(相邻两步之间是否恰隔一次 process_frame 发射)、run 可等待性(wd8 契约)、键风险(S13 新键)。
|
||||
|
||||
Godot 4 帧循环 process 段的迭代序(engine-reference 口径):**① `emit process_frame`**(所有连接的 Callable 同步依次调用;`await process_frame` 的恢复点=此刻挂在信号上的临时连接被调用)→ **② 节点 `_process`**(Timer 节点在此段)→ **③ 帧末**(SceneTreeTimer 超时、延迟删除等)。官方文档:process_frame「Emitted immediately before Node._process is called on every node」。await 恢复点与显式 connect 回调**同处①、同一相位**——这是全部等价性论证的支点。
|
||||
|
||||
| 形态 | 帧相位 | 步进节律 | run 可等待 | 键风险 | 裁决 |
|
||||
|---|---|---|---|---|---|
|
||||
| **process_frame 信号连接+步进状态机** | 与 await 恢复点同相位(同一 emit 内) | 恒等(常驻连接,每发射恰走一步) | 保留(函数级单次 await 完成信号,见 §4) | 零新键 | **采纳** |
|
||||
| SceneTreeTimer 链 | timeout 在③帧末——相位不同 | `create_timer(0)` 同帧即燃→节律塌缩;加时长→漂移 | 须循环内 await→键不消 | await-in-loop 残留+每步分配 | 否 |
|
||||
| Timer 节点 | timeout 在②节点 process 段——相位不同 | wait_time 按秒计,一帧节律不精确 | 须 await timeout 链→键不消 | 键残留+须建 Node 入树(RefCounted 控制器破形、生命周期管理新增) | 否 |
|
||||
| 递归协程代循环 | 同相位(恢复点内即调下一步) | 恒等 | 天然(await 协程链) | 零键 | 备选否决——n 个并发函数状态链、错误中断语义更浑、可读性差 |
|
||||
| 线程 / WorkerThreadPool | 脱离主循环 | — | — | 测量确定性破坏+面板 setter 跨线程 | 否(一句话排除) |
|
||||
|
||||
godot-master 惯用法对齐:异步操作移出循环、改由信号触发的独立方法承载(其 NEVER-list 第 7 条同款);动态连接用毕即断(第 27 条);逻辑件保持 RefCounted 不引入 Node(When-NOT-to-use-Node);连接前 `is_connected` 守卫(迭代 39「恰好连接一次」先例)。
|
||||
|
||||
## 4. 推荐案:process_frame 信号步进状态机
|
||||
|
||||
### 4.1 代码结构草图(伪代码级)
|
||||
|
||||
```gdscript
|
||||
signal _batch_finished ## 批量模拟整批收尾完成(无参数;发射时点=报告注入与运行态复位之后;
|
||||
## 消费方=run() 自身收尾放行——外部 `await 控制器.run(n)` 经此放行)
|
||||
|
||||
# run 期活成员(批末失效,下次 run 重写——非无效成员)
|
||||
var _sim_n := 0
|
||||
var _sim_i := 0
|
||||
var _sim_stats := {}
|
||||
var _sim_autoplay = null
|
||||
var _sim_logger = null
|
||||
var _finished := false
|
||||
|
||||
func run(n: int) -> void:
|
||||
_running = true
|
||||
# …logger 建会话/set_sim_running(true)/进度 0/n/stats 六键束/_autoplay()——逐字保持现码…
|
||||
_sim_n = n; _sim_i = 0; _sim_stats = …; _sim_autoplay = …; _sim_logger = logger
|
||||
_finished = false
|
||||
if n > 0:
|
||||
var tree: SceneTree = panel.get_tree()
|
||||
if not tree.process_frame.is_connected(_step_frame):
|
||||
tree.process_frame.connect(_step_frame) # 恰连接一次守卫(迭代 39 先例)
|
||||
_step_frame() # 首步同步执行——与 await 形态「第 0 局在调用栈内跑完」对齐
|
||||
await _batch_finished # 函数级单次 await——不在任何循环体内(键消除的落点)
|
||||
else:
|
||||
_finish_batch() # n=0:与 await 形态一致——循环零进,同步收尾零帧
|
||||
|
||||
# 每帧恰执行一步(process_frame 发射点回调);步尽次帧收尾
|
||||
func _step_frame() -> void:
|
||||
if _sim_i < _sim_n:
|
||||
_run_one_level(_sim_autoplay, _sim_stats, _sim_i, panel, _sim_logger) # 逐字保持
|
||||
panel.set_sim_progress("模拟中:%d/%d …" % [_sim_i + 1, _sim_n]) # 逐字保持
|
||||
_sim_i += 1
|
||||
else:
|
||||
panel.get_tree().process_frame.disconnect(_step_frame) # 先断连(防再入)
|
||||
_finish_batch()
|
||||
_batch_finished.emit() # 放行 run() 的 await 与外部 await run(n) 的调用方
|
||||
|
||||
# 收尾单点(运行态复位还原为「run 收尾单次执行」——待裁点 1 的申报改动落点)
|
||||
func _finish_batch() -> void:
|
||||
_finished = true
|
||||
_sim_logger.close_session()
|
||||
panel.set_sim_running(false)
|
||||
_running = false
|
||||
panel.set_sim_report(HudPresenter.tune_sim_report(_sim_n, panel.atk_pct(), panel.hp_pct(), _sim_stats, _base_hp))
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- **await 只剩一处、在函数级**(`await _batch_finished`),文件内不再有任何 for/while——await-in-loop 键从文本形态上根除,且该文件此后对键**结构性免疫**(无循环即无循环内 await)。
|
||||
- **run 保持协程身份**:含 await 即仍是协程——`_on_tune_simulate` 不 await 调用(返回函数态、丢弃,与现行为逐字一致);wd8 的 `await ctrl.run(2)` 挂起到 `_batch_finished` 发射、恢复时整批已完成——**契约零变化、wd8 断言零改动**。
|
||||
- `_run_one_level` 除删去尾部两行(回归还原,见 §2.3)外逐字保持(含 5 参签名,参数≤5 临界不恶化)。
|
||||
- 头注按 code-conventions §2.1 增 `_batch_finished` 契约一行(现 4 行→5 行,S10 ≤8 行内)。
|
||||
- 收尾段内四语句的相对次序(close/两运行态复位/报告)对两个断言面均不可观测(wd8 在整批完成后检查、探针在帧边界检查)——按草图次序落码即可,实现期查 git 历史原序可进一步对齐。
|
||||
|
||||
### 4.2 帧相位等价性论证(逐步对齐表)
|
||||
|
||||
以 n=3 为例,旧(await)新(状态机)两形态逐帧对齐:
|
||||
|
||||
| 时点 | 旧形态 | 新形态 | 等价 |
|
||||
|---|---|---|---|
|
||||
| 调用点同步段(按钮信号链内) | setup→第 0 局→进度 1/n→await 挂起 | setup→connect→`_step_frame()` 跑第 0 局→进度 1/n→`await _batch_finished` 挂起 | 同一调用栈、同一同步段、语句同序 |
|
||||
| 第 1 帧 ①(emit process_frame) | 恢复→第 1 局→进度 2/n→再 await | `_step_frame` 回调→第 1 局→进度 2/n | **同一 emit、同一相位**(帧首、节点 _process 之前) |
|
||||
| 第 k 帧(1≤k≤n−1) | 第 k 局 | 第 k 局 | 步进体=同一函数 `_run_one_level`+同一进度语句 |
|
||||
| 第 n 帧 ① | 恢复(循环自然尽)→close→报告→返回 | `_step_frame` else 分支→断连→close→复位→报告→emit→run 返回 | 终止语句同帧同相位,恰多等的一帧来自旧形态末次 await——草图 else 分支精确复刻 |
|
||||
| n=0 | 循环零进,同步收尾,不挂起 | else 直调 `_finish_batch`,同步收尾,不挂起 | 一致(含 run 返回形态:均非挂起返回) |
|
||||
|
||||
连接次序论证(与同信号其他订阅者的相对序):产品码内 process_frame 订阅面仅两处——本件与 `settlement_fx_view.gd:94` 的一次性 await(等文本度量,战斗结算呈现期,与模拟批不并存;T0 实查复核)。探针 ⑤ 守卫环的 await 连接时点恒晚于本件(按下返回后才首轮 await)→ 每帧步进先于探针复查,两种形态一致。旧形态每次恢复后重新挂尾连接、新形态常驻连接——对「连接时点早于 run()」的订阅者,两形态中本件都排其后;差异仅在「run 途中新增订阅者」的假想场景,现库为零(已列风险 3)。
|
||||
|
||||
## 5. 等价性证明清单(四判据)
|
||||
|
||||
| 判据 | 结论 | 依据 |
|
||||
|---|---|---|
|
||||
| ① 步数与帧数一一对应不变 | **严格成立** | §4.2 对齐表:第 i 局恒在(调用点 i=0/第 i 帧发射点 i≥1),收尾恒在第 n 帧发射点,n=0 退化路径一致 |
|
||||
| ② 每步工作量与执行时点不变(同相位) | **严格成立** | 步进体逐字同一函数;执行点同为 emit process_frame(①段,帧首)——await 恢复点与信号回调在引擎内同处一列连接、同一 emit 内被同步调用 |
|
||||
| ③ 终止条件与终止时读数不变 | **严格成立** | 终止=i 走满 n(else 分支↔循环自然尽);终止时语句(close/复位/报告)同帧执行 |
|
||||
| ④ 输出逐字不变 | **成立+执行化验证** | 报告=未触碰的 `tune_sim_report(stats)`;stats 为种子纯函数(帧时点不进值);JSONL 由未触碰的 autoplay 写、close 时点同帧——逐位一致由双实现对拍执行证明(见下) |
|
||||
|
||||
执行化验证=**双实现对拍**(test-conventions §5.3「重放:改前改后配对」词汇,非变异类):新增配对套件——`game/tests/` 面置**遗留形态夹具**(现 run() 的 await 形态逐字副本,尾部两行按还原语义置收尾;tests/ 不在 S13/S8 扫描面,夹具内循环 await 合法在册);同一假面板+确定性假驱动分别驱动两形态,断言五行全等:每局调用时记录的**帧索引序列**(直接证明「每步恰一帧、相位同点」——把 §4.2 的论证变成当轮真实执行证据)、驱动读到的运行态序列、进度串序列、stats 六键逐位、报告全文逐字。
|
||||
|
||||
**已声明缺口(不能严格证明的点)**:
|
||||
|
||||
1. **脚本错误中断路径**:GDScript 无错误陷阱 API。旧形态:步进体内脚本错误→协程死亡→静默停摆(运行态永真、报告永不落)。新形态:错误中断 `_step_frame`→计数未推进→次帧重试同一步(确定性错误→逐帧重试,探针 1800 帧守卫可抓;生产态=持续重试的可见坏,与旧「静默卡死」同级不同形)。此差异不可消除,接受并文档化(待裁点 3);测量批遇错本就整批作废,两形态都不产出可用读数。
|
||||
2. **微观连接序对未来订阅者**:若未来有人在 run 途中向 process_frame 新增连接,常驻连接与挂尾连接的相对序会分叉——现库零此场景,登记为实现期 T0 实查项+代码评审注记。
|
||||
|
||||
## 6. gdstyle 键账预期(逐规则核对)
|
||||
|
||||
| 规则 | 预期 | 依据 |
|
||||
|---|---|---|
|
||||
| quality/await-in-loop(裸键,本案标的) | **消除** | 全文件零 for/while,await 仅函数级一处 |
|
||||
| quality/allocation-in-loop | 不命中 | 文件零循环;`PlaytestLogger.new()` 在 run 顶层(现状即如此,非循环内) |
|
||||
| max-function-length ≤50 | 达标 | run 约 22 行、`_step_frame` 约 12 行、`_run_one_level` 删两行后约 10 行 |
|
||||
| max-branches ≤8 | 达标 | `_step_frame` 一个 if/else;run 一个 if/else |
|
||||
| max-local-variables ≤10 | 达标 | run 局部 3(logger/stats/autoplay——余者转成员);`_step_frame` 局部 1 |
|
||||
| max-returns ≤6 | 达标 | 全 void |
|
||||
| max-parameters ≤5 | 达标(临界持平) | `_run_one_level` 5 参逐字保持;新函数 0 参 |
|
||||
| max-class-variables ≤15 | 达标 | 现 5+新增 6 成员=11(`_batch_finished` 信号若计入则 12)——成员皆 run 期活承载,非凑数袋 |
|
||||
|
||||
键账流程:键消失后闸判定即绿(消失键不参与红判定);基线死键由批末用户人工 `--refresh` 自然清去(16→15,降幅 <10%,不需 `--force`)。
|
||||
|
||||
## 7. 行为零变化风险点
|
||||
|
||||
1. **测量读数分布**:stats/JSONL/报告是 (种子, atk, hp) 纯函数、帧时点不进值——结构上零漂移;执行证据=双实现对拍逐位+探针 ⑤ 输出四串断言。
|
||||
2. **探针断言面**:⑤ 守卫环语义依赖浮窗运行态贯穿整批——本设计还原该语义(§2.3)→ 探针由「静态推演红」转绿;探针其余段(①–④、⑥–⑩)零触碰。
|
||||
3. **发布态零影响**:浮窗角标 `_debug_entry` 门控(`main.gd:200`,发布态恒隐、浮窗无 UI 开启口——系统测试与冒烟既有断言面在役);tune_sim 全链路发布态不可达,本改动不触任何发布路径。
|
||||
4. **生命周期**:控制器由 `main._tune_sim` 应用期持有(RefCounted 不因帧回调悬挂);`is_connected` 守卫防信号绕过 disabled 的二次 run 造成双连接双步进;收尾先断连防再入;`_batch_finished` 发射时 run 自身的 await 连接恒在位(不存在零听众发射——n=0 路径不经 emit)。
|
||||
5. **并发暴露面**:`_on_tune_simulate` 无 is_running 早退(现状即无,本设计不新增——守卫=按钮置灰〔还原后贯穿整批〕+两层调试入口 is_running 互查);与还原前相比,运行态中途置假的再入洞被顺手封死(还原语义的附带收益,申报面见待裁点 1)。
|
||||
|
||||
## 8. 验收载体
|
||||
|
||||
| # | 载体 | 判什么 | 入闸 |
|
||||
|---|---|---|---|
|
||||
| 1 | T0 实跑复核:standee_fx_sweep 单套件+probe_gate --full | 确认 §2.3 潜伏红现状(改动前读数) | 开工首步 |
|
||||
| 2 | wd8 三断言〔wd8〕(既有,零改动) | 每局运行态真/收尾运行态假+报告注入/run 可等待——**卡内须显式申报该套件**(套件名与涉案文件无字面关联,diff 推导可能漏选) | run_all 关联档 |
|
||||
| 3 | 双实现对拍配对套件(新增,§5) | 帧索引序列/运行态序列/进度串/stats 逐位/报告逐字——五面对拍 | run_all 关联档 |
|
||||
| 4 | ui_tune_probe ⑤(既有,零改动) | 真实 UI 全链路 N=10:守卫环完成+报告四串+运行期钮禁用 | probe_gate --full |
|
||||
| 5 | 批末 `run_all_gates.sh --code` | 所选域全绿;static_scan S13 对账确认 await 键消失、无新键 | 批末 |
|
||||
|
||||
## 9. 估时
|
||||
|
||||
| 项 | 估时 |
|
||||
|---|---|
|
||||
| T0 现状复核(两断言面实跑) | 0.25 工作日 |
|
||||
| 控制器重构(§4.1 草图落码+头注契约行) | 0.25–0.5 工作日 |
|
||||
| 双实现对拍(夹具+配对套件) | 0.25–0.5 工作日 |
|
||||
| 孤立验证+批末代码域闸+键账对账 | 0.25 工作日 |
|
||||
| **合计** | **1–1.5 工作日** |
|
||||
|
||||
## 10. 待裁点清单
|
||||
|
||||
1. **潜伏红处置(必裁)**:现码 `_run_one_level` 尾部两行与 wd8/探针 ⑤ 静态矛盾(§2.3)。推荐:随批还原「run 收尾单次置 false」,作为已申报行为改动进卡(T0 实跑确认现状后施工);该还原同时封死运行中途的模拟再入洞。若用户掌握「每局置 false 系有意行为」的背景,请指出——但该选择下 wd8 与探针 ⑤ 必红、批不可绿,需另行裁决断言面处置。
|
||||
2. **双实现对拍是否入批**:推荐入(把帧相位等价从纸面论证变成当轮执行证据;tests/ 面不入 S13 扫描面、夹具内循环 await 合法)。备选:仅靠 wd8+探针 ⑤(省一测试件,相位等价无执行化证据)。
|
||||
3. **错误路径差异接受度**:脚本错误下「逐帧重试」对「静默停摆」的差异(§5 缺口 1)不可消除。推荐:接受并文档化。备选:`_on_tune_simulate` 加 is_running 早退守卫兜底——+1 行为面、system_test〔wd7〕前置断言随之需复核,代价大于收益。
|
||||
|
||||
## 11. 关联文档同步面(随批义务备查,经反哺点通道落文)
|
||||
|
||||
- `design/engineering/architecture/architecture.md`「测试与质量域」:S13 测量面豁免登记首条(2026-10-27 tune_sim await)**注销**;同段其余条目(battle_orchestrator 第三条等)不在本案范围。
|
||||
- `tools/gdstyle_baseline.txt`:await 裸键随批末人工 `--refresh` 消失(禁实现批中途 refresh)。
|
||||
- `game/tests/README.md` 能力清单:配对套件入表归写卡段(实现批禁写该文件)。
|
||||
@@ -1,171 +0,0 @@
|
||||
# 设计——站桩状态件拆分(S13 max-class-variables 键清偿)
|
||||
|
||||
设计讨论段过程稿 v1.0——待主会话汇总裁决。
|
||||
|
||||
## 0. 一句话结论
|
||||
|
||||
把 `_StandeeState` 沿「身份命值 / 资产演出」职责缝拆成两个独立文件类(12 + 11 成员),三个演出探针计数器移到宿主;宿主类变量 19 → 10,两新文件各自 ≤15,站桩外部契约与呈现时序零变化。
|
||||
|
||||
**先纠一个前提**:主会话实测的「_StandeeState 成员 13 个、独立成文件即 13≤15 合规」不成立。实测(gdstyle v0.4.0 二进制逐案验证):该文件 `_StandeeState` 真实成员是 **25 个**;基线键账 19 是 gdstyle 一个解析缺陷造出的截断读数——内嵌类里**带行尾注释的属性声明**(`var _intent_scale := 1.0: # 注释`)会把该内嵌类的成员计数截断,其后的成员全部漏记进宿主。把 `_StandeeState` 原样拆成独立文件,键账是 25 不是 13,照样红。
|
||||
|
||||
## 1. 机检事实(gdstyle v0.4.0 计数语义,实测五案)
|
||||
|
||||
| 案 | 内容 | gdstyle 读数 | 结论 |
|
||||
|---|---|---|---|
|
||||
| 1 | standee_body.gd 原文件 | 外层类 19(1:1),内嵌类零命中 | 19 = 顶层 6 + 漏记内嵌 13 |
|
||||
| 2 | 内嵌 25 成员抽成独立文件 | 该类 25 | **拆出即 25 > 15,方案①不成立** |
|
||||
| 3 | 内嵌类全普通 var(无属性) | 内嵌类单独报 25,宿主 6 不报 | 无属性时内嵌类独立计数,正常 |
|
||||
| 4 | 内嵌类 12 普通 var + 带行尾注释属性 + 12 普通 var + 宿主 6 | 宿主 18(6+12 漏记) | 属性行尾注释 = 截断点 |
|
||||
| 5 | board_cell_unit.gd(旁证) | 基线 30 = 顶层 6 + 漏记 24 | 同一规则,账目吻合 |
|
||||
|
||||
有效规则:**类各自计数;内嵌类遇到「属性声明 + 行尾注释」即成员计到该属性为止,其后成员漏进宿主**。standee_body.gd 的截断点 = `_intent_scale`(37 行),其后 13 个成员(`_glyph_rot` 起到 `_flash_count`)漏进宿主:6 + 13 = 19。board_cell_unit.gd 截断点 = `edge`(30 行),6 + 24 = 30,同款吻合。
|
||||
|
||||
含义:不动内嵌形态,把三行属性声明移到内嵌类末尾(或删其行尾注释)就能让账变回「宿主 6 / 内嵌 25」——但内嵌 25 仍超阈。**真正的债是状态件 25 个成员本身**,任何合规解都必须把它拆成 ≥2 个类或砍到 ≤15。
|
||||
|
||||
## 2. 现状成员全列(31 个:宿主 6 + 状态件 25)
|
||||
|
||||
### 2.1 宿主顶层(6 个——全部有外部冻结契约)
|
||||
|
||||
| 成员 | 类型 | 写入方 | 读取方 |
|
||||
|---|---|---|---|
|
||||
| `st` | _StandeeState | 成员初始化器;`_init` 灌 _owner/_hero_state/_kind | 宿主全部内部函数经 `st.X` 读写;**外部零直访**(全仓 grep 证实) |
|
||||
| `box` | Vector2(150,176) | battle_stage_view `_sync_layout`(198/208 行);fx_probe 三处 | `_place_portrait`/`_portrait_rect`/`_pedestal_rect`/`content_rect`/`_draw_*` 五域;battle_stage_view 两个 center 出口读 |
|
||||
| `font` | Font | battle_stage_view `set_world_font`(232/235 行) | `_efont` |
|
||||
| `slot_row` | StatusSlotRow | battle_stage_view(140/265 行) | `set_effects`/`set_effects_cleared_feedback`/`mark_dead`/`_revive`;battle_stage_view `_sync_companions`;ui_probe/ui_click_probe |
|
||||
| `_intent_charge` | bool | `set_pending`(源码锚行 194)、`mark_dead` | `_play_intent_motion`;standee_fx_sweep_test 直读(103 行) |
|
||||
| `has_world_hp_bar` | true 常量 | 无(声明即终值) | ui_probe 141 行 |
|
||||
|
||||
### 2.2 _StandeeState(25 个)
|
||||
|
||||
| # | 成员 | 类型 | 写入方 | 读取方 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | `_owner` | Node2D | `_init` | 三个属性 setter(queue_redraw) |
|
||||
| 2 | `_kind` | String | `_init` | `set_hero_state`/`_revive`/`_portrait_glyph`/`_draw`/`_draw_hp_bar`/`_portrait_color` |
|
||||
| 3 | `_portrait_sprite` | Sprite2D | `set_portrait_texture`/`_place_portrait` | 同函数 + `_draw_portrait`/`set_hero_state`/`_settle_hero_idle`/`portrait_probe` |
|
||||
| 4 | `_portrait_tex` | Texture2D | `set_portrait_texture` | 仅 `_place_portrait` 判空(与 sprite.texture 冗余) |
|
||||
| 5 | `_hero_tex` | Dictionary | `register_hero_state` | `set_hero_state`/`_settle_hero_idle`/`hero_state_probe` |
|
||||
| 6 | `_hero_state` | int | `_init`/`set_hero_state`/`_settle_hero_idle`/`_revive` | `set_hero_state`/`hero_state_probe` |
|
||||
| 7 | `_state_revert_tw` | Tween | `set_hero_state` | 同函数(重启先杀) |
|
||||
| 8 | `_order` | int | `_set_order` | `_draw_hp_bar`(顺位徽标) |
|
||||
| 9 | `_intent_glyph` | String | `set_pending` | `intent_probe`/`_draw_intent_badge` |
|
||||
| 10 | `_intent_col` | Color | `set_pending` | `_draw_intent_badge` |
|
||||
| 11 | `_intent_visible` | bool | `set_pending`×3/`mark_dead` | `intent_probe`/`_draw_intent_badge` |
|
||||
| 12 | `_intent_scale` | float(属性→重绘) | `_play_intent_motion` 的 tween | `_draw_intent_badge` |
|
||||
| 13 | `_glyph_rot` | float(属性→重绘) | `_play_intent_motion` 的 tween | `_draw_portrait` |
|
||||
| 14 | `_display_name` | String | `set_data` | `display_name`/`name_line_probe`/`_draw_armor_name_line` |
|
||||
| 15 | `_enemy_id` | String | `set_data` | `enemy_id`(d12 解析主键) |
|
||||
| 16 | `_armor` | String | `set_data` | `name_line_probe`/`_draw_armor_name_line` |
|
||||
| 17 | `_dead` | bool | `mark_dead`/`_revive` | `set_data`/`set_hero`/`is_dead`/`flash_hit`/`_portrait_glyph`/`set_pending`/`mark_dead` |
|
||||
| 18 | `_hp_max` | float | `set_data`/`set_hero` | `_set_hp`/`_draw_hp_bar` |
|
||||
| 19 | `_hp_cur` | int | `_set_hp` | `_draw_hp_bar`(数字即时值) |
|
||||
| 20 | `hp_value` | float(属性→重绘+clamp) | `_set_hp` 的 tween | `_draw_hp_bar`(条宽) |
|
||||
| 21 | `_hp_tween` | Tween | `_set_hp` | 同函数(重启先杀) |
|
||||
| 22 | `_hp_flash_tw` | Tween | `flash_hit` | 同函数(重启先杀;回色读 `_dead`) |
|
||||
| 23 | `_death_shards` | int | `_spawn_death_shards` | `fx_probe` |
|
||||
| 24 | `_hit_sparks` | int | `_spawn_hit_spark` | `fx_probe` |
|
||||
| 25 | `_flash_count` | int | `flash_hit` | `fx_probe` |
|
||||
|
||||
### 2.3 外部触面(拆分边界 = 全部保持)
|
||||
|
||||
写状态的外部方只有 battle_stage_view(box/font/slot_row 三 var + 全部经方法)与 fx_probe(box 三处);读面 = 两个 center 出口、六个 probe 出口、`_intent_charge` 测试直读、theme_projection_test 三条源码锚断言(679–683 行:`GOLD_BRIGHT` 顺位墨、`HERO_BLUE_BRIGHT`/`GOLD_BRIGHT` 护甲墨、`_intent_charge = pid in CHARGE_SKILL_IDS`)——三条锚所在函数(`_draw_hp_bar`/`_draw_armor_name_line`/`set_pending`)**全部留在宿主且锚行逐字不动**。
|
||||
|
||||
## 3. 方案形态评估
|
||||
|
||||
### 方案 A(主会话原①):_StandeeState 升格独立文件
|
||||
|
||||
**淘汰。** 实测拆出即 25 > 15(机检事实案 2),不削成员不合规;而削到 15 需砍 10 个,全是承重成员(见方案 B 的砍不动论证),等于把 A 逼成 B+拆分。
|
||||
|
||||
### 方案 B(主会话原②):原地真实削减 4 个(19→15)
|
||||
|
||||
**淘汰。** 被计入 19 的是宿主 6(全部外部冻结:box/font/slot_row/has_world_hp_bar 探针契约面、_intent_charge 源码锚成员、st 本体)+ 漏记的 13(`_glyph_rot`/身份三元组/`_armor`/`_dead`/`_hp_max`/`_hp_cur`/`hp_value`/两条 tween 槽/三个探针计数)。逐个过堂:身份三元组合一个字典 = 丢类型的凑计数袋(违反 code-conventions §1.1①⑤);三个探针计数合一个字典同理且键变字符串;`_hp_cur` 与 `hp_value` 一个是即时目标一个是 tween 滞后值,不可互推;两条 tween 槽的重启语义各自独立;`_glyph_rot` 是 tween 目标属性。**诚实削减余额 ≈ 0(顶多 `_portrait_tex` 一个冗余成员)**,−4 凑不出来。
|
||||
|
||||
### 方案 C(推荐):沿职责缝拆两个独立文件类 + 三个演出探针计数器移宿主
|
||||
|
||||
25 个成员按领域分三堆,各自命得出名字:
|
||||
|
||||
**新件一 `game/presentation/views/standee_vitals.gd`「站桩身份与命值态」(12 成员)**
|
||||
- 成员:`_owner`、`_kind`、`_display_name`、`_enemy_id`、`_armor`、`_order`、`_dead`、`_hp_max`、`_hp_cur`、`hp_value`(属性→重绘+clamp)、`_hp_tween`、`_hp_flash_tw`。
|
||||
- 职责语句:站桩是谁、活没活、血量几何的唯一账面——身份五元组(种类/名/id/护甲/顺位)+ 存活位 + 血量账与两条血量系 tween 槽。
|
||||
- 单一变化原因:战斗结算快照投影的字段形态(set_data/set_hero 投影什么它记什么)。
|
||||
- 迁入行为(防纯数据袋):`apply_hp(hp)`=原 `_set_hp` 整体搬移(clamp、重启 `_hp_tween`、tween 写 `hp_value`);`hp_value` 属性 setter 逐字。`_hp_flash_tw` 归此件:`flash_hit` 的回色分支读 `_dead`,与存活位同域。
|
||||
- extends **RefCounted**(godot-master 判据:瞬态逻辑数据包、随宿主生灭、零序列化零 Inspector——Resource 的共享/.tres 语义此处零收益)。
|
||||
|
||||
**新件二 `game/presentation/views/standee_motion.gd`「站桩资产与演出态」(11 成员)**
|
||||
- 成员:`_owner`、`_portrait_sprite`、`_portrait_tex`、`_hero_tex`、`_hero_state`、`_state_revert_tw`、`_intent_glyph`、`_intent_col`、`_intent_visible`、`_intent_scale`(属性→重绘)、`_glyph_rot`(属性→重绘)。
|
||||
- 职责语句:站桩的资产挂点与一次性演出——立绘精灵落位与换装、主角三态注册与 0.35s 短驻回归、意图徽标弹入动画。
|
||||
- 单一变化原因:美术素材落位规则与演出编排设计(立绘 48px 档、三态帧档、§4.6.4 三档运动签名)。
|
||||
- 迁入行为:`set_portrait_texture(tex, flip, box)`(原函数整体搬移,box 由宿主传入——box 是宿主冻结 var);`register_hero_state`;`apply_hero_state(state, is_hero)`(原 `set_hero_state`,唯一改形 = `st._kind != "hero"` 早退改参判 `is_hero`——早退序逐字);`reset_state()`(原 `_revive` 内「`_hero_state = RESET` 强制绕同态早退」两拍的 encapsulation);`play_intent_motion(charge)`(原 `_play_intent_motion`,`_intent_charge` 改参传入);`state_probe()`。
|
||||
|
||||
**宿主 standee_body.gd 保留(类变量 10)**
|
||||
- 五个冻结 var 原位 + `st`(vitals 实例,**名字保留**——约 40 处引用与 tween 路径串 `"st.hp_value"` 零改)+ `mo`(motion 实例,命名待裁)+ 三个演出探针计数器 `_death_shards`/`_hit_sparks`/`_flash_count`。
|
||||
- 计数器归宿主的内聚依据:唯一写入方 = 宿主演出函数(`_spawn_death_shards`/`_spawn_hit_spark`/`flash_hit`),唯一读取方 = 宿主 `fx_probe()` 出口——仪器跟着驱动它的函数走;同时给 vitals 让出余量(15 满额 → 12)。
|
||||
- 保留函数:`_init`、`set_data`/`set_hero`(跨两域编排)、`set_effects`/`set_effects_cleared_feedback`(slot_row 域)、`set_pending`(分档计算 + 源码锚行,字段写改指 mo)、`mark_dead`/`flash_hit`/`play_hit_impact`/`_spawn_*`/`_revive`(跨域演出编排)、`_draw` 全族与几何函数(绘制是宿主 CanvasItem 职责)、六个 probe/display_name/enemy_id/is_dead 出口(外形零变,体内前缀改指)。
|
||||
|
||||
接线形态:**保持 `_owner: Node2D` 直回引,不改 Callable 注入、不改信号**。依据:①现状形态,setter 体逐字(`_owner.queue_redraw()`)即重绘时序零漂移——tween 每帧写属性 → setter 同步触发,正是「弹入动画逐帧重绘」的承载;②Node 非 RefCounted,state→宿主回引无环引用泄漏(与 BattleFxHost 场景不同——那边是两 RefCounted 互持才禁双向);③queue_redraw 是 CanvasItem 公开 API,不属「件回调宿主私有族」禁令射程。
|
||||
|
||||
淘汰的变形:**两内类同居主文件**(diff 更小)——依赖成员排序躲解析缺陷(属性须排各类末尾),未来任何人往类中部加一个带注释属性就静默漏账(基线恶化闸要到 19→29 才红,9→15 区间六格漂移无感知);两新件独立文件则完全脱离该缺陷的作用面。**改属性行注释形态躲缺陷**同理淘汰——赌解析器怪癖不如离开怪癖作用面。
|
||||
|
||||
## 4. 写入路径对账(外部写入方零改动清单)
|
||||
|
||||
| 外部触点 | 现状 | 改后 |
|
||||
|---|---|---|
|
||||
| battle_stage_view 140/265 行 `slot_row =` | 宿主 var 直写 | 不变(var 原位) |
|
||||
| battle_stage_view 198/208 行 `box =` | 宿主 var 直写 | 不变;box 仍是无 setter 普通 var,**不触发重绘是现状语义**(重排后的呈现由后续 set_data/字体注入等 queue_redraw 承载),设计不补挂不拆挂 |
|
||||
| battle_stage_view 232/235 行 `font =` + `queue_redraw` | var 直写 | 不变 |
|
||||
| battle_stage_view 132–138/267 行 set_portrait_texture/register_hero_state | 宿主方法 | 同名宿主方法保留(1–2 行转调 mo,box 作参),battle_stage_view 一行不改 |
|
||||
| battle_stage_view 313/316/388 行 set_hero_state | 宿主方法 | 同名保留,转调 `mo.apply_hero_state(state, st._kind == "hero")` |
|
||||
| battle_stage_view 333–335 行 play_hit_impact/flash_hit/mark_dead | 宿主方法 | 不变(宿主保留) |
|
||||
| hud_presenter 77/78/137/162/163 行 set_hero/set_effects | 宿主方法 | 不变 |
|
||||
| fx_probe/ui_probe/ui_struct_probe/ui_click_probe 全部读数 | 六 probe 出口 + box/has_world_hp_bar/slot_row | 出口外形零变(fx_probe 改读宿主计数器、intent_probe/portrait_probe 前缀改指 mo) |
|
||||
| standee_fx_sweep_test 103 行 `s1._intent_charge` | 宿主 var 直读 | 不变(成员原位) |
|
||||
| 内部 tween 路径串 | `"st.hp_value"`(vitals 成员名保留 → 零改);`"st._intent_scale"`/`"st._glyph_rot"` | 改 `"mo._intent_scale"`/`"mo._glyph_rot"`(搬进 mo 的同一函数体内) |
|
||||
|
||||
重绘/重排时序零变化论证:三个属性 setter 体逐字(`_owner.queue_redraw()`);tween 目标路径只换持有者前缀、写序不变;box/font/slot_row 写入面与现状同拍同序(battle_stage_view 一行不改 = 接线时序恒等)。
|
||||
|
||||
## 5. gdstyle 键账预期(逐文件 ≤15)
|
||||
|
||||
| 文件 | 类变量实数 | 基线对账 |
|
||||
|---|---|---|
|
||||
| standee_body.gd | **10**(5 冻结 + st + mo + 3 计数器) | 基线登记 19,实数 10 < 19 = 改小不红 |
|
||||
| standee_vitals.gd | **12** | 无基线键,12 ≤ 15 = 零命中 |
|
||||
| standee_motion.gd | **11** | 无基线键,11 ≤ 15 = 零命中 |
|
||||
|
||||
函数级键:**零函数迁入新键**——六个搬移函数逐字搬运(仅前缀与两处改参),长度/分支/局部/返回/参数全在原值内(最大者 `apply_hero_state` 4 参数 4 分支);宿主新增转调壳 1–2 行零键。基线不随批刷新(改小即绿;收账归后续全清批人工 `--refresh`,须用户批准——与 battle_orchestrator 50→38 先例同口径)。
|
||||
|
||||
## 6. 行为零变化风险点
|
||||
|
||||
1. **tween 属性路径串**:`"st.hp_value"`/`"mo._intent_scale"`/`"mo._glyph_rot"` 拼错 = 运行时属性找不到、动画静默失效。兜底:fx_probe 段的意图弹入断言、hero_state_probe 三态断言、fx_shot_probe 帧取证都在闸内。
|
||||
2. **hero 三态机改形两处**(`is_hero` 参数化、`reset_state` 封装):早退序与 RESET 哨兵语义必须逐拍对齐——`set_hero_state` 的三连早退(非主角/同态/未注册)条件序不变;`_revive` 强制回 idle 两拍改两调用、顺序不变。
|
||||
3. **`_hp_flash_tw` 回色读 `_dead`**:flash_hit 留宿主、跨读 `st._dead`,与现状同一拍。
|
||||
4. **源码锚三条**(theme_projection 679–683):锚行所在函数留宿主且锚行逐字,改造只动同函数其他行的 `st.` 前缀。
|
||||
5. **成员初始化时序**:st/mo 于成员初始化器构造、`_init` 灰 `_owner`/`_kind`——与现状同形,构造期零属性写早于 `_owner` 赋值。
|
||||
6. **counters 迁移**:三个计数器无 setter 无重绘语义,纯读写易位;`fx_probe()` 返回键名逐字。
|
||||
|
||||
## 7. 验收载体建议(真实入口)
|
||||
|
||||
| 载体 | 断言面 | 绑定 |
|
||||
|---|---|---|
|
||||
| static_scan S13(gdstyle_gate 回执) | 「基线外新违规 0、恶化 0」+ standee_body 键账 10 | 被测改动本身的直接判据(键清偿),grep 回执可定位 |
|
||||
| run_all 关联套件 | standee_fx_sweep_test(_intent_charge 直读、fx_probe().flash_count、enemy_id 解析);theme_projection_test(三条源码锚) | 拆分后宿主成员与源码锚零变 |
|
||||
| probe_gate --full | fx_probe 段(碎裂 5/火花 6/闪白计数/三态切换/死亡残位 idle);ui_probe(intent_probe 三档、name_line_probe、portrait_probe、has_world_hp_bar、slot_row);ui_struct_probe ⑥standee 出框断言;ui_click_probe slot_row tooltip | 外部契约面逐一可达 |
|
||||
| render_gate | fx_shot_probe 取证 + 战斗舞台 golden | 站桩呈现像素级零变化 |
|
||||
| run_smoke / run_system_test | 恒跑保险 | 活性 |
|
||||
|
||||
对照表口径:本批为非行为改动(结构重组)逐行申报 + 既有断言面全绿作呈现零变化证明;S13 键账数字即键清偿判据,无需新增断言。
|
||||
|
||||
## 8. 估时
|
||||
|
||||
写卡段不计。实现批(worktree):宿主改造与函数搬移 ≈2h;两新件与头注(≤8 行、无反向链接)≈0.5h;闸跑(S13 + run_all 关联 + probe_gate --full + render_gate + 冒烟/系统)与取证 ≈1.5h;对照表与实现报告 ≈0.5h——**合计 ≈0.5 工作日**。
|
||||
|
||||
## 9. 反哺点(预登记)
|
||||
|
||||
1. architecture.md「模块归属·呈现层」表登记两新件(standee_vitals/standee_motion,各一句职责)。
|
||||
2. 相邻发现(不属本批):board_cell_unit.gd 内嵌类 `_CellPaintState` 27 成员受同一 gdstyle 解析缺陷截断(基线 30 = 6 + 24 漏记),属 gdstyle 存量债同族,是否立卡清偿待裁。
|
||||
3. `_portrait_tex` 与 `_portrait_sprite.texture` 冗余(单一事实源可归一)——本批不动(零变化优先),留债册。
|
||||
|
||||
## 10. 待裁点
|
||||
|
||||
1. **方案形态确认**:推荐案 C(两独立文件 + 计数器归宿主)vs 淘汰案 B(原地 −4,凑不出)与两内类变形(赌解析缺陷)。前提修正:原①「拆出即合规」实测不成立。
|
||||
2. **探针计数器落点**:宿主(推荐——写入方/读取方同在宿主,vitals 让出余量)vs vitals 内(15 满额零余量,快照投影类加一个字段即红)。
|
||||
3. **motion 实例成员命名**:`mo`(推荐,短、域对)vs 其他;vitals 实例沿用 `st`(引用面与 `"st.hp_value"` 路径串零改)。
|
||||
4. **基线收账时点**:本批不刷新(改小即绿,先例口径)vs 随批人工 `--refresh`(须用户批准)。
|
||||
@@ -1,236 +0,0 @@
|
||||
# 设计——组合根注册面(S13 真修复:main.gd 类变量归 15)
|
||||
|
||||
状态行:设计讨论段过程稿 v1.0——待主会话汇总裁决(2026-10-29)
|
||||
|
||||
## 0. 背景与判据来源
|
||||
|
||||
用户 2026-10-29 裁「不允许任何豁免」:main.gd 的 S13 键(`game/presentation/main.gd|quality/max-class-variables = 49`,阈值 15)必须真实修复,architecture 在册的 S13 豁免登记(「组合根类变量面即探针契约面」)随批注销。主会话已点头的主方向:把屏壳+覆盖层一级句柄收进一个「注册面/接口层门面」件,探针从 `main.X` 改走注册面地址。
|
||||
|
||||
本设计的判据来源:
|
||||
|
||||
- code-conventions §1.1 拆分边界纪律五条(职责轴拆分、集体身份、过阈值只作发现信号、拆不出即停卡、禁无效成员别名)与 §1.3 依赖单向(组合根=main.gd+其构造注入的组合根拆件)。
|
||||
- architecture「呈现层装配与会话生命周期」「模块归属·呈现层」「测试与质量域」三节。
|
||||
- godot-master 的 Node 取舍判据("Use RefCounted for logic objects and data containers. Reserve Node for things that must exist in the scene tree")与信号卫生条款;本仓既有先例:ConfigDB 迭代 41 用「三张域容器」解决同构的成员数超标问题,ModalFlow/各交互控制器均为持引用的 RefCounted。
|
||||
- 源码实查:main.gd 915 行 49 var(实数复核);探针+system_test 的 `main.X` 成员引用 867 处(机械统计,扣除 main.tscn/get_node/get_viewport 等非成员形态);四个流程承接件 `root.X` 引用约 350 处。
|
||||
|
||||
## 1. 注册件形态
|
||||
|
||||
### 1.1 推荐形态:一个门面+三个域容器(四文件,全 RefCounted,不挂树)
|
||||
|
||||
| 新件 | 文件 | extends | 类变量数 | 职责一句话 |
|
||||
|---|---|---|---|---|
|
||||
| **界面注册面** | `game/presentation/ui_registry.gd` | RefCounted | **3** | 呈现层界面元素清单:持有三域容器、LAYER_CONTRACT 合同表、`node(key)` 合同寻址、`apply_layer_contract(root)` 唯一落位口 |
|
||||
| **屏壳与全屏容器域** | `game/presentation/ui_screens.gd` | RefCounted | **9** | 三屏壳、屏内一级子层、全屏态、浮层角标、排播泵节点的句柄册 |
|
||||
| **战区视图域** | `game/presentation/ui_battle.gd` | RefCounted | **5** | 战斗屏 A–D 区视图与结算演出句柄册 |
|
||||
| **模态层域** | `game/presentation/ui_modals.gd` | RefCounted | **14** | 十三个模态覆盖层句柄+ModalFlow 栈编排(登记、开合、锁谓词) |
|
||||
|
||||
main.gd 新增一个成员 `ui`(类型 UiRegistry),探针与流程件的新地址形如 `main.ui.modals.level_screen`、`main.ui.battle.board_zone`、`main.ui.screens.menu_screen`。
|
||||
|
||||
**为什么是三容器而不是一件**: gdstyle 阈值 15 是按文件的,句柄 27 个+flow/row_pacer 共 29 个进一个文件必然超阈、又要开新基线键=留债,违用户裁决出口。 分组轴不是拍脑袋切的——它就是 LAYER_CONTRACT 的 kind 轴(modal/shell/state/float/node)加上 battle.md 的战区轴,三组身份先于本批存在(详见 §2),是「按既有领域轴收拢」,不是「为凑 15 而切」。
|
||||
|
||||
**为什么是 RefCounted 不是 Node**: 注册面是纯句柄容器+合同数据,零 `_process`、零绘制、零树位需求——按 godot-master 判据「Node 只留给必须在场景树里存在的东西」应取 RefCounted。 它持有的节点(屏壳/覆盖层/视图)都是 `_build_ui` 一次装配、随 main 同生死的常驻件,不含任何会话期 `queue_free` 对象(局态在 run_scope,留 main),RefCounted 持 Node 引用无悬挂风险;本仓先例充分:ModalFlow、TreasureInteractController、CampShopPresenter、DebugSession、SettingsStore 全是持引用 RefCounted。 若做成 Node 挂树,反而要回答「它占哪个树位」「进不进 LAYER_CONTRACT」「冒烟 V1d 怎么看它」三个新问题,纯增噪声。
|
||||
|
||||
**class_name**: 四件均给 class_name(UiRegistry/UiScreens/UiBattle/UiModals),main 里 `var ui: UiRegistry` 类型化;随批跑一次编辑器扫描刷新全局类缓存+同步 .uid(code-conventions 语言纪律 5)。
|
||||
|
||||
### 1.2 逐成员去向对账表(main.gd 现有 49 var,三档:进注册面/留 main/消灭)
|
||||
|
||||
**进注册面(28)**——成员名在容器内去下划线(变为公共地址面,与 LAYER_CONTRACT 键名对齐):
|
||||
|
||||
| # | 现 main 成员 | 去向 | 依据 |
|
||||
|---|---|---|---|
|
||||
| 1 | `_menu_screen` | `ui.screens.menu_screen` | 屏壳(kind=shell) |
|
||||
| 2 | `_camp_screen` | `ui.screens.camp_screen` | 屏壳 |
|
||||
| 3 | `_adventure_screen` | `ui.screens.adventure_screen` | 屏壳 |
|
||||
| 4 | `_start_overlay` | `ui.screens.start_overlay` | 菜单屏内一级子层 |
|
||||
| 5 | `_battle_root` | `ui.screens.battle_root` | 冒险屏内一级子层 |
|
||||
| 6 | `_inter_overlay` | `ui.screens.inter_overlay` | 全屏态(kind=state) |
|
||||
| 7 | `_inter_label` | `ui.screens.inter_label` | 过场层附随标签 |
|
||||
| 8 | `debug_badge` | `ui.screens.debug_badge` | 全局浮层(kind=float) |
|
||||
| 9 | `_row_pacer` | `ui.screens.row_pacer` | LAYER_CONTRACT kind=node 注册层(节点本体仍 add_child 到 main,注册面只持引用,树位零变化) |
|
||||
| 10 | `stage` | `ui.battle.stage` | 战斗屏 B 区 |
|
||||
| 11 | `log_view` | `ui.battle.log_view` | B 区明细带 |
|
||||
| 12 | `info_panel` | `ui.battle.info_panel` | C 区 |
|
||||
| 13 | `board_zone` | `ui.battle.board_zone` | D 区(含 toast/fx/board_view/ap_bar) |
|
||||
| 14 | `settlement_fx` | `ui.battle.settlement_fx` | 结算演出覆盖层 |
|
||||
| 15 | `legend_overlay` | `ui.modals.legend_overlay` | 模态层(kind=modal,13 件全集) |
|
||||
| 16 | `node_overlay` | `ui.modals.node_overlay` | 模态层 |
|
||||
| 17 | `level_screen` | `ui.modals.level_screen` | 模态层(host=adventure_screen,TAG_SCREEN_STATE) |
|
||||
| 18 | `curio_overlay` | `ui.modals.curio_overlay` | 模态层 |
|
||||
| 19 | `_end_overlay` | `ui.modals.end_overlay` | 模态层 |
|
||||
| 20 | `shop_overlay` | `ui.modals.shop_overlay` | 模态层 |
|
||||
| 21 | `camp_overlay` | `ui.modals.camp_overlay` | 模态层(shell=camp_screen) |
|
||||
| 22 | `settings_overlay` | `ui.modals.settings_overlay` | 模态层 |
|
||||
| 23 | `status_panel` | `ui.modals.status_panel` | 模态层 |
|
||||
| 24 | `career_overlay` | `ui.modals.career_overlay` | 模态层 |
|
||||
| 25 | `save_select_overlay` | `ui.modals.save_select_overlay` | 模态层 |
|
||||
| 26 | `confirm_dialog` | `ui.modals.confirm_dialog` | 模态层 |
|
||||
| 27 | `debug_overlay` | `ui.modals.debug_overlay` | 模态层(TAG_NON_LOCKING) |
|
||||
| 28 | `_modal_flow` | `ui.modals.flow` | 模态编排与模态层同域(登记/开合/锁谓词的宿主) |
|
||||
|
||||
**留 main(14)+新增(1)=改后 15**:
|
||||
|
||||
| # | 成员 | 保留理由 |
|
||||
|---|---|---|
|
||||
| 1 | `db` | 核心配置读视图——组合根唯一加载单点读取入口(`_ready` 装配) |
|
||||
| 2 | `run_scope` | 会话承载节点——架构在册「局态一律住 RunScope,组合根经 run_scope.X 读写」;173 处探针引用零迁移 |
|
||||
| 3 | `save_manager` | autoload 读视图——architecture 在册「main.save_manager 语义零迁移」 |
|
||||
| 4 | `meta` | autoload 读视图(同上) |
|
||||
| 5 | `settings_store` | 系统级设置存储——非界面元素(无视觉面),`_ready` 装配、`_quit_game` 落盘、SettingsOverlay 构造注入 |
|
||||
| 6 | `logger` | 试玩日志器——组合根埋点面(非界面元素) |
|
||||
| 7 | `_debug_entry` | 调试会话门控(组合根启动态布尔) |
|
||||
| 8 | `_confirm_consumer` | 确认弹窗分派状态量(组合根自身状态) |
|
||||
| 9 | `_confirm_consumer_slot` | 分派附随槽号(与 8 同一关注点成对读写) |
|
||||
| 10 | `_debug` | DebugSession——调试会话状态机持有(逻辑件非界面件) |
|
||||
| 11 | `_treasure_ui` | TreasureInteractController——组合根拆件(核心写调用代执行) |
|
||||
| 12 | `_bonus` | CurioInteractController——组合根拆件 |
|
||||
| 13 | `_camp_pres` | CampShopPresenter——组合根拆件 |
|
||||
| 14 | `_tune_sim` | TuneSimController——调参测量控制器(逻辑件) |
|
||||
| 15 | `ui`(新增) | 界面注册面——本设计的唯一新成员 |
|
||||
|
||||
这 14+1 全部是「组合根自身状态+拆件引用+autoload 读视图」,正是 §1.1 拆分纪律下组合根该留的最小内聚面;没有一件是因为「计数不够了才留下」的。
|
||||
|
||||
**消灭(7)**——全部是别名或一行转发,属拆分纪律⑤明令禁止保留的无效成员:
|
||||
|
||||
| # | 成员 | 本体 | 消灭后地址 |
|
||||
|---|---|---|---|
|
||||
| 1 | `board_view` | = board_zone.board_view | `ui.battle.board_zone.board_view`(探针惯用 `var bv = ...` 局部承接,每文件 1–2 处) |
|
||||
| 2 | `ap_bar` | = board_zone.ap_bar | `ui.battle.board_zone.ap_bar` |
|
||||
| 3 | `_modals` | = _modal_flow.stack | `ui.modals.flow.stack`(ui_struct 登记序断言) |
|
||||
| 4 | `_row_queue` | 委托属性 = _row_pacer.pending_rows() | `ui.screens.row_pacer.pending_rows()`(main 自身 3 处+pacing_queue_test 1 处;同一 Array 引用,语义不变) |
|
||||
| 5 | `_seed_edit` | = debug_overlay.seed_edit | `ui.modals.debug_overlay.seed_edit.text`(仅 main._seed_value 内部消费,探针零引用) |
|
||||
| 6 | `_settlement_stop_pending` | 委托属性(读=timer.is_armed(),写=arm()/disarm()) | `run_scope.settlement_stop_timer` 直呼(ui_click_probe 2 处读+main_adventure_flow 3 处写) |
|
||||
| 7 | `_deferred_modal` | 委托属性 = _modal_flow._deferred | `ui.modals.flow._deferred`(t17_defer_probe 1 处) |
|
||||
|
||||
对账:14(留)+28(进注册面)+7(消灭)=49 ✓;main 改后 = 14+1(ui)=**15,恰在阈值内**。
|
||||
|
||||
### 1.3 main.gd 改后类变量实数
|
||||
|
||||
**15**(14 留+ui)。gdstyle 的 max-class-variables 语义是「超过 15 才红」,15=绿。此后 main 每想加成员就是过阈红——这正是拆分纪律③的合规用法:过阈值作发现信号,新句柄该进注册面、新职责该拆新件。
|
||||
|
||||
## 2. 职责语句+单一变化原因
|
||||
|
||||
| 件 | 职责语句 | 单一变化原因 | 集体身份判据 |
|
||||
|---|---|---|---|
|
||||
| ui_registry | 「呈现层界面元素清单的唯一事实源——哪些层、什么序、地址在哪」 | 界面元素集合或层序变化(加屏/加覆盖层/改层序) | 它就是今天散在 main 的 LAYER_CONTRACT+_layer_node+一级句柄三样东西的合体;合同键、登记序、句柄址本是同一份清单的三个投影 |
|
||||
| ui_screens | 「不进模态栈的树位层册——三屏壳与其一级子层、全屏态、浮层角标、排播泵节点」 | 屏壳/全屏态/浮层集合变化 | 集体身份=LAYER_CONTRACT 里 kind≠modal 的项(shell/state/float/node)+屏内一级子层句柄 |
|
||||
| ui_battle | 「战斗屏四区(A 状态/B 明细/C 数据/D 棋盘)视图与结算演出句柄册」 | 战斗区视图构成变化(battle.md 三区面) | battle.md 三区+演出,是架构文档反复引用的既有概念,非本批发明 |
|
||||
| ui_modals | 「模态层域——十三个模态覆盖层句柄+模态栈编排(登记/开合/输入锁谓词)」 | 模态层集合或模态编排语义变化 | 集体身份=「被 ModalStack 登记的层」——遮挡互斥、开合同步、锁谓词是这 13 件共享的行为面 |
|
||||
|
||||
**禁凑计数袋自检(拆分判据①–⑤逐条)**:
|
||||
|
||||
1. 拆分沿职责轴:三容器的轴=LAYER_CONTRACT kind 轴+战区轴,两者都是本批之前就存在的领域轴;过阈值(49→15)只是**发现信号**,不是切分依据。
|
||||
2. 集体身份:每件命得出名字、说得清「共同表达什么」(见上表),没有一个容器是「剩下的成员」。
|
||||
3. 过阈值只作动机=违规:本设计若只把 30 个句柄原样搬进一件,那才是凑计数;按领域轴分三域+把合同机器(今天在 main 里同样占职责面的 LAYER_CONTRACT/_layer_node)一并归位,是职责收拢。
|
||||
4. 拆不出内聚单元须停卡:本设计拆得出(见上),不停卡。
|
||||
5. 禁无效成员/别名:本批**净消灭 7 个别名/转发成员**(§1.2 第三表)+退役 main 侧六个纯转发方法(§4.2),方向是减不是留。
|
||||
|
||||
依赖方向自检(§1.3):注册面只持视图引用、零核心写调用、零信号连接——它不是新的写调用出口,组合根单点装配不变;视图仍经信号到 main(或 main 拆件)再到 core,依赖单向零触碰。
|
||||
|
||||
## 3. 探针契约迁移
|
||||
|
||||
### 3.1 新地址形态
|
||||
|
||||
**推荐**:`main.ui.<域>.<句柄>`(例:`main.ui.modals.level_screen`、`main.ui.battle.board_zone`、`main.ui.screens.menu_screen`)。三段式地址每段都有领域含义(组合根→注册面→域→元素),与 ConfigDB 的 `db.<域容器>.<成员>` 两段式同构——本仓已验证的容器寻址形态。
|
||||
|
||||
**备选一(双容器直挂,`main.modals.X` 两段式)**:少一跳,但 main 要放 3 个容器成员,改后 main=16 过阈,只能再靠合并 `_confirm_consumer_slot` 之类凑减员——凑计数味,淘汰。
|
||||
**备选二(单件+字典存储+方法访问器 `main.ui.layer("legend_overlay")`)**:丢了类型化字段,且约 30 个访问器方法有撞 max-public-methods 默认阈值的风险(board_view 现值 27 已在基线,默认阈值必然更低)=新基线键=留债,淘汰。
|
||||
|
||||
### 3.2 改址策略(约 867 处探针/系统测试引用+约 200 处流程件 root.X 引用+main 自身)
|
||||
|
||||
**机械映射表**(实现批以脚本生成+对账,人工复核语义位):映射表条目形如 `旧路径 → 新路径`,来源即 §1.2 对账表。三类引用分别处理:
|
||||
|
||||
1. **属性读/写(约 750 处)**:`main.<名>` → `main.ui.<域>.<名′>`(`名′`=去下划线后的名)。前缀链式读写在 GDScript 天然支持(`main.ui.modals.debug_overlay.seed_edit.text = "42"` 与现形态同构);探针里 `var bv = main.board_view` 的局部承接习惯使别名消灭的实际改动收敛到每文件 1–2 处。
|
||||
2. **方法调用(约 110 处,其中绝大多数零迁移)**:组合根流程方法(`_start_adventure_from_menu` 16、`_open_save_select` 7、`_on_save_select_closed` 9、`_on_camp_closed` 6、`_on_battle_end_continue` 4、`_show_debug_overlay` 4、`_resume_from_menu` 3、`_flush_row_queue` 3、`_seed_value` 3 等)**留 main,零迁移**——它们是模式流转与流程入口,本就是组合根职责。真正改址的方法引用只有四条:`main._input_locked()`(18 处)→ `main.ui.modals.flow.locks_input()`;`main._layer_node(key)`(3 处,system_test)→ `main.ui.node(key)`;`main._open_modal/_close_modal`(探针各 1 处+流程件 root. 共约 23 处)→ `main.ui.modals.flow.open/close`;`root._open_modal_after_playback`(2 处)→ `root.ui.modals.flow.open_after_playback`。
|
||||
3. **字符串键取值(smoke_boot 的 `main.get("<名>")` 6 处)**:`main.get("run_scope")`/`main.get("settings_store")` 零迁移(留 main);其余改 `main.get("ui").<域>.<名′>`(get 只解析一层,后续走公共字段)。
|
||||
|
||||
**流程承接件随批同规改址**:main_ui_build 的赋值目标改 `root.ui.<域>.<名′> = ...`;main_adventure_flow/main_overlay_flow/main_debug_flow 的 `root.<名>` 同表映射。构造注入的 context 束(CurioFlowContext/CampFlowContext 的 overlay/toast/start_overlay 等键值)改址取值,注入时点与值不变。
|
||||
|
||||
**源码级断言随批重锚(易漏项,实查全量在案)**:
|
||||
|
||||
- `source_guard_test.gd` V1d「层序落位单口」:现扫描 main.gd 源码中 `_apply_layer_contract` 之外零 `move_child(`。合同机器迁入 ui_registry 后,重锚为「扫全 `game/presentation/*.gd`:`move_child(` 只允许出现在 ui_registry.gd 的 `apply_layer_contract` 函数体内」(判据同步强化:从扫单文件变扫全目录,比原判据更严)。
|
||||
- `theme_projection_test.gd` V6:`main_src.contains("debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)")` 字符串断言 → 改为 ui.modals.debug_overlay 新串。
|
||||
- 其余 main.gd 源码断言(V8 GP 影子账残留检查)为「禁止出现」型,不受影响;`meta_progression_forge_test` 经 `load("res://presentation/main.gd")` 直呼 static `build_adventure_params`——留 main,零迁移。
|
||||
|
||||
**改址完整性自检**(验收辅证):映射表驱动的全仓 grep——`game/` 下(探针/tests/flow 四件/main 自身)旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留必须为 0(按 49 名逐名 grep,报告留档)。
|
||||
|
||||
### 3.3 architecture 登记句改写建议
|
||||
|
||||
「呈现层装配与会话生命周期 §三屏壳与组合根句柄面」现句(含 S13 豁免登记)整句退役,建议改写为:
|
||||
|
||||
> 屏成员与覆盖层句柄经**界面注册面**(main.ui,`ui_registry.gd`+三域容器 ui_screens/ui_battle/ui_modals,全 RefCounted)统一暴露;探针挂载假设=`main.ui.<域>.<句柄>` 路径(2026-10-29 用户裁「不允许任何豁免」——原「组合根 main.gd 一级句柄(main.X 路径零迁移)」挂载假设与 S13 豁免登记同批注销,探针面全量改址,行为零变化由 probe_gate/render_gate/冒烟/系统测试四闸主证)。组合根 main.gd 成员面收口为组合根自身状态+拆件引用+autoload 读视图(类变量 15,阈内)。层序唯一事实源=`ui_registry.LAYER_CONTRACT`+`ui.apply_layer_contract()`;模态登记/开合/锁谓词单口=`ui.modals`(ModalFlow 语义零变化)。
|
||||
|
||||
「模块归属·呈现层」表同步增四行(四新件),main_ui_build 行的「层序逻辑不在此件——唯一事实源仍是 main.LAYER_CONTRACT」句改指 ui_registry。
|
||||
|
||||
## 4. main.gd 改后形态
|
||||
|
||||
### 4.1 剩余成员清单
|
||||
|
||||
见 §1.2 第二表(14 留+ui,逐个理由在表内,不重复)。文件头注同步改写:组合根职责语句追加一句「界面句柄与层清单在 ui 注册面(ui_registry.gd)」。
|
||||
|
||||
### 4.2 接线流程变化
|
||||
|
||||
1. **装配入口**:`_ready` 在 `_build_ui()` 之前 `ui = UiRegistry.new()`(容器随门面构造);`MainUiBuild.build(self)` 八步内部赋值目标全部改 `root.ui.<域>.<名′>`,八步顺序、add_child 顺序、连接语句逐条不变。
|
||||
2. **MainUiBuild 交付物改型**:build 签名不变(仍 `build(root)`),改的是写入目标——从「给 root 造 30 个一级成员」变「往 root.ui 三容器登记」。装配序与 z 序零改动(合同落位仍最后一步)。
|
||||
3. **合同机器搬家**:`LAYER_CONTRACT` 常量(内容逐字不动)、`_apply_layer_contract()`(root 作参传入)、`_layer_node(key)`(改为 ui_registry.`node(key)` 的 19 键 match)、`_register_modal`(改入 ui_modals 为 `register_layer(m, tags)`,anchors preset+flow.register 语义逐字)四样整体迁入注册面;main 侧不留转发壳。
|
||||
4. **模态口收口**:main 的六个纯转发方法退役——`_open_modal`/`_close_modal`/`_on_modal_closed`/`_input_locked`/`_open_modal_after_playback`/`_on_pump_ended`。调用方(三个流程件、context 注入束、row_pacer.pump_ended 注入点、信号 connect 的 bind 目标、探针)一律改指 `ui.modals.flow` 真方法;`_replay_locked_click` **留 main**(读 run_scope.locked_click+调 _on_board_action,是组合根行为,作为回调注入 flow 不变)。
|
||||
5. **`_seed_value()`**:种子框读取改 `ui.modals.debug_overlay.seed_edit.text`(全工程唯一种子框读取处纪律不变)。
|
||||
|
||||
### 4.3 LAYER_CONTRACT 与 _apply_layer_contract
|
||||
|
||||
合同表条目、顺序、tags、host/shell 标注**逐字零变化**,只换宿主文件;落位算法逐字搬运(move_child 单口语义不变,冒烟 V1d 判据按 §3.2 重锚后仍覆盖「全 presentation 无第二落位点」)。改层序仍只改合同表。
|
||||
|
||||
### 4.4 RunScope 生命周期零变化声明
|
||||
|
||||
`_begin_session`/闲时会话/整节点 `queue_free` 机制**一字不动**;run_scope 留 main,注册面与三容器**零会话期引用**(不持 adventure/runner/settlement,控制器仍走现值回调),会话更替对注册面完全透明。存活性矩阵第五引用面的四持句柄件+_row_pacer 逐面同源比对断言(system_test V3a–V3i)逻辑零变化,仅 `_modal_flow`→`main.ui.modals.flow`、`_row_pacer`→`main.ui.screens.row_pacer` 两处取址随批改。
|
||||
|
||||
## 5. 行为零变化风险点
|
||||
|
||||
1. **装配与接线时序**:容器在 `_ready` 建闲时会话之前创建并装配完毕,八步 build 顺序、`_apply_layer_contract` 末位调用点、信号连接顺序逐条不变。风险形态=漏改一处地址→运行期 null 实例 SCRIPT ERROR→被冒烟闸③与探针 error_scan 抓住(不静默)。
|
||||
2. **模态开合**:ModalFlow 的八个查询/钩子 Callable(start_visible_get/inter_visible_get/settlement_get/rows_empty_get/flush_rows/on_open_sync/on_close_sync/replay_click)注入值不变,仅 `root._start_overlay.visible` 这类 lambda 体内取址改 `root.ui.screens.start_overlay.visible`;开合编排、挂起兜底、点击重放语义零触碰。
|
||||
3. **会话更替**:注册面零局态引用(§4.4),queue_free 不触及;row_pacer 节点本体仍 add_child 到 main、树位由合同落位,注册面只持引用——第五引用面断言改址后逐面同源比对仍成立。
|
||||
4. **别名消灭的断言等价性**:board_view/ap_bar/_modals/_row_queue 四件消灭后,探针断言经多一跳取到**同一对象引用**(属性链与别名同指),断言语义逐条等价;system_test V1 的句柄等价断言(`main.board_view == main._adventure_screen.board_view` 型)改址为 `ui.battle.board_zone.board_view == ui.screens.adventure_screen.board_view` 后仍是有效的装配结构断言。
|
||||
5. **接缝属性消灭的读/写映射**:`_settlement_stop_pending` 读=armed→`is_armed()`、写=arm/disarm→同名方法直呼,映射一一对应且 run_scope 在探针用时点恒非空(_ready 即建,永非 null 契约);`_deferred_modal`→`flow._deferred` 同字段直读。
|
||||
6. **演出链**:settlement_fx/row_pacer 的 play/enqueue 调用点改址不改序——结算行排播、轮横幅、锁期点击重放的时序敏感面(T17)零触碰;t17_defer_probe 挂起态断言改读 `flow._deferred`,判据不变。
|
||||
7. **源码级断言漏改**:V1d/V6 两处实查在案(§3.2),随批重锚;若存在未登记的字符串匹配型断言,run_all 关联档跑批暴露——本设计已全量 grep `presentation/main.gd` 引用面确认只有上列两件。
|
||||
|
||||
RNG 消费序零触碰(本批不涉任何随机面);PARITY 触面(battle_orchestrator.gd)不在 diff;呈现层订阅禁令、核心写调用唯一出口纪律零触碰。
|
||||
|
||||
## 6. 验收载体建议
|
||||
|
||||
| 闸 | 载体与判据 |
|
||||
|---|---|
|
||||
| probe_gate | **默认段+`--click`+`--full` 全跑**——探针是本批改址的第一消费方(ui_click_probe 1079 行是最大户),只跑默认段会漏最深的改址面;判据=全段退出码 0 |
|
||||
| render_gate | golden 零差异(shot_probe 七屏+菜单 golden+棋盘 golden)——视觉零变化的主证 |
|
||||
| run_smoke | V1 装配句柄在位(get() 键改址后)+V2 启动态六条——boot 侧证明注册面装配完整 |
|
||||
| run_system_test | V1–V9 全绿:LAYER_CONTRACT 寻址(改 ui.LAYER_CONTRACT/ui.node)、句柄等价、存活性矩阵、模态互斥、两连局+续玩 |
|
||||
| run_all(关联档) | 申报套件:source_guard_test(V1d 重锚)、theme_projection_test(V6 字符串)、pacing_queue_test(_row_queue 改址)、meta_progression_forge_test(static 入口零变化);main.gd 是否按横切面回落全量套件见 §8 待裁点 |
|
||||
| static_scan | S9 过(四新文件全类型标注);S13 键账:main.gd 键从基线消失、四新文件零新键(§7) |
|
||||
| 改址完整性自检 | §3.2 的 49 名逐名 grep 残留=0,报告留档(实现报告对照表挂行) |
|
||||
|
||||
验收闭合口径(test-conventions §8):判据绑定面=「探针经新地址取到同一节点并驱动真实输入路径」——probe_gate 全绿+系统测试全绿+golden 零差异三件齐,即「改址不改变行为」的真实入口主证;grep 自检只作完整性辅证,不作行为判据。
|
||||
|
||||
## 7. gdstyle 键账预期
|
||||
|
||||
| 文件 | 改后类变量 | 键账 |
|
||||
|---|---|---|
|
||||
| main.gd | **15**(14+ui) | 基线键 `main.gd|quality/max-class-variables = 49` 消失——还债方向下降,注销合法 |
|
||||
| ui_registry.gd | 3 | 零新键 |
|
||||
| ui_screens.gd | 9 | 零新键 |
|
||||
| ui_battle.gd | 5 | 零新键 |
|
||||
| ui_modals.gd | 14 | 零新键(阈内,余量 1) |
|
||||
|
||||
基线 refresh 人工跑(`--refresh`):净减 1 键(约 15 键的 6.7%),低于 10% 骤降守卫,无需 `--force`。四新文件其余质量键(max-public-methods/max-file-length 等)预期零命中——容器纯字段无长函数,match 键数(19)在 max-branches 默认内,若实现批实测出新键按基线外 NEW 红处理、不得开豁免(用户裁决口径统一适用)。
|
||||
|
||||
§3.3 的登记句改写即豁免注销文案;「S13 豁免登记第二/三条」(tune_sim_controller、battle_orchestrator)不在本批范围、原文不动。
|
||||
|
||||
## 8. 估时与待裁点
|
||||
|
||||
**估时:3–4 个工作日**。构成:映射表脚本生成+四文件建件+main/流程件改址 1–1.5 天;探针/系统测试/冒烟改址+源码级断言重锚 1 天;闸循环(probe_gate --click --full/render golden/smoke/system_test/run_all 关联档/static_scan)修复余量 0.5–1 天;architecture 登记句+模块归属表+卡片改动—验收对照表 0.5 天。低于迭代冻结线(5 工作日),可编批。
|
||||
|
||||
**待裁点(呈用户裁决)**:
|
||||
|
||||
1. **注册面拓扑**:推荐「一门面+三域容器」(§1.1,main=15);备选「双容器直挂」因 main 会过阈 16、需再凑减员而淘汰。是否照推荐案执行。
|
||||
2. **合同机器是否随批迁入注册面**:推荐迁(LAYER_CONTRACT+_apply_layer_contract+_layer_node+_register_modal → ui_registry/ui_modals,职责闭合);不迁则注册面只管址不管序,main 留合同——两案都可达 15,迁是内聚更优解但多动 V1d/system_test 约 8 处。
|
||||
3. **消灭与改名清单**:七个别名/转发成员消灭+六个 main 纯转发模态方法退役+容器内成员去下划线(对齐合同键名)——涉及探针断言面写法(`main._input_locked()`→`ui.modals.flow.locks_input()` 等),请整体确认或逐项裁。
|
||||
4. **run_all 关联档口径**:main.gd 是全探针宿主,保守口径=按横切面回落全量套件;精确口径=只跑 §6 申报四件。请裁跑批档位。
|
||||
5. **编批**:估时 3–4 天在冻结线内,编入哪个迭代由迭代编排段定。
|
||||
@@ -1,231 +0,0 @@
|
||||
# 需求卡片——gdstyle 尾波清偿批
|
||||
|
||||
> **版本状态**:v2.0 定稿——设计段裁决已闭合(D1–D6 裁决记录见第 6 节,2026-10-29 用户裁),零待裁点,可编排。
|
||||
> **接收方**:待办清单条目「gdstyle 尾波清偿批——基线余量 11 键定向整改(2026-10-29 登记)」。
|
||||
> **来源**:gdstyle 尾波清偿分析(2026-10-29 基线重锚后余量清点)。**唯一事实源**:`tools/gdstyle_baseline.txt`(2026-10-29 重锚版,余量 16 键)+ `reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md`(§三波次方案、§六文档设计段裁定记录——裁定全部继续有效)。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
这批做什么:把 gdstyle 静态质量闸(S13)基线余量 16 键中的 11 键定向清偿——6 键降到阈值内(闸不再记它,下称归绿),5 键按第 6 节裁决维持或降值后走 architecture 豁免登记(批末随实测值落文)。手段只有两类:存量文件内部拆私有函数(呈现层先例)、按职责拆协作件(核心层先例)。
|
||||
|
||||
什么状态算完:
|
||||
|
||||
1. 11 键逐键达到第 7 节写明的预期结果(归绿 6/豁免 5——豁免键实测值落 architecture 豁免登记段)。
|
||||
2. 游戏行为零变化:同种子下事件流、步骤流、断点快照、棋盘渲染逐位一致(第 4 节红线)。
|
||||
3. 批末代码域闸全绿(冒烟+单元+集成+探针+渲染 golden+静态扫描),键账对账完成(第 13 节)。
|
||||
4. 实现报告与反哺点清单落 `reports/`(末卡产出物落位卡)。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
本卡属需求性工程条目(结构整改、改游戏代码面),按五段流水线凭工程债证据写卡;四个拆件项的设计段裁决于 2026-10-29 经用户裁闭合(记录见第 6 节)。证据指认:
|
||||
|
||||
- `tools/gdstyle_baseline.txt`——2026-10-29 人工重锚后的现行基线,16 键;本卡 11 键逐条列于第 3 节,键名与本卡逐字一致。
|
||||
- `reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md` §六裁定记录 7 条(段组织、波 2/波 6 形态、config_db 定性、判定口径、独立审查折入、2026-10-27 三卡归并)——继续有效,本卡沿用其中对呈现层「内部拆私有函数、不拆构建步件」与「全部波不改游戏规则与玩家可见行为」的裁定。
|
||||
- `design/engineering/architecture/architecture.md` v1.24——轴丙 BoardInstaller(装板域拆件)已随本卡设计闭合落文(模块归属功能层新行+拆件定稿节增补),实现照册施工。
|
||||
- 并排执行卡:`reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md` v1.1(键 7 拆除执行合同——D6 并排编队,见第 6 节)。
|
||||
|
||||
## 3. 现状事实(代码级,开工自行复核;行号为 2026-10-29 实查)
|
||||
|
||||
基线 16 键中本批承接 11 键,其余 5 键(`main.gd` 类变量 49、`tune_sim_controller.gd` 循环内 await、`board_cell_unit.gd` 类变量 30、`standee_body.gd` 类变量 19、`battle_orchestrator.gd` 类变量 38)走豁免通道另行讨论,不在本卡。
|
||||
|
||||
| # | 基线键 | 现状/阈值 | 涉案位置 |
|
||||
|---|---|---|---|
|
||||
| 1 | `board_view.gd\|quality/max-function-length\|_paint_cell = 139` | 139/50 | `game/presentation/views/board_view.gd:601-739` |
|
||||
| 2 | `board_view.gd\|quality/max-branches\|_paint_cell = 24` | 24/8 | 同上 |
|
||||
| 3 | `board_view.gd\|quality/max-local-variables\|_paint_cell = 22` | 22/10 | 同上 |
|
||||
| 4 | `board_view.gd\|quality/allocation-in-loop`(裸键) | 命中 | `board_view.gd:249`——rebuild() 建格循环内 `_CELL_UNIT.new()` |
|
||||
| 5 | `board_view.gd\|quality/max-class-variables = 32` | 32/15 | `board_view.gd:49-85`(var 成员 31)+:93(`cell_size` 只读属性;计数以闸实测为准) |
|
||||
| 6 | `board_view.gd\|quality/max-public-methods = 27` | 27/20 | 全文件:11 setter+6 探针出口+4 几何契约出口+3 入站事件+2 生命周期(rebuild/refresh)+1 访问器(board()) |
|
||||
| 7 | `level_runner.gd\|quality/max-public-methods = 50` | 50/20 | `game/core/level_runner.gd`——其中商店同签名委托 17 个公开方法(751-828 行)+3 个私有转发(`_bind_shop`:728、`_spend_discounted`:772、`_shop_draw_shelf`:783)+`_shop` 成员(:44) |
|
||||
| 8 | `level_runner.gd\|quality/max-class-variables = 30` | 30/15 | `level_runner.gd` 类成员区(含 `hero_hp`/`gp` 两属性) |
|
||||
| 9 | `level_runner.gd\|quality/max-returns\|_enter_node = 7` | 7/6 | `level_runner.gd:486-513`——shop 分支 pool/legacy 双 return(:509、:511) |
|
||||
| 10 | `battle_orchestrator.gd\|quality/max-file-length = 1035` | 1035/1000 | `game/core/battle_orchestrator.gd`——装板与变异布置域六函数合计约 140 行(:414-549) |
|
||||
| 11 | `adventure_runner.gd\|quality/max-class-variables = 28` | 28/15 | `game/core/adventure_runner.gd:13-45` |
|
||||
|
||||
支撑事实:
|
||||
|
||||
- board_view 公开方法 27 个全是契约面:setter 是组合根注入面(依赖单向纪律),探针出口(cells_probe/diggable_probe/hover_probe/fog_params_probe/type_glow_probe/cell_rect_probe)是探针断言面,几何出口与入站事件是演出与输入契约。可降空间极小。
|
||||
- battle_orchestrator 装板域六函数全仓零外部调用,仅本文件三处调用(:271 begin_battle、:801 _exit_distribution、:835 player_request_refresh)——拆件不触任何外部调用面。
|
||||
- 六函数现行均无超标键(基线无其函数级键);`_install_new_board` 体内 443-452 行为宿主态复位块(五处计数清零+板序推进+board_changed 发射+秘宝叠加层退役)——按第 6 节 D1 裁决留宿主薄壳。
|
||||
- `_board_generator` 全文件仅四处使用(:42 声明、:233 创建、:239 fatal 接线、:416 装板消费)——装板族独占,随件迁移后宿主成员退役(38→37)。
|
||||
- level_runner 商店委托面被呈现层 5 文件(camp_shop_presenter/main_adventure_flow/main_overlay_flow/main_ui_build/shop_overlay_view)、`game/sim/level_autoplay.gd`、测试 4 套件(level_shop_economy/pool_case_d/tree_rules_v11/hero_ledger)引用——shop_overlay_view 三处命中均为注释投影引用(:15/:88/:152 实查),代码调用面在 presenter/组合根拆件/sim 侧。
|
||||
- `tools/run_all_gates.sh` PARITY_TOUCH_FACES 含 `game/core/battle_orchestrator.gd`——本批必触面。
|
||||
- level_runner 商店委托面的完整行级调用点清单(19 壳含 2 死壳、跨类同名陷阱、呈现/sim/测试逐点行号)以并排卡 v1.1 §3 为准——本卡不重复罗列。
|
||||
|
||||
## 4. 设计契约(违反即返工的红线条款)
|
||||
|
||||
- 🔴 **行为零变化**:本批全部改动为结构整改,游戏行为零变化——同种子下事件流/步骤流/断点快照/存档往返/棋盘渲染逐位一致;玩家可见面零变化;`design/gdd/systems/` 零修订预期。
|
||||
- 🔴 **RNG 取号序零漂移**:禁 `randomize()`/自建随机;battle_orchestrator 装板域拆件时 `board_gen`/`variant_place` 两封闭流随件迁移**取号序不变**(流名、开流时点、消费序零漂移——先例句「fx_reveal 封闭流随件迁移取号序不变」同款)。
|
||||
- 🔴 **PARITY 触面**:battle_orchestrator.gd 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚。
|
||||
- 🔴 **呈现零变化**:board_view 改动的画面判据=`game/tests/golden/` 既有三张棋盘基线(L1 dungeon/L2 underdark/L3 deep_underdark),对拍差异非零即红;重建基线只许用户批准,实现批禁自行换锚。
|
||||
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,此处立卡内执行条款):①每个拆出单元须有可陈述的职责语句与单一变化原因(实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只许作为发现信号,作为拆分或收拢的动机即违规;④按纪律拆不出内聚单元 → 停卡呈报走豁免/还债通道,禁硬拆凑绿;⑤拆分沿职责轴不沿阈值轴。
|
||||
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名——装板域拆件后宿主 `_board_generator` 成员随之退役(38→37);机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
|
||||
- 🔴 **基线纪律**:禁为过闸 refresh 换绿;还债=数值下降自然绿;出现恶化=停卡呈报(细则第 13 节)。
|
||||
- 🔴 **attune 族与 begin_battle 序列禁动**:battle_orchestrator 的 attune 族原位保留(迭代 39 副卡语义领地);begin_battle 受理段序与五段驱动逻辑禁动——装板域拆件只改 `_install_new_board()` 调用点的取件改址。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
做什么:第 3 节 11 键中本卡直接执行的三项改动(第 7 节逐键方案、第 12 节任务卡)——board_view 拆分(键 1–4)、_enter_node 载荷合并(键 9)、装板域拆件(键 10);键 7 的拆除执行合同=并排卡「level_runner 商店委托层拆除」v1.1(D6 裁定并排编队,见第 6 节)。
|
||||
|
||||
不做什么:
|
||||
|
||||
- 商店委托壳拆除的执行——D6 裁并排编队:执行合同=在册定稿卡 v1.1(零待裁点),本卡不重复执行、只承接键账与豁免登记。
|
||||
- 悬停域拆件与断点域拆件——D2/D4 裁不拆(第 6 节),键 5/6/11 直送豁免终局。
|
||||
- 5 个豁免讨论键(main.gd/tune_sim_controller/board_cell_unit/standee_body/battle_orchestrator 类变量)——去向:豁免通道批末与本批 5 键合并一次落文,本卡不落文、不落反哺点。
|
||||
- 波次方案其余文件(审计报告 §三波 1–8)——已由迭代 39/40/41 清偿,不在本卡。
|
||||
- `game/tests/README.md`——实现批禁写;GP 钱包行真实入口列已随本卡 v2.0 改为 ShopSession 直连(计划入口,闸双通道认卡),批末核对表上名字与实际落地一致。
|
||||
- 数值表、RNG 流词表、信号载荷 schema——零触碰。
|
||||
|
||||
## 6. 设计段裁决记录(2026-10-29 用户裁——D1–D6 全部闭合)
|
||||
|
||||
| 编号 | 裁决 | 依据(推导链摘要) |
|
||||
|---|---|---|
|
||||
| D1 | ✅ 装板域拆新件 BoardInstaller,两修正 | 六函数构成可命名内聚单元(生成→决议→装板→摇号→布置,单一变化原因=棋盘设置顺序与变异布置算法);三调用点全宿主内实查零外泄;不在 v1.22 保留面;文件长键唯一归绿路径。**修正一**:复位块(442-451 行)留宿主薄壳 `_install_and_reset`,非逐字搬运;**修正二**:`_board_generator` 装板族独占(四处实查)随件迁移,宿主成员退役 38→37。已落 architecture v1.24 轴丙。 |
|
||||
| D2 | ❌ 悬停域不拆 | 键 5/6 无一可由此归绿(类变量 32→30 仍红、公开方法持平 27);波 6 既定裁=普通视图内部拆私有函数、不立周边件;悬停 11 函数全部低于阈值(无 S13 标的),拆分仅剩计数动机、踩 §1.1-③ 灰区;新件+束注入+入站口委托的代价不成比例。键 5/6 直送豁免;`_r0` 归属认定随之作废。 |
|
||||
| D3 | ✅ 商店域候选 A(删委托壳),`_shop` 公开化留宿主 | ShopSession 迭代 37 已建(33 公开方法实查),委托面=纯 Middle Man(2026-10-26 真拆分设计会话已裁「纯转传委托=反模式」);拆除方向 2026-10-26 已在册登记,本卡系执行既定发令;公开方法 50→33。`_shop` 公开化留宿主——`_enter_node` shop 分支与断点片段仍需持引用,非无效成员;类变量 30 不降,归豁免。执行合同=并排卡「level_runner 商店委托层拆除」v1.1(零待裁点)——其契约精度高于本卡初案(19 壳含 2 死壳行级清单、`_shop`→公开成员更名形态、两段式中间态、跨类同名判别),按其施工。 |
|
||||
| D4 | ❌ 断点域不拆 | 键 11 无键可绿(28→22 仍红);现位置不违反任何已立边界——SlotStore 拆分立的界约束的是 save_manager 不吞断点逻辑,非要求断点逻辑离宿主,断点协议住在冒险生命周期 owner 内本身内聚;`_save_manager` 非断点独占(:371 boss 首杀读、:521 abandon 清断点写盘实查),件化须双持引用、束复杂度超收益;27 键冻结契约扰动收益为零。若未来断点协议自身扩展,届时按职责轴立件。键 11 直送豁免。 |
|
||||
| D5 | ✅ 五个降值键豁免登记终局 | board_view 类变量 32/公开方法 27、level_runner 公开方法 33(删壳后)/类变量 30、adventure_runner 类变量 28——可降途径已按代价裁完,残留面全为契约承载或运行本态;无偿还计划的债=未注记豁免,不如把理由落权威文档。批末按实测值落 architecture「测试与质量域」S13 豁免登记段(先例=battle_orchestrator 第三条形态:键永久基线内、禁再恶化、豁免不等于了结)。 |
|
||||
| D6 | ✅ 商店域并排编队(写卡期修正:原「吸收」案否决) | v2.0 初稿裁「本卡吸收在册条目、删除其卡」;落笔时发现该域已有定稿执行卡——「level_runner 商店委托层拆除」v1.1(2026-10-29,复核门通过零待裁点),契约精度高于本卡 T6 粗案,销定稿卡重写粗案=无收益损耗。改判:**两卡同迭代并排编队**(编排段并列排入、执行顺序先后皆可——level_runner 交叠为不相邻区段零冲突),本卡承接键账与豁免登记、不重复执行拆除;在册条目与其卡维持,随其自身批完成删除。 |
|
||||
|
||||
## 7. 逐键方案(11 键:现状值/阈值/方案方向/预期结果)
|
||||
|
||||
预期分两档:**归绿**(拆后实测低于阈值,下批重锚后键消失)与**豁免终局**(维持或降值,批末随实测落 architecture 豁免登记段)。
|
||||
|
||||
| 键 | 现状/阈值 | 方案方向 | 预期结果(档位) |
|
||||
|---|---|---|---|
|
||||
| 1 board_view _paint_cell 长度 | 139/50 | 拆分层私有函数族(键 1–3 同一改动,见 T1)——五段=基底瓦片→字形与色牌→立面投影→秘宝/变异叠加→迷雾,段间只经 u.st/glyph/digit_col 传值;段内分支仍超 8 时沿绘制层轴继续下钻 | ≤50,**归绿** |
|
||||
| 2 board_view _paint_cell 分支 | 24/8 | 同上 | ≤8,**归绿** |
|
||||
| 3 board_view _paint_cell 局部变量 | 22/10 | 同上 | ≤10,**归绿** |
|
||||
| 4 board_view allocation-in-loop | 命中 | `.new()` 移入逐项构建私有函数 `_build_cell_unit(c, stride)`,循环体只调构建器(先例=battle_end_overlay._seal_img/_ledger_row 族) | 消除,**归绿** |
|
||||
| 5 board_view 类变量 | 32/15 | 无拆分动作(D2 裁不拆——第 6 节) | 32 维持,**豁免终局** |
|
||||
| 6 board_view 公开方法 | 27/20 | 无动作(27 个逐类核对全为探针契约面与依赖单向纪律承载面) | 27 维持,**豁免终局** |
|
||||
| 7 level_runner 公开方法 | 50/20 | 执行合同=并排卡「level_runner 商店委托层拆除」v1.1(19 委托壳删除+`_shop` 公开化;本卡不重复执行——D6) | 约 33,**降值后豁免终局**(豁免登记随本卡批末落文) |
|
||||
| 8 level_runner 类变量 | 30/15 | 无动作(`_shop` 留宿主——D3 裁,非无效成员) | 30 维持,**豁免终局** |
|
||||
| 9 level_runner _enter_node 返回数 | 7/6 | shop 分支 if/else 双 return 合并为载荷变量单 return;两个 payload 字典逐字保持(pool 分支 `{"gp": gp, "shelf": true}`、legacy 分支 `{"gp": gp}`),零契约风险。备选(code-conventions §1.1-③ 红线):若实现期发现合并构成纯计数扭曲则留债呈报——本卡按「合并属同一停点语义的两条发射路径归一」认定有内聚收益 | 6,**归绿** |
|
||||
| 10 battle_orchestrator 文件长 | 1035/1000 | D1 装板域拆件:六函数迁出+宿主薄壳承接复位块+`_board_generator` 成员退役 | 约 910–920(拆后实测),**归绿** |
|
||||
| 11 adventure_runner 类变量 | 28/15 | 无动作(D4 裁不拆——第 6 节) | 28 维持,**豁免终局** |
|
||||
|
||||
## 8. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md | 「战斗编排域拆件定稿」节轴丙与功能层 BoardInstaller 行——**已随本卡 v2.0 设计闭合落文(v1.24)**,实现照册施工;level_runner 行「外部调用面由同签名委托承载」句(D3 候选 A 实现后失真);「测试与质量域」S13 豁免登记段(D5 五键——批末按实测值落文) | 设计权威文档——实现批禁直改;level_runner 句与豁免登记逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
|
||||
| game/tests/README.md | 「GP 钱包/escrow/商店收口/共享池」行真实入口列——已随本卡 v2.0 改为 ShopSession 直连(计划入口,闸双通道认卡);「棋盘悬停反馈」行已随 v1.0 入表(能力独立成立,不随 D2 裁定变化) | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
|
||||
| design/gdd/systems/(全树) | 无关联文档——结构整改不改游戏规则与玩家可见行为(审计报告 §六.5 判定口径沿用) | 无修订预期;若实现中发现契约句被触碰,停卡呈报走反哺点通道 |
|
||||
|
||||
## 9. 卡前文件结构图
|
||||
|
||||
| 文件 | 职责 | 改动性质 |
|
||||
|---|---|---|
|
||||
| game/presentation/views/board_view.gd | 棋盘视图壳层(格态渲染入口、入站事件、探针出口) | 修改(非行为改动——_paint_cell 拆分层函数族、rebuild 构建器;验收=对照表行 V1) |
|
||||
| game/core/level_runner.gd | 关卡域生命周期编排者 | 修改(非行为改动——仅 _enter_node 载荷合并〔载荷逐字保持〕;商店委托壳区段归并排卡,本卡不触——验收=对照表行 V3) |
|
||||
| game/core/battle_orchestrator.gd | 战斗结算编排中枢 | 修改(非行为改动——装板域六函数迁出、宿主薄壳承接复位块、`_board_generator` 成员退役、三调用点改址;验收=对照表行 V4) |
|
||||
| game/core/board_installer.gd | 棋盘安装与变异布置域件(新增,architecture v1.24 功能层在册) | 新增(非行为改动;验收=对照表行 V4) |
|
||||
| game/tests/unit/core/level_shop_economy_test.gd | 关卡图与商店宿主套件 | 修改(仅新增断言 _test_shop_node_entered_payload〔尾波 V1〕;委托面调用点改址归并排卡) |
|
||||
| game/tests/unit/core/run_time_fatal_test.gd | 运行期违约通道负面套件 | 修改(wr5 棋盘生成半边改指 BoardInstaller 新组装点——T0 复核补查项:卡面 §3 漏查的该测试白盒取数点 `_board_generator` 随成员退役断链,wr5 断言目标违约→封印传导不变) |
|
||||
| game/tests/static_scan.sh | 静态扫描域承载 | 修改(S7 B1 域文件集与 S8 await 文件集增行 board_installer——工程随动,architecture 拆件定稿节 S7/S8 随动条在册) |
|
||||
|
||||
新增件「为什么不能复用」理由与唯一落点核查见第 10 节;对不上即卡片不成立。
|
||||
|
||||
## 10. 落位与可复用性预检
|
||||
|
||||
- **board_installer.gd(新增)**:复用面核查——装板与变异布置逻辑现行只存在于 battle_orchestrator(全仓 grep 六函数名仅本文件三处调用,无第二实现),无既有件可复用;不能并入 BattleFxHost(效果引擎宿主域,变化原因不同)也不能并入 RewardGrant(授予管线域)。落点唯一:B1 域新文件,`game/core/`。分层:core 层 RefCounted,零 UI、零 await,经引用束注入取协作对象,禁裸引用 autoload(S5);BoardGenerator 实例件内自建并接线 fatal 回调。
|
||||
- **新增函数**:_build_cell_unit、_paint_cell_* 段函数族、宿主薄壳 `_install_and_reset`——全部是既有函数体的逐字搬运或循环体内联体出函,无新增逻辑;迁移函数对账见第 11 节。**零新增数据件、零新增常量表**。
|
||||
- **调用路径显式声明**:board_installer 只被 battle_orchestrator 三调用点(经宿主薄壳)调用——禁反向持有宿主引用(注入回调单向,先例=BattleFxHost 兑付回调)。
|
||||
|
||||
## 11. 实现规范预算(新件对照 gdstyle 默认阈值;写码前对账,超预算面=停卡退回写卡段)
|
||||
|
||||
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账(基线源函数键) |
|
||||
|---|---|---|---|
|
||||
| board_installer.gd | 预算 1(install) | 预算 7(引用束成员 rng/db/minesweeper/reward_economy/encounter 引用/fatal Callable+自建 BoardGenerator) | 六函数现行均无超标键(基线无其函数级键);`_install_new_board` 拆件体与宿主薄壳两段合计行数逐字=计数不变=新文件零新增键 |
|
||||
| 新增私有函数(board_view/level_runner 内) | —(私有不计数) | 零新增成员(类变量只降不升) | _paint_cell 三键随拆分消除;段函数逐个低于默认阈值(超 8 分支的段沿绘制层轴下钻,见第 7 节键 1) |
|
||||
|
||||
存量触面一查:涉案存量文件 T0 读数写明「S13 键较登记值只降不升」预期——board_view 6 键(3 归绿+1 消除+2 维持不升)、level_runner `_enter_node` 键归绿(键 7/8 归并排卡与豁免通道,本卡不触)、battle_orchestrator 文件长归绿(类变量 38→37 只降);adventure_runner 本批零触碰(键 11 维持)。`_init` 一律引用束注入(字典束),防 max-parameters 新键(先例=迭代 40 卡①)。
|
||||
|
||||
## 12. 任务卡 T0..T7(估时为区间;工作量限制只属迭代层)
|
||||
|
||||
**T0 读数复核与对账(0.25–0.5 工作日)**
|
||||
|
||||
- [ ] 以当轮 master 重测 11 键实测值,与基线登记值逐键对账(审计报告 §四.6 纪律:禁按本卡行号直接施工);对不上即停卡呈报
|
||||
- [ ] 复核涉案文件行数与第 3/7/9/11 节全部 file:line 引用;漂移处就地改卡并记录
|
||||
|
||||
**T1 board_view 拆分——4 键归绿(1–1.5 工作日)**(取用:T0 读数;产出:归绿键 1–4)
|
||||
|
||||
- [ ] `_paint_cell` 拆五段分层函数族 `_paint_cell_base/_paint_cell_ink/_paint_cell_facade/_paint_cell_overlays/_paint_cell_fog`(骨架见第 7 节键 1;主函数留格态读取与终写),函数体逐字搬运、段内超 8 分支沿绘制层轴下钻
|
||||
- [ ] rebuild() 建格循环抽 `_build_cell_unit(c: Vector2i, stride: float) -> Node2D`,`.new()` 与属性装配逐字迁入
|
||||
- [ ] 孤立验证:`godot --headless --script res://tests/run_all.gd -- --only=type_glow,theme_projection,player_copy` 全绿+`tools/probe_gate.sh --click` 全绿(出红只跑红件最小单元)
|
||||
- [ ] `tools/render_gate.sh` 棋盘 golden 三张对拍差异 0.00%(非零即停机呈报)
|
||||
|
||||
**T2 level_runner _enter_node 载荷合并——键 9 归绿(0.25 工作日)**
|
||||
|
||||
- [ ] shop 分支 pool/legacy 双 return 合并为载荷变量单 return,两 payload 字典逐字保持(pool `{"gp": gp, "shelf": true}`/legacy `{"gp": gp}`)
|
||||
- [ ] 新增断言 `level_shop_economy_test.gd:_test_shop_node_entered_payload`(规格见对照表 V3)
|
||||
- [ ] 孤立验证:`-- --only=level_shop_economy` 全绿
|
||||
|
||||
**T3 battle_orchestrator 装板域拆件——键 10 归绿(1–1.5 工作日)**(前置:architecture v1.24 轴丙在册)
|
||||
|
||||
- [ ] 建 `game/core/board_installer.gd`(引用束注入,第 10 节落位预检),装板逻辑六函数迁件;`_install_new_board` 拆件体=生成→决议→装板→摇号→布置(415-441 行段),宿主薄壳 `_install_and_reset` 承载复位块(443-452 行段:五处计数清零+板序推进+board_changed 发射+秘宝叠加层退役),时序逐字
|
||||
- [ ] 宿主三调用点(:271/:801/:835)改调薄壳;删宿主 `_board_generator` 成员(38→37,禁无效成员)
|
||||
- [ ] static_scan.sh S7 B1 域文件集与 S8 await 文件集增行
|
||||
- [ ] 孤立验证:`-- --only=variant_placement,round_flow,seal_polarity` 全绿+`python tools/run_smoke.py`
|
||||
- [ ] 文件长实测 ≤1000(键归绿);类变量实测 37
|
||||
|
||||
**T6 批末对账与收口(0.5 工作日)**
|
||||
|
||||
- [ ] 全量闸:`bash tools/run_all_gates.sh --code`(改动全为代码面)全绿;闸 11 触面按第 4 节 PARITY 条款由用户裁决
|
||||
- [ ] 键账对账:11 键终值对照第 7 节预期逐键核(归绿 6/豁免 5;键 7 终值视并排卡落地时序——同批编队即见 33);重锚由用户发令人工 `--refresh`(第 13 节);豁免登记 5 条+既有讨论 5 键按实测值落 architecture(反哺点通道)
|
||||
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+实现决定记录+逐拆出单元职责语句一行)与 `reports/iter<N>-反哺点-<日期>.md`(第 8 节同步面逐条落点)写齐方算收口
|
||||
|
||||
合计估时约 3–4.25 工作日(切分预案:T3 拆件裁决被证伪时按留债口径 −1~1.5 并回写第 7 节预期;并排卡 v1.1 的 ≈1.5 工作日不占本卡估时,编队总量由编排段合并计)。
|
||||
|
||||
## 13. 验证闸——改动—验收对照表
|
||||
|
||||
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(`tools/run_all_gates.sh --code`);里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。测试执行两入口铁规不破。总判据=每行改动以「既有断言面全绿+golden 零差异+(V4)同种子对拍」证明零行为漂移,无新增玩家可见面;全量闸电池=冒烟 run_smoke.py+系统测试 run_system_test.py+`run_all.gd` 全量+probe_gate --click --full+render_gate+static_scan(含 S13 对账)。
|
||||
|
||||
| 行 | 需求点(键) | 改动(文件:行) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V1 | 键 1/2/3/4——_paint_cell 拆分层函数族+rebuild 构建器 | board_view.gd:601-739 拆五段、:246-262 抽 _build_cell_unit | 复用 theme_projection_test.gd:_smoke_type_glow、type_glow_test.gd、player_copy_sweep_test.gd:_sweep_board_glyph(既有断言零改动);新增断言零条;render_gate 棋盘 golden 三张 | 单元+探针+golden | BoardView.rebuild()→refresh()→type_glow_probe();board_shot_probe 真实场景帧 | 既有套件断言面+golden 逐像素(差 ≤16/changed ≤2%)——**既有三张基线即改前基线,对拍差异非零即红;重建基线须用户批准** | 既有:未开格类型微光(8 邻作用集/五组色相/零玩法写入);既有:玩家面文案与危险格格面字形 |
|
||||
| V3 | 键 9——_enter_node 载荷合并 | level_runner.gd:503-511 双 return 并单 return | 新增 level_shop_economy_test.gd:_test_shop_node_entered_payload〔尾波 V1〕:pool 态 node_entered 载荷含 `shelf: true` 且 gp 等于进店时钱包现值;legacy 态载荷无 `shelf` 键。复用该套件商店房段既有断言 | 单元 | LevelRunner.start_level_external→pick_next_node 进 shop 节点 | node_entered 信号载荷(两 payload 字典逐字保持是本改动判据本体) | 既有:GP 钱包/escrow/商店收口/共享池 |
|
||||
| V4 | 键 10——装板域拆件 | board_installer.gd 新建;battle_orchestrator.gd:414-549 迁出、:442-451 复位块留薄壳、:271/:801/:835 改址 | 复用 variant_placement_test.gd:_smoke_variant_placement/_smoke_global_variant、round_flow_skill_pool_test.gd:_smoke_full_battle、seal_polarity_test.gd 全套;新增断言零条;PARITY 对拍按第 4 节条款 | 单元+集成+MC 对拍(须批准) | BattleOrchestrator.begin_battle()/player_request_refresh() | 同种子变异布置逐位断言面+全战斗步骤流逐行回放断言;board_gen/variant_place 取号序零漂移由同种子断言钉住 | 既有:变异布置门控;既有:轮内流与结算五段全序 |
|
||||
|
||||
反向核对:diff 中每个行为改动均有行——本批申报行为改动仅 V3 一处(载荷合并,行为保持);其余行均为非行为改动(结构整改,判据=零漂移证明)。孤儿断言:无(新增断言仅一条:V3 行〔尾波 V1〕,已挂行)。
|
||||
|
||||
## 14. 基线纪律(S13)
|
||||
|
||||
1. 禁为过闸 refresh 换绿:基线重生成只由用户发令,批末键账对账后人工 `python tools/gdstyle_gate.py --refresh` 一次执行(禁闸内自动重生成、禁实现批中途 refresh)。
|
||||
2. 还债=数值下降自然绿:拆件后同键数值下降不判红,无需动基线;归绿键在下批重锚后自然消失。
|
||||
3. 出现恶化(同键数值较登记值上升、基线外新键)=停卡呈报,禁自行消化。
|
||||
4. 重锚守卫:新键数较旧基线少逾 10% 须 `--force` 显式确认——本批预期归绿 6 键(16→约 10,降幅约 37%;键 7 随并排卡降值 50→33,同批编队时同一次重锚即含),须带 `--force` 由用户执行。
|
||||
5. 豁免键范围:既有豁免 5 键(main.gd 类变量等——不在本批对账范围;battle_orchestrator 类变量 38→37 为已登记豁免键,只降不升)+本批 D5 裁定 5 键(批末按实测值落文——键 7 实测值视并排卡落地时序;落文前照常按基线对账)。
|
||||
|
||||
## 15. MC/数值与 RNG 零触碰声明
|
||||
|
||||
本批零数值改动、零数据表改动、零 RNG 流词表改动、零玩法字面量引入——结构整改不改数值与 RNG 消费序。board_gen/variant_place 封闭流随件迁移取号序不变(流名、开流时点、消费序零漂移——同种子逐位一致)。数值与 RNG 零触碰则 MC 对拍不补跑;battle_orchestrator.gd 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚(批末闸 11 判 NEED-APPROVAL 时由用户裁决:批准实跑或裁跳过,卡内不定案)。
|
||||
|
||||
## 16. 异常分级
|
||||
|
||||
- **L1 自救**:迁移函数编译错、探针断言调用面改址漏改——就地修复重跑最窄确认。
|
||||
- **L2 记录继续**:实测值与第 7 节预期区间偏离但在同档位内(如降值幅度略小)——记入实现报告「实现决定记录」。
|
||||
- **L3 停机写报告等用户**:①拆分边界纪律④触发——按职责轴拆不出内聚单元(T1 五段/T3 装板域形态被证伪);②机检预算互斥——新件实数超第 11 节预算或迁移函数现出超标键=上游缺陷停卡退回写卡段;③golden 对拍差异非零;④S13 键恶化或基线外新键;⑤PARITY 触面处置分歧;⑥断言面被下游兜底吸收致判据绑不上(按 test-conventions §8.4 出口呈报)。
|
||||
|
||||
## 17. 测试削弱申报(允许改动的旧断言及理由)
|
||||
|
||||
零申报——本批不删任何断言、不改判据阈值、不缩扫描面、不把真实入口换成下层直调;唯一新增断言=V3 行〔尾波 V1〕(既有断言零改动)。商店委托面的测试改址归并排卡 v1.1 管辖(其自报零申报——只改调用地址,断言条件与期望值零变化)。未申报的削弱由独立验收审计判红。
|
||||
|
||||
## 18. 独立验收审计
|
||||
|
||||
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事(test-conventions §8.7):逐行核对第 13 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面;检查测试削弱(对照第 17 节申报);核对 V4 行「非行为改动」判定依据(零漂移证明是否在当轮真实跑批中成立)。未过不得合并。
|
||||
|
||||
## 19. 代拍板白名单(允许 agent 自行拍板的微决策)
|
||||
|
||||
1. 迁移函数头注注释的指址微调(词表与语义不动——「指址须真」纪律)。
|
||||
2. 新件私有 helper 命名在职责语义不变前提下的微调。
|
||||
3. 断言失败消息尾缀编号分配与措辞(〔尾波 Vn〕系列)。
|
||||
4. 调用面改址的机械改写(import/preload 顺序、空行排版)。
|
||||
5. 第 7 节键 1 段函数在五段骨架内的下钻粒度(沿绘制层轴)。
|
||||
|
||||
超清单决策记入实现报告「实现决定记录」节。
|
||||
|
||||
## 20. 裁决记录重申
|
||||
|
||||
D1–D6 已全部裁决闭合(2026-10-29 用户裁,第 6 节):装板域拆新件(两修正)/悬停域不拆/商店域候选 A 并排编队(执行合同=并排卡 v1.1)/断点域不拆/五降值键豁免终局——**零待裁点,卡片可编排**。豁免登记 5 条与既有讨论 5 键合并,批末按实测值经反哺点通道一次落文 architecture。
|
||||
@@ -1,185 +0,0 @@
|
||||
# 需求卡片——level_runner 商店委托层拆除批
|
||||
|
||||
- 版本:v1.1(2026-10-29,grilling 复核门通过——修正四项:跨类同名扫描判类归属、`_shop` 词级归零判据、set_shop_pool 陈旧调用方陈述订正、测试面精确计数)
|
||||
- 来源:待办清单「level_runner 商店委托层拆除——迭代 37 冻结契约期过渡件」(2026-10-26 登记,来源=批次移交;需求性工程条目,改动面=游戏代码)
|
||||
- 执行通道:需求改动——经迭代编排编入迭代后在独立 worktree 施工(仪式归 /iter);本卡估时合计 ≈1.5 个工作日(区间 1.5–2,超 2 停批呈报)
|
||||
- 迭代号:由编排段落位(本卡 `iter<N>` 占位符届时代换)
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
拆除 LevelRunner 的商店同签名委托层(19 个纯转传方法+「冻结公开面」契约注释),全部外部调用方直连 ShopSession;游戏行为零改动。
|
||||
|
||||
完成定义(全部满足才算完):
|
||||
|
||||
1. level_runner.gd 壳块(:722–728 区块注释涉委托句+:751–828 十九个委托)归零;宿主商店成员以公开名 `shop` 承载取件。
|
||||
2. 产品码、sim、测试面全部调用点改为 `<runner 表达式>.shop.<方法>` 直连,全仓无旧委托调用残留。
|
||||
3. 全部单元套件、冒烟、代码域闸绿;现有断言读数逐位不变(零新增断言、零断言删除)。
|
||||
4. 架构文档同步点入反哺点清单;实现报告与验收审计报告落 `reports/`。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
跳过设计线的证据指认(需求性工程条目,第〇步核验放行 2026-10-29):
|
||||
|
||||
- 待办清单条目实况:委托壳=迭代 37 卡④ ShopSession 拆分时立的「冻结公开面」契约过渡件;架构登记=`design/engineering/architecture/architecture.md:109`「外部调用面由 LevelRunner 同签名委托承载(外部零变化)」。
|
||||
- 拆除形态权威=`architecture.md:154`「调用直连:不留中间人委托壳(纯转传=Middle Man 反模式,2026-10-26 用户裁定)」。
|
||||
- 2026-10-29 写卡会话裁决:改址定式四条(公开成员取件/零调用死壳删/测试直连私有面/契约注释随壳消失)+ spend_gp 归属确认非问题(共享冒险钱包的校验扣款原语,宿主 ShopSession 语义自洽、不迁移)。
|
||||
|
||||
## 3. 现状事实(代码级,开工自行复核)
|
||||
|
||||
委托壳块:
|
||||
|
||||
1. level_runner.gd:723–725 区块注释(:723「商店房兑付」节头保留;:724「本类保留同签名委托」句+:725「白盒入口——外部调用面与断点取数面零变化」两句随壳删除)+:751–828 共 19 个同签名转传方法:shop_products:751/current_price:755/purchased_tier:759/buy_product:763/player_request_refresh:767/_spend_discounted:772/set_shop_pool:778/_shop_draw_shelf:783/pool_stock:787/pool_price:791/shop_shelf:795/shop_refresh_free_left:799/shop_refresh_cost:803/shop_refresh:807/spend_gp:811/buy_pool_item:815/is_shop_pool:819/shop_bp_shelf:823/shop_bp_visit_buys:827。
|
||||
2. 零外部调用方死壳 2 枚:`_spend_discounted`(全库仅 tree_rules_v11_test.gd:6 注释提及)、`pool_stock`(外部同名调用全为 CurioDeck.pool_stock,如 adventure_feats_test.gd:545——同名不同件)。
|
||||
|
||||
外部调用面(产品码与 sim):
|
||||
|
||||
3. 呈现层:camp_shop_presenter.gd:173–203(12 处)/main_adventure_flow.gd:81–86(6 处)/main_overlay_flow.gd:135/138/main.gd:773(player_request_refresh)/curio_interact_controller.gd:163(spend_gp——奇物三选一付费刷新出账)。
|
||||
4. sim:level_autoplay.gd:341/350/363/372/418/421(6 处)+:335 注释。
|
||||
5. 场景 .tscn 零引用、tests/system_test.gd 零引用(2026-10-29 全仓扫描)。**跨类同名方法不属本批面**(残留扫描判类归属的依据):BattleOrchestrator.player_request_refresh(round_flow_skill_pool_test ×5、seal_polarity_test:185、main.gd:775)与 CurioDeck.pool_stock(adventure_feats_test ×3、feat_vouchers_test ×2、pool_case_d_test ×3、level_shop_economy_test:1360/1361)——17 公开名 grep 命中须按接收方类归属判别,禁误改这两处同名面。
|
||||
|
||||
外部调用面(测试):
|
||||
|
||||
6. level_shop_economy_test.gd 实改址 25+白盒 `_shop_draw_shelf` :1344/:1355(公开名 grep 命中 27,内含跨类同名 `deck().pool_stock` :1360/:1361 非本批面)/hero_ledger_test.gd:60/66/adventure_feats_test.gd:364/pool_case_d_test.gd:45–47(:47=shop_bp_shelf)/treasure_effects_test.gd:229/233/curio_refresh_paid_test.gd:52–54/meta_progression_forge_test.gd:735–740。
|
||||
|
||||
保留面(非委托,仅随成员更名):
|
||||
|
||||
7. 宿主内部使用:level_runner.gd:99/102/104/305–306/506–507/704/729(建件、pool 注入、断点取数、进离店编排);钱包生命周期 `close_wallet`:718 归宿主自有(写 gp+发 clear 事件,不经商店)。
|
||||
8. 商店件本体 shop_session.gd 公开面现成(spend_gp:262 等),测试直连其私有 `_draw_shelf`:133/`_spend_discounted`:59 属测试侧改址。
|
||||
|
||||
登记与账面:
|
||||
|
||||
9. 架构:architecture.md:109(委托承载句+公开面格)/:154(直连原则);`design/` 全目录仅此一处委托登记(grep 考证 2026-10-29)。
|
||||
10. gdstyle 基线:tools/gdstyle_baseline.txt:11–13——level_runner 三键 max-class-variables=30/max-public-methods=50/max-returns|_enter_node=7。
|
||||
11. 能力清单:game/tests/README.md 旅程段四「GP 钱包/escrow/商店收口/共享池」行真实入口列引用委托名——已随本卡写作更新为直连形态(写卡段义务,实现批禁写该文件)。
|
||||
12. shop_session.gd:4 头注「公开面由 LevelRunner 同签名委托承载」句随拆除失效(商店件唯一注释级 diff,见契约 3)。
|
||||
|
||||
## 4. 设计契约(违反即返工;🔴=触碰停机呈报)
|
||||
|
||||
1. 🔴 直连不留壳:19 个委托全删(含死壳 2 枚),禁保留任何同签名别名/转发/兼容壳;外部取件唯一形态=公开成员 `LevelRunner.shop`(level_runner.gd:44 私有 `_shop` 更名,公开面=成员本身,不设访问器方法)。
|
||||
2. 🔴 行为零改动:商店双模式定价、货架、RNG 取号序列、钱包账面、事件发射逐项同前;全部现有断言同种子逐位不变;`data/tables`、RngService、ConfigDB 消费零 diff;无数值改动禁跑 MC。
|
||||
3. ShopSession 行为零改动:shop_session.gd 不改任何可执行行;唯一允许 diff=头注 :4 委托承载句随批更新(非行为)。
|
||||
4. 测试直连私有面仅限白盒两入口(shop_session `_draw_shelf`/`_spend_discounted`),依据=「测试/探针直连件读写」(architecture.md:152 裁定段);产品码禁直连任何 `_` 前缀私有成员。
|
||||
5. 拆分边界纪律(判据权威=code-conventions §1.1,本批为拆除/收敛向):本批零拆出新件——结构变化仅壳删除与成员公开化两项;保留单元(LevelRunner 商店房编排段、ShopSession、呈现控制器)职责语句不变;凡「为达标保留的转发别名」按凑计数袋处理,禁。
|
||||
6. 🔴 禁为机检文本保留无效成员(code-conventions §1.1 同款):机检键与本卡壳删除契约互斥时(如任何键要求公开方法数不得下降),实现段一律停卡呈报,不得自造第三条路。
|
||||
7. 测试削弱申报:零申报——不删任何断言、不改判据阈值、不缩扫描面;测试只改调用地址。实现期发现必须改判的断言=上游缺陷,停卡退回写卡段。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
做:壳块与死壳删除;`_shop`→`shop` 公开化(含内部引用点);产品码/sim/测试调用点改址;注释同步六处(shop_session.gd:4、level_runner.gd:723–725 区块涉委托两句〔删 :724–725、留 :723 节头〕、level_autoplay.gd:335、shop_overlay_view.gd:88/152、tree_rules_v11_test.gd:6);level_runner 头注涉委托表述随批核查同步。
|
||||
|
||||
不做(去向):
|
||||
|
||||
1. spend_gp 迁 GpWallet 与三处内联扣账去重——2026-10-29 用户裁「可选微整理、不进本批」;日后要做属游戏代码重构,另立卡走流水线。
|
||||
2. gdstyle 基线重锚(`python tools/gdstyle_gate.py --refresh` 人工专用)——本批公开方法数自然下降不触发重锚;基线死键清账时机归用户发令(待办清单在册)。
|
||||
3. architecture.md:109 改写——实现批禁写 `design/`,入反哺点清单(§6)。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md | :109 ShopSession 行——「外部调用面由 LevelRunner 同签名委托承载(外部零变化)」句失效;公开面格需随改址后实际对外面重写:补 spend_gp(奇物付费刷新对外出账口)与 current_price/pool_price/purchased_tier/shop_refresh_free_left/is_shop_pool/shop_bp_shelf/shop_bp_visit_buys 等实际被直连方法;set_shop_pool 调用面改述:pool 注入经 LevelRunner 构造 ctx 供给(level_runner.gd:101–102 内部直调 ShopSession.set_shop_pool;原委托块注释「AdventureRunner._start_current_level 唯一调用方」系陈旧表述——全仓 grep 证实产品码零调用方,随壳删除作废),测试面直连 shop.set_shop_pool | 反哺点清单(`reports/iter<N>-反哺点-<日期>.md`),用户裁决后归文档批落文;实现批禁直改 |
|
||||
|
||||
其余文档无关联点:GDD 商店/秘宝/天赋树各节机制陈述(扣账口唯一、刷新双源、折价边界、爬价公式)不因调用面搬家而变(grep 考证 2026-10-29)。
|
||||
|
||||
## 7. 落位与可复用性预检
|
||||
|
||||
- **新增件清点**:零新增文件、零新增函数、零新增数据件。唯一「新增面」=LevelRunner 公开成员 `shop`——更名既有私有成员 `_shop`(level_runner.gd:44),复用既有 ShopSession 实例与 `_bind_shop` 装配(:728),零新装配、零新引用、零新职责。
|
||||
- **唯一面核查**:grep 19 个方法名全仓——委托职责拆除后调用面唯一落点=ShopSession(第二承载不存在);`_shop_draw_shelf`/`_spend_discounted` 转发壳删除后,白盒入口唯一落点=shop_session 私有方法本体。
|
||||
- **复用面核查**:不新增任何 helper/访问器——「更名公开」即全部;呈现层持件沿用既有 `_runner_get` 取值回调(camp_shop_presenter.gd:170 现形态),不新引入注入面。
|
||||
- **分层与交互面**:调用方向不变——views→(信号)→组合根→core;呈现控制器经取值回调持 runner 后以 `runner.shop` 取件(组合根拆件直连=架构「模块归属·呈现层」既有口径);sim 属测量面直构既有惯例;测试直连 core 公开成员+白盒两私有入口(契约 4)。
|
||||
|
||||
## 8. 实现规范预算
|
||||
|
||||
- **新件三查**:零新增文件——空转。
|
||||
- **存量触面一查**(level_runner.gd,基线 tools/gdstyle_baseline.txt:11–13):max-public-methods 预期 50→33(删 17 公开委托、增 0;私有委托 2 枚同删不入此数);max-class-variables=30 不变(成员更名不改数);max-returns|_enter_node=7 不变(`_enter_node` 零触碰)。T0 读数步核对「S13 键较登记值只降不升」,基线值本批不动。
|
||||
- **shop_session.gd**:零可执行行 diff,键面不变。
|
||||
- **指标例外申报**:无。
|
||||
|
||||
## 9. 文件结构图(卡前;全部「复用既有」——零新增件,与 §7 互指)
|
||||
|
||||
```
|
||||
game/core/level_runner.gd 壳块删除+成员公开化+内部引用更名+区块注释【非行为——R2/R3/R4】
|
||||
game/core/shop_session.gd 仅头注 :4 委托句更新(零可执行行 diff)【非行为——R4】
|
||||
game/presentation/camp_shop_presenter.gd 调用点改址 12 处【非行为——R1】
|
||||
game/presentation/main_adventure_flow.gd 调用点改址 6 处【非行为——R1】
|
||||
game/presentation/main_overlay_flow.gd 调用点改址 2 处【非行为——R1】
|
||||
game/presentation/main.gd 调用点改址 1 处【非行为——R1】
|
||||
game/presentation/curio_interact_controller.gd 调用点改址 1 处【非行为——R1】
|
||||
game/presentation/views/shop_overlay_view.gd 注释同步 2 处【非行为——R4】
|
||||
game/sim/level_autoplay.gd 调用点改址 6 处+注释 1 处【非行为——R1/R4】
|
||||
game/tests/unit/core/level_shop_economy_test.gd 改址 25+白盒 2(grep 全量核对)【非行为——R1】
|
||||
game/tests/unit/core/hero_ledger_test.gd 改址 2 处【非行为——R1】
|
||||
game/tests/unit/core/adventure_feats_test.gd 改址 1 处【非行为——R1】
|
||||
game/tests/unit/core/pool_case_d_test.gd 改址 3 处【非行为——R1】
|
||||
game/tests/unit/core/treasure_effects_test.gd 改址 2 处【非行为——R1】
|
||||
game/tests/unit/core/curio_refresh_paid_test.gd 改址 3 处【非行为——R1】
|
||||
game/tests/unit/core/meta_progression_forge_test.gd 改址 3 处【非行为——R1】
|
||||
game/tests/unit/core/tree_rules_v11_test.gd 头注同步 1 处【非行为——R4】
|
||||
```
|
||||
|
||||
## 10. 任务卡 T0..T2
|
||||
|
||||
施工遵循闸机轮次纪律:里程碑步(T1)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。
|
||||
|
||||
### T0 调用面直连(壳仍在位——中间态全绿) 估时 0.5–1 个工作日
|
||||
|
||||
- 取用:—(首批)。
|
||||
- 产出:全部调用点 `*.shop.*` 直连形态(壳在位,行为零改动的中间态);T1 依赖「删壳后零编译错」以本产出为完整性基线。
|
||||
- [ ] level_runner.gd:44 成员更名 `var shop: ShopSession`(行注释同步),内部引用 :99/:102/:104/:305–306/:506–507/:704/:729 全部随更名;核查=grep `_shop`(词级)于 level_runner.gd 仅剩保留件 `_bind_shop`(:65/:104/:728——宿主回调装配面,非委托)
|
||||
- [ ] 产品码改址六件(形态=`<runner 表达式>.shop.<方法>`,方法名与实参逐字不变):camp_shop_presenter.gd:173–203/main_adventure_flow.gd:81–86/main_overlay_flow.gd:135/138/main.gd:773/curio_interact_controller.gd:163/shop_overlay_view.gd:88/152 仅注释
|
||||
- [ ] sim 改址:level_autoplay.gd:341/350/363/372/418/421+:335 注释
|
||||
- [ ] 测试面改址七件:level_shop_economy_test.gd(grep 全量核对;白盒 :1344/:1355 改 `r8.shop._draw_shelf()`)/hero_ledger_test.gd:60/66/adventure_feats_test.gd:364/pool_case_d_test.gd:45–47(:46 改 `lr.shop._draw_shelf()`、:47 改 `lr.shop.shop_bp_shelf()`)/treasure_effects_test.gd:229/233/curio_refresh_paid_test.gd:52–54(`lr.shop.spend_gp(...)`)/meta_progression_forge_test.gd:735–740(`lr.shop.current_price(...)`)
|
||||
- [ ] 注释同步:tree_rules_v11_test.gd:6 头注 `level_runner._spend_discounted`→`shop_session._spend_discounted`;level_autoplay.gd:335 注释调用名同步
|
||||
- [ ] 验证:`python tools/run_smoke.py` 绿;单元与集成 `--script res://tests/run_all.gd` 全绿(中间态=直连可编译可过+行为零改动初证);level_runner 三键读数核对只降不升(§8 预期值)
|
||||
|
||||
### T1 壳拆除与完整性证明 估时 0.5 个工作日
|
||||
|
||||
- 取用:T0 全调用点直连形态在位。
|
||||
- 产出:终态 level_runner(壳归零);T2 的闸与审计对象。
|
||||
- [ ] 删除 level_runner.gd:723–725 区块注释中涉委托与白盒两句(:724–725;保留 :723「商店房兑付」节头与 :727 件注入说明)+:751–828 十九个委托全量(含死壳 `_spend_discounted`:772/`pool_stock`:787)
|
||||
- [ ] shop_session.gd:4 头注委托承载句更新(「外部调用面=调用方经宿主公开成员 `shop` 直连」表述)
|
||||
- [ ] 验证:`python tools/run_smoke.py` 绿+全单元套件绿(壳删后绿=T0 改址无遗漏的编译级证明)
|
||||
- [ ] 残留扫描:grep 19 个方法名于 `game/`(排除 shop_session.gd 本体定义、level_runner.gd 内部 `shop.` 使用点、跨类同名方法——BattleOrchestrator.player_request_refresh 与 CurioDeck.pool_stock 按现状事实 5 清单判接收方类归属)——产品码与测试面零命中,输出留实现报告
|
||||
- [ ] 注释收尾核查:level_runner 头注涉委托表述已同步(§5 做项)
|
||||
- [ ] 里程碑出口:`tools/run_all_gates.sh --code` 全绿、回执落 `game/tests/.gates/receipt.json`
|
||||
|
||||
### T2 收口(产出物落位卡) 估时 0.5 个工作日
|
||||
|
||||
- 取用:T1 终态(壳归零、套件绿、回执在盘)。
|
||||
- 产出:三份过程件+合回呈报。
|
||||
- [ ] 反哺点清单 `reports/iter<N>-反哺点-<日期>.md`:§6 表逐条落点——architecture.md:109 ShopSession 行改写内容全文随单;无其他落点
|
||||
- [ ] 实现报告 `reports/iter<N>-实现报告-<日期>.md`:各卡状态+实现决定记录+实机目检总清单(本批零玩家可观测改动——写明「无新增目检项」)+遗留读数义务(无)+残留扫描输出留痕
|
||||
- [ ] 独立验收审计 `reports/iter<N>-验收审计-<日期>.md`:未参与实现的会话或子代理执行(test-conventions §8.7 四事);审计在迭代 loop 内启动的子代理算 loop
|
||||
- [ ] 审计通过后呈报用户合回(worktree-guard 按 diff 文件性质推域校验回执;审计判红→修复→出红最小单元最窄确认→闸重跑)
|
||||
- [ ] 批后收尾(待办条目整条删除、roadmap 换代)归 batch-closure——不在本卡任务内,此处仅登记去向
|
||||
|
||||
## 11. 验证闸(改动—验收对照表)
|
||||
|
||||
本卡零新增断言——对照表全行由既有断言与静态扫描承接,无〔卡短名 Vn〕尾缀需求。
|
||||
|
||||
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| R1 调用面直连改址(非行为改动——调用目标/实参/返回/副作用逐项同前,仅取件路径文本变化) | §9 结构图产品码 6 件+sim 1 件+测试 7 件全部调用点 | 既有套件回归两轮全绿:T0 中间态轮+T1 壳删后轮(level_shop_economy/hero_ledger/adventure_feats/pool_case_d/treasure_effects/curio_refresh_paid/meta_progression_forge 全套+冒烟) | 单元+接口 | 各套件既有真实入口(直构 LevelRunner/AdventureRunner 链) | 既有断言逐位不变(行为零改动正向证据)+壳删后编译通过(改址无遗漏) | 既有:GP 钱包/escrow/商店收口/共享池;既有:奖励三选一候选/刷新付费/呈现 |
|
||||
| R2 壳块拆除(非行为改动——纯转传方法与契约注释删除,行为承载在 ShopSession 不变) | level_runner.gd:723–725 区块涉委托两句(:724–725)+:751–828(含死壳 `_spend_discounted`:772/`pool_stock`:787) | 残留扫描零命中(T1 静态步)+T1 套件绿 | 静态+单元 | grep 全仓(19 方法名清单固定)+套件真实入口 | 扫描面>0 前置(grep 命令对 19 名单非空可执行)+壳删后零引用可编译;命中行按接收方类归属判别(现状事实 5 跨类同名清单) | 既有:GP 钱包/escrow/商店收口/共享池 |
|
||||
| R3 宿主成员公开化(非行为改动——私有 `_shop` 更名公开 `shop`,装配与读写路径不变) | level_runner.gd:44+内部引用 :99/:102/:104/:305–306/:506–507/:704/:729 | 随 R1 两轮套件绿 | 单元 | 套件真实入口 | 同 R1(内部使用点行为不变) | 既有:GP 钱包/escrow/商店收口/共享池 |
|
||||
| R4 注释同步六处(非行为改动——注释文本,无运行时可观测面) | shop_session.gd:4/level_runner.gd:722–724/level_autoplay.gd:335/shop_overlay_view.gd:88/152/tree_rules_v11_test.gd:6 | 随批代码域闸绿(静态扫描覆盖文件头纪律面) | 静态 | —(静态判据) | 观测面局限申报:注释无运行时提交面,判据=静态扫描+评审注记 | 既有:GP 钱包/escrow/商店收口/共享池 |
|
||||
|
||||
## 12. 异常分级
|
||||
|
||||
- **L1 自救**:更名/改址漏点编译错→就地补改后重跑最窄确认(冒烟或单套件)。
|
||||
- **L2 记录继续**:套件出红且根因属本批改址笔误→出红最小单元最窄确认修复+实现报告记录;连续 3 次同红灯升级 L3。
|
||||
- **L3 停机呈报**:①出红根因=上游缺陷(非本批改动所致)→停卡退回写卡段;②机检键与本卡契约互斥(如需保留壳/别名才达标)→停机呈报,禁自造第三条路(机检预算互斥条款);③改址中发现任何行为差异(同种子读数漂移)→立即停批(行为零改动契约被打破);④ShopSession 需要可执行行改动才能达成改址→停机呈报(契约 3 被打破)。
|
||||
|
||||
## 13. 代拍板白名单
|
||||
|
||||
1. 注释措辞与所在行随改址微调(不改语义)。
|
||||
2. 测试内局部变量随调用链展开的机械适配(不改断言判据)。
|
||||
3. 残留扫描的 grep 命令形态与输出留痕方式(实现报告正文承载)。
|
||||
4. level_runner 头注与区块注释涉委托表述的同步措辞。
|
||||
5. 单元套件运行的分批执行方式(闸机轮次纪律内的最窄确认选择)。
|
||||
|
||||
超白名单的微决策记入实现报告「实现决定记录」节。
|
||||
|
||||
## 14. 待裁点
|
||||
|
||||
零待裁点,开工门=U0。(改址定式与 spend_gp 归属均经 2026-10-29 会话裁决,见 §2。)
|
||||
@@ -0,0 +1,380 @@
|
||||
# 需求卡片:呈现层结构收敛批(gdstyle 存量债清偿·波 6+波 8 呈现侧——视图内部拆私有函数+工厂/参数面收敛+类变量全清)
|
||||
|
||||
- 版本:**v1.2**(v1.1 = 2026-10-27 用户裁决四条款折入——全清口径取代残留申报+print 删除落死+main/await 两键架构豁免;v1.2 = 2026-10-28 用户裁「拆分边界纪律(DDD/高内聚)」落卡——新增契约 9+u1 子域拆件改法+状态件职责语句义务+审计⑨+L3 增款+读数锚重锚〔基线 216→168、恶化 2→1,随波 0 刷新 d219dd3d 与迭代 40 归绿〕;自审与 grilling 记录见 §12)
|
||||
- 来源:[待办清单](../待办清单.md)「gdstyle 存量债全量清偿——216 键按病根分波整改」条目(2026-10-26 登记,P0,状态=文档设计已闭合+待写卡)——**需求性工程条目,证据指认形态**(唯一事实源:[审计-gdstyle存量债清点与清偿方案-2026-10-26.md](审计-gdstyle存量债清点与清偿方案-2026-10-26.md) §六第 3 条〔波 6 视图内部拆私有函数、不拆构建步件〕+第 7 条〔归并裁定:本卡=波 6(54 键/17 文件)+波 8 呈现侧 8 文件(17 键)=71 键〕);设计段裁定=纯代码内部收敛、**零设计改动**
|
||||
- 归属:`game/presentation/` 25 文件(波 6 十七件+波 8 呈现侧八件)+消费面随动改址(§7 结构图注记;v1.1 增 board_view 写入行随动,见 §0);treasure_interact_controller 已移卡 1(B1 战斗域拆件批),不在本卡
|
||||
- 排期:未编入(迭代批卡片;估时 ≈5.0–5.5 个工作日,估 ≈5.3d)
|
||||
- 开工门:U0+复核门过(§12);**零待裁点**(2026-10-27 用户裁决记录:print 删除;await 按 v1.19 测量面豁免——§11)
|
||||
|
||||
## 0. 前置依赖与并行性
|
||||
|
||||
- **第〇步核对(2026-10-27 写卡会话)**:来源条目=需求性工程条目(状态行含「文档设计已闭合+待写卡」;证据指认=清点报告 §六逐波裁定+本卡 §3 逐文件实查),放行。设计段闭合凭据(2026-10-26 用户裁)=①纯代码波写卡前确认零设计改动+按当时 master 重测读数(已做,见 §3);②波 6 形态=视图内部拆私有函数、不拆构建步件;③波 8 呈现侧散条随本卡收编(§六第 7 条归并裁定)。**v1.1 补核对(同日用户裁决四条款)**:全清口径取代残留申报(71=69 清+2 豁免)、print 删除落死、main/await 两键按 architecture v1.19 豁免登记、其余类变量大户收拢内部状态件——四条款为类变量键清偿的设计闭合凭据,已落 §1/§4/§7/§8.4/§11。
|
||||
- **与迭代 39 卡组的文件交叠(串行义务,呈编排段裁先后)**:iter 39 主卡(冒险域拆件批)触 `level_map_screen.gd`(:334-343 bonus 读面改指 hero)、`hud_presenter.gd`(:20/313 同面)、`curio_interact_controller.gd`(16 处调用改指 stop())、`main.gd`(装配面)——与本卡四文件重叠。两批无论先后,后开工批 T0 自吸收行号漂移;**禁编入同迭代同波并行**。姊妹副卡(同调配装)触 core 域零叠;技能池触发器卡触 core/data 零叠。**v1.1 交叠集扩展:board_view.gd 加入错波集**(u3 收拢随动其写入行约 40 行,见 u3 行)——交叠义务同四文件(后开工批 T0 吸收漂移;board_view 结构拆件仍归 iter 39 领地,本卡只做写入行机械改址,见 §5 不做清单)。
|
||||
- 与同事项卡 1(B1 战斗域拆件批:battle_orchestrator/settlement/damage_controller/treasure_interact_controller)、卡 2(核心数据面:core/data 侧)**零文件交叠**。
|
||||
- 本卡禁触 adventure_runner/level_runner(iter 39 规避清单);禁触 battle_orchestrator(其行数恶化债 c4c69701 归卡 1 还债)。~~board_view 禁触~~(v1.1 收窄:board_view 结构拆件仍禁触,写入行机械改址随动允许——u3 全清口径的必要执行面,2026-10-27 裁决第 5 条)。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**目标**:呈现层 25 文件 71 键结构收敛——超长构建/绘制/格式化函数拆私有函数族(波 6 形态裁定)、工厂件公开面与参数族收敛(波 8)、类变量大户收拢内部状态件全清(v1.1:2026-10-27 裁决,残留申报废除)、测量面 print 残留删除(信息已由 toast/JSONL 承载)、main/await 两键按 v1.19 架构豁免申报。**游戏行为与玩家可见呈现零变化**(契约 1):本批零行为改动、零新文件、零新公开概念。
|
||||
|
||||
**改动单元清单**(需求点,逐单元验收行见 §8 对照表;键数=2026-10-27 实测,与清点报告 §五逐条吻合;v1.1 收拢清单=逐件成员构成实查产出,冻结成员与收拢面逐条见 §3 S17):
|
||||
|
||||
| # | 单元(文件) | 现行键(值/阈值) | 改法 |
|
||||
|---|---|---|---|
|
||||
| u1 | camp_overlay_view.gd | 类变量 19/15;循环内 new×7;_init 149 行 28 局部(:42);_rebuild_tree 61 行 21 局部(:222);_rebuild_forge 72 行 20 局部(:301);refresh_camp 61 行 17 局部(:386) | _init 拆四柜台构建私有族;_rebuild_*/refresh_camp 拆行板构建私有族;循环体提行板构建私有函数;**类变量收拢(v1.2 改法=按柜台子域拆件,禁四柜台混装一袋)**:探针冻结 5 成员(S17)保持宿主,其余 14 个按子域分组各成状态件——树域(_tree_holder)/锻造域(_forge_lock_l/_forge_workbench/_forge_zone_weapon/_forge_zone_armor/_forge_rows/_ws_scroll/_ws_lock_l)/同调域(_attune_header_l/_attune_btns/_attune_nodes)/刷新与最近域(_refresh_l/_refresh_btn/_recent_list),每件一句职责语句(分组微调属代拍板白名单,契约 9)→ 宿主=冻结 5+子域件 4=9(键照清) |
|
||||
| u2 | level_map_screen.gd | **类变量 22/15(基线登记 21——iter38 恶化债 c4c69701,本卡归绿义务)**;_init 135 行 21 局部(:58);_draw_graph 78 行 9 分支 27 局部(:423) | _init 拆构建私有族;_draw_graph 拆绘制私有族(节点/通道/底栏);**类变量收拢(v1.1)**:探针冻结 6 成员(S17:_cand_ids/_hover_id/_content_size/_layout_cache/abandon_btn/status_badge)保持宿主,其余 16 个收进内部状态件(_node_icons/_noise_rect/_tint_level 三件在状态件内持 `_layer_decor` 域字典,装饰域归并形态随迁)→ 宿主 7;恶化债归绿被 ≤15 吸收(键消失);状态件须有职责语句、装饰域与图状态跨子域不混装(契约 9) |
|
||||
| u3 | board_cell_unit.gd | 类变量 31/15;_draw 147 行 29 分支 19 局部(:135) | _draw 拆绘制私有族(底面/接触带/数字徽标/封印/高亮/点迹各域);**类变量收拢(v1.1)**:探针直读 4 成员(glyph/fog_state/plate/glyph_color)保持宿主,board_view 直写 26 成员收进内部状态件、board_view 写入行随动改址(约 40 行 `u.X =` → `u.st.X =`,机械改址零语义——S17 实查:31 成员中 30 个被 board_view 直写 47 行,本件为被动绘制壳,全清唯一路径=写入行随动;状态件职责语句=「单格绘制输入集」——被动绘制壳的全部绘制入参,单一变化原因成立〔契约 9 预检〕)→ 宿主 6(4 冻结+_glow_layer+状态件) |
|
||||
| u4 | standee_body.gd | 类变量 29/15;循环内 new×2(:268/:296);_draw 84 行 26 局部(:414) | _draw 拆绘制私有族(立绘/血条/意图/护甲徽标/顺位徽标);循环体提私有构建函数;**类变量收拢(v1.1)**:外部直访 4 成员(box/font/slot_row/has_world_hp_bar——battle_stage_view 直写 :122/:180/:214/:268、fx_probe/ui_probe 直读,S17)保持宿主,其余 25 个收进内部状态件(含 _death_shards/_hit_sparks/_flash_count 三探针出口计数——经 fx_probe() 方法出口,随迁方法读点)——演出计数与装配态可分则按子域分组,整件收拢须给「站桩演出状态」职责语句并核单一变化原因(契约 9)→ 宿主 5 |
|
||||
| u5 | hero_info_panel_view.gd | 循环内 new×2(:55/:189);_init 74 行(:24);set_treasure_inventory 57 行 13 局部(:162) | _init 拆段构建私有族;槽位循环体提私有构建函数 |
|
||||
| u6 | battle_end_overlay.gd | 类变量 20/15;循环内 new×4(:222/:251/:271/:303);_init 81 行(:31);open_victory 参数 8/5(:116) | _init 拆行板构建私有族;循环体提私有构建函数;open_victory 可选尾参收拢 opts 字典(4 参);**类变量收拢(v1.1)**:探针直读 4 成员(_btn/_gp_name/_gp_row/_gp_val,S17)保持宿主,其余 16 个收进内部状态件 → 宿主 5 |
|
||||
| u7 | debug_overlay.gd | 类变量 17/15;_build 124 行 22 局部(:153) | _build 拆五区块构建私有族(探针直引公开面逐字保留);**类变量收拢(v1.1)**:探针直读 3 成员(seed_edit/_sim_btn/_dbg_btn,S17)保持宿主,其余 14 个收进内部状态件(_run_data/_run_labels 经 run_data_probe()/update_run_data() 方法出口,随迁方法读点)→ 宿主 4 |
|
||||
| u8 | ui_assembler.gd | 循环内 new(:156);build_start_overlay 83 行 16 局部(:97) | build_start_overlay 拆列/行构建私有族;立绘循环体提私有构建函数 |
|
||||
| u9 | battle_stage_view.gd | 循环内 new(:266);_init 97 行(:27);_enemy_portrait_tex return 9/6(:233) | _init 拆子视口/世界/壳层构建私有族;_enemy_portrait_tex 改查表+回退(映射语义零变化) |
|
||||
| u10 | curio_pick_overlay.gd | _init 52 行(:27);_icon_for_id return 7/6(:192) | _init 拆构建私有族;_icon_for_id 改查表+回退 |
|
||||
| u11 | settings_overlay.gd | _build 77 行 13 局部(:31) | _build 拆行构建私有族 |
|
||||
| u12 | battle_log_view.gd | _format_row 68 行 21 局部 13 return 9 分支(:144) | _format_row 按行型拆私有格式化函数族(iter38 卡⑥类型修复后现行形态为准) |
|
||||
| u13 | curio_interact_controller.gd | 类变量 18/15 | **引用束注入(v1.1)**:16 个注入成员(db/4 视图/11 Callable)全部来自 _init(ctx) 逐成员抄写(:32-48)=CurioFlowContext 冗余面——删除 16 成员、正文读点改址 ctx 束(u20 三束键名,S12);_pending_curio/_curio_context 纯内部态保持 → 宿主 3(ctx+2)。探针零成员直读(S17——press_candidate 等全走方法面),零冻结面 |
|
||||
| u14 | ap_bar_view.gd | _init 69 行(:34) | _init 拆构建私有族(源码锚句逐字保留) |
|
||||
| u15 | board_zone_view.gd | _init 59 行(:21) | _init 拆构建私有族 |
|
||||
| u16 | board_fx_view.gd | 循环内 new(:93) | play_perfect_sweep 循环体提私有 band 构建函数 |
|
||||
| u17 | legend_overlay.gd | 循环内 new×2(:35/:37) | ENTRIES 循环体提私有行构建函数 |
|
||||
| u18 | ui_kit.gd | 公开方法 26/20;beams_rect 13 局部(:333);modal_shell 参数 6(:453);BCard._init 参数 6(:752);bcard 参数 6(:812) | ①删零消费 frame_skinned(:566)/verb_button(:662)②私有化 modal_dim/beams_rect/gradient_base/switch_toggle(消费方全在本卡触面文件或单条测试行随动;load_font 保留公开——探针三行直引,收敛算术不需要它)→26→20 ③modal_shell 尾参哨兵收拢(6→5)④BCard._init/bcard 可选尾参收拢 opts(6→5)⑤beams_rect 像素循环拆私有函数 |
|
||||
| u19 | hud_presenter.gd | refresh 参数 8(:14);_refresh_out_of_battle 参数 6(:147);tune_sim_report 参数 10(:188) | refresh/_refresh_out_of_battle 运行态尾参收拢 ctx 字典(4 参);tune_sim_report 统计束收拢(5 参);文案逐字不变 |
|
||||
| u20 | curio_flow_context.gd | 类变量 16/15;_init 参数 16/5(:25) | 参数与成员按域收拢三束(views/getters/flow 字典)→ 4 参 4 成员 |
|
||||
| u21 | camp_flow_context.gd | _init 参数 12/5(:21) | 同 u20 三束收拢 → 4 参 |
|
||||
| u22 | battle_narrator.gd | bonus_card_text return 9/6(:100) | match 分支拆私有文案函数/查表(文案逐字不变,现役单测断言零改动) |
|
||||
| u23 | tune_sim_controller.gd | print 残留(:43);循环内 await(:65);run 11 局部(:36) | 统计六成员收拢一 stats 字典(与 u19 束同构)→≤10 局部;**print 一行删除(v1.1 落死)**:日志路径信息由 logger 会话产物与落盘 JSONL 承载(禁改 set_sim_report 文本——契约 1 文案逐字不变);**循环内 await 架构豁免(v1.19 §「S13 测量面豁免登记」在册)**:禁重构测速循环,豁免状态进实现报告申报 |
|
||||
| u24 | playtest_logger.gd | print 残留×2(:160/:161) | **两行删除(v1.1 落死)**:路径信息已由 toast 承载(main_debug_flow.gd:16 `show_toast("已转储诊断: "+path)`)、上下文 JSON 已落转储文件——stdout 重复输出零独有信息 |
|
||||
| u25 | main.gd | 类变量 49/15 | **架构豁免(v1.1)**:组合根类变量面=探针契约面(约 46 句柄被探针挂载假设钉死),v1.19「呈现层装配与会话生命周期」节 S13 豁免登记在册——**键永久基线内、禁再恶化;禁收拢 main 句柄、禁为清键改写探针挂载契约**。卡内任务=核对注记在位(v1.19 :183)+实现报告申报豁免状态(依据指针 v1.19);死成员清点删除任务随豁免取消(类变量面冻结) |
|
||||
|
||||
**完成定义**:
|
||||
1. u1–u25 落地;`python tools/gdstyle_gate.py` 读数:**基线外新违规(NEW)=0**;**恶化(WORSENED)=0**(开工时点唯一在册红 level_map_screen 类变量由 u2 归绿吸收;battle_orchestrator 行数已随迭代 40 归绿——v1.2 重锚);**71 键=69 键清零+2 键豁免**(main 类变量、tune_sim 循环内 await——v1.19 两处豁免登记段在册,键永久基线内;§8.4 账目)。
|
||||
2. 呈现逐像素零变化:§7 T0 建锚面(甲/乙/丙三组)改后对拍全 0.00%。
|
||||
3. 现役全套断言面绿:探针面(含源码锚字面量契约)与单元/集成套件零红、零删改(契约 5)。
|
||||
4. 撤销证明逐行落地(§8 对照表末列);三份产出物写齐(T5,含豁免两键申报件);独立验收审计过。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
| # | 出处 | 取用条款 |
|
||||
|---|---|---|
|
||||
| D1 | [审计-gdstyle存量债清点与清偿方案-2026-10-26.md](审计-gdstyle存量债清点与清偿方案-2026-10-26.md) §六第 3 条 | 波 6 形态=视图内部拆私有函数、**不拆构建步件**(main_ui_build 先例动机是组合根超限,普通视图不类比——2026-10-26 用户裁) |
|
||||
| D2 | 同上 §六第 7 条 | 归并裁定:本卡=波 6+波 8 呈现侧 8 文件=71 键;treasure_interact_controller 归卡 1 |
|
||||
| D3 | 同上 §三波次表+§四纪律 | 改前建 golden 基线或对拍 0.00%;基线禁改禁 refresh;还债=数值下降自然绿;呈现零变化 |
|
||||
| D4 | [architecture](../design/engineering/architecture/architecture.md) **v1.19**「三屏壳与组合根句柄面」节(:183) | 探针挂载假设 `main.X` 路径零迁移;**S13 豁免登记在册:组合根类变量面即探针契约面(约 46 句柄被探针挂载假设钉死),max-class-variables 对本件按架构契约豁免(键永久基线内、禁再恶化),豁免理由在册本节,禁为清键改写探针挂载契约** |
|
||||
| D5 | 本卡 §3 逐文件实查(2026-10-27,master 8b146321) | 现状行号与键值;**逐文件实查确认不触碰任何 owner 契约(GDD 零修订预期)——实现段查到触碰点立即停笔呈报,禁内联求裁** |
|
||||
| D6 | architecture **v1.19**「测试与质量域·S13 测量面豁免登记」段(:311) | tune_sim_controller 循环内 await(测速循环逐帧让出)是调参测量的 wall-clock 步进承载语义——重构即测量口径漂移,违行为零变化红线;**该键按架构豁免(键永久基线内),禁重构测速循环**;同件 print 残留不豁免(随全清批删除) |
|
||||
|
||||
## 3. 现状事实(2026-10-27 写卡会话实测于 master 8b146321;开工日 T0 复核行号)
|
||||
|
||||
**S13 读数**(v1.2 重锚——波 0 刷新 git d219dd3d 后基线 168 键):基线外新违规 0/恶化 1(level_map_screen 类变量 22>21=**本卡还债义务**,iter38 卡① _layout_cache 缓存成员特批带红挂账 c4c69701;battle_orchestrator 行数红已随迭代 40 卡①还债归绿——实测 1037=登记 1037)。25 文件逐文件读数见 §1 改动单元清单(gdstyle v0.4.0 实测,与清点报告 §五 2026-10-26 读数逐条吻合、行号为本次实测)。
|
||||
|
||||
**探针与测试直引面**(重构冻结面,逐条实测;v1.1 补全收拢件冻结成员——S17):
|
||||
|
||||
| # | 事实 | 出处 |
|
||||
|---|---|---|
|
||||
| S1 | debug_overlay 公开面被 8 探针+系统测试直引:set_sliders/effect_text/press_apply_for_probe/press_reset_for_probe/press_simulate_for_probe/set_sim_count/visible/get_index/seed_edit;ui_tune_probe 另有**源码契约**:debug_overlay.gd 源码禁含 "create_t"/"UiKit.motion" token(零动效契约)+子树零 AnimationPlayer | `game/probe/ui_tune_probe.gd:46-67/225-239`;`game/tests/system_test.gd:204/228/258` |
|
||||
| S2 | camp_overlay_view **双重源码契约**:ui_struct_probe 源扫描 `count("UiKit.STONE") == count("UiKit.STONE_DEEP")`(裸 STONE 禁令);theme_projection_test 源锚 `custom_minimum_size = Vector2(0, 336)` 恰 3 处、`size_flags_vertical = Control.SIZE_FILL` 恰 4 处、`SIZE_SHRINK_CENTER` ≥3 处 | `game/probe/ui_struct_probe.gd:46-50`;`game/tests/unit/presentation/theme_projection_test.gd:722-730` |
|
||||
| S3 | camp_overlay 探针直引成员:_balance_label/**_tree_buy_btns/_tree_fork_btns/_workshop_holder/_workshop_rows**+refresh_camp/closed/visible(v1.1 实查补 _balance_label——ui_probe 直读 .text 判余额文案,原 S3 漏记) | `game/probe/ui_click_probe.gd`、`ui_probe.gd:36-42`、`screen_flow_probe.gd`(grep 实测) |
|
||||
| S4 | settings_overlay 探针直引:retarget/_motion_btn/_volume/find_button 面;legend_overlay:visible/close/get_index+player_copy_sweep_test 直构 `.new()`+`ENTRIES` 常量消费+smoke_boot `main.get("legend_overlay")` | `game/probe/ui_click_probe.gd:286-343`;`game/tests/unit/presentation/player_copy_sweep_test.gd:69-71`;`game/tests/smoke_boot.gd:76` |
|
||||
| S5 | ap_bar/log_view/info_panel/level_screen/stage/_end_overlay/board_zone/curio_overlay 探针直引成员与方法面(含私有成员 _cand_ids/_hover_id/_btn_stop/_log/_summary/_curio_section/_gp_val 等)逐条在案:press_candidate/status_badge/route_chosen/abandon_btn/press_card/press_confirm/press_continue/open_pick/is_open/verdict_text/continue_pressed/_btn_legend/_btn_stop/_dots/is_refresh_ready/confirm_visible/press_refresh_for_probe/press_confirm_for_probe/refresh_remaining_text/parsed_text/mode/armor_text/attack_text/item_slots/hero_standee/enemy_body_at/enemy_box/round_label/status_badge/legend_toggled/toast;**v1.1 补:battle_end 四句柄直读=_btn(5 处)/_gp_name/_gp_row/_gp_val(3 处)** | `game/probe/` 八探针 grep 实测(深访问清单已录实现报告素材口径,T0 复核) |
|
||||
| S6 | standee_body 直构面:fx_probe `new("enemy")`/box/set_data/set_pending/intent_probe();standee_fx_sweep_test preload 直构+`s2.box` 读;theme_projection 源锚四句(GOLD_BRIGHT 顺位行/HERO_BLUE_BRIGHT/GOLD_BRIGHT 护甲/`_intent_charge = pid in CHARGE_SKILL_IDS`+GOLD_DEEP 旧判据禁句) | `game/probe/fx_probe.gd:15-30`;`game/tests/unit/presentation/standee_fx_sweep_test.gd:87-90`;`game/tests/unit/presentation/theme_projection_test.gd:689-696` |
|
||||
| S7 | ap_bar_view 源锚:`UiKit.label("",UiKit.FS_CAPTION, false, UiKit.STONE_DEEP)` 逐字在位+"STONE_FAINT" 全文零命中 | `game/tests/unit/presentation/theme_projection_test.gd:696-700` |
|
||||
| S8 | ui_kit 工厂消费方普查(逐方法 grep 产品码+probe/sim/tests,2026-10-27 实测):**零消费=frame_skinned/verb_button**(仅注释提及);消费方全在本卡触面=modal_dim(camp:45)/beams_rect(ui_assembler:104+theme:639)/gradient_base(level_map:65+theme:664)/switch_toggle(settings_overlay:76/:91);测量面直引(保留公开)=load_font+FONT_UI(board_shot_probe:49/type_glow_shot_probe:71/ui_font_asset_test:15);跨面消费(保留公开)=label 137/motion 96/panel_flat 35/load_tex 35/button 44/modal_shell 9/panel_skinned 9/primary_button 7/glow 族 7/keystone_badge 5/page_shell 5/scaled 5/vignette_rect 4/tg_band 3/backdrop_tile 3/danger_button 3/icon_rect 2/bcard 2+static var motion_scale(探针 15 处直引)/victory_fx_style | `game/presentation/views/ui_kit.gd:566/662/333/453/752/812`;grep 普查表(T0 存档) |
|
||||
| S9 | ui_kit **扫描契约**:ui_contrast_probe 全 presentation 递归扫描——裸 `Color8(` 计数逐文件对空白名单(ui_kit 本体为合法定义面)、素材 preload 红线=0;theme T5② 源锚 `UiKit.panel_flat(SLOT_BACKDROP_SOFT, PANEL_BORDER, 0, 1)`;V4 四文件(ui_kit/ui_assembler/settings_overlay/debug_overlay)源码零 "styled_slider/tooltip_theme/_tip_theme/overlay.theme" token;theme V1-V3 直接调用 button()/vignette_rect()/beams_rect()/gradient_base() 做 Linear 白名单断言 | `game/probe/ui_contrast_probe.gd:164-195`;`game/tests/unit/presentation/theme_projection_test.gd:524-535/584-668` |
|
||||
| S10 | main.gd 类变量 49 个(:61-148 实数);探针 `main.X` 一级句柄直引 46 名(run_scope/level_screen/debug_overlay/camp_overlay/settings_overlay/legend_overlay/ap_bar/log_view/info_panel/board_zone/stage/curio_overlay/_end_overlay/_start_overlay/save_select_overlay/career_overlay/status_panel/shop_overlay/node_overlay/board_view/db/meta/save_manager/settings_store/debug_badge/LAYER_CONTRACT/_modals/_deferred_modal/_confirm_consumer/_row_queue/_row_pacer/_settlement_stop_pending/_inter_overlay/_battle_root/_menu_screen/_camp_screen/_adventure_screen/_treasure_ui/_bonus/_camp_pres/_modal_flow/_tune_sim/_debug/_debug_entry/_seed_edit/confirm_dialog 等——46 名全量清单 T0 存档);装配拆件经 root 显式传参消费 main 成员(main_ui_build/main_*_flow 五件);**v1.1:该键按 v1.19 :183 豁免登记(组合根类变量面=探针契约面)——面冻结,u25 任务改申报件** | `game/presentation/main.gd:61-148`;`game/probe/` 12 探针 grep 实测 |
|
||||
| S11 | hud_presenter 单调用面:refresh 唯一产品消费方=main.gd:810;tune_sim_report 唯一消费方=tune_sim_controller.gd:67;hud_presenter_test 直测静态族(feat_holdings_lines 等)不经 refresh;**核心读取只走 settlement.presentation_snapshot() 成文快照面(头注纪律)** | `game/presentation/main.gd:810`;`game/presentation/tune_sim_controller.gd:67`;`game/presentation/hud_presenter.gd:1-14` |
|
||||
| S12 | flow context 单装配面:CurioFlowContext 构造=main_ui_build.gd:132(16 参 lambda 束,**curio_interact_controller 同行构造 `new(CurioFlowContext.new(...))`——v1.1 持 ctx 方案的装配单点**);CampFlowContext 构造=main_ui_build.gd:152(12 参);成员消费=curio_interact_controller(v1.1 改形后=ctx 束直读,正文 16 成员读点改址)/camp_shop_presenter(:23-34 读 12 处) | `game/presentation/main_ui_build.gd:130-153`;`game/presentation/curio_interact_controller.gd:31-48`;`game/presentation/camp_shop_presenter.gd:21-34` |
|
||||
| S13 | open_victory 现行 8 参(:116-117);消费方 8 处——传可选参者 5 处须随动(main.gd:454/:459 八参、main_adventure_flow.gd:100/:166 四参、ui_struct_probe 四参),三参调用 3 处(fx_probe:53/standee_fx_sweep_test×2/curio_interact:107)缺省兼容零改动;open_defeat 不在收编账目零触碰 | grep 实测(§8 wr 行) |
|
||||
| S14 | 测量面:playtest_logger print 两行(:160/:161——诊断转储路径与上下文 JSON);同路径信息已由 toast 承载(main_debug_flow.gd:16 `show_toast("已转储诊断: "+path)`)且转储 JSONL 文件本身落盘;tune_sim_controller print 一行(:43 日志路径)+循环内 await(:65 逐帧让出驱动浮窗进度刷新);playtest_logger 被 4 个 sim 驱动件构造消费(adventure_monte_carlo:104/rhythm_batch:21/level_autoplay:40,118/verifier_batch:41);**v1.1 处置定案=print×3 删除、await 豁免(D6)** | `game/presentation/playtest_logger.gd:160-161`;`game/presentation/tune_sim_controller.gd:43/65`;`game/presentation/main_debug_flow.gd:15-16` |
|
||||
| S15 | golden 现行基线集五张:棋盘三图(900×760 裁剪区)/menu_boot(全屏)/level_map(全屏,iter38 卡①改前建锚先例——对拍经 golden_compare 直跑,render_gate 现行只对拍棋盘三图+menu_boot);shot_probe 七屏帧(menu/settings/career/camp/level/battle/status);加严口径=棋盘三图裁剪区内差异一律判失效 | `game/tests/golden/README.md`;`tools/render_gate.sh` |
|
||||
| S16 | level_map_screen 探针冻结成员:_cand_ids(ui_struct/ui_click 3 处)/ _hover_id(ui_input_probe:109)、_content_size(S16 公式同源锚 :152)、_layout_cache(iter38 特批债成员——layout_probe() 判同实例断言 V1/V2,本体不经成员直读)、display_probe()→_drawn_disp(绘制记录唯一读出——经方法出口)、abandon_btn/status_badge(探针直引 5+1 处) | `game/probe/ui_struct_probe.gd:157/289`、`ui_input_probe.gd:109/152`、`ui_click_probe.gd:491-492`;`game/tests/unit/presentation/level_map_info_fog_test.gd:199-230` |
|
||||
| S17 | **收拢件冻结与外部契约面全集(v1.1 逐件实查,2026-10-27)**:①camp_overlay_view 探针直读 5=_balance_label/_tree_buy_btns/_tree_fork_btns/_workshop_holder/_workshop_rows(ui_probe:36-42/ui_click_probe:70-116);②level_map_screen 探针直读 6=_cand_ids/_hover_id/_content_size/_layout_cache/abandon_btn/status_badge(S16+ui_click_probe);_runner 装配注入无直读(组合根零成员直写 grep 实测);③board_cell_unit=被动绘制壳:31 成员中 30 个被 board_view 直写(`u.edge = _cell` :248/:295、`u.bg_sb = sb` :710、`u.glyph = glyph` :711、`u.plate = …` :719、`u.fog_state = …` :778/:780 等 47 行实测),探针/测试直读 4=glyph(ui_input_probe:271/:363-366)/fog_state(:400-:492 多处)/plate+glyph_color(player_copy_sweep_test:139-142);board_view 外产品码零直写;④standee_body 外部直访 4=box(battle_stage_view:180/:190 直写、:367 直读、fx_probe:17/:41/:109 直写、standee_fx_sweep_test:87/:90 读)/font(:214/:217)/slot_row(:122/:204/:268)/has_world_hp_bar(ui_probe:141 直读);⑤battle_end_overlay 探针直读 4=_btn/_gp_name/_gp_row/_gp_val(S5 补);组合根零成员直写;⑥debug_overlay 探针直读 3=seed_edit(15 处)/_sim_btn/_dbg_btn(ui_tune_probe:132+standee_fx_sweep_test:119/:121);_run_data/_run_labels 经 run_data_probe()/update_run_data() 方法出口;⑦curio_interact_controller 探针零成员直读(_bonus 面全走方法——press_card/_curio_card_texts() 等,grep 实测) | `game/probe/` 全目录+`game/tests/` grep 实测(逐条出处随行);T0 复核存档 |
|
||||
|
||||
## 4. 设计契约(红线,违反 = L3 停机呈报)
|
||||
|
||||
🔴 **契约 1 · 呈现零变化**:一切视图/工厂/投影改动像素级零变化——§7 T0 建锚面改后对拍差异非零即红(golden 逐像素);文案拼装逐字不变(battle_narrator_test 等现役断言零改动);信号面、`main.LAYER_CONTRACT` 层序合同、模态编排(ModalFlow/ModalStack)、装配序零触碰;print 删除三行=stdout 诊断文本移除(页面/toast/落盘信息零变化),禁顺手改任何 set_sim_report/报告文案。
|
||||
|
||||
🔴 **契约 2 · 探针断言面禁削弱**:S1–S7/S9/S10/S16/S17 所列探针直引公开面(方法/成员/常量/信号)逐字保留——**私有化、改名、搬文件均不进口径**;收拢件冻结成员(S17 ①–⑥)住宿主类不变不进状态件;源码锚字面量契约(camp STONE 等式与三组计数锚、ap_bar 锚句、standee 四句、debug 三句、V4 token 禁令、ui_contrast Color8/preload 扫描)随拆分逐字保持——拆分只许把锚句整行原样留在文件内,禁改写措辞、禁换行重排锚句。测试与探针随动仅限消费面迁移(访问路径改写),断言语义与判据逐条保持。
|
||||
|
||||
🔴 **契约 3 · main.X 句柄面冻结(架构豁免)**(architecture v1.19 :183 豁免登记在册):main.gd 类变量面=探针契约面,按架构契约豁免(键永久基线内、禁再恶化)——**禁收拢 main 句柄、禁删除成员、禁改名、禁为清键改写探针挂载契约**;`main.LAYER_CONTRACT` 常量零触碰。u25=注记核对+申报件(§1)。
|
||||
|
||||
🔴 **契约 4 · S13 纪律**:`tools/gdstyle_baseline.txt` 禁改禁 refresh(还债=数值下降自然归绿;豁免键=键留基线内绿,豁免依据在 architecture v1.19 在册,非基线注记);本批不得引入基线外新违规——**拆出的每个私有函数与内部状态件自身在阈值内**(≤50 行/≤10 局部/≤8 分支/≤6 return/≤5 参数),批末 gate NEW=0 是验收判据;机检键与本卡契约互斥时一律停卡呈报,禁自造第三条路。
|
||||
|
||||
🔴 **契约 5 · 测试削弱申报=零**:现役断言(单元/集成/探针/源码锚)零删除、零放宽、零缩小扫描面;测试直构面的随动改址只改访问路径;实现期任何「顺手简化断言」判红。
|
||||
|
||||
🔴 **契约 6 · 波 6 形态裁定**:视图内部拆私有函数,**不拆构建步件**——禁新建任何 .gd 文件(D1);v1.1 内部状态件一律**宿主文件内 inner class**(`class XxxState extends RefCounted` 嵌套声明,裁决两形态〔inner class/独立小状态类〕中与零新文件相容的唯一形态);拆分零行为变化、零新信号、零新公开成员(ui_kit 净 −6 公开方法是唯一减面);私有函数命名与归属属代拍板白名单(§10)。
|
||||
|
||||
🔴 **契约 7 · 类变量全清与豁免边界(v1.1)**:七收拢件宿主类变量收拢后 ≤15(键消失=S13 对账绿;u2 恶化债归绿被吸收);main/await 两键豁免在册(D4/D6)不参与清偿;收拢只收纯状态数据与无外部直访成员,**禁为计数造转发属性/别名/空壳成员**(§13);board_view 随动只许写入行机械改址(`u.X =` → `u.st.X =` 等价形),发现非机械改址点即停呈。
|
||||
|
||||
🔴 **契约 8 · 豁免键零重构**:tune_sim 测速循环(:65 逐帧 await)**禁重构**(D6——wall-clock 步进承载语义,重构即测量口径漂移);main 句柄面禁收拢(契约 3)。豁免键在实现报告各申报一行(键值/依据指针 v1.19 段名/禁再恶化注记)。
|
||||
|
||||
🔴 **契约 9 · 拆分边界纪律(DDD/高内聚,2026-10-28 用户裁)**:一切拆分(私有函数族/内部状态件/参数束)的边界沿职责轴、不沿阈值轴——①每个拆出单元须有可陈述的职责语句(实现报告逐件一行)与单一变化原因;②内部状态件须有集体身份:成员共同表达一个可命名的领域概念,**禁跨子域混装**(u1 四柜台子域为硬例——树/锻造/同调/刷新各成状态件);「探针直读之外剩下的成员」打包=凑计数袋,禁;③「过阈值」只许作为发现信号,作为收拢动机即违规;④某视图按本条拆不出内聚单元 → 该键不强清:停卡呈报走豁免/还债通道(main.gd 同款架构豁免登记),禁硬拆凑绿;⑤私有函数族边界沿绘制/构建域(底面/徽标/封印等既判分组为准),无域可循的长函数拆分停卡呈报。code-conventions §1.1 为上位规约。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
**做**:u1–u25;消费面随动改址(§7 结构图注记行;含 board_view 写入行机械随动——u3 全清必要执行面);T0 锚面采集;撤销证明;产出物(含豁免申报件)。
|
||||
|
||||
**不做**(去向明示):
|
||||
- 三宿主拆件(adventure_runner/level_runner/board_view 结构拆件)→ iter 39 主卡(本卡对 board_view 只做 u3 随动的写入行机械改址,禁结构触碰);battle_orchestrator/settlement/damage_controller/treasure_interact_controller → 卡 1;core/data 侧 86 键 → 卡 2;波 7 现成卡与波 0 基线 refresh → 各自通道(本批禁自行 refresh,契约 4);
|
||||
- **不拆构建步件**(main_ui_build 分步形态不类比到普通视图——D1);不新建任何文件(内部状态件=宿主内 inner class——契约 6);不动 open_defeat 与任何清单外公开方法语义;
|
||||
- **main 句柄面零收拢零删除(契约 3);tune_sim 测速循环零重构(契约 8)**——两豁免键只核对申报、不做任何键清偿动作;
|
||||
- design/ 与根规则文件任何编辑 → 反哺点清单(§6);MC/对拍锚零触碰(数值与 RNG 零改动=零 MC,纪律 §四.4);
|
||||
- user 目检项登记不阻塞(§8.2)。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点 | 同步义务 |
|
||||
|---|---|---|
|
||||
| `game/tests/golden/README.md` | 乙组新建基线(camp/settings/battle 帧)判定记录+甲组判读记录 | 批内机械同步(game 内 .md,非禁写面) |
|
||||
| `game/tests/验证集清单.md` | 测试直构面随动改址不改断言语义与数量——预期零变化;若实现期补静态判据则机器提取重生成(tools/extract_checks.py) | 批内机械同步(game 内 .md,非禁写面) |
|
||||
| `design/engineering/architecture/architecture.md` | 预期零修订——v1.19 两处豁免登记段在册(D4/D6 依据);零新件、模块归属表零行变化、组合根句柄面条款不受影响;ui_kit 公开面收敛不动模块表(无 ui_kit 独立行) | 反哺点 · 列清单(预期零改动注记;实现中若发现表述漂移逐条列) |
|
||||
| `待办清单.md` | 来源条目状态推进(写卡段回写归主会话;实现批收尾归 batch-closure) | 反哺点 · 列清单 |
|
||||
|
||||
## 7. 任务卡
|
||||
|
||||
### 卡前 · 文件结构图
|
||||
|
||||
| 文件 | 职责 | 行为改动 |
|
||||
|---|---|---|
|
||||
| `game/presentation/views/camp_overlay_view.gd` | u1 拆私有函数族+类变量收拢内部状态件(复用既有·修改) | 非行为 → wr1 |
|
||||
| `game/presentation/views/level_map_screen.gd` | u2 拆私有函数族+类变量收拢(装饰域字典随迁状态件)(复用既有·修改) | 非行为;**恶化债归绿+键清** → wr2 |
|
||||
| `game/presentation/views/board_cell_unit.gd` | u3 拆绘制私有族+类变量收拢(复用既有·修改) | 非行为 → wr3 |
|
||||
| **随动·`game/presentation/views/board_view.gd`** | **u3 写入行机械改址约 40 行(`u.X =` → `u.st.X =`,v1.1 新增随动件——S17 ③)** | 非行为(机械改址零语义)→ wr3 |
|
||||
| `game/presentation/views/standee_body.gd` | u4 拆绘制私有族+类变量收拢(复用既有·修改) | 非行为 → wr4 |
|
||||
| `game/presentation/views/hero_info_panel_view.gd` | u5(复用既有·修改) | 非行为 → wr5 |
|
||||
| `game/presentation/views/battle_end_overlay.gd` | u6 拆私有+open_victory 4 参化+类变量收拢(复用既有·修改) | 非行为(签名收拢缺省兼容)→ wr6 |
|
||||
| `game/presentation/views/debug_overlay.gd` | u7 拆五区块+类变量收拢(复用既有·修改) | 非行为 → wr7 |
|
||||
| `game/presentation/ui_assembler.gd` | u8(复用既有·修改) | 非行为 → wr8 |
|
||||
| `game/presentation/views/battle_stage_view.gd` | u9(复用既有·修改) | 非行为 → wr9 |
|
||||
| `game/presentation/views/curio_pick_overlay.gd` | u10(复用既有·修改) | 非行为 → wr10 |
|
||||
| `game/presentation/views/settings_overlay.gd` | u11(复用既有·修改) | 非行为 → wr11 |
|
||||
| `game/presentation/views/battle_log_view.gd` | u12(复用既有·修改) | 非行为 → wr12 |
|
||||
| `game/presentation/curio_interact_controller.gd` | u13 引用束注入(删 16 冗余成员持 ctx)(复用既有·修改) | 非行为 → wr13 |
|
||||
| `game/presentation/views/ap_bar_view.gd` | u14(复用既有·修改) | 非行为 → wr14 |
|
||||
| `game/presentation/views/board_zone_view.gd` | u15(复用既有·修改) | 非行为 → wr15 |
|
||||
| `game/presentation/views/board_fx_view.gd` | u16(复用既有·修改) | 非行为 → wr16 |
|
||||
| `game/presentation/views/legend_overlay.gd` | u17(复用既有·修改) | 非行为 → wr17 |
|
||||
| `game/presentation/views/ui_kit.gd` | u18 公开面收敛+参数收拢(复用既有·修改) | 非行为(消费面随动改址承载撤销证明)→ wr18 |
|
||||
| `game/presentation/hud_presenter.gd` | u19 参数束收拢(复用既有·修改) | 非行为 → wr19 |
|
||||
| `game/presentation/curio_flow_context.gd` | u20 三束收拢(复用既有·修改) | 非行为 → wr20 |
|
||||
| `game/presentation/camp_flow_context.gd` | u21 三束收拢(复用既有·修改) | 非行为 → wr21 |
|
||||
| `game/presentation/battle_narrator.gd` | u22(复用既有·修改) | 非行为 → wr22 |
|
||||
| `game/presentation/tune_sim_controller.gd` | u23 stats 束+print 删除+await 豁免申报(复用既有·修改) | 非行为(print 删除=stdout 诊断文本)→ wr23 |
|
||||
| `game/presentation/playtest_logger.gd` | u24 print×2 删除(复用既有·修改) | 非行为 → wr24 |
|
||||
| `game/presentation/main.gd` | u25 豁免申报件(零改动——v1.19 :183 豁免在册,面冻结)(复用既有·零修改) | 非行为(申报)→ wr25 |
|
||||
| 随动·`game/presentation/main_ui_build.gd` | u20/u21 两构造行改束传参(清单外单行随动) | 非行为 → wr20/21 |
|
||||
| 随动·`game/presentation/camp_shop_presenter.gd` | u21 ctx 束读改址 12 处(清单外随动) | 非行为 → wr21 |
|
||||
| 随动·`game/presentation/main_adventure_flow.gd` | u6 open_victory 四参调用改址 2 处(清单外随动) | 非行为 → wr6 |
|
||||
| 随动·`game/presentation/shop_overlay_view.gd` | u18 bcard 五参调用改址 1 处(清单外随动) | 非行为 → wr18 |
|
||||
| 随动·`game/presentation/views/node_overlay.gd`/`status_panel.gd`/`confirm_dialog.gd`/`settlement_review_overlay.gd` | u18 modal_shell 尾参改址各 1 处(清单外随动) | 非行为 → wr18 |
|
||||
| 随动·`game/probe/fx_probe.gd` | u6 open_victory 四参改址 1 处(测量面随动) | 非行为 → wr6 |
|
||||
| 随动·`game/probe/ui_struct_probe.gd` | u6 open_victory 四参改址 1 处(测量面随动) | 非行为 → wr6 |
|
||||
| 随动·`game/tests/unit/presentation/theme_projection_test.gd` | u18 beams/gradient 私有化改址 2 处(断言语义不变) | 断言面随动 → wr18 |
|
||||
|
||||
(零新增文件;私有函数族与内部状态件随各宿主文件内新增——落位预检见下节。)
|
||||
|
||||
### 接口块
|
||||
|
||||
**T0 产出(T1–T5 取用)**:①改前 S13 读数表(25 文件 71 键现行值 `文件|规则|函数 = 值`,实现报告素材);②golden 锚三组(甲组在库基线判读记录;乙组 camp/settings/battle 三帧基线入 `game/tests/golden/`+README 判定记录;丙组 battle_end/curio_pick/legend/debug 直构改前帧——落临时区,批末退役);③**S17 冻结面复核清单**(七收拢件冻结成员逐名+board_view 直写 47 行清单——u3 随动改址的行级依据)。
|
||||
|
||||
**内部状态件形态(v1.1 收拢件统一形,u1/u2/u3/u4/u6/u7 取用)**:
|
||||
|
||||
```gdscript
|
||||
# 宿主文件内嵌套声明(零新文件——契约 6);探针/外部直访冻结成员(S17)住宿主,不进状态件;状态件须有职责语句+单一子域(契约 9,跨子域混装禁)
|
||||
class _DrawState extends RefCounted:
|
||||
var glyph_col := UiKit.INK # 纯状态数据成员逐个迁入(命名随宿主原成员)
|
||||
# 宿主侧:
|
||||
var st := _DrawState.new() # 状态件单成员(宿主类变量 −N+1)
|
||||
# 内部读点改址:self.X → st.X(宿主私有函数族与 _draw 一并落);
|
||||
# 经方法出口的状态(fx_probe()/run_data_probe()/update_run_data())读点随迁方法体,方法签名与返回值零变化
|
||||
```
|
||||
|
||||
**u18 ui_kit 新形态**(T3 落地,wr18 断言取用):
|
||||
|
||||
```gdscript
|
||||
# 删除:frame_skinned / verb_button(全库零消费,S8 普查凭据)
|
||||
# 私有化(改名加下划线,消费方随动):_modal_dim / _beams_rect / _gradient_base / _switch_toggle
|
||||
# (load_font 保留公开——board_shot/type_glow 探针与 ui_font_asset_test 三行直引,收敛算术不需要它)
|
||||
# 公开方法 26→20(≤阈值,键清偿)
|
||||
const PANEL_DEFAULT := true # modal_shell 面板哨兵(非 StyleBox 实例)
|
||||
static func modal_shell(parent: Control, dim_color: Color, min_size := Vector2.ZERO,
|
||||
separation := 12, panel_sb = null) -> Dictionary
|
||||
# panel_sb == null → 无面板(原 with_panel=false)
|
||||
# panel_sb == PANEL_DEFAULT → 默认样式盒面板(原 with_panel=true+panel_sb=null——settlement_review 形态)
|
||||
# panel_sb is StyleBox → 自定义样式盒面板(原双参形态)
|
||||
static func bcard(title: String, desc: String, band: Color, icon_path: String, opts := {}) -> BCard
|
||||
# opts 键 {price: String = "", footnote: String = ""}——BCard._init 同形收拢(6→5 参)
|
||||
```
|
||||
|
||||
**u19 hud_presenter 新签名**(T3/T4 取用):
|
||||
|
||||
```gdscript
|
||||
static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApBarView, ctx: Dictionary) -> void
|
||||
# ctx 五键:{settlement, runner, level_active: bool, db, refresh_remaining: int}(原 :14 尾五参收拢)
|
||||
static func _refresh_out_of_battle(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApBarView, ctx: Dictionary) -> void
|
||||
static func tune_sim_report(n: int, atk_pct: int, hp_pct: int, stats: Dictionary, base_hp: int) -> String
|
||||
# stats 六键:{wins: int, dmg_all: Array, hp_left_win: Array, hp_boss: Array, rounds_all: Array, death_nodes: Dictionary}
|
||||
```
|
||||
|
||||
**u20/u21 flow context 新形态**(T4 取用;u13 改址同取键名):
|
||||
|
||||
```gdscript
|
||||
# CurioFlowContext / CampFlowContext 同形:
|
||||
func _init(db_ref, views: Dictionary, getters: Dictionary, flow: Dictionary) -> void
|
||||
# views = {curio_overlay, end_overlay, board_view, toast}/camp 侧 {camp_overlay, shop_overlay, toast, start_overlay, logger}
|
||||
# getters = {meta_get, save_get, adventure_get, runner_get, adventure_mode_get}/camp 侧 {meta_get, save_get, runner_get}(Callable 活引用——禁快照语义不变)
|
||||
# flow = {open_modal, open_modal_after_playback, close_modal, refresh_presentations, fatal_screen, gp_summary}/camp 侧 {open_modal, close_modal, refresh_presentations}
|
||||
```
|
||||
|
||||
**u13 curio_interact_controller 新形态**(T4 取用):`_init(ctx: CurioFlowContext)` 保持——16 抄写成员删除(:32-48 赋值块),正文 `db`/`_meta_get`/`curio_overlay`/…/`_gp_summary` 读点改址 `ctx.db`/`ctx.getters.meta_get`/`ctx.views.curio_overlay`/…/`ctx.flow.gp_summary`(键名按上表);`_pending_curio`/`_curio_context` 保持宿主。装配行 main_ui_build.gd:132 零改动(仍 `CurioInteractController.new(CurioFlowContext.new(...))`,构造参数随 u20 改束传参)。
|
||||
|
||||
**u6 battle_end 新签名**:`open_victory(verdict_line: String, continue_label: String, board_rect: Rect2, opts := {}) -> void`,opts 键 `{gp_summary: String = "", ks_summary: String = "", bonus_summary: String = "", gp_gain: int = -1, gp_total: int = -1}`。
|
||||
|
||||
**u23/u24 测量面定案(v1.1)**:playtest_logger :160/:161 两行删、tune_sim_controller :43 一行删(grep 残留=撤销证明);tune_sim :65 await 零触碰(D6 豁免——实现报告申报行:`tune_sim_controller 循环内 await=v1.19 测试与质量域·S13 测量面豁免登记段在册,键永久基线内`)。
|
||||
|
||||
**u25 豁免申报件(v1.1)**:零代码改动;实现报告申报行:`main 类变量 49/15=v1.19 呈现层装配节 S13 豁免登记在册(组合根类变量面=探针契约面),键永久基线内、禁再恶化`;T0 核对注记在位(v1.19 :183)。
|
||||
|
||||
**T 卡间接口**:T0 产出锚面与读数表+冻结面复核清单(全部卡取用);T1 产出 level_map/board_cell 收拢后读数(T5 复核取用);T3 产出 ui_kit/hud_presenter 新签名(T4 tune_sim stats 束按 u19 stats 六键构造);各卡验收随卡落地。
|
||||
|
||||
### 落位与可复用性预检
|
||||
|
||||
| 新增件 | 复用面(为何不能复用既有) | 唯一面 | 分层与交互 |
|
||||
|---|---|---|---|
|
||||
| 各宿主文件内私有函数族(约 60–80 个私有函数,随拆分产生) | **零新增文件、零新增公开件**——全部落既有宿主文件内(契约 6);私有函数非「新增件」意义上可复用单元:它们是被拆函数的原文分段,禁抽共享骨架(波 2 同款裁定精神:13 文件结构各异,强行归一有抽象层风险) | 每个私有函数唯一归属其宿主视图;禁把 helper 散落到别的文件(波 6 形态裁定) | 视图内部自调用,零跨层交互新增;Core 零 UI 不破(本批零触 core/);随机零消费、ConfigDB 读面零新增 |
|
||||
| **各收拢件宿主内 inner class 状态件(_DrawState 形,u1/u2/u3/u4/u6/u7 六件各一,新增)** | **不能复用既有件也不能跨视图共用一个状态类**:各视图绘制态/运行态彼此独立、零共用结构(camp 柜台行板登记、cell 绘制输入、standee 演出态、battle_end 行板与 fx 计数、debug 表值态各成一套,字段集无交集)——强归一共用类=跨视图耦合+字段冗余;也不能复用 flow context 束(那是对组合根回调的活引用束,非视图绘制态) | 每件唯一归属其宿主文件(inner class 随宿主),禁散落到别的文件(契约 6 零新文件) | 宿主内部自持有(RefCounted 值件,不进场景树、零信号),冻结成员(S17)住宿主不进件;零跨层交互新增 |
|
||||
| golden 三帧基线(乙组 camp/settings/battle) | 复用 shot_probe 现成七屏帧采集面与 golden_compare.py 判据(iter38 卡① 手法)——不扩 golden_baseline_refresh.sh(工具改动超本批面) | 三帧各一,落 `game/tests/golden/`+README 判定记录 | 采集=探针隔离档(无断点+出厂设置 1280);对拍判据复用现行容差 |
|
||||
| u18 `PANEL_DEFAULT` 哨兵常量 | modal_shell 六参收拢的最小形态——拆分两个函数会 +1 公开方法破 20 收敛(S8 收敛算术),哨兵是唯一不加方法的收拢形态 | 常量唯一,定义于 ui_kit | 纯 ui_kit 内部判别语义,消费方仅改传参形态 |
|
||||
|
||||
### T0 事实坐实+改前锚面采集(≈0.45d,**时点铁序:本卡全部锚面采集先于一切生产码改动**)
|
||||
|
||||
- [ ] 复核 S1–S17 行号与直引清单(吸收 iter39 批漂移——若 iter39 已合回,u2/u13/u19/u25 相关行号重定位);产出探针直引 46 名全量清单、ui_kit 消费方普查表、**S17 七收拢件冻结成员复核清单+board_view 直写 47 行清单(u3 随动改址行级依据)**存档实现报告素材。可核查结果:复核清单在案。
|
||||
- [ ] 产出改前 S13 读数表(71 键现行值逐键)。可核查结果:读数表进实现报告素材。
|
||||
- [ ] **甲组判读**(在库 golden 五张):跑渲染闸对拍段+golden_compare 直跑 level_map——棋盘三图/level_map/menu_boot changed 全 0.00% 方可动码(棋盘三图按加严口径裁剪区内差异一律停机呈报)。可核查结果:判读记录进 golden/README 判定记录节。
|
||||
- [ ] **乙组建锚**(无在库基线三屏):改前采集 shot_probe 的 camp/settings/battle 三帧→各自连采两轮逐像素比对实测跨跑次一致性=0.00%→直拷落盘 `game/tests/golden/`(文件命名属代拍板白名单 §10.3,随 README 判定记录登记)+README 判定记录(改前建锚、触发原因=呈现层结构收敛批对拍锚)。**battle 帧若两轮比对非 0.00%(动效相位不确定)→ 该屏锚降级丙组直构对拍**,判定记录写明。可核查结果:三帧基线或降级注记在案。
|
||||
- [ ] **丙组改前帧**(模态/覆盖层四件):临时抓帧脚本(--script 或临时场景,直构 battle_end_overlay.open_victory/curio_pick_overlay.open_pick/legend_overlay.open/debug_overlay 构建态,落 mktemp 临时区,禁入 git、批末退役);同法采集改前帧存档。可核查结果:四件改前帧与采集脚本在案(脚本禁入 git)。
|
||||
- [ ] **豁免注记核对(v1.1)**:architecture v1.19 :183(组合根豁免段)与 :311(测量面豁免段)两处注记在位核对,段名与键指针抄录实现报告(u25/u23 申报件素材)。可核查结果:两段在位核对记录在案(缺位=停卡呈报)。
|
||||
|
||||
### T1 营地与地图面拆分(≈1.6d)
|
||||
|
||||
- [ ] u1 camp_overlay_view:_init 拆四柜台构建私有族、_rebuild_tree/_rebuild_forge/refresh_camp 拆行板构建私有族、七处循环体提私有构建函数;**类变量收拢**——冻结 5 成员保持(S17 ①),其余 14 个迁 `_CampState` inner class、宿主读点改 st.X;源码锚句(S2 两组)整行原样保留。可核查结果:gdstyle 单文件复扫该文件键全清(类变量 9/15 键消失——子域件形 v1.2);ui_struct camp 源扫描绿;theme camp 三锚绿;camp 乙组帧对拍 0.00%。
|
||||
- [ ] u2 level_map_screen:_init/_draw_graph 拆私有族;**类变量收拢**——冻结 6 成员+状态件保持(S17 ②),其余 16 个迁 `_MapState`(_node_icons/_noise_rect/_tint_level 在状态件内持 `_layer_decor` 域字典);S16 冻结成员与 layout_probe/display_probe 行为逐字不变。可核查结果:单文件复扫类变量 ≤15(键消失,恶化债归绿被吸收);level_map_info_fog_test 全绿(V1/V2 缓存断言继承);level_map golden 对拍 0.00%。
|
||||
- [ ] u3 board_cell_unit:_draw 拆绘制私有族;**类变量收拢**——探针直读 4 成员+_glow_layer+状态件保持(S17 ③),board_view 直写 26 成员迁 `_CellPaintState`、board_view 写入行机械改址约 40 行(`u.X =` → `u.st.X =`,逐行对照 T0 直写清单,等价形禁改语义)。可核查结果:单文件复扫类变量 6/15 键消失+函数级键全清;board_view 随动行 grep 对账(改址行数=清单行数);棋盘三图 golden 0.00%(甲组);ui_input/player_copy 直读面回归绿。
|
||||
- [ ] u4 standee_body:_draw 拆绘制私有族、循环体提私有构建函数;**类变量收拢**——外部直访 4 成员保持(S17 ④),其余 25 个迁 `_StandeeState`(fx 出口三计数随迁,fx_probe() 方法体读点改 st.X、返回键名零变化);standee 源锚四句(S6)逐字保留。可核查结果:单文件复扫键全清(类变量 5/15 键消失);standee_fx_sweep_test+fx_probe+theme 源锚段绿。
|
||||
- [ ] 验证步骤:甲/乙组对应锚复拍(board 三图+level_map+camp+battle 帧)全 0.00%;波内出红只跑红件最小单元。
|
||||
|
||||
### T2 战斗屏与覆盖层拆分(≈1.25d)
|
||||
|
||||
- [ ] u5/u6/u7:hero_info_panel(段构建私有族+槽位循环提函数)、battle_end_overlay(行板私有族+open_victory 四参化——S13 五处传参消费点按接口块改址;**类变量收拢**——探针直读 4 句柄保持(S17 ⑤),其余 16 个迁 `_EndOverlayState`)、debug_overlay(五区块私有族——S1 全部公开面与源码契约零触碰;**类变量收拢**——直读 3 成员保持(S17 ⑥),其余 14 个迁 `_DebugState`,run_data_probe()/update_run_data() 方法体读点随迁、签名与返回零变化)。可核查结果:三文件函数级键全清+类变量键全清(5/4/4 均键消失);ui_tune/debug 系探针直跑绿;ui_struct/丙组 battle_end 对拍 0.00%。
|
||||
- [ ] u8–u12:ui_assembler(build_start_overlay 拆列/行私有族+立绘循环提函数)、battle_stage_view(拆构建私有族+_enemy_portrait_tex 查表化)、curio_pick_overlay(拆构建+_icon_for_id 查表化)、settings_overlay(拆行私有族)、battle_log_view(_format_row 按行型拆私有格式化族)。可核查结果:五文件函数级键全清;ui_struct/丙组 curio_pick/settings 帧对拍 0.00%;reward_overlay_test/player_copy_sweep_test/theme 源锚段绿。
|
||||
- [ ] u14–u17:ap_bar(拆构建私有族,S7 锚句逐字保留)、board_zone(拆构建私有族)、board_fx(循环体提 band 构建函数)、legend(ENTRIES 循环提行构建函数)。可核查结果:四文件键清;ui_probe/ui_click ap_bar 直引面回归绿;fx_probe 直构面绿。
|
||||
- [ ] 验证步骤:乙组 battle/settings 帧+丙组四件对拍全 0.00%;波内出红只跑红件最小单元。
|
||||
|
||||
### T3 装配与工厂件收敛(≈0.75d)
|
||||
|
||||
- [ ] u18 ui_kit 按接口块落地五步:删 frame_skinned/verb_button→私有化四件(消费方改址:camp:45/ui_assembler:104/level_map:65/settings:76/:91+theme:639/:664)→modal_shell 哨兵收拢(八消费点改址)→BCard._init/bcard opts 收拢(curio_pick:99/shop_overlay:212 改址)→beams_rect 像素循环拆私有函数。可核查结果:单文件复扫公开方法 ≤20(键清偿)、参数键全清;theme V1–V3/T5② 段绿;ui_contrast 扫描段绿(ui_kit 素材 preload=0、Color8 面零外溢)。
|
||||
- [ ] u19 hud_presenter 按接口块三签名收拢;消费方改址=main.gd:810(ctx 五键)+tune_sim_controller:67(stats 六键)。可核查结果:参数键三键清;hud_presenter_test+system_test 呈现段绿;refresh 后呈现与改前逐帧同像(battle golden 帧 0.00%)。
|
||||
- [ ] u25 main.gd **豁免申报件(零改动)**:核对 T0 豁免注记核对记录;实现报告申报行落位(键值 49/15+依据指针 v1.19 :183+禁再恶化注记);对 main.gd 的 diff 零行(面冻结实证)。可核查结果:git diff main.gd 为空+申报行在案;12 探针+system_test 全绿。
|
||||
- [ ] 验证步骤:全套闸按改动域选档跑一次全绿(里程碑步出口)。
|
||||
|
||||
### T4 交互与上下文件+测量面定案执行(≈0.85d)
|
||||
|
||||
- [ ] u20/u21 flow context 三束收拢(接口块形态);消费方改址=main_ui_build 两构造行+camp_shop_presenter 12 处 ctx 读(束键访问改写,零语义变化)。可核查结果:curio_flow_context 类变量 16→4、_init 4 参(两键清偿);camp_flow_context _init 4 参(键清偿);ui_click/ui_struct 三选一与营地段回归绿。
|
||||
- [ ] u13 curio_interact_controller 引用束注入:16 抄写成员删除、正文读点按接口块键名改址 ctx 束;_pending_curio/_curio_context 保持(S17 ⑦——探针零成员直读实证)。可核查结果:单文件复扫类变量 3/15 键消失;ui_click/ui_struct 三选一真链段绿(press_candidate/press_confirm/press_refresh 面零变化)。
|
||||
- [ ] u22 battle_narrator bonus_card_text 拆私有文案族(battle_narrator_test 零改动全绿)。可核查结果:读数改善在案(键清);battle_narrator_test 绿。
|
||||
- [ ] u23/u24 测量面定案执行:playtest_logger :160/:161 两行删、tune_sim :43 一行删(禁改 set_sim_report 文本)、u23 stats 束收拢(≤10 局部);**:65 await 零触碰**(D6——禁重构测速循环);tune_sim 链路回归=ui_tune_probe 批量模拟段直跑绿(wall-clock/进度语义保持)。可核查结果:三行 print grep 零命中(撤销证明载体);tune_sim 键读数=stats/局部两键清+await 豁免在册;u23 await 豁免申报行(依据 v1.19 :311)落实现报告。
|
||||
- [ ] 验证步骤:全套闸按改动域选档跑一次全绿。
|
||||
|
||||
### T5 撤销证明+产出物落位卡(≈0.45d,末卡)
|
||||
|
||||
- [ ] 逐 wr 行撤销证明(§8.1 末列——读数对拍类:回退该文件 hunk→对照 T0 读数表该文件键读数回升=红→还原复绿;消费面迁移类:回退生产 hunk→随动消费方调用断红=更强证明;print 类:回退→源码 grep 命中=红;随动改址类〔board_view〕:回退改址 hunk→board_view 写入行对迁出成员断红)。记录进实现报告。
|
||||
- [ ] S13 批末读数对拍:gate 输出 NEW=0、WORSENED=0(开工时唯一在册红 level_map_screen 类变量由 u2 归绿吸收——v1.2 重锚)、**71 键账目对账(§8.4)逐键核对=69 键消失+2 键豁免在册**(main 49/15、tune_sim await——两申报行落位)。可核查结果:读数对拍表+豁免申报对账进实现报告。
|
||||
- [ ] 写齐三份产出物(实现报告〔各卡状态+读数对照+豁免两键申报行+实机目检总清单——乙组三屏与丙组四态实机开合目检登记(登记不阻塞)〕/代拍板追认单/反哺点清单〔§6 逐条落点〕);临时抓帧脚本与丙组过程帧按中间产物纪律退役。
|
||||
- [ ] 合并前置:独立验收审计(§8.3)逐行「通过」。
|
||||
|
||||
**估时合计 ≈5.3d**(区间 5.0–5.5;v1.2 子域拆件增量 ≈+0.1d 已含区间内;v1.0 ≈4.0d 上调 ≈1.3d——收拢增量明细:u1/u2/u4 各 ≈0.15d+u3 收拢与 board_view 随动改址 ≈0.25d+u6/u7 各 ≈0.12d+u13 束注入改址 ≈0.2d+print 删除与豁免申报 ≈0.1d;超软盒预挂=iter39 先行合回致行号重定位面扩大时 T0 +0.2d)。
|
||||
|
||||
## 8. 验证闸
|
||||
|
||||
### 8.1 改动—验收对照表
|
||||
|
||||
撤销证明三型:**读数型**=回退该文件 hunk → 对照 T0 改前读数表该文件键读数回升=红 → 还原复绿(结构拆分与收拢单元的断言载体);**迁移型**=回退生产 hunk → 随动消费方调用断红(签名/改名/束注入单元的更强证明,迁移不对称作断言);**grep 型**=print 删除类,回退 → 源码 grep 命中=红。对拍锚=T0 三组(甲:棋盘三图/level_map/menu_boot;乙:camp/settings/battle 帧;丙:battle_end/curio_pick/legend/debug 直构帧)。**收拢件断言三件套(v1.1)=S13 键消失(类变量计数对账绿)+golden 逐像素 0.00%+探针冻结面断言零变化(S17 冻结成员直引面回归绿)**。
|
||||
|
||||
| 需求点 | 改动(文件) | 验收测试(名称+落点) | 层级 | 真实入口 | 撤销证明 |
|
||||
|---|---|---|---|---|---|
|
||||
| wr1 u1 营地覆盖层拆分+收拢 | camp_overlay_view | S13 键消失(10 键清:函数级 9+类变量);S17 ① 冻结 5 成员断言零变化;ui_struct camp 源扫描+theme camp 三锚;乙组 camp 帧对拍 0.00% | 静态+探针+golden | ui_struct_probe 真实驱动+shot_probe 帧 | 读数型+锚句 grep |
|
||||
| wr2 u2 关卡地图拆分+收拢 | level_map_screen | S13 键消失(6 键清:函数级 5+类变量≤15);S16/S17 ② 冻结成员断言零变化;level_map_info_fog_test(V1/V2 继承);level_map golden 0.00% | 静态+单元+golden | open_choices 真实入口(测试白盒夹具) | 读数型 |
|
||||
| wr3 u3 棋盘格单元拆分+收拢+board_view 随动 | board_cell_unit(+随动 board_view 写入行约 40 行) | S13 键消失(4 键清:函数级 3+类变量);S17 ③ 探针直读 4 成员断言零变化;board_view 改址行 grep 对账;迁移型断言(回退随动 hunk→写入行断红);棋盘三图 golden 0.00%(甲组) | 静态+探针+golden | board_shot_probe 真实抓帧+ui_input/player_copy 直读面 | 读数型+迁移型 |
|
||||
| wr4 u4 站桩拆分+收拢 | standee_body | S13 键消失(4 键清);S17 ④ 外部直访 4 成员断言零变化(box/font/slot_row/has_world_hp_bar);fx_probe+standee_fx_sweep_test;theme 源锚四句 | 静态+单元+探针 | fx_probe 直构真链 | 读数型+锚句 grep |
|
||||
| wr5 u5 信息面板拆分 | hero_info_panel_view | S13 读数(4 键清);player_copy_sweep_test;ui_probe info_panel 直引面 | 静态+单元+探针 | 直构+探针真链 | 读数型 |
|
||||
| wr6 u6 战末覆盖层+open_victory 收拢+类变量收拢 | battle_end_overlay(+随动 5 消费点) | S13 键消失(4 键清:函数级 3+类变量);S17 ⑤ 四句柄断言零变化;迁移型断言(回退→五消费点断红);丙组对拍 0.00%;t17_defer/ui_struct/ui_probe _end_overlay 面绿 | 静态+探针+golden | ui_struct_probe open_victory 真链 | 迁移型 |
|
||||
| wr7 u7 调试浮窗拆分+收拢 | debug_overlay | S13 键消失(3 键清:函数级 2+类变量);S17 ⑥ 三成员断言零变化(seed_edit/_sim_btn/_dbg_btn);ui_tune_probe 全段(公开面+零动效源码契约);system_test 调试段;theme V4/debug 源锚 | 静态+探针+系统 | ui_tune_probe 真实驱动 | 读数型+契约 grep |
|
||||
| wr8 u8 装配器拆分 | ui_assembler | S13 读数(3 键清);theme V4/退役判据段;ui_probe 启动态 | 静态+单元+探针 | shot_probe 启动态真链 | 读数型 |
|
||||
| wr9 u9 战斗舞台拆分 | battle_stage_view | S13 读数(3 键清);ui_probe stage 直引面;乙组 battle 帧对拍 | 静态+探针+golden | 探针真链 | 读数型 |
|
||||
| wr10 u10 三选一覆盖层拆分 | curio_pick_overlay | S13 读数(2 键清);reward_overlay_test;丙组对拍 0.00%;ui_struct/ui_click curio 段 | 静态+单元+探针+golden | 直构+探针真链 | 读数型 |
|
||||
| wr11 u11 设置覆盖层拆分 | settings_overlay | S13 读数(2 键清);乙组 settings 帧对拍;ui_click 设置段+theme V4 | 静态+探针+golden | 探针真链 | 读数型 |
|
||||
| wr12 u12 结算日志拆分 | battle_log_view | S13 读数(4 键清);theme_projection :386 直构断言+player_copy :100 | 静态+单元 | 直构真链 | 读数型 |
|
||||
| wr13 u13 三选一交互件引用束注入 | curio_interact_controller(+main_ui_build:132 构造行随 u20 束形态) | S13 键消失(类变量 3/15);迁移型断言(回退→ctx 束读点断红);S17 ⑦ 探针方法面零变化;ui_click/ui_struct 三选一真链段 | 静态+探针 | 装配真实构造链+探针真链 | 迁移型 |
|
||||
| wr14 u14 AP 条拆分 | ap_bar_view | S13 读数(1 键清);S7 源锚逐字;ui_probe/ui_click ap_bar 直引面 | 静态+探针 | 探针真链 | 读数型+锚句 grep |
|
||||
| wr15 u15 棋盘区容器拆分 | board_zone_view | S13 读数(1 键清);board_zone 直引面(status_badge/legend_toggled/toast) | 静态+探针 | 探针真链 | 读数型 |
|
||||
| wr16 u16 棋盘动效循环提函数 | board_fx_view | S13 读数(1 键清);fx_probe 逻辑层+棋盘三图 golden(fx 不入静止帧对拍) | 静态+探针+golden | fx_probe 真链 | 读数型 |
|
||||
| wr17 u17 图例循环提函数 | legend_overlay | S13 读数(1 键清);player_copy_sweep 直构+ui_struct legend 段;丙组对拍 | 静态+单元+探针+golden | 直构+探针真链 | 读数型 |
|
||||
| wr18 u18 ui_kit 公开面收敛 | ui_kit(+随动 6 文件:theme/shop_overlay/node_overlay/status_panel/confirm_dialog/settlement_review_overlay) | S13 读数(5 键清);迁移型断言(回退→随动消费点断红);theme V1–V3/T5②+ui_contrast 扫描;menu_boot/camp/battle 帧对拍 | 静态+单元+探针+golden | theme 直构真链+探针 | 迁移型 |
|
||||
| wr19 u19 HUD 投影参数收拢 | hud_presenter(+main:810/tune_sim:67) | S13 读数(3 键清);迁移型断言;hud_presenter_test+battle golden 帧 | 静态+单元+golden | 真实 refresh 调用链 | 迁移型 |
|
||||
| wr20 u20 三选一流上下文收束 | curio_flow_context(+main_ui_build:132) | S13 读数(2 键清);迁移型断言;ui_click 三选一段 | 静态+探针 | 装配真实构造链 | 迁移型 |
|
||||
| wr21 u21 营地流上下文收束 | camp_flow_context(+main_ui_build:152/camp_shop_presenter) | S13 读数(1 键清);迁移型断言;ui_click 营地段 | 静态+探针 | 装配真实构造链 | 迁移型 |
|
||||
| wr22 u22 叙述件拆分 | battle_narrator | S13 读数(1 键清);battle_narrator_test 零改动全绿 | 静态+单元 | 直构真链 | 读数型 |
|
||||
| wr23 u23 批量模拟控制器+测量面定案 | tune_sim_controller | S13 读数(print+局部两键清;await 豁免在册);print grep 零命中;**await 豁免申报行**(非行为改动+依据指针 v1.19 :311);ui_tune_probe 批量模拟段(进度/报告语义零变化) | 静态+探针 | ui_tune_probe 真实驱动 | 读数型+print grep |
|
||||
| wr24 u24 试玩日志器 print 删除 | playtest_logger | S13 读数(1 键清);print grep 零命中;sim 四驱动件直构回归+诊断转储 toast 链 | 静态+集成 | main_debug_flow 转储真链 | grep 型 |
|
||||
| wr25 u25 组合根豁免申报 | main.gd(零改动) | **豁免申报行**(非行为改动+依据指针 v1.19 :183);git diff main.gd 为空(面冻结实证);S10 46 名直引面断言零变化;12 探针+system_test 全绿 | 静态+探针+系统 | 探针 main.X 真链 | 零改动实证(diff 空)+申报件核 |
|
||||
| wr26 产出物 | T5 三份(含豁免两键申报行) | 件核(wr26) | — | — | 缺项红 |
|
||||
|
||||
### 8.2 测试方式两分法与目检登记
|
||||
|
||||
本批零行为改动=无调试接口验证项;能力面(debug_overlay/批量模拟)经 ui_tune_probe 真链回归即闭环。用户目检项(登记不阻塞,入实现报告实机目检总清单):乙组三屏(camp/settings/battle)开合观感、丙组四态(战末/三选一/图例/调试浮窗)开合观感、营地三柜台与锻造工坊交互回归——全部为「与改前一致」判读。
|
||||
|
||||
### 8.3 独立验收审计
|
||||
|
||||
入口=未参与实现的会话或子代理;报告落 `reports/iter<N>-验收审计-<日期>.md`;抽查重点=①T0 时点铁序(锚面采集先于码改——git 提交序核)②golden 对拍读数复现(抽 3 锚直跑)③S13 读数对拍表逐键复核+基线文件 git diff 零变化+**71=69 清+2 豁免账目复核(豁免两键依据指针 v1.19 段名在册)**④源码锚字面量契约抽检(S2/S6/S7/S9)⑤撤销证明抽两条复现⑥探针直引 46 名+S17 冻结成员零迁移抽检⑦**board_view 随动改址抽 5 行复核(等价机械形、零语义漂移)**⑧main.gd git diff 为空+await 行零触碰复核⑨拆分边界抽检(契约 9:各状态件/私有函数族职责语句逐件在案、u1 子域分组核对,跨子域混装或凑计数袋即红)。未过不得合并。
|
||||
|
||||
### 8.4 S13 账目(71 键=69 清+2 豁免,v1.1 全清口径)
|
||||
|
||||
**清偿 69 键(键消失)**:u1×10/u2×6/u3×4/u4×4/u5×4/u6×4/u7×3/u8×3/u9×3/u10×2/u11×2/u12×4/u13×1/u14×1/u15×1/u16×1/u17×1/u18×5/u19×3/u20×2/u21×1/u22×1/u23×2(print+run 局部)/u24×1。(69=10+6+4+4+4+4+3+3+3+2+2+4+1+1+1+1+1+5+3+2+1+1+2+1,逐项与 §1 改动单元清单一一对应。)
|
||||
|
||||
**豁免 2 键(键留基线内绿、永久在册、禁再恶化——非残留,架构契约豁免)**:main 类变量 49/15(v1.19 :183——组合根类变量面=探针契约面,禁收拢禁改写)+tune_sim_controller 循环内 await :65(v1.19 :311——测速循环 wall-clock 步进承载语义,禁重构)。两键各落实现报告申报行(wr23/wr25)。
|
||||
|
||||
回归措辞:里程碑步(T 卡段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。
|
||||
|
||||
## 9. 异常分级
|
||||
|
||||
- **L1(自救)**:行号漂移(T0 复核自吸收);私有函数命名、inner class 状态件命名与注释措辞;对拍帧采集的等价实现形态(探针帧直拷 vs 临时脚本)。
|
||||
- **L2(记录继续)**:乙组 battle 帧跨跑次非 0.00% 降级丙组(判定记录写明);消费面随动改址的单行等价写法(含 board_view 写入行 `u.st.X =` 等价形);读数改善幅度与预估偏差(非清键义务单元);u4 fx 出口计数随迁后 fx_probe() 返回键序变化(键名零变化前提下)。
|
||||
- **L3(停机呈报)**:任何 golden 对拍差异非零(契约 1);探针直引面/源码锚契约与拆分或收拢互斥(契约 2——S17 冻结成员被误迁状态件即属此);board_view 改址遇非机械点(写入行与读取交织/条件内联——契约 7);main 句柄面出现任何改动企图、测速循环重构企图(契约 3/8);机检键与契约互斥(契约 4);拆分或收拢产生基线外新违规且不可在阈值内消化(契约 4);发现收编清单外同病根新键(禁扩面——呈报由用户裁);**逐文件实查发现触碰 owner 契约/GDD 陈述**(D5——停笔呈报,禁内联求裁);豁免注记(v1.19 两段)缺位或段名漂移(T0 核对不通过);拆分边界无职责语句可陈述/状态件跨子域混装/凑计数袋(契约 9——停卡呈报走豁免/还债通道)。
|
||||
|
||||
## 10. 代拍板白名单(超清单必呈报)
|
||||
|
||||
1. 各宿主内私有函数命名、分组与注释随迁措辞(语义不变前提下)。
|
||||
2. 各收拢件 inner class 状态件命名(`_XxxState` 形)与件内成员命名(随宿主原成员名迁入)。
|
||||
3. 乙组基线帧文件命名(随 golden/README 现行命名规则)与丙组临时采集脚本的实现形态。
|
||||
4. wr 断言挂点与读数表格式。
|
||||
5. 提交切分与 worktree 分支命名。
|
||||
6. u23/u25 豁免申报行的行文措辞(键值/依据指针/禁再恶化三要素在案前提下)。
|
||||
|
||||
## 11. 待裁点
|
||||
|
||||
**零待裁点(2026-10-27 用户裁决记录:print 删除;await 按 v1.19 测量面豁免)**。
|
||||
|
||||
(原 W1 测量面卫生键处置已按裁决落死——print×3 删除〔信息已由 toast/JSONL 承载,见 S14/D6〕、循环内 await 按 v1.19「测试与质量域·S13 测量面豁免登记」段豁免〔键永久基线内、禁重构测速循环〕;main 类变量按 v1.19「三屏壳与组合根句柄面」节豁免登记。三项处置全部进 §1 单元清单与 §8.1 对照表,无需实现段再裁。)
|
||||
|
||||
## 12. 自审六查与复核记录
|
||||
|
||||
**自审六查(2026-10-27 写卡会话)**:①规格覆盖——u1–u25→wr1–wr25 逐条对上、T0–T5 各卡可指认、恶化债/锚面/裁点各有落点;②步骤扫描——每步一动作一可核查结果,接口块给签名不给实现体,无「TBD/酌情」行(T0 乙组降级分支为带判据的条件路径非酌情);③类型一致性——接口块签名与 §3 实查、wr 行、T3/T4 取用关系逐字一致(refresh ctx 五键=main:810 现八参尾五;stats 六键=tune_sim:67 现十参中六;S17 冻结成员清单与 §1 收拢列逐件对上);④审查焦点——呈现零变化(三组锚)与探针直引面(S1–S17)为最可能坑点,已逐文件挂 wr 行与契约 2;行为改动覆盖:本批零行为改动,print 删除(stdout 文本——wr23/24 以 grep 与 ui_tune 真链承载);⑤篇幅比例——零实现体抄写,接口块全为签名与键清单;⑥落位预检——零新增文件原则下四件新增面(私有函数族/inner class 状态件/golden 基线/PANEL_DEFAULT 哨兵)各有不能复用理由与唯一落点,与结构图对上。
|
||||
|
||||
**grilling 自检一轮(2026-10-27,写卡会话内对抗复核)折入记录**:①收敛算术复核——ui_kit 26−2−4=20 成立(modal_shell 哨兵收拢不增方法;拆分方案会 21 超阈,已弃);②open_victory 三参消费点缺省兼容免改址(fx_probe/standee_fx_sweep/curio_interact)——S13 改为「传参者 5 处随动」;③level_map 恶化债归绿判据写死 ≤21(gdstyle 判红线=登记值 21,「回到登记值以下」歧义消除);④撤装置教训回扣——u2 换层装饰域归并禁计数迎合(契约 7 显式禁转发/别名,_cand_ids/_hover_id/_content_size/_drawn_disp 四探针直引成员排除出归并候选);⑤撤销证明两型分层(读数型/迁移型)补强——纯拆分文件回退后现役套件仍绿,读数对拍表是唯一断言载体,已在对照表末列写死;⑥补 S16(level_map 探针冻结成员清单)与 §8.4 残留键账目——完成定义第 1 条账目闭合;⑦**load_font 私有化撤换(实查翻案)**——初稿拟私有化 load_font,逐消费方复核发现其直引含两处渲染闸探针(board_shot_probe:49/type_glow_shot_probe:71)+ui_font_asset_test:15,私有化须动渲染闸探针;换选 switch_toggle(消费方 settings_overlay:76/:91 全在本卡触面、零探针测试面),收敛算术不变、随动面缩 3 行且零探针触碰——S8/接口块/T3/wr18/结构图五处随改;⑧W1 案① tune_sim print 处置收紧为「删除」并禁改 set_sim_report 文本(并入报告文本属文案变化,违契约 1 文案逐字不变);⑨乙组基线帧命名改挂代拍板白名单(初稿行内命名自造,禁行句式剔除)。
|
||||
|
||||
**v1.1 修订自审六查(2026-10-27 裁决折入会话)**:①裁决覆盖——四条款逐条落位:全清口径→§1 目标/§8.4 账目(69=62+7 类变量键,逐件累加核过);print 删除→u23/u24 改法列+T4+wr23/wr24;main/await 豁免→D4/D6+契约 3/8+u23/u25 任务改写+wr23/wr25 申报行;大户收拢→u1/u2/u3/u4/u6/u7/u13 改法列+接口块状态件形态+T1/T2/T4 任务行;②步骤扫描——收拢任务每件带「冻结成员保持+迁件清单+可核查结果(键消失+冻结面断言零变化+对拍 0.00%)」三段,无酌情行;u3 随动带 T0 行级清单前置;③类型一致性——S17 冻结清单与 §1 收拢列、契约 2、wr 行三处逐名一致(camp 5/level_map 6/board_cell 4/standee 4/battle_end 4/debug 3/curio_interact 0);u13 改址键名与 u20 接口块束键逐字同源;④审查焦点——冻结面补全是本轮最大坑点:原卡 S3/S5 漏记直读成员(camp _balance_label、battle_end _btn/_gp_name/_gp_row/_gp_val、debug _sim_btn/_dbg_btn、standee has_world_hp_bar),若按原清单收拢即探针断红——v1.1 已补全 S17 并挂契约 2;board_view 禁触冲突为第二坑点(board_cell 30/31 成员被其直写),按裁决全清口径的唯一路径落机械随动+错波扩展+L3 兜底(§0/§5/契约 7/§9 四处闭环);⑤篇幅比例——收拢清单以成员名列举进 §1/S17,零实现体;⑥落位预检——inner class 状态件六件各填「为什么不能复用」(各视图绘制态彼此独立无共用结构;与 flow context 束异质),零新文件保持。
|
||||
|
||||
**v1.1 grilling 自检一轮(同会话对抗复核)折入记录**:①**board_cell_unit 被动壳定性(实查翻案)**——31 成员逐名核外部直访:30 个被 board_view 直写 47 行+探针直读 4 个皆在写入集内,纯内部仅 _glow_layer;按「句柄成员不收」判据本无收拢面,但裁决全清口径下唯一路径=写入行随动改址(约 40 行机械形)——落 u3+§0 禁触条目收窄(board_view 结构拆件仍禁、错波集扩五文件)+契约 7 非机械点停呈+§8.3 抽 5 行复核;②**探针直读成员非全部冻结(出口判据补强)**——fx 出口三计数(_death_shards/_hit_sparks/_flash_count 经 fx_probe() 方法)与 _run_data/_run_labels(经 run_data_probe()/update_run_data() 方法)不被字段直访,判可收拢、方法体读点随迁——判据句(字段直访冻结/方法出口可收)写进接口块状态件形态注记;③**curio_interact 冗余面发现(实查翻案)**——16 个注入成员=_init(ctx) 逐成员抄写件(:32-48 实读),与 ctx 完全同源;u20 三束后直接持 ctx=3 成员,比原「域归并改善非清零」方案更彻底且零新概念(构造注入先例形态),S12/u13/wr13 三处随改,装配行零随动;④**u25 死成员清点任务随豁免取消**——豁免语义=类变量面冻结(契约 3),清点删除动机(键清偿)消失;wr25 改零改动实证(git diff 空)+申报行,避免豁免与清点并存的面语义打架;⑤**69 清账目复核**——v1.0 清偿 62 键构成重算(u23×2=print+run 局部,await 另计残留)+七件类变量键(u1/u2/u3/u4/u6/u7/u13 各+1)=69,与豁免 2 键合计 71 对平;u13 原在清偿列 0 键(改善非清零),v1.1 转 +1——清单逐项累加在 §8.4 留痕;⑥**估时逐件落账**——上调 ≈1.3d 拆到八笔(u1/u2/u4 各 0.15+u3 0.25+u6/u7 各 0.12+u13 0.2+print/申报 0.1),防整段模糊上调;T0 冻结面复核扩容(S17 七件+board_view 47 行清单)计 +0.05d;⑦**契约 6 与裁决两形态冲突收口**——「独立小状态类」需新 .gd 文件违 D1,inner class 相容——卡内定死 inner class 单形态(裁决给的是形态自由、契约 6 是硬红线,取交集);⑧**冻结成员补全反推(原卡 S 清单缺陷)**——S3 原记 camp 四成员漏 _balance_label(ui_probe:36 直读 .text),若按原清单收拢即探针断红;S5 原为方法面汇总未展开 battle_end 四句柄直读(_btn 5 处/_gp_val 3 处);debug _sim_btn/_dbg_btn(ui_tune:132+standee_fx_sweep_test:119/121)、standee has_world_hp_bar(ui_probe:141)、level_map abandon_btn/status_badge(ui_click 直引)同为实查新增——八处全部补进 S3/S5/S6/S16/S17,冻结面口径由「探针公开方法面」扩为「字段直访全集」。
|
||||
|
||||
## 13. 禁为机检文本保留无效成员(重构类必填条款)
|
||||
|
||||
禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名/转发属性;本批收敛(拆分+收拢)不得以「探针便利」「基线计数」为由保留任何清单外死成员或新增同种装置;u1–u7/u13 收拢与 u2 归并、u25 申报的每一笔处置必须以 S17 实查冻结面或真实零消费为凭据(对账表在案);禁以转发属性形态「保住」被收拢成员的外部写法(字段直访契约面一律随动改址或冻结保持,二选一,无第三态);机检键与本卡契约互斥时实现段一律停卡呈报,不得自造第三条路(code-conventions §1.1 同款)。
|
||||
@@ -1,229 +0,0 @@
|
||||
# 需求卡片:战斗一屏样张批(2026-10-28)
|
||||
|
||||
> **来源**:待办清单条目「战斗一屏样张 P0 未开工」(设计面=美术轨;状态=美术设计已闭合+待写卡)
|
||||
> **唯一事实源**:`design/art/art-bible.md` **v3.22** + `design/art/art-prompts.md` §5「资产出图工单(四组九件)」
|
||||
> **规则指针**:`AGENTS.md` 硬性红线(含 2026-10-28 新立的「禁变异类测试与撤销类取证」验证口径)/`design/engineering/process-conventions.md` §1–§3/`code-conventions.md`/`test-conventions.md` §8/`doc-conventions.md` §12
|
||||
> **旧卡说明**:`reports/需求卡片-战斗一屏样张批-2026-10-16.md`(v1.4)于 2026-10-17 被裁定不满足开发条件、终止开工,属非有效卡,本卡不继承其任何裁决;其考证过的代码现状与断言设计可作参考。
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**做什么**:把已经定稿的战斗一屏美术规格,变成一张可判定的样张和一批可运行的实装。
|
||||
|
||||
1. 用 PIL 代码绘制产出**战斗一屏样张**(1280×800 基座 + 1920×1080 全局等比 1.35× 两版),内容覆盖 `art-bible` §1.4 整屏内容清单与战斗表现内容清单。
|
||||
2. 把 §1.4 整屏四项闸与战斗表现五项标准,写成**可在样张脚本内执行的机检断言**。
|
||||
3. 把五项设计定值**落进实装代码**(血条换色、名字行垫素底、顺位徽标提档、护甲图标换件、站桩文字不压地台)。
|
||||
4. 程序化产出两件素材并入包(地台件、护甲图标三枚)。
|
||||
|
||||
**完成定义(全部满足才算完)**:
|
||||
|
||||
- 样张两版产出,方向稿目检通过(用户判定),目检通过后机检冻结;
|
||||
- 整屏四项断言 + 战斗表现五项断言在样张脚本内全绿;
|
||||
- 五项代码定值落码完成,对应断言在冒烟面内通过;
|
||||
- 地台件与护甲三枚 PNG 入包并被实装引用;
|
||||
- 三份批件写齐(实现报告/代拍板追认单/反哺点清单)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 设计事实源(必填)
|
||||
|
||||
**样张过审 + art-bible 条款版本**:
|
||||
|
||||
| 依据 | 版本/节 | 本卡取用 |
|
||||
|---|---|---|
|
||||
| `design/art/art-bible.md` | **v3.22** | §1.4 整屏样张闸四项;§2 明度三档带与世界底层两子带;§4.1 色板(余量 0,第二道门=不得三通道全 <8);§4.2 血条=危险红 `#A8321F`;§6.1 背景契约与地台独立件;§7.2 文字可读性;§7.4 字号六档与豁免清单;§8.2 尺寸档与甲/乙类缩放;§8.4 方向集 |
|
||||
| `design/art/art-prompts.md` | §5 资产出图工单(四组九件) | 本卡素材需求的直接来源:工单七字段(路径命名/尺寸档/色板约束/明度归属/程序化与否/验收判据/出图要点) |
|
||||
| `design/gdd/ux/battle.md` | 现行 | **屏级分区布局与格边长公式的唯一裁决源**——本卡涉及分区尺寸只指路,不复述数值 |
|
||||
|
||||
**已定死、本卡不再讨论的定值**:站桩素底=深档 `#282220`;五处换色合并(铲刃→`#C4C4C4`、提灯→`#B07A14`、食人魔皮→`#B8A582`、石君王灰皮→`#786E62`、轻甲木色→`#CDB88C`);新增两枚(`#868C9A` 重甲冷灰、`#A79CB8` 卓尔浅紫灰皮);48 色余量已归零;渲染手段=PIL 代码绘制;素材输入级别=丙(样张即设计目标图)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 现状事实(代码级实查,每条带 file:line)
|
||||
|
||||
1. **样张脚本现役**:`tools/render_sample_sheet_v3.py`(1174 行)已有断言框架——`CHECKS` 列表定义于 `:113`,断言登记于 `:117`,全绿判定于 `:1033`,报告输出于 `:1164`。另存 `tools/render_sample_sheet.py`(1009 行)为旧版。本批在 v3 脚本内扩展。
|
||||
2. **血条填充是裸字面量**:`game/presentation/views/standee_body.gd:444` 画填充用 `Color(0.41, 0.61, 0.91)`,即 `#689CE8`(蓝族,v3.22 §4.2 已登记为违例退役值),**未经 UiKit 常量**。
|
||||
3. **血条条底同为裸字面量**:`standee_body.gd:441` 用 `Color(0.10, 0.10, 0.11)`(引擎默认主题深底近似)。
|
||||
4. **素底牌已在役**:`game/presentation/views/ui_kit.gd:193` `HP_BAR_BACK := Color8(40, 34, 32)`(即 `#282220`),血数垫牌绘制于 `standee_body.gd:451`。**深档素底色无需新增,直接复用本常量。**
|
||||
5. **顺位徽标违规**:`standee_body.gd:437-438` 用裸值 `13` 绘制①②③(`UiKit.GOLD_BRIGHT`),既不在 §7.4 ①条带内读数在册面、也不在②装饰 caption 在册面,属「清单外 11–13px 文字」,v3.22 已裁定提档 `FS_HINT` 14。
|
||||
6. **护甲图标是字形占位**:`standee_body.gd:8-10` `const ARMOR_ICONS := {"light": "◇", "ward": "◆", "heavy": "▣"}`;绘制于 `:485` 与 `:496`(`:496` 用 `12` 绘制护甲字形,与名字同排)。
|
||||
7. **名字行与地台重叠(实装债)**:名字行基线 `standee_body.gd:495` = `Vector2(..., box.y - 1.0 - STANDEE_FOOT_MARGIN)`,而 `STANDEE_FOOT_MARGIN := 12.0` 定义于 `:13` → **基线 y = box.y - 13**。地台矩形 `standee_body.gd:405` 返回 `Rect2(18.0, box.y - 18.0, box.x - 36.0, 12.0)`,纵向覆盖 **box.y-18 .. box.y-6**。名字行基线落在地台带内,**重叠确认**(非传闻)。
|
||||
8. **B 区高度文码不符**:`game/presentation/views/battle_stage_view.gd:28` `custom_minimum_size = Vector2(0, 252)`(代码 252),而 `art-bible` §8.2 站桩立绘排版方案二①定 B 区高 **270**。二者差 18px。
|
||||
9. **血数 11px 属豁免**:`standee_body.gd:453-454` 以 `11` 绘制血数并垫 `HP_BAR_BACK` 牌,合 §7.4 豁免①(14.3:1),**不在本批改动范围**。
|
||||
10. **素材在盘但不入 git、且是旧档**:立绘与瓦片位于主检出 `game/assets/art/`(`character/` 26 件含八敌与主角 `character_hero_idle`/`attack`/`hit`/`portrait`;`board/` 瓦片),**整个 `game/assets/art/` 不入 git**(`git ls-files game/assets/art` 计数 0),fresh worktree 内缺位。取用靠 `tools/render_sample_sheet_v3.py:50-56` 的 `asset_root()` 两级回退(worktree → 主检出),脚本可直接取到,**样张可画**。
|
||||
11. **立绘为旧档占位、且未接线进实装**:`character_hero_idle.png` 仅 1220 字节(2026-09-25),属旧档占位,非精细手绘终稿(重产工单在 `art-prompts` §5.4,属后续素材批);同时 `standee_body.gd:20-21` 立绘挂点为 `null`、`set_portrait_texture`(`:208`)未被调用,实装站桩仍是**字形回退**态。本批不修接线。
|
||||
|
||||
---
|
||||
|
||||
## 4. 设计契约(违反=返工红线)
|
||||
|
||||
**(1)🔴 实现批禁写 `design/` 与根规则文件**:本批唯一可写目录=`reports/`;`art-bible`、`art-prompts`、`battle.md` 等一律只读。所有「文档该改什么」进反哺点清单,由用户裁决后归文档批落文。
|
||||
|
||||
**(2)🔴 样张必过 §1.4 整屏四项闸**:文字对比 ≥4.5:1/明度三档带成立(含世界底层两子带)/首焦唯一/文字不压纹理底。
|
||||
|
||||
**(3)🔴 方向稿目检先行**:目检通过后才做机检冻结;机检过了但气质被否决的,以目检为准返工。
|
||||
|
||||
**(4)🔴 禁删断言、禁放宽阈值换绿**:断言红就修实现,不动判据。
|
||||
|
||||
**(5)🔴 禁变异类测试与撤销类取证**(2026-10-28 用户裁,前口径已废):不许写「注入缺陷看断言是否变红」的变异验证,不许写「撤销改动看断言是否变红」的撤销证明。证明方式=每个需求点与每个行为改动都要有**从真实入口进入的验收断言**,可 grep 定位、**在当轮真实跑批中执行并通过**,判据绑被测改动特有的可观测提交面。证明做不出来=**停卡呈报**。
|
||||
|
||||
**(6)🔴 数值单一事实源**:色值、字号一律收 `UiKit` 常量,禁在视图里写裸 `Color(...)` 与裸字号字面量(本批正是要清掉 `:441`、`:444`、`:437`、`:496` 这四处)。
|
||||
|
||||
**(7)🔴 48 色余量已为 0**:本批**不新增任何色值**,只使用 v3.22 在册色;需要色值处一律引 `UiKit` 现有常量。
|
||||
|
||||
**(8)🔴 RNG 单点**:禁 `randomize()`/自建 `RandomNumberGenerator`;样张脚本的确定性散布沿用现役写法(`standee_body.gd:275, 302`)。
|
||||
|
||||
**(9)🔴 Core 层零 UI 依赖**:本批只动呈现层与工具脚本,core 侧零触碰,完整战斗仍须可 `--headless --script` 跑通。
|
||||
|
||||
**(10)🔴 样张判定对象不含立绘精细度**:样张以现有旧档立绘出方向稿(见第 3 节第 10、11 条),判定对象=布局分区、明度三档带、文字对比、首焦唯一、构图关系;**立绘自身的清晰度与精细度不作本批判定对象**,也不得据本批样张给立绘下结论。立绘重产(`art-prompts` §5.4)落位并完成站桩接线后,须**重出样张复验**——本条进反哺点清单。
|
||||
|
||||
---
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
### 5.1 做
|
||||
|
||||
1. PIL 画一屏样张两版(1280×800 基座;1920×1080=全局等比 1.35× + 左右黑边),内容按 §1.4 整屏内容清单 + 战斗表现内容清单(含类型微光呈现组、图类型色板变体组至少两套、三组关键帧条、主角与敌方描边同屏对照)。
|
||||
2. 整屏四项 + 战斗表现五项的机检断言进 `tools/render_sample_sheet_v3.py` 的 `CHECKS`。
|
||||
3. 五项代码定值落码 + 断言:血条换 `#A8321F`(清 `#689CE8`)、站桩名字行垫 `HP_BAR_BACK` 素底且不压地台、顺位徽标提档 `FS_HINT`、护甲图标由字形换三枚 24×24 PNG、地台件独立引用。
|
||||
4. 两件素材程序化产出并入包:地台件 `scene_stage_plaza.png`(源 48×12 九宫格)、护甲图标三枚 `ui_armor_light/ward/heavy.png`(源 24×24)。
|
||||
5. 三份批件:实现报告/代拍板追认单/反哺点清单。
|
||||
6. **改前/改后并排对拍图**:改动前先用同一脚本、同一参数存一版**基线样张**,改动后与基线并排成图,作为用户目检的对照材料。基线留存是真实前后对照,不是人为制造红灯,不违反「禁变异类测试与撤销类取证」红线——红线禁的是「故意改坏看断言是否变红」,本项是「改好之后与原样并排」。
|
||||
|
||||
### 5.2 不做(含去向)
|
||||
|
||||
| 不做的项 | 去向 |
|
||||
|---|---|
|
||||
| B 区舞台背景插画 `scene_stage_bg.png` 正式出图 | 样张内按远景/中景两带用既有色值程序化铺出**设计目标态**;正式出图工单仍在 `art-prompts` §5.1,由后续素材批执行 → 进反哺点清单 |
|
||||
| 主角与三 Boss 立绘重产 | `art-prompts` §5.4 工单仍在,由后续素材批执行 → 进反哺点清单 |
|
||||
| 三关色板终值 | 待「三关色相 × 五组微光互辨抽测」条目(待办清单已登记,状态=待美术设计) |
|
||||
| 营地场景图 | 独立条目,与本批无关 |
|
||||
| B 区高度 252→270 的实装对齐 | 本批**只登记不修**:样张按代码现状 252 出(样张须反映实机)→ 进反哺点清单 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 关联文档同步面(必填)
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| `design/art/art-bible.md`(v3.22) | §1.4 整屏四闸的**通过事实**与抽样读数;§4.1 站桩素底深档 `#282220` 的实装落地;§6.1/§7.2 站桩文字位机检断言 | 进 `reports/iter<N>-反哺点-<日期>.md`,由用户裁决后归文档批落文 |
|
||||
| `design/art/art-prompts.md` §5 | 组二地台件、组三护甲三枚已「程序化产出即终稿」;组一背景、组四立绘仍待出图 | 同上 |
|
||||
| `design/gdd/ux/battle.md` | B 区高度:文 270 vs 代码 252 的 18px 差异 | 同上 |
|
||||
| `design/gdd/systems/战斗循环/战斗表现.md` | 「一屏样张的验收标准」五项过闸结果 | 同上 |
|
||||
| `design/engineering/test-conventions.md` | §8.4 撤销证明条文与 2026-10-28 新验证口径相冲突(旧口径已废) | 同上 |
|
||||
| `AGENTS.md` | 「验收闭合」红线句仍保留「撤销该改动能让对应断言变红」旧措辞,与新口径冲突 | 同上 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 任务卡 T0..Tn
|
||||
|
||||
### 7.0 文件结构图
|
||||
|
||||
| 文件 | 职责 | 复用/新增 | 改动性质 | 验证闸行号 |
|
||||
|---|---|---|---|---|
|
||||
| `tools/render_sample_sheet_v3.py` | 样张绘制与机检断言宿主 | 复用既有(扩展出口与 `CHECKS`) | 行为改动 | V1–V9 |
|
||||
| `game/presentation/views/standee_body.gd` | 站桩绘制:血条、素底、徽标、护甲、地台引用 | 复用既有(就地改) | 行为改动 | V5–V8 |
|
||||
| `game/presentation/views/ui_kit.gd` | 色值与字号常量单点 | 复用既有(`HP_BAR_BACK`、`FS_HINT` 已在) | 非行为改动(如需补常量则标行为) | V5、V7 |
|
||||
| `game/assets/art/scene/scene_stage_plaza.png` | 地台九宫格件 | 新增(程序化产出) | 非行为改动(新增素材) | V9 |
|
||||
| `game/assets/ui/icons/ui_armor_{light,ward,heavy}.png` | 护甲三档图标 | 新增(程序化产出) | 行为改动(替换字形占位) | V8 |
|
||||
| `game/tests/` 冒烟面 | 五项定值的验收断言落点 | 复用既有冒烟段 | 行为改动(新增断言) | V5–V8 |
|
||||
| `reports/` 三份批件 | 实现报告/代拍板追认单/反哺点清单 | 新增 | 非行为改动 | — |
|
||||
|
||||
### 7.1 卡片与估时
|
||||
|
||||
| 卡 | 内容 | 估时(工作日) |
|
||||
|---|---|---|
|
||||
| T0 | 开工准备:worktree、`.godot` 与字体 `.import` 边车拷贝、确认 v3 脚本可跑 | 0.25 |
|
||||
| T1 | 样张底板:两版画布、B/C/D 分区(数值按 `battle.md` 指路,B 区按代码 252)、格边长 | 0.5 |
|
||||
| T2 | 内容清单铺画:类型微光组、色板变体组、关键帧条、描边同屏对照 | 1.5 |
|
||||
| T3 | 整屏四项断言进 `CHECKS` | 1.0 |
|
||||
| T4 | 战斗表现五项断言进 `CHECKS` | 1.0 |
|
||||
| T5 | 血条填充换 `#A8321F`(经 `UiKit` 常量)、条底收常量 | 0.25 |
|
||||
| T6 | 站桩名字行垫 `HP_BAR_BACK` 素底,且文字位不压地台(消 5px 重叠) | 0.5 |
|
||||
| T7 | 顺位徽标提档 `UiKit.FS_HINT` | 0.25 |
|
||||
| T8 | 护甲图标由字形换三枚 24×24 PNG | 0.5 |
|
||||
| T9 | 地台件与护甲三枚程序化产出并入包 | 0.5 |
|
||||
| T10 | 产出物落位卡:三份批件写齐 + 改前/改后并排对拍图产出 | 0.25 |
|
||||
| | **合计** | **≈6.5(区间 5.5–7.5)** |
|
||||
|
||||
**卡间接口**:
|
||||
|
||||
- T1 **产出**:`draw_base(canvas_w, canvas_h, b_h) -> Image`(B 区高由参数传入,T2/T3 依赖)
|
||||
- T3/T4 **取用**:T1 的 `Image` 与分区矩形;**产出**:`CHECKS` 内断言条目(供 T10 汇总)
|
||||
- T5–T8 **取用**:`UiKit.HP_BAR_BACK`、`UiKit.FS_HINT`、`UiKit` 新增血条填充常量(由 T5 定义,T6 复用)
|
||||
- T9 **取用**:T8 定义的护甲三档键 `{"light","ward","heavy"}`
|
||||
|
||||
**步骤要求**:一步=一个动作 + 一个可核查结果,`- [ ]` 记步。实装步骤给确切签名与 file:line,**实现体不写**。
|
||||
|
||||
---
|
||||
|
||||
## 8. 验证闸(改动—验收对照表)
|
||||
|
||||
| # | 需求点 | 改动(文件:行 / 行为) | 验收测试(名称 + 落点) | 层级 | 真实入口 | 判据绑定面 | 证明方式 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V1 | 样张两版产出 | `tools/render_sample_sheet_v3.py` 新增两版出口 | `sample_sheet_two_editions` 落冒烟面 | 探针 | `python tools/render_sample_sheet_v3.py` 真实跑批 | 两版位图文件尺寸(1280×800 / 1920×1080) | 产物两版尺寸分别为 1280×800 与 1920×1080,跑批通过 |
|
||||
| V2 | 文字对比 ≥4.5:1 | 同上(断言进 `CHECKS`) | `splash_text_contrast` 落 `CHECKS` | 探针 | 样张脚本真实跑批 | 样张位图文字像素区域对比度读数 | 断言在跑批内取绿 |
|
||||
| V3 | 明度三档带成立(含两子带) | 同上 | `splash_luma_three_bands` 落 `CHECKS` | 探针 | 同上 | 样张位图逐区明度带读数(世界底 / 中 / 顶层) | 断言在跑批内取绿 |
|
||||
| V4 | 首焦唯一 | 同上 | `splash_single_focus` 落 `CHECKS` | 探针 | 同上 | 样张位图对比度最高点分布(唯一性) | 断言在跑批内取绿 |
|
||||
| V5 | 血条=危险红 `#A8321F` | `standee_body.gd:444` 填充改引 `UiKit` 常量;`:441` 条底收常量 | `hp_bar_fill_is_danger_red` 落冒烟面 | 单元 | 冒烟套真实跑批 | 血条填充像素采样色值 | 断言在跑批内取绿;全仓 grep 零 `#689CE8` 与零裸 `Color(0.41, 0.61, 0.91)` |
|
||||
| V6 | 站桩名字行垫素底、不压地台 | `standee_body.gd:495-497` 基线改为地台上方 + 垫 `HP_BAR_BACK` | `standee_name_not_on_plinth` 落冒烟面 | 单元 | 冒烟套真实跑批 | 名字行绘制基线 y 与地台顶 y 坐标 | 断言在跑批内取绿(名字行基线 y < 地台顶 y) |
|
||||
| V7 | 顺位徽标提档 14 | `standee_body.gd:437-438` 裸 `13` → `UiKit.FS_HINT` | `order_badge_uses_fs_hint` 落冒烟面 | 单元 | 冒烟套真实跑批 | 顺位徽标字号取值(FontFile 大小) | 断言在跑批内取绿;grep 该处零裸字号 |
|
||||
| V8 | 护甲图标换三枚 PNG | `standee_body.gd:8-10` 常量改路径;`:485`/`:496` 绘制改贴图 | `armor_icon_textures_bound` 落冒烟面 | 单元 | 冒烟套真实跑批 | 三档键 → 对应 PNG 资源引用(ResourceLoader 加载结果) | 断言在跑批内取绿;三档键各绑到对应 PNG |
|
||||
| V9 | 地台件与护甲三枚入包 | 产出入 `game/assets/` 并被实装引用 | `plinth_and_armor_assets_loaded` 落冒烟面 | 接口 | 冒烟套真实跑批 | `game/assets` 下资源文件存在且被实装引用(尺寸 48×12 / 24×24) | 断言在跑批内取绿(资源可加载且尺寸 48×12 / 24×24) |
|
||||
| V10 | 改前/改后对拍图产出 | T1 存基线样张;T10 生成并排图 | `sample_sheet_before_after` 落冒烟面 | 探针 | 样张脚本真实跑批 | 基线版与改后版两张源样张文件 + 并排图输出文件 | 断言在跑批内取绿:基线版与改后版两张源文件均存在、尺寸一致、并排图已生成 |
|
||||
|
||||
- **方向稿目检**(用户判定)在 V1–V4 之前执行,目检通过后才冻结机检。
|
||||
- **独立验收审计**:入口 `reports/iter<N>-验收审计-<日期>.md`,由未参与实现的会话或子代理执行,未过不得合并。
|
||||
- **用户目检项一律「登记不阻塞」**:登记进实现报告即完成卡内义务,不作为合并或下一迭代开工的前置。
|
||||
- 重闸表述:批末按本批改动域选档跑 `tools/run_all_gates.sh`(本批含代码面,走代码域)。
|
||||
|
||||
---
|
||||
|
||||
## 9. 异常分级
|
||||
|
||||
- **L1 自救**:单条断言红且定位明确 → 一次重试修实现,不改动判据。
|
||||
- **L2 记录继续**:同一红灯连续三次 → 记录进实现报告,继续推进其余卡,不停批。
|
||||
- **L3 停机写报告等用户**:触碰第 4 节任何一条 🔴 红线;或样张四闸中任一闸无论如何都过不去(可能意味着规格本身有缺口);或需要新增色值(余量为 0,须呈报作者裁)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 代拍板白名单
|
||||
|
||||
1. 样张脚本内的临时变量命名、辅助函数拆分方式。
|
||||
2. 断言在 `CHECKS` 内的 id 命名与登记顺序。
|
||||
3. 程序化产出素材时的绘制实现细节(颜色取自 v3.22 在册值、不新增色)。
|
||||
4. 两版样张的输出文件名与落盘目录(落 `artwork/` 在途区)。
|
||||
|
||||
超此清单者一律呈报。
|
||||
|
||||
---
|
||||
|
||||
## 11. 待裁点
|
||||
|
||||
**零待裁点,开工门=U0。**
|
||||
|
||||
说明:B 区高度文 270 vs 代码 252 的差异已在第 5.2 节定死处置(本批按代码 252 出样张、只登记不修),不构成待裁点;样张所需色值全部已在 v3.22 在册,本批零新增色,故无额度类分叉。
|
||||
|
||||
---
|
||||
|
||||
## 12. 落位与可复用性预检
|
||||
|
||||
**复用面**:
|
||||
|
||||
- 样张绘制**复用既有** `tools/render_sample_sheet_v3.py`(1174 行,已有画布、分区、`CHECKS` 框架),不新建脚本——新脚本会与既有断言体系并行,形成两套事实源。
|
||||
- 色值与字号**复用既有** `UiKit` 常量(`HP_BAR_BACK`、`FS_HINT`、血条填充新常量同址登记),禁在视图内写裸字面量。
|
||||
- 站桩绘制**就地改** `standee_body.gd`,不新建站桩视图。
|
||||
|
||||
**唯一面**:
|
||||
|
||||
- 血条填充色只落在 `UiKit` 一处常量,`:444` 与 `:441` 两处绘制点均引它,禁各自写字面量。
|
||||
- 护甲三档键 `{"light","ward","heavy"}` 只在 `standee_body.gd` 常量处定义一次,`:485` 与 `:496` 共用。
|
||||
- 地台几何已在 `:405` 单一来源(注释明写「防两处漂移」),本批不另立第二处几何。
|
||||
|
||||
**分层与交互面**:
|
||||
|
||||
- 样张脚本(`tools/`)→ 只产出图与断言报告,不进游戏运行时;与呈现层的交互=读取 `UiKit` 常量值,只读不写。
|
||||
- 呈现层(`standee_body.gd`)→ 经 `UiKit` 取色与字号,不直连数据表;数值只经 ConfigDB 单点(本批无玩法数值改动)。
|
||||
- 新增素材(PNG)→ 落 `game/assets/` 被呈现层按路径加载,路径串只在常量处定义一次。
|
||||
- 跨层红线不因新增而绕:Core 零 UI、随机只经 RngService(本批无随机改动)、数值只经 ConfigDB。
|
||||
@@ -0,0 +1,356 @@
|
||||
# 需求卡片:核心数据面结构收敛批(gdstyle 存量债清偿·卡 2——数据校验族/生成器族/效果引擎/core-data 散条 86 键)
|
||||
|
||||
- 版本:**v1.2**(v1.1=2026-10-27 用户全清裁决四项折入+拆件面实查补全;v1.2=2026-10-28 用户裁「拆分边界纪律(DDD/高内聚)」落卡——新增契约 7+审计⑪+L3 增款+基线读数锚重锚〔216→168 键,随波 0 刷新 d219dd3d〕;自审六查与 grilling 自检记录见 §12)
|
||||
- 来源:[待办清单](../待办清单.md)「gdstyle 存量债全量清偿——216 键按病根分波整改」条目(2026-10-26 登记,P0,状态=文档设计已闭合+已写卡)(唯一事实源:清点报告 [审计-gdstyle存量债清点与清偿方案-2026-10-26](审计-gdstyle存量债清点与清偿方案-2026-10-26.md) §六第 2/3/4/7 条裁定——证据指认形态,见 §2)
|
||||
- 归并账目(清点报告 §六第 7 条):本卡收编=**波 2(40 键/13 文件)+波 4(17 键/2 文件)+effect_engine(8 键)+波 8 core/data 侧 10 文件(21 键)=86 键/26 文件**;与卡 1(B1 战斗域拆件批 45 键)、卡 3(呈现层结构收敛批 71 键)账目闭合 45+86+71=202+三宿主规避 14=216。**2026-10-27 用户全清裁决:86 键全部清零**——v1.19 在册豁免仅两处(组合根 main 句柄面/测量面 tune_sim await),均不在本卡文件集,本卡零豁免零残留
|
||||
- 归属:`game/data/schemas/` 12 文件+`game/core/` 14 文件+`game/data/tables/adventure.tres`(等值迁移)+**新件 8**(`game/core/config_domain_combat.gd`/`config_domain_run.gd`/`config_domain_crossrun.gd`/`slot_store.gd`/`meta_state_store.gd`+`game/data/schemas/adventure_quota_segment.gd`/`adventure_value_segment.gd`/`adventure_cap_segment.gd`)+消费方改址(`game/core/`、`game/presentation/`、`game/tests/`、`game/probe/`、`game/sim/` 约 60 文件,实查合计 ≈1330 处——§3.5 分面计数)
|
||||
- 排期:未编入(迭代批卡片;预配迭代 41——卡①与波 7 迭代 40 先行合回,串行序见 §0;估时 **≈7.9 个工作日,区间 7.4–8.4**,逐 T 卡实估见 §7;超迭代冻结线 5 个工作日——编入时循迭代 39 特批先例由用户裁)
|
||||
- 开工门:U0+复核门过(§12)——零待裁点(2026-10-27 用户裁决落定,§11)
|
||||
|
||||
## 0. 前置依赖与并行性
|
||||
|
||||
- **第〇步核对(2026-10-27 写卡会话)**:来源条目=需求性工程条目(整行无设计线段、首段落「文档设计已闭合+已写卡」)——逐波裁定(清点报告 §六第 1–6 条)+2026-10-27 整合裁定(§六第 7 条)+2026-10-27 全清设计补课(架构 v1.19)即证据指认,放行。
|
||||
- **全清裁决(2026-10-27 用户,本卡修订依据,实现段零裁断)**:①config_db 双键(公开方法 44/类变量 25)彻底清零=行族访问器归位各 schema 表类+表持有成员按域收进域容器 Resource;②save_manager 52/meta_progression 31 彻底清零=SlotStore/MetaStateStore 拆件(架构 v1.19 :89/:90 行已登记);③adventure_table 类变量 44 拆子 Resource 段(形态同 settlement_table 拆段——嵌套段单 .tres 保持);④unit_container spawn 参数 10 签名引用束化。红线不变:ConfigDB 仍是唯一加载与持有单点(架构 :88 定稿注记口径)。
|
||||
- **卡间串行(迭代 40 先行合回)**:卡①文件集(battle_orchestrator/grant_segment/combat_segment/settlement_table/damage_controller/treasure_interact_controller+BattleFxHost/RewardGrant 两新件)与波 7 现成卡(结构小件定点修批 v1.3,同触 board_generator.gd/reward_economy.gd 两 `_fatal`)在迭代 40 先行合回——本卡改址 battle_orchestrator 的 spawn 调用点按**卡①合回后形态**(行号 T0 重锚);本卡对 board_generator/reward_economy 两文件的拆分行号**禁照搬 §3 锚**,一律 T0 重核(后行者吸收漂移义务,波 7 卡自带同款)。
|
||||
- **spawn 参数键入本卡(K6′)**:签名束化必改全部调用方——battle_orchestrator 调用点经卡①(迭代 40)先行收敛,本卡(迭代 41)改址顺路;v1.0 的「卡间零交叠留残」义务随串行序解除。
|
||||
- **与卡③(呈现层结构收敛批)触碰=呈现侧改址行**:hud_presenter/camp_shop_presenter/main/save_select_overlay/treasure_interact_controller 等文件的访问点换址(纯改址、无结构改动)——编排错波,后行者 T0 吸收漂移(迭代 39 副卡同款先例)。
|
||||
- **与迭代 39 两卡(已编)的文件触碰**:副卡(同调配装充能域封装批)触 effect_engine.gd(仅 :94 注释面 RunLedger 表述清)与 meta_progression_forge_test.gd(:290-291 直构改址)——本卡重构 effect_engine.gd 本体并改址同一测试文件的其他行;同文件异行域,编排错波(39 先于 41),后行者 T0 吸收行号漂移。
|
||||
- **PARITY/MC 纪律**:本批零数值改动、零 RNG 流改动、零 PARITY 触面(S8_FILES/PARITY_TOUCH_FACES 零命中)→ 零 MC、零对拍补跑。存档面等价由现役 save 断言面+读写逐位断言承载(wr6),不属对拍补跑。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
**目标**:86 键收编文件的结构债**全数清偿**——①数据校验族 13 文件 validate()/cross_validate() 按校验域拆私有函数族(2026-10-26 用户裁:各文件内部拆、不抽共享骨架);②生成器族两件拆私有阶段函数(RNG 消费序冻结);③effect_engine 拆解释器与校验私有域(全同步语义、装载声明序、四词表封闭零变化);④**config_db 归位+域容器**:35 个行族/resolve/门控访问器归位各 schema 表类(表管自己的行查询)、19 个表持有成员按域收进 3 个域容器 Resource,ConfigDB 只剩加载/校验/override/诊断门面;⑤**存档域拆件**:SlotStore(槽位文件域)+MetaStateStore(存档内元进度数据读写唯一层)建件收编,save_manager 瘦身剩磁盘 IO+版本迁移链+断点族+门面,meta_progression 纯转发读退役、业务规则与写口编排留置(封闭面 20);⑥波 8 core/data 散条按 K 清单收敛(adventure_table 拆段、action_economy 删并、spawn 束化、其余拆分/私有化)。**游戏行为零变化**(契约 1)。
|
||||
|
||||
**清偿账目**:86 键全清——校验族 40+生成器族 17+效果引擎 8=65 键由文件内私有拆分清偿(gdstyle 直扫键消失,闸读数下降自然绿);波 8 core/data 侧 21 键由结构收敛清偿:config_db 44+25 两键=归位+容器(44→8/25→9)、save_manager 52=拆件(52→7)、meta_progression 31=瘦身(31→20)、adventure_table 44=拆段(44→12)、action_economy 18=删并(18→15)、unit_container spawn 参数=束化(10→1)、save_manager `_peek_summary_at`/load_from_disk 返回键与 meta_progression tree_can_buy 返回键=留置函数原位拆分清偿。新件 8 封闭面全部在阈(§7 预检逐件核验),零基线外 NEW。
|
||||
|
||||
**完成定义**:
|
||||
1. §7 结构图全部行落地(含 8 新件);`tools/gdstyle_gate.py` 改前改后读数对拍:**基线外 NEW=0(含新件)、恶化=0、在案键计数较 T0 实测基线(波 0 刷新后 168 键,git d219dd3d)下降 86**(86 键消失清单+新件键账表进实现报告);
|
||||
2. 行为等价证据齐:数据校验族断言面(data_config 八套件+core 直引 12 文件)全绿;生成器同种子逐位一致(现役 determinism 断言继承);效果引擎现役四套件全绿;**存档读写逐位等价**(save 现役断言面改址保持全绿——原子写/兜底/拒读/迁移链语义零变化);
|
||||
3. 撤销证明逐 wr 行落地(§8.1 末列);三份产出物写齐(T10);独立验收审计过。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
| # | 出处 | 取用条款 |
|
||||
|---|---|---|
|
||||
| D1 | 待办清单条目「gdstyle 存量债全量清偿」(需求性工程条目证据指认) | 波次框架、纪律、本卡放行凭据 |
|
||||
| D2 | 清点报告 §六**第 2 条**(波 2 形态=各文件内部拆校验域私有函数族、不抽共享骨架、零新概念零架构登记) | 校验族拆分形态 |
|
||||
| D3 | 清点报告 §六**第 3 条**(全部波不改游戏规则与玩家可见行为;design/gdd/systems/ 零修订预期) | 行为零变化总纲 |
|
||||
| D4 | 清点报告 §六**第 4 条**(波 8 config_db 公开方法收敛=纯代码删冗余/私有化) | **已被 D7 取代**——方法集由「删冗余/私有化」扩为「归位+域容器」(2026-10-27 全清裁决),本行仅存账目沿革 |
|
||||
| D5 | 清点报告 §六**第 7 条**(2026-10-27 整合裁定:本卡=波 2+波 4+effect_engine+波 8 core/data 侧=86 键;文件交叠冲突归零) | 收编范围与卡间边界 |
|
||||
| D6 | 2026-10-27 写卡会话**逐文件实查声明**:26 收编文件全数实读+gdstyle 0.4.0 直扫复测(读数与 2026-10-26 基线零漂移);公开面消费方 grep 全域核验;未发现触碰任何 owner 契约/GDD 陈述的病根——三处文档机械指址漂移(§6 反哺点承载,陈述本体不变) | 本卡写法③证据基座 |
|
||||
| D7 | **2026-10-27 用户全清裁决四项**(§0 抄录;待裁点 1 案 B 变体=归位+域容器 Resource〔非词典化〕、待裁点 2 案 B=域对象拆件经设计段先行定稿) | config_db/save/meta/adventure/spawn 五面的清偿深度与形态 |
|
||||
| D8 | `design/engineering/architecture/architecture.md` **v1.19**::88 ConfigDB 行定稿注记(行族访问器归位+域容器持有+「经 ConfigDB 单点读取=经其持有的表对象」口径);:89 SlotStore 行;:90 MetaStateStore 行(「数据读写原语族+只读投影」——本卡 K2′ 读投影设计的直接依据);:126 meta_progression 行定稿注记(纯转发读退役+业务规则与写口编排留本类 ≤20+tree_can_buy 留公开对外暴露列);:183 组合根 S13 豁免在册(本卡改址经 `main.save_manager` 既有句柄、零新增句柄成员——豁免面不扩大) | 拆件设计与红线口径的唯一架构凭据 |
|
||||
|
||||
## 3. 现状事实(2026-10-27 写卡会话实查于 master 8b146321,gdstyle 0.4.0 直扫——与基线零漂移;修订会话复测于 be2f6ca6,两次提交均为写卡文档面、代码零漂移。开工日 T0 复核行号——迭代 40 卡①/波 7 合回后全表重锚)
|
||||
|
||||
### 3.1 数据校验族(波 2,40 键/13 文件)
|
||||
|
||||
| 文件 | 键(现值/阈值) | 实查 |
|
||||
|---|---|---|
|
||||
| `game/data/schemas/meta_tree_table.gd` | validate 长度 86/50·分支 26/8·局部 13/10·嵌套 5/4 | :27-111(单循环体+requires/requires_level/彩蛋三尾段) |
|
||||
| `game/data/schemas/treasure_item_table.gd` | validate 长度 147/50·分支 44/8·局部 26/10·嵌套 6/4 | :61-206(行头校验/活行校验/同调行校验三段可分,:104 调 EffectEngine.validate_trigger_row) |
|
||||
| `game/data/schemas/board_gen_table.gd` | validate 长度 67/50·分支 20/8·局部 16/10 | :14-81 |
|
||||
| `game/data/schemas/enemy_table.gd` | validate 长度 116/50·分支 32/8·局部 29/10 | :36-150(行核心/池模板/行序纪律/锚行四段) |
|
||||
| `game/data/schemas/forge_table.gd` | validate 长度 95/50·分支 30/8·局部 20/10 | :31-126(行校验+初始持有覆盖尾段+默认轴交叉尾段) |
|
||||
| `game/data/schemas/level_gen_params.gd` | validate 长度 59/50·分支 15/8·局部 18/10 | :15-72(行校验+层深递进尾段) |
|
||||
| `game/data/schemas/meta_table.gd` | validate 长度 60/50·分支 14/8·局部 14/10 | :15-74(boss_keystone/conversion/attune_refresh 三行族天然分段) |
|
||||
| `game/data/schemas/reward_table.gd` | validate 长度 99/50·分支 30/8·局部 20/10 | :16-113(行校验+字典完整性/池护栏/clear_default 三尾段) |
|
||||
| `game/data/schemas/skill_table.gd` | validate 长度 80/50·分支 29/8 | :19-97(按 type=basic/damage/buff/debuff 四段类型校验) |
|
||||
| `game/data/schemas/variation_table.gd` | validate 长度 58/50·分支 20/8 | :24-80(行校验+互锁段) |
|
||||
| `game/data/schemas/status_effect_table.gd` | validate 分支 12/8 | :14-51(按 unit=percent/flat/ac 三段量纲域) |
|
||||
| `game/core/config_db_cross_validator.gd` | cross_validate 长度 107/50·分支 21/8·局部 24/10·嵌套 5/4;validate_skill_pool_links 局部 11/10 | :8-113(①①b②③⑤⑥⑦编号块天然分段);:121-159 |
|
||||
| `game/core/config_db_resolver.gd` | resolve_enemy_rowset 分支 12/8;_resolve_progress 长度 52/50·分支 16/8·局部 11/10 | :33-81(行集寻址);:107-157(缺位标注 if 链+告警去重块) |
|
||||
|
||||
### 3.2 生成器族(波 4,17 键/2 文件)
|
||||
|
||||
| 文件 | 键(现值/阈值) | 实查 |
|
||||
|---|---|---|
|
||||
| `game/core/board_generator.gd` | generate 长度 62/50·局部 14/10;_attempt 长度 51/50;measure_inferability 长度 64/50·分支 12/8·局部 13/10·嵌套 5/4;_finalize 参数 6/5 | :20-80(params 快照段 :26-39 可提);:85-134(布雷+剃雷段可提);:151-213(single/subset 两算子与派生约束段可提);:336(`_db` 形参全函数零消费——删即 5 参) |
|
||||
| `game/core/node_map_generator.gd` | check_params 分支 12/8;validate_output 长度 132/50·返回 7/6·分支 34/8·局部 22/10;_build 局部 15/10;_add_forks 局部 12/10;_assign_types 分支 11/8;_check_fork_rules 嵌套 5/4 | :68-106(域校验段/结构可行性段两分);:111-241(六阶段早退结构天然分拆);:246-286;:292-334(锚收集段无 RNG 可提);:359-402(配比填余段/岔口修型段两分——后者零 RNG);:468-514(支路签名比较嵌套) |
|
||||
|
||||
### 3.3 effect_engine(8 键)
|
||||
|
||||
| 文件 | 键(现值/阈值) | 实查 |
|
||||
|---|---|---|
|
||||
| `game/core/effect_engine.gd` | rebuild 长度 55/50·嵌套 5/4;_cond_ok 长度 52/50·返回 19/6·嵌套 5/4;validate_trigger_row 分支 14/8·局部 11/10;多余 else(no-else-return) | :95-148(feats装载/同调装载/树规则合成三段,装载序 feats→treasure→tree);:259-309(13 算子 match——比较族/ends_with/has/计数器族四组);:341-388(when 键校验段/do 键校验段);:210/:212=bucket_of 的 elif-after-return(:207-214) |
|
||||
|
||||
### 3.4 波 8 core/data 散条(21 键/10 文件)
|
||||
|
||||
| 文件 | 键(现值/阈值) | 实查 |
|
||||
|---|---|---|
|
||||
| `game/core/config_db.gd` | 公开方法 44/20;类变量 25/15 | 公开方法实测 44 个(修订会话逐方法构成核验见 §3.5);类变量=19 类型化表持有+is_ready+5 私有。类变量外部直读核验:19 持有变量全部有生产直读(db.hero 159 处/db.settlement 177 处/db.adventure 137 处等) |
|
||||
| `game/core/save_manager.gd` | 公开方法 52/20;_peek_summary_at 返回 7/6;load_from_disk 返回 8/6 | 公开方法实测 52 个,构成核验见 §3.5(槽位族 10+元进度族 35+断点族 4+IO/迁移 3) |
|
||||
| `game/core/status_container.gd` | apply_effect 返回 9/6·嵌套 5/4;_new_instance 参数 7/5 | :28-66(三臂 match 公共尾部都是 `_instances.append(_new_instance(...)); return true`);:69-80 |
|
||||
| `game/core/unit_container.gd` | spawn 长度 81/50·参数 10/5·局部 17/10 | :36-118(英雄段 :55-63/行集段 :69-112 两分);签名 10 参,调用方=battle_orchestrator(迭代 40 卡①合回后 T0 重锚)+测试 6 文件 10 处(damage_controller_test 1/roll_multiplier_test 3/round_flow_skill_pool_test 2/skill_unlock_test 1/level_shop_economy_test 2——修订会话 grep 实查;部分调用省略尾部缺省参) |
|
||||
| `game/core/reward_economy.gd` | roll_board 长度 54/50·局部 11/10;_skewed_cell_rows 局部 13/10 | :37-88(资格清单规范化段 :42-52 在开流前,可无虞提取);:220-259(分摊量计算段/权重装配段两分) |
|
||||
| `game/core/meta_progression.gd` | 公开方法 31/20;tree_can_buy 返回 8/6 | 构成核验见 §3.5(纯转发 2/hero_override 单调用点内联 3/内部自用私 2/并组 3 组/零生产私 1/留置 20);:320-350(requires/requires_level 两循环段可提) |
|
||||
| `game/core/treasure_items.gd` | validate_use 分支 11/8·嵌套 5/4 | :88-131(空间解析段/预读窗口段两分) |
|
||||
| `game/core/action_economy.gd` | 类变量 18/15 | 18 变量逐个核验:**`_next_round_mode` 只写零读(死存储,:36 声明/:219 写入,全库无第三处)**;**`_ap_exhausted_last` 可派生**(:275 在 _finish_round 内由 path_tag 派生,与 :274 `_last_round_end` 同源同刻——ap_exhausted_last_round() :280-282 改派生读语义逐字);**`last_round_end` 属性对外仅 minesweeper_rules.gd:495 一处消费**(architecture.md :102 该行只列「last_round_end」于消费依赖列,未钉属性形态;「ap/rap/phase 只读」三属性在架构对外暴露列——不动) |
|
||||
| `game/core/minesweeper_rules.gd` | _do_dig 长度 53/50 | :280-332(连锁揭示循环段 :301-329 可提——cell_revealed 发射序即链序,整体搬迁零漂移) |
|
||||
| `game/data/schemas/adventure_table.gd` | 类变量 44/15 | 44 变量=44 个 @export 标量槽(修订会话逐列复核:配额 13+件值 13+cap 9+knob 9——v1.0 行「37 个 @export」计法有误随本版订正,账目 44 不变)。**列族分组**:curio_quota_*(13,"kind/tier" 13 组合)/curio_value_*(13)/curio_cap_*(9)/knob 9(clear_heal_pct、curio_candidate_count、shop_refresh_*3、feat_ticket_*4)。外部直读核验:36 个配额/件值/cap 槽生产直读为零(仅 2 处测试例外:pool_case_d_test.gd:164/165/190 直写 curio_cap_gp 模拟满层、adventure_feats_test.gd:206 直读 curio_value_max_hp_common);生产消费全走 curio_quota()/curio_value()/curio_cap() 三个访问器与 9 个 knob 槽。adventure.tres 在册 36 个标量属性(等值迁移载体) |
|
||||
|
||||
### 3.5 拆件面实查(2026-10-27 修订会话消费方 grep 全域——改址计数与封闭面设计依据)
|
||||
|
||||
- **config_db.gd 44 公开方法构成**(留置 8+归位 33+删 2+私 1=44 闭合):留置=门面/诊断/加载/override 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload);归位=**溶解 16**(feat_row/feat_rows/tree_node/tree_rows/status_effect_row/level_row/level_gen_params_row/level_count/treasure_item_row/treasure_transitional_rows/treasure_attunement_rows/skill_row/shop_price_a/shop_price_b/forge_default_attack_type/forge_default_armor_type——底层表方法或属性现成,访问点改直连)+**迁移 14**(shop_gp_drop_row/shop_level_gp_bonus/shop_price_level_bonus/shop_products/shop_product_row/shop_pool_rows/shop_pool_row 7+meta_boss_keystone_row/meta_attune_refresh_row 2+forge_routes/forge_route/forge_armor_route_by_type 3+variant_pool/global_variant_row 2——实扫逻辑随方法入表类)+**委托 3**(resolve_board_gen/resolve_enemy_rowset/resolve_difficulty_modifiers——resolver 协作件经装配段注入三表,resolver 文件与键零搬移);删 2(meta_conversion_row/forge_weapon_route_by_type——生产零消费,K1′);私 1(validate_skill_pool_links——测试 2 文件 9 处改 _ 前缀,K1′)。成员直读 `db.<表>` 537 处(core 99/呈现 24/测量面 414)+访问器调用 264 处=**改址 ≈800 处**。
|
||||
- **save_manager.gd 52 公开方法构成**:槽位族 10(attach_path/attach_slot_template/slot_path/active_slot/has_write_target/activate_slot/create_slot/delete_slot/peek_slot_summary/peek_summary_at→SlotStore;消费面 main/save_select_overlay/hud/main_overlay_flow/main_ui_build ≈12 处+探针 ≈17 处+测试 ≈77 处)+元进度族 35(钥石 3〔keystone_balance/add_keystone/spend_keystone〕/道具 2/树 3/叉侧 3/锻造 9/同调 2/Y 账本 2/真视 2/计数 5/摘要 2/首冒险 2→MetaStateStore;消费面 meta_progression 内部+attunement.gd+adventure_runner.gd+hud/camp 呈现+sim/探针/测试,grep 实查 ≈340 处)+断点族 4(set_breakpoint/clear_breakpoint/has_breakpoint/breakpoint_snapshot——留置 save_manager)+IO/迁移 3(load_from_disk/write_to_disk/register_migration——留置)。**改址 ≈450 处**。
|
||||
- **meta_progression.gd 31 公开方法构成**(瘦身 −11+并组回加 +3=留置 20):纯转发读退役 2(keystone_balance〔grep 实查 67 处接收者混布——生产 3:hud 2/camp 1,测量面 64 按接收者实例机械区分:meta 实例随本项退役改 `meta_state.` 直连、save 实例随 K2′ 族改址〕、is_item_unlocked〔treasure_interact_controller 1 处〕——消费方直连 meta_state);hero_override 单调用点内联 3(forge_weapon_atk_bonus/forge_armor_ac_bonus/tree_stat_flat——v1.0 行「内部零调用」实查笔误随本版订正:三件均由 hero_override :303-305 调用,内联后输出逐字等价);内部自用私 2(tree_spent_total/tree_gate_text——测试 1 文件 2 处改 _ 前缀);并组 3 组(tree_camp_rows+tree_fork_groups→tree_camp_status〔消费方 camp_shop_presenter 各 1 处〕、hero_attack_type+hero_armor_type→hero_type_axes〔main.build_adventure_params 2 处+测试 2 处〕、forge_select_weapon+forge_select_armor→forge_select(kind, route_id)〔camp 2 处+测试 4 处〕);零生产私 1(forge_route_unlocked——生产零、测试 7 处改 _ 前缀);留置 20(封闭面定稿=架构 v1.19 :126 对外暴露列 6 件+UI 投影/写口编排——§7-K3′ 列全)。
|
||||
- **新件封闭面预演**(gdstyle 阈值实测:max-public-methods 21 即红/max-class-variables 含私有成员 16 即红):SlotStore 公开 10/类变量 4 ✓;MetaStateStore 公开 19(写口原语 13+读投影 6)/类变量 1 ✓;域容器×3 类变量 7/7/5、零方法 ✓;adventure 段件×3 类变量 13/13/9、零方法 ✓——全部 ≤阈零 NEW。
|
||||
|
||||
## 4. 设计契约(红线,违反 = L3 停机呈报)
|
||||
|
||||
🔴 **契约 1 · 行为零变化**:①fail-fast 契约与校验覆盖面零变化——全部 validate/cross_validate 对同一输入的错误清单**逐字等价**(类别、文案、追加顺序);②生成结果逐位零变化——board_generator/node_map_generator 同种子同参产出与改前逐位一致,**RNG 消费序冻结**(拆分只许整段搬迁取数代码,禁重排任何 rng_stream/纯流取号调用);③伤害数值与效果语义零触碰;④效果引擎**装载声明序**(feats→treasure→树规则,行内数组序)与**四词表封闭**(EVENTS/EFFECT_KINDS/FACTS/OPS 常量零改动)零变化;⑤玩家可见呈现零变化;⑥**存档序列化语义零变化**——tmp+rename 原子写、无激活态拒写、高版本拒读禁写、损坏兜底改名、迁移链幂等、旧单档一次性迁移判据,对同一输入的盘面结果与返回值逐字等价(现役 save 断言面为载体)。
|
||||
|
||||
🔴 **契约 2 · 断言面逐字保留**:现有 validate 系单测(data_config 八套件+core 直引 12 文件)、生成器断言面(board_generator_test/node_map_generator_test/node_map_determinism_test 等)与 save/meta 断言面(save_manager_domain/save_slot_isolation/save_slot_summary/save_boot_no_activate/breakpoint_resume/meta_progression_forge/tree_requires_level 等)**禁删禁改判据**;确需改判据=测试削弱申报节逐条列明理由。测量面改址(§7-K 列明的调用点换址)=访问路径改写,断言语义与判据逐条保持。
|
||||
|
||||
🔴 **契约 3 · S13 纪律**:`tools/gdstyle_baseline.txt` 禁改禁 refresh(波 0 已于 2026-10-28 批外刷新至 168 键,批内禁改口径不变);还债=数值下降自然绿;**在案键的函数禁搬移文件**(基线函数级键逐一核对:save_manager 两函数键与 meta_progression tree_can_buy 返回键全部原位留置——本卡搬移面均为无键方法,§3.5 已核对);新件封闭面按 §3.5 预演值落地、禁超阈;机检键与卡片契约互斥时停卡呈报。
|
||||
|
||||
🔴 **契约 4 · 禁为机检文本保留无效成员**(req-card 第 13 条,本卡属重构类):禁为迎合机检消息文本(含计数)保留或新增无效成员/别名/死存储/**转发壳**(action_economy `_next_round_mode` 删除即本契约的执行例;K1′ 删除的两访问器禁以兼容名留转发、K3′ 退役的两纯转发禁在 meta_progression 留同名委托);机检键与本卡契约互斥时实现段一律停卡呈报,不得自造第三条路。
|
||||
|
||||
🔴 **契约 5 · 公开面收敛边界(全清口径)**:文件内拆分只准动私有函数体与私有签名;公开签名/公开方法数/类变量数的改动**逐项按 §7-K1′–K6′ 清单执行**(每项已列改法、归位映射与消费方影响面),清单外公开面禁动;新件公开面=清单列明的封闭面,禁超禁缩(缩=消费面断裂,超=NEW 键)。
|
||||
|
||||
🔴 **契约 6 · 核心层纪律不破**:Core 层零 UI 依赖(拆分后完整战斗仍可 `--headless --script` 跑通);数值单一事实源(adventure_table 拆段后玩法数值仍只存 `data/tables/*.tres` 经 ConfigDB 单点读取——口径按架构 v1.19 :88:「经 ConfigDB 单点读取」=经其持有的表对象,访问器语义不变);RNG 单点(零新增随机);**新件零 autoload**(SlotStore/MetaStateStore 由 save_manager 组装持有、经 `save.slots`/`save.meta_state` 直连——组合根句柄面与 autoload 链零新增,架构 :89/:90 消费依赖单向)。
|
||||
|
||||
🔴 **契约 7 · 拆分边界纪律(DDD/高内聚,2026-10-28 用户裁)**:一切拆分(私有函数族/新件/段件/容器)的边界沿职责轴、不沿阈值轴——①每个拆出单元须有可陈述的职责语句(「X 域归 Y 件,因为 Z」,实现报告逐件一行)与单一变化原因;②单元须有集体身份:成员共同表达一个可命名的领域概念——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③成员被互不相干调用方分别消费=边界切错,按消费域重切;④「过阈值」只许作为发现信号,作为拆分动机即违规;⑤职责上不可分且拆不出内聚单元 → 停卡呈报走豁免/还债通道(architecture「S13 豁免登记」同款),禁硬拆凑绿。code-conventions §1.1(高内聚低耦合/禁为机检保留无效成员)为本条上位规约。**v1.2 审查预检结论**:本卡 T1–T9 拆分族与新件 8 逐项核对均有职责语句与集体身份(校验域/装载域/管线阶段/槽位文件域/存档内元进度数据域/三域容器/列族段),无凑计数形态——本条对卡 2 为确认性纪律,无改法变更。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
**做**:§3 所列 26 文件的结构拆分与 §7-K1′–K6′ 公开面收敛(含 8 新件建件与 ≈1330 处消费方改址);adventure.tres 等值迁移;撤销证明;产出物。
|
||||
|
||||
**不做**(去向明示):
|
||||
- config_db 类变量词典化(域容器 Resource 为既裁形态,词典化不采——D7);save/meta 的第三种拆法(SlotStore/MetaStateStore 为架构 v1.19 定稿件,禁另起形态);
|
||||
- 卡①文件集的结构改动(本卡对其仅 spawn 调用点一行改址)与卡③呈现层结构收敛(本卡对其仅访问点改址行)→ 各归其卡,编排错波;
|
||||
- 波 7 五小件(现成卡 v1.3,迭代 40)、三宿主残留债(迭代 39)、波 0 基线 refresh(直改)→ 各归其位;
|
||||
- design/ 与根规则文件任何编辑 → 反哺点清单(§6);
|
||||
- MC/对拍锚重跑 → 用户发起(本批零触发)。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点 | 同步义务 |
|
||||
|---|---|---|
|
||||
| `design/gdd/systems/战斗循环/地图战斗资源.md` | :83 引 `reward_economy.gd#roll_board` 内部行号(「循环第 65-67 行」)——roll_board 提取规范化段后行号漂移;`_rollable_rows()` 207-213 指址不变 | 反哺点 · 列清单(①:行号随动,陈述本体——收 pool 全集与资格一视同仁语义——零变化) |
|
||||
| `design/gdd/systems/冒险循环/冒险结构.md` | :267「adventure_table curio_value_*(…列族)」——拆段后标量槽随段件嵌套(段路径),值域陈述(int [0,999]/kind×tier)不变 | 反哺点 · 列清单(②:落点列改指段路径) |
|
||||
| `design/engineering/architecture/architecture.md` | v1.19 定稿注记四行的实现批后现状改写::88 ConfigDB 行(「实现卡随批改址」→改写为容器三件现状+公开面 8 实数);:89/:90 两新件行(「实现批建件」→现状登记);:126 meta_progression 行(「随件退役」→改写为公开面 20 现状);另 :102 minesweeper 行消费依赖列「A3 last_round_end」属性→方法注记;:90 action_economy 行与 :92/:93/:103/:104 四行(公开 API 零变化——T0 核后记「零改动」注记) | 反哺点 · 列清单(③:v1.19 定稿注记的现状改写由文档批执行,本卡只列落点) |
|
||||
| `game/tests/验证集清单.md` | 测量面改址涉及测试文件的调用点地址(机器提取重生成) | 批内机械同步(game 内 .md,非禁写面) |
|
||||
| `待办清单.md` | 来源条目状态推进(主会话统一回写——本卡代理禁改) | 反哺点 · 列清单(④:状态核对注记) |
|
||||
|
||||
## 7. 任务卡
|
||||
|
||||
### 卡前 · 文件结构图
|
||||
|
||||
| 文件 | 职责 | 行为改动 |
|
||||
|---|---|---|
|
||||
| `game/data/schemas/meta_tree_table.gd` | validate 拆行校验域+requires/requires_level 尾段(复用既有·修改) | 非行为 → wr1 |
|
||||
| `game/data/schemas/treasure_item_table.gd` | validate 拆行头/活行/同调行三域(复用既有·修改) | 非行为 → wr1 |
|
||||
| `game/data/schemas/enemy_table.gd` | validate 拆行核心/池模板/行序域+resolve_rowset 委托收编(复用既有·修改) | 非行为 → wr1/wr8 |
|
||||
| `game/data/schemas/forge_table.gd` | validate 拆行校验+两尾段+forge 族 3 方法归位(复用既有·修改) | 非行为 → wr1/wr8 |
|
||||
| `game/data/schemas/reward_table.gd` | validate 拆行校验+三尾段(复用既有·修改) | 非行为 → wr1 |
|
||||
| `game/data/schemas/board_gen_table.gd` | validate 拆行校验域+resolve_row 委托收编(复用既有·修改) | 非行为 → wr2/wr8 |
|
||||
| `game/data/schemas/level_gen_params.gd` | validate 拆行校验+层深递进尾段(复用既有·修改) | 非行为 → wr2 |
|
||||
| `game/data/schemas/meta_table.gd` | validate 拆三行族域+meta 族 2 方法归位(复用既有·修改) | 非行为 → wr2/wr8 |
|
||||
| `game/data/schemas/skill_table.gd` | validate 拆四类型域(复用既有·修改) | 非行为 → wr2 |
|
||||
| `game/data/schemas/variation_table.gd` | validate 拆行校验+互锁域+variant_pool/global_variant_row 归位(复用既有·修改) | 非行为 → wr2/wr8 |
|
||||
| `game/data/schemas/status_effect_table.gd` | validate 拆量纲域(复用既有·修改) | 非行为 → wr2 |
|
||||
| `game/data/schemas/difficulty_table.gd` | resolve_modifiers 委托收编(复用既有·修改) | 非行为 → wr8 |
|
||||
| `game/data/schemas/level_table.gd` | level_count 归位(复用既有·修改) | 非行为 → wr8 |
|
||||
| `game/data/schemas/shop_table.gd` | shop 族 7 方法归位(复用既有·修改) | 非行为 → wr8 |
|
||||
| `game/core/config_domain_combat.gd` | **新增**——战斗域容器(board_gen/variation/status_effects/enemy/skill/hero/settlement 7 类型化成员) | 非行为 → wr8 |
|
||||
| `game/core/config_domain_run.gd` | **新增**——冒险域容器(level/difficulty/level_gen_params/reward/adventure/action_economy/shop 7 成员) | 非行为 → wr8 |
|
||||
| `game/core/config_domain_crossrun.gd` | **新增**——跨局域容器(meta/meta_tree/treasure_items/feats/forge 5 成员;跨局循环=单局之外的长线进度域) | 非行为 → wr8 |
|
||||
| `game/core/config_db.gd` | 19 表成员→3 容器+33 访问器归位+删 2 私 1+resolver 装配注入三表(K1′) | 非行为 → wr8 |
|
||||
| `game/core/config_db_cross_validator.gd` | cross_validate 拆七编号块域+_check_cast_side(复用既有·修改) | 非行为 → wr2 |
|
||||
| `game/core/config_db_resolver.gd` | 拆键收集/缺位标注/告警发射域(复用既有·修改——文件零搬移,键原位) | 非行为 → wr2 |
|
||||
| `game/core/slot_store.gd` | **新增**——存档槽位文件域件(槽位挂载与模板/激活与建删/摘要窥视 10 公开,架构 :89) | 非行为 → wr6 |
|
||||
| `game/core/meta_state_store.gd` | **新增**——存档内元进度数据读写唯一层(写口原语 13+读投影 6=19 公开,架构 :90) | 非行为 → wr6 |
|
||||
| `game/core/save_manager.gd` | 槽位族/元进度族 45 方法收编出户+断点族/IO/迁移链留置+读盘域提取+状态分家(K2′) | 非行为 → wr6 |
|
||||
| `game/core/meta_progression.gd` | 纯转发退役 2+内联 3+并组 3+私 3+留置 20+meta_state 成员(K3′) | 非行为 → wr7 |
|
||||
| `game/core/board_generator.gd` | 拆 params 快照/布雷/single-subset 算子域+_finalize 删 _db 参(复用既有·修改) | 非行为 → wr3 |
|
||||
| `game/core/node_map_generator.gd` | validate_output 拆六阶段+check_params 两分+构建域拆分(复用既有·修改) | 非行为 → wr3 |
|
||||
| `game/core/effect_engine.gd` | rebuild 三装载域+_cond_ok 四算子域+validate_trigger_row 两键域+bucket_of elif 收口(复用既有·修改) | 非行为 → wr4 |
|
||||
| `game/core/status_container.gd` | apply_effect 公共尾部收口+_new_instance 打包 5 参(复用既有·修改) | 非行为 → wr5 |
|
||||
| `game/core/treasure_items.gd` | validate_use 拆空间解析/预读窗口域(复用既有·修改) | 非行为 → wr5 |
|
||||
| `game/data/schemas/adventure_quota_segment.gd` | **新增**——令牌配额段(curio_quota_* 13 @export;嵌套段单 .tres 保持) | 非行为 → wr9 |
|
||||
| `game/data/schemas/adventure_value_segment.gd` | **新增**——令牌件值段(curio_value_* 13 @export) | 非行为 → wr9 |
|
||||
| `game/data/schemas/adventure_cap_segment.gd` | **新增**——已拿上限段(curio_cap_* 9 @export) | 非行为 → wr9 |
|
||||
| `game/data/schemas/adventure_table.gd`+`game/data/tables/adventure.tres` | 36 列族槽拆 3 段件+.tres 等值迁移+访问器改读段+knob 9 留置(K4′) | 非行为 → wr9 |
|
||||
| `game/core/action_economy.gd` | 删死存储+派生合并+last_round_end 属性→方法(K5) | 非行为 → wr10 |
|
||||
| `game/core/reward_economy.gd` | roll_board 拆规范化域+_skewed_cell_rows 两域(复用既有·修改) | 非行为 → wr10 |
|
||||
| `game/core/minesweeper_rules.gd` | _do_dig 拆连锁揭示域(复用既有·修改) | 非行为 → wr10 |
|
||||
| `game/core/unit_container.gd` | spawn 签名束化(10→1 参 req 束)+体内拆英雄/行集两域(K6′) | 非行为 → wr11 |
|
||||
| `game/core/attunement.gd`/`adventure_runner.gd` 等 core 消费面 | save 族/`db.<表>` 访问点改址(复用既有·修改) | 非行为 → wr6/wr7/wr8 |
|
||||
| `game/presentation/`(main/hud_presenter/camp_shop_presenter/save_select_overlay/treasure_interact_controller 等) | 纯转发退役直连+槽位族/`db.<表>` 改址(复用既有·修改) | 非行为 → wr6/wr7/wr8 |
|
||||
| `game/tests/`…+`game/probe/`…+`game/sim/`…(约 50 文件) | 五组改址与测量面随动(复用既有·修改) | 断言面(改址非削弱)→ wr6/wr7/wr8/wr9/wr11 |
|
||||
|
||||
### 落位与可复用性预检
|
||||
|
||||
- **新件 8 逐件「为什么不能复用既有」**:
|
||||
- 域容器×3(`config_domain_*.gd`):config_db 本体即 God Class 本体(44 方法/25 成员)——「按域分组的类型化表持有」是新职责所有者,复用 config_db 内部结构=延续 God Class(D7 裁决的整管对象正是它);架构 v1.19 :88「类型化域容器属性(每域一张容器)」。落位 `game/core/`(持有结构与 owner ConfigDB 同层同域)。
|
||||
- `slot_store.gd`:save_manager 本体 God Class(52 方法)——槽位文件域唯一所有者是新职责切面,架构 :89 行登记;落位 `core/`(D3 存档域)。
|
||||
- `meta_state_store.gd`:save 与 meta 双 God Class 的共同病根=同一「存档内元进度数据域」摊在两文件——归一件即新职责本体,架构 :90 行登记;落位 `core/`。
|
||||
- adventure 段件×3:adventure_table 44 成员超阈本体——列族分组是新持有结构,复用=维持 44 列平铺;形态同 settlement_table 拆段既裁(嵌套段单 .tres 保持);落位 `game/data/schemas/`(表 schema 同层)。
|
||||
- **唯一面**:新件类名全库 grep 零同名(ConfigDomainCombat/Run/Crossrun、SlotStore、MetaStateStore、AdventureQuota/Value/CapSegment——修订会话 grep 确认零命中);既有文件内新增私有函数只落其所属文件,不抽共享骨架为既裁(D2);跨文件同名私有方法(多个 schema 各自的 `_validate_row`)属 GDScript 类作用域私有,互不冲突,grep 全库名确认盘上无第二处同职责实现。
|
||||
- **分层与交互面**:新件全部构造注入/组装持有,零裸引用 autoload(S5 不触);域容器/段件不 load 不 preload(S3 不触);新件零随机(S1/S2 不触);SlotStore/MetaStateStore→save_manager 单向依赖(S6 反向引用面不触——零信号零订阅);resolve 委托经装配段注入(resolver 文件与键零搬移——契约 3)。Core 零 UI 不破(全套件 headless 可跑)。
|
||||
- **改址五组计数**(§3.5 实查,T0 复核):①`db.<表>` 成员直读 537 处→`db.<容器>.<表>`;②config_db 访问器调用 264 处→表类直连/归位新名(映射表见 K1′);③save 槽位族 ≈110 处→`save.slots.`;④save/meta 元进度族 ≈340 处→`save.meta_state.`(读面部分随投影改形);⑤meta 纯转发退役/并组 ≈60 处+spawn 调用点 10 处+K5 一处。合计 ≈1330 处——改址一律符号级 grep 全域后机械替换+逐文件复核(残余人工核),断言语义逐条保持(契约 2)。
|
||||
- **K1′–K6′ 逐项**(公开面收敛清单,契约 5 载体——每项改法、映射与消费方影响面):
|
||||
- **K1′ config_db(44→8、25→9)**:①19 表成员收进三容器——`combat`(board_gen/variation/status_effects/enemy/skill/hero/settlement)/`run`(level/difficulty/level_gen_params/reward/adventure/action_economy/shop)/`crossrun`(meta/meta_tree/treasure_items/feats/forge),分组判据=消费方域归属(战斗编排域 7/冒险 runner 域 7/跨局元进度域 5);ConfigDB 类变量余 is_ready+_diagnostics+_resolver+_validator+_reload_gate+_fatal_flag+3 容器=9。②33 访问器归位映射(改址映射表,命名避开表类既有成员名——routes 属性在册故 forge_routes()→ForgeTable.route_rows()、shop_products()→product_rows() 等):溶解 16(db.feat_row→db.crossrun.feats.row_by_id、db.tree_node→db.crossrun.meta_tree.row_by_id、db.status_effect_row→db.combat.status_effects.row_by_id、db.level_row→db.run.level.row_by_level_index、db.level_gen_params_row→db.run.level_gen_params.row_by_level_index、db.level_count→db.run.level.level_count、db.treasure_item_row→db.crossrun.treasure_items.row_by_id、db.treasure_transitional_rows/attunement_rows→同名表方法、db.skill_row→db.combat.skill.row_by_id、db.shop_price_a/price_b→db.run.shop.price_a/price_b 属性、db.forge_default_attack_type/armor_type→db.crossrun.forge.default_attack_type/armor_type 属性);迁移 14(db.shop_gp_drop_row→db.run.shop.gp_drop_row、shop_level_gp_bonus→level_gp_bonus_at、shop_price_level_bonus→price_level_bonus_at、shop_product_row→product_row、shop_pool_row→pool_row、shop_pool_rows→pool_rows、db.meta_boss_keystone_row→db.crossrun.meta.boss_keystone_row、db.meta_attune_refresh_row→db.crossrun.meta.attune_refresh_row、db.forge_route→db.crossrun.forge.route、db.forge_armor_route_by_type→db.crossrun.forge.armor_route_by_type、db.variant_pool→db.combat.variation.variant_pool、db.global_variant_row→db.combat.variation.global_variant_row);委托 3(db.resolve_board_gen→db.combat.board_gen.resolve_row、db.resolve_enemy_rowset→db.combat.enemy.resolve_rowset、db.resolve_difficulty_modifiers→db.run.difficulty.resolve_modifiers——resolver 实例由 load_tables 装配段注入三表)。③删 meta_conversion_row(生产零;测试 3 处改直扫 `db.crossrun.meta.conversion` 行集同判据)+删 forge_weapon_route_by_type(生产零;forge_table_test 2 处改扫 route_rows() 同判据)。④私 validate_skill_pool_links→_validate_skill_pool_links(测试 2 文件 9 处改 _ 前缀;cross_validator 自有公开同名方法不动)。⑤空表护栏语义:溶解面原 null-guard 仅覆盖「表未加载」态——生产消费全部在 load_tables 成功后(D6 实查),加载期护栏由 is_ready 门承担, ForgeTable 缺省轴语义与 schema 字段默认值同口径(normal/light)零行为变化。
|
||||
- **K2′ save_manager 拆件(52→7)**:①SlotStore 收编槽位族 10(attach_path/attach_slot_template/slot_path/active_slot/has_write_target/activate_slot/create_slot/delete_slot/peek_slot_summary/peek_summary_at),槽位态随迁(_slot_template/_path/_active_slot),save_manager 留 _data/_migrations/_read_only+slots/meta_state 两组装成员=类变量 5;peek 的只读推演内核 _peek_summary_at(键在案)留 save_manager 原位,SlotStore 两 peek 方法经槽路径派生委托(迁移链/规整归 IO 域)。②MetaStateStore 收编元进度族 35——**公开面 19=写口原语 13**(spend_keystone/unlock_item/set_tree_level/set_fork_side/set_forge_route_level/add_forge_unlock/set_forge_weapon/set_forge_armor/set_attunement_equipped/set_attune_refresh_level/add_vision_used/apply_adventure_summary/mark_first_adventure_done)**+读投影 6**(keystone_balance()、item_unlocked(id)、tree_state()→{nodes, fork_sides}、forge_state()→{levels, unlocked, weapon, armor}、attune_state()→{equipped, refresh_level}、career_state()→{clear_counts, boss_first_kill, boss_kill_count, adventure_total, adventure_cleared, vision_used, recent_summaries, first_adventure_done}——读投影即架构 :90「只读投影」形态,值拷贝出户 duplicate 纪律随迁);add_keystone 私有化 _add_keystone(生产零、测量 21 处改 _ 前缀——K2 同法)。③save_manager 留置 7 公开:load_from_disk/write_to_disk/register_migration+断点族 4;读盘域提取 `func _load_parsed(f: FileAccess) -> bool`+`func _peek_migrated(parsed: Variant) -> Variant`(:320-355/:175-209 两函数与迁移循环同构可提——corrupt_fallback 调用点随段迁移,副作用序逐字)。④跨件协作:两 store 持 save 注入引用,建/删/激活的数据重置与读写盘经 save 内部 _ 前缀协作家族(_reset_to_default/_load_parsed/_rename_overwrite 等),store 零 _data 副本零缓存(load 整体换新不陈旧);激活失败回退四态(路径/激活号/禁写位/数据)跨件原子性由现役 save_slot_isolation 断言面承载。⑤消费方直连:`save.slots.<m>`/`save.meta_state.<m>`(存档 UI/营地树 UI/锻造 UI/调试面);组合根句柄面零新增(契约 6)。
|
||||
- **K3′ meta_progression(31→20,封闭面定稿)**:纯转发退役 2(keystone_balance/is_item_unlocked——消费方改 `meta.meta_state.<m>` 直连);内联 3(forge_weapon_atk_bonus/forge_armor_ac_bonus/tree_stat_flat 收编进 hero_override 单调用点——输出逐字等价);私 3(tree_spent_total/tree_gate_text〔测试 1 文件 2 处〕/forge_route_unlocked〔测试 1 文件 7 处〕改 _ 前缀);并组 3 组(tree_camp_status()→{rows, fork_groups}、hero_type_axes()→{attack, armor}、forge_select(kind, route_id)——camp/main 与测试改址 ≈10 处);留置公开 20=buy_treasure_unlock/refresh_treasure_unlocks/treasure_shop_status/forge_buy_level/forge_buy_unlock/forge_select/hero_type_axes/forge_shop_status/settle_adventure/hero_override/tree_can_buy〔v1.19 :126 对外暴露列在册——留公开,测试零改址〕/tree_buy/tree_toggle_fork/tree_buy_fork/tree_rule_keys/tree_camp_status/toggle_attunement/attune_camp_status/attune_refresh_charges/buy_attune_refresh;补公开成员 `meta_state`(_ready 装配)。写口唯一性保持:全部购买/切换/装配写路径仍只经本类编排(扣币 spend_keystone+域写原语+write_to_disk 时序归本类门面)。
|
||||
- **K4′ adventure_table 拆段(44→12)**:36 个列族标量槽拆 3 段件——`AdventureQuotaSegment`(curio_quota_* 13)/`AdventureValueSegment`(curio_value_* 13)/`AdventureCapSegment`(curio_cap_* 9),段内 @export 槽名逐字不动;宿主留 3 段成员+9 knob=12 ≤ 15 ✓(knob 留置=生产直读零改址);curio_quota(kind, tier)/curio_value(kind, tier)/curio_cap(kind) 三访问器签名与返回语义逐字不变(内部改读段成员;未列组合 = 0/缺省 99 语义保持);validate() 域判据经访问器读数不变(现役文案逐字);`adventure.tres` 等值迁移(36 在册值逐槽照抄入嵌套段 sub_resource、单 .tres 保持、缺省槽保持缺省语义);测试改址 4 处(pool_case_d_test.gd:164/165/190 直读写→段路径、adventure_feats_test.gd:206 直读→段路径——断言语义不变)。改后宿主类变量 12+段件 13/13/9 全在阈。
|
||||
- **K5 action_economy(18→15)**:删 `_next_round_mode` 死存储(:36 声明+:219 死写;`notify_settlement_done` 形参保留签名不变);`_ap_exhausted_last` 删除、`ap_exhausted_last_round()` 改派生读 `_last_round_end.get("path_tag", "") == "ap_exhausted"`(同源同刻等值——:274/:275 实查依据);`last_round_end` 属性→方法 `func last_round_end() -> Dictionary`(消费方仅 minesweeper_rules.gd:495 一处改方法调用)。
|
||||
- **K6′ unit_container(spawn 参数 10→1)**:签名改 `func spawn(req: Dictionary) -> bool`——束键封闭词表:必载 level_index/node_depth/hero_hp,可选 unit_count_overrides=[]/enemy_atk_overrides=[]/hero_atk_override=-1/hero_max_hp_override=-1/hero_attack_type=""/hero_armor_type=""/row_kind="battle"(缺省语义与现行形参缺省逐字同值);体内拆分照旧(`_spawn_hero_unit`/`_spawn_rowset` 两私有域)。调用点改址 11 处 7 文件(battle_orchestrator 1〔按卡①合回后形态〕+测试 10——束字面量构造,断言语义不变)。
|
||||
|
||||
### T0 事实坐实+改前读数采集(≈0.3d)
|
||||
|
||||
- [ ] 复核 §3 全部 file:line(**按迭代 40 卡①/波 7 合回后 master 重锚**——spawn 调用点、board_generator/reward_economy 两 `_fatal`、卡③/迭代 39 触碰行);跑 `python tools/gdstyle_gate.py` 记录改前读数(在案键计数、NEW/WORSENED 判定)。可核查结果:改前读数表进实现报告素材。
|
||||
- [ ] 留档行为等价对拍基线:data_config 八套件与生成器 determinism 断言记录改前全绿读数;坏表夹具错误清单留档;**save 断言面套件名与断言数留档**(save_manager_domain/save_slot_isolation/save_slot_summary/save_boot_no_activate/breakpoint_resume/save_rng_roundtrip 等——wr6 逐位等价载体)。可核查结果:改前基线读数在案。
|
||||
- [ ] 五组改址计数复核(§3.5 五组 grep 读数逐组重跑留档——机械替换的完备性依据)。可核查结果:改址计数表在案。
|
||||
- [ ] 核实窄确认载体:单元面直跑形态(`--headless --path . --script res://tests/run_all.gd`)与单套件过滤机制。可核查结果:T1–T9 验证步骤的命令形态定稿。
|
||||
|
||||
### T1 数据校验族·大表组(5 文件 17 键,≈0.7d)
|
||||
|
||||
- [ ] meta_tree_table:validate 拆 `func _validate_row(row: Dictionary, seen: Dictionary, fork_seen: Dictionary) -> Array`(行内全判据,fork_seen 引用传递)+`func _validate_requires_dangling(rows: Array, seen: Dictionary) -> Array`+`func _validate_requires_level(rows: Array, seen: Dictionary) -> Array`(requires 与 requires_level 两尾段分离);validate 本体留空表护栏+行循环 append_array+彩蛋计数尾段。可核查结果:错误追加序与改前逐字等价(现役 meta_progression_forge_test/table_structure_guard 断言绿)。
|
||||
- [ ] treasure_item_table:validate 拆 `func _validate_row_head(row: Dictionary, iid: String) -> Array`(:76-107 display_name→form 段)+`func _validate_row_active(row: Dictionary, iid: String) -> Array`(:111-141 活行段,kind_seen 内建)+`func _validate_row_attunement(row: Dictionary, iid: String, kind_seen: Dictionary) -> Array`(:142-205 同调段);validate 本体留空表护栏+seen/dup+三域顺序调用(retired/deferred continue 位置逐字)。可核查结果:treasure_target_violation_test/table_structure_guard/config_db_test 秘宝段全绿,EffectEngine.validate_trigger_row 调用点零变化。
|
||||
- [ ] enemy_table:validate 拆 `func _validate_row_core(row: Dictionary) -> Array`(:52-88 进度键/枚举/值域段)+`func _validate_row_pool(row: Dictionary, eid: String) -> Array`(:90-116 池模板段)+`func _validate_rowset_order(rowset_key: String, last_rowset_key: String, closed_rowset: Dictionary, L: int, rk: String, band: int) -> Array`(:129-138 行序纪律段);validate 本体留 seen/dup、行序状态机、锚行尾段。可核查结果:现役敌人表断言面(config_db_test/round_flow_skill_pool_test 前置)全绿。
|
||||
- [ ] forge_table:validate 拆 `func _validate_route_row(row: Dictionary, kind_by_id: Dictionary) -> Array`(:47-106 行段)+`func _validate_initial_coverage(routes: Array) -> Array`(:107-125 初始持有覆盖+默认轴交叉尾段)。可核查结果:forge_table_test 全绿(含 13 处行级判据)。
|
||||
- [ ] reward_table:validate 拆 `func _validate_row(row: Dictionary, cell_dict: Dictionary, tallies: Dictionary) -> Array`(:25-101 行段;tallies={cell_positive_live, clear_value_ok} 引用传递)+validate 本体留三尾段(字典完整性/池护栏/clear_default)。可核查结果:reward_dangling_treasure_test/table_structure_guard/seal_polarity_test 前置全绿。
|
||||
- [ ] 验证步骤:数据面窄确认(data_config+受涉 core 套件直跑全绿)+`D:/code/gdstyle/gdstyle.exe` 直扫五文件——17 键全部消失。
|
||||
|
||||
### T2 数据校验族·小表组+跨表校验器+解析器(8 文件 23 键,≈0.7d)
|
||||
|
||||
- [ ] board_gen_table:validate 拆 `func _validate_row(row: Dictionary, levels: Dictionary, anchor_ok: Dictionary) -> Array`;validate 本体留空表护栏+锚行尾段。
|
||||
- [ ] level_gen_params:validate 拆 `func _validate_row(row: Dictionary, seen: Dictionary, layers_by_level: Dictionary) -> Array`;本体留层深递进尾段。
|
||||
- [ ] meta_table:validate 拆 `func _validate_boss_keystone() -> Array`+`func _validate_conversion() -> Array`+`func _validate_attune_refresh() -> Array`;本体留三行族空护栏+顺序拼接。
|
||||
- [ ] skill_table:validate 拆 `func _validate_basic_row(sid: String, row: Dictionary, cd: int) -> Array`/`func _validate_damage_row(...)`/`func _validate_buff_row(...)`/`func _validate_debuff_row(...)`(同签名形态);本体留 seen/type 分派+普攻存在性+pity 尾段。
|
||||
- [ ] variation_table:validate 拆 `func _validate_row(row: Dictionary, seen: Dictionary) -> Array`;本体留互锁段(或并入 _validate_row——以分支 ≤8 为准)。
|
||||
- [ ] status_effect_table:validate 拆 `func _validate_magnitude_domain(row: Dictionary, eid: String) -> Array`(percent/flat/ac 三段量纲域)。
|
||||
- [ ] config_db_cross_validator:cross_validate 拆七编号块域——`func _cv_reward_dangling(st, rt, push_diag: Callable) -> void`/`func _cv_reward_treasure(st, rt, loaded: Dictionary, push_diag: Callable) -> void`/`func _cv_poolmap(st_tab, effect_ids: Dictionary, push_diag: Callable) -> void`/`func _cv_source_labels(st_tab, push_diag: Callable) -> void`/`func _cv_counter_closure(loaded: Dictionary, treasure_tab, feats_tab, push_diag: Callable) -> void`(①①b②③⑤⑥⑦对应;货架块 ⑥ 并入 _cv_reward_treasure 或独立 `_cv_shelf_pool`——以各件 ≤50 行/≤8 分支为准);validate_skill_pool_links 拆 `func _check_cast_side(skill_table: SkillTable, status_table: StatusEffectTable) -> Array`。
|
||||
- [ ] config_db_resolver:resolve_enemy_rowset 拆 `func _level_keys_of(rows: Array) -> Array[int]`+`func _band_keys_of(rows: Array, l_star: int, row_kind: String) -> Array[int]`+`func _band_rows(rows: Array, l_star: int, row_kind: String, d_star: int) -> Array[Dictionary]`(纯行扫描,告警发射序不变);_resolve_progress 拆 `func _depth_keys_of(rows: Array, l_star: int) -> Array[int]`+`func _missing_label(l_clamped: bool, d_clamped: bool, l_star: int, L: int, d_star: int, D: int) -> String`+`func _emit_missing_warning(table_id: String, missing: String, l_star: int, d_star: int, L: int, D: int) -> void`(去重注册表语义逐字)。
|
||||
- [ ] 验证步骤:数据面窄确认全绿(config_db_fatal_oob/counter_prefix_fatal/level_gen_params_test/config_db_resolver_test/config_db_cross_validator_test 等)+直扫八文件——23 键全部消失。
|
||||
|
||||
### T3 生成器族(2 文件 17 键,≈0.7d)
|
||||
|
||||
- [ ] board_generator:拆 `func _board_params(row: Dictionary, L: int, D: int) -> Dictionary`(:26-39 快照段——零 RNG);`func _populate_mines(b: BoardData, params: Dictionary, rng_stream: RandomNumberGenerator) -> int`(:93-127 布雷+剃雷段——Fisher-Yates 取号段整体搬迁,返回 ring_removed);`func _apply_single_rules(constraints: Array, r: Dictionary, known_mines: Dictionary) -> bool`+`func _derived_constraints(constraints: Array) -> Array`+`func _apply_derived_rules(derived: Array, r: Dictionary, known_mines: Dictionary) -> bool`(measure_inferability 的 single/subset 算子域——返回 changed,主循环序不变);`_finalize` 删 `_db` 形参(:336,调用点 :79 一处随动)。可核查结果:board_generator_test/board_gen_reward_test 全绿+同种子改前改后逐位一致断言绿(RNG 消费序冻结——契约 1②)。
|
||||
- [ ] node_map_generator:validate_output 拆六阶段域——`func _vo_node_fields(nodes: Array, errs: Array) -> Dictionary`(字段/dup/类型/深度,返回 {by_id, indeg, ok})+`func _vo_edges(nodes: Array, by_id: Dictionary, indeg: Dictionary, errs: Array) -> bool`+`func _vo_flow_facts(nodes: Array, indeg: Dictionary, errs: Array) -> Dictionary`(entries/terminals/Boss 终点判据)+`func _vo_depth_reach(nodes: Array, by_id: Dictionary, entries: Array, terminals: Array, errs: Array) -> bool`(最长路径+可达性)+`func _vo_shop_rules(nodes: Array, by_id: Dictionary, entries: Array, terminals: Array, errs: Array) -> bool`(摆放约束①+_all_paths_one_shop+_check_fork_rules)+`func _vo_count_rules(nodes: Array, params: Dictionary, by_id: Dictionary, entries: Array, terminals: Array, errs: Array) -> void`(多终点深度互异+宽度上限+参数档对照)——validate_output 本体=空图护栏+六阶段顺序调用+阶段间早退合并(返回 ≤6);check_params 拆 `func _cp_domain(params: Dictionary) -> Array`+`func _cp_structural(params: Dictionary) -> Array`;_build 拆 `func _build_region(rg: RandomNumberGenerator, r: int, e: int, t: int, prevs: Array) -> void`(区域段——_build 本体零 RNG,拆分自由);_add_forks 拆 `func _collect_fork_anchors(L: int, t: int, e: int) -> Array`(锚收集——零 RNG,shuffle 与扩岔循环留本体保取号序);_assign_types 拆 `func _fill_ratios(rg: RandomNumberGenerator) -> void`(e==1 配比填余段——shuffle+randf 取号序整体搬迁)+`func _fix_detour_heads() -> void`(岔口修型段——零 RNG);_check_fork_rules 拆 `func _fork_signature(outs: Array, by_id: Dictionary) -> Array`+`func _fork_has_unique(comps: Array, i: int) -> bool`(嵌套 5→≤4)。可核查结果:node_map_generator_test/node_map_growth_test/node_map_determinism_test 全绿+同参数同种子逐位一致(纯流取号序冻结)。
|
||||
- [ ] 验证步骤:核心面窄确认全绿+直扫两文件——17 键全部消失。
|
||||
|
||||
### T4 效果引擎(8 键,≈0.35d)
|
||||
|
||||
- [ ] rebuild 拆 `func _load_feat_triggers(feat_ids: Array) -> void`+`func _load_attune_triggers(item_ids: Array) -> void`+`func _push_tree_rules(tree_rules: Array) -> void`——**调用序=装载声明序 feats→treasure→tree 逐字**(契约 1④),sense_sharp/guard 双行 push 序随段整体搬迁。
|
||||
- [ ] _cond_ok 拆四算子域:`func _cmp_ok(op: String, actual: Variant, val: Variant) -> bool`(eq..lte 六比较)+`func _ends_with_ok(actual: Variant, val: Variant) -> bool`+`func _has_ok(c: Dictionary, actual: Variant) -> bool`+`func _counter_op_ok(ctx: EffectContext, c: Dictionary, op: String, actual: Variant) -> bool`(mod_zero/mod_eq/advantageous/gte_ref/lt_ref);_cond_ok 本体=fact/op/val 取值+分派+未知算子 assert(false)+return false(返回 ≤6、嵌套 ≤4)。语义逐字:判定结果与 unknown-op 致命路径零变化。
|
||||
- [ ] bucket_of 的 elif-after-return 收口(:207-214)→ 独立 if 序或 match——前缀判定序 round→lvl→adv→battle 缺省逐字(no-else-return 键消失)。
|
||||
- [ ] validate_trigger_row 拆 `func _vtr_when_keys(rid: String, tr: Dictionary, errs: Array) -> void`+`func _vtr_do_keys(rid: String, tr: Dictionary, row: Dictionary, errs: Array) -> void`——错误追加序逐字(:341-388 现序=trigger 键→on→when→do 键→kind→counter_id→value_from 双侧)。
|
||||
- [ ] 验证步骤:效果面窄确认全绿(effect_words_t1_test/tree_rules_v11_test/counter_prefix_fatal_test/adventure_feats_test/round_flow_skill_pool_test)+直扫——8 键全部消失。
|
||||
|
||||
### T5 存档域拆件——SlotStore/MetaStateStore 建件收编+save_manager 瘦身(≈1.5d)
|
||||
|
||||
- [ ] SlotStore 建件(K2′①):槽位族 10 方法+槽位态三成员随迁;`attach_path`/`attach_slot_template`/`activate_slot`/`create_slot` 的数据侧协作经 save 内部 _ 前缀协作家族(重置默认态/加载/写盘/回退四态),`delete_slot` 的 _remove_file 与 `_migrate_legacy_save` 的 `_copy_file` 随迁(槽文件域原语),`_rename_overwrite` 留 save_manager(IO 原语单点)经注入引用调用;save_manager._ready 旧单档迁移改调 slots 侧入口(幂等判据逐字)。可核查结果:save_boot_no_activate/save_slot_isolation/save_slot_summary 直跑全绿+grep 槽位族 10 名在 save_manager 零命中。
|
||||
- [ ] MetaStateStore 建件(K2′②):元进度族 35 收编为公开 19(写口原语 13+读投影 6)+_add_keystone 私有——投影按 K2′② 键构成逐字落地,值拷贝出户随迁;零 _data 副本零缓存。可核查结果:save_manager_domain/save_rng_roundtrip 直跑全绿+gdstyle 直扫两新件公开方法/类变量零 NEW。
|
||||
- [ ] save_manager 瘦身:断点族 4+load_from_disk/write_to_disk/register_migration 留置;读盘域提取 `func _load_parsed(f: FileAccess) -> bool`(:320-355 解析/版本/迁移/规整段——corrupt_fallback 调用点随段迁移,副作用序逐字)+`func _peek_migrated(parsed: Variant) -> Variant`(迁移循环提取,失败返回 null=现「返回未填充 out」逐字);load_from_disk 本体留文件存在分支+corrupt 委托(返回 ≤6);_init 组装 slots/meta_state 两成员。可核查结果:直扫 save_manager 公开方法 52→7、_peek_summary_at 返回 7→≤6、load_from_disk 返回 8→≤6。
|
||||
- [ ] 存档族改址(≈450 处):槽位族 →`save.slots.`(≈110 处——呈现 ≈12/探针 ≈17/测试 ≈77);元进度族 →`save.meta_state.`(≈340 处——读面 tree_level/forge_route_level/clear_count 等随投影改形为 `.tree_state().nodes.get(...)` 等同值读);断点族零改址。可核查结果:改址后 save 断言面全套直跑全绿(T0 留档套件清单)+grep 五组前缀零漏改。
|
||||
- [ ] 验证步骤:存档面窄确认全绿(save_manager_domain/save_slot_isolation/save_slot_summary/save_boot_no_activate/breakpoint_resume/save_rng_roundtrip+integration 三件+probe 直跑)+直扫三文件——save_manager 52→7、新件零 NEW。
|
||||
|
||||
### T6 meta_progression 瘦身+status_container/treasure_items 拆分(≈0.7d)
|
||||
|
||||
- [ ] meta_progression 瘦身(K3′):纯转发退役 2+内联 3(hero_override 输出逐字)+私 3(含 forge_route_unlocked)+并组 3 组+`meta_state` 成员装配;本类数据读写全部改经 meta_state(读投影同值改形)。可核查结果:tree_requires_level_test/meta_progression_forge_test 改址后全绿+grep 纯转发零残留(`save.keystone_balance`/`save.item_unlocked` 在本文件零命中)+直扫公开方法 31→20、tree_can_buy 返回键 ≤6。
|
||||
- [ ] 树购买真链验证:tree_buy→meta_state.set_tree_level→write_to_disk→重读读回的真链断言改址保持(tree_requires_level_test 购买/cap/门槛判据逐字)。可核查结果:真链断言绿。
|
||||
- [ ] status_container:apply_effect 按「三臂语义逐字+公共尾部收口」重构——守卫两 return 保留,independent/refresh/stack 三臂与未知 policy 告警保持现行为(independent 恒追加/refresh 命中改 R 未命中追加/stack 满层拒零写入·未满加层·未命中追加/未知 policy 告警拒),追加尾部收口单点;`_new_instance` 签名改 `func _new_instance(effect_id: String, layers: int, dur: int, source: Dictionary, snap: Dictionary) -> Dictionary`(7→5 参,snap={m, unit, display})。可核查结果:seal_polarity/roll_multiplier/damage_controller/system_contracts 四套件全绿(满层拒绝/空刷新/快照语义现役断言面)。
|
||||
- [ ] treasure_items:validate_use 拆 `func _spatial_reject_reason(row: Dictionary, kinds: Array, target: Vector2i, board_size: Vector2i) -> String`+`func _window_cells(target: Vector2i, board_size: Vector2i) -> Array`+`func _preview_window_dead(resolved: Array, cell_unrevealed_cb: Callable) -> bool`。可核查结果:treasure_items_test 全绿。
|
||||
- [ ] 验证步骤:受涉套件窄确认全绿+直扫三文件——8 键消失+meta_progression 公开方法 31→20 读数记录。
|
||||
|
||||
### T7 config_db 归位+域容器(≈1.4d)
|
||||
|
||||
- [ ] 三容器建件(K1′①):ConfigDomainCombat/Run/Crossrun(Resource、类型化成员、零方法)+config_db 三容器成员替换 19 表成员+load_tables 装配段改写(loaded→容器成员)。可核查结果:三新件直扫类变量 7/7/5 零 NEW。
|
||||
- [ ] 访问器归位(K1′②):溶解 16+迁移 14+委托 3——迁移面按映射表入 shop_table(7 方法)/meta_table(2)/forge_table(3)/variation_table(2);三表收 resolver 注入成员(类变量 1→2);命名避开表类既有成员名(K1′② 映射表——routes 属性在册故 route_rows() 等)。可核查结果:受涉表类直扫公开方法/类变量零 NEW+resolver 文件零 diff(键原位核验)。
|
||||
- [ ] 删 2+私 1(K1′③④):meta_conversion_row/forge_weapon_route_by_type 删除+validate_skill_pool_links 私有化。可核查结果:grep 两删除名零命中。
|
||||
- [ ] 全域改址(≈800 处):`db.<表>`→`db.<容器>.<表>`(537)+访问器→表类直连/归位新名(264)——按映射表机械替换+逐文件复核;诊断/门控保留核验:push_diag/is_fatal/diagnostics 族/reset_diagnostics/set_reload_gate/reload 与 EC8 门语义逐字(reload_gated 拒绝路径现役断言)。可核查结果:data_config 八套件+core 直引 12 文件改址后全绿(行数据逐字断言=表值等价载体)+config_db_fatal_oob/level_shop_economy/forge_table_test/table_structure_guard/config_db_test 全绿+直扫 config_db 44→8、25→9。
|
||||
- [ ] 验证步骤:数据面+核心面窄确认全绿+`db.combat.`/`db.run.`/`db.crossrun.` 前缀 grep 抽检(每容器 ≥5 文件零旧形态残留)。
|
||||
|
||||
### T8 adventure_table 拆段+.tres 等值迁移(≈0.4d)
|
||||
|
||||
- [ ] 三段件建件(K4′):AdventureQuotaSegment/Value/CapSegment(段内槽名逐字)+宿主 3 段成员+访问器改读段(签名与返回语义逐字)+validate() 判据经访问器读数不变。可核查结果:段件直扫类变量 13/13/9 零 NEW+宿主 44→12。
|
||||
- [ ] adventure.tres 等值迁移:36 在册标量值逐槽照抄入嵌套段 sub_resource(单 .tres 保持);缺省槽不写入=缺省语义保持。可核查结果:deck_total()=102 结构锚断言绿+adventure_feats/pool_case_d/feat_vouchers/table_structure_guard 全绿+表值逐字对拍(改前改后 curio_quota/curio_value/curio_cap 全 13×4+13×4+9 组合读数零差异——T0 留档读数)。
|
||||
- [ ] 测试改址 4 处(pool_case_d_test :164/:165/:190 段路径读写、adventure_feats_test :206 段路径读)。可核查结果:改址断言绿。
|
||||
|
||||
### T9 散条组——action_economy/reward_economy/minesweeper_rules/unit_container spawn 束(≈0.6d)
|
||||
|
||||
- [ ] action_economy:K5 三件(删 _next_round_mode 死存储+_ap_exhausted_last 派生合并+last_round_end 属性→方法)+minesweeper_rules.gd:495 改址一处。可核查结果:minesweeper_rules_test/round_flow_skill_pool_test 的 round_end 载荷断言全绿(ap_exhausted_last_round 派生读等值——一滴不剩 when 面现役断言)+直扫类变量 18→15。
|
||||
- [ ] reward_economy:拆 `func _normalize_eligible(eligible: Array) -> Array`(:42-52 去重/排序段——开流前,零 RNG 风险)+`func _skew_amounts(down: Array, up: Array) -> Array`(两次 _largest_remainder_split 调用段)+`func _apply_skew(base: Array, down: Array, up: Array, drops: Array, gains: Array) -> Array`(权重装配段——守恒 assert 随段迁移)。可核查结果:board_gen_reward_test/seal_polarity_test 前置全绿+roll_board 取号序冻结(同种子身份批/清图批尾/区间行逐位一致——现役 reward_roll 流断言)。
|
||||
- [ ] minesweeper_rules:拆 `func _reveal_chain(c: Vector2i, reveal_order: Array, was_sealed: bool) -> void`(:301-329 揭示循环段——cell_revealed 发射序即链序,整体搬迁)。可核查结果:minesweeper_rules_test 全绿(cell_revealed 事件序现役断言)。
|
||||
- [ ] unit_container spawn 束化(K6′):签名改 `func spawn(req: Dictionary) -> bool`(束键封闭词表逐字)+体内拆 `func _spawn_hero_unit(hero_hp: int, atk_override: int, max_hp_override: int, hero_attack_type: String, hero_armor_type: String) -> bool`+`func _spawn_rowset(rowset: Array, unit_count_overrides: Array, enemy_atk_overrides: Array, hp_mult: float, atk_mult: float) -> bool`(英雄段/行集段随分;束键解包留本体)。调用点改址 11 处 7 文件(battle_orchestrator 调用点按卡①合回后形态+测试 10 处束字面量构造)。可核查结果:damage_controller/roll_multiplier/round_flow_skill_pool/skill_unlock/level_shop_economy 前置全绿+grep `\.spawn(` 调用点全束形零旧签名残留+直扫 spawn 参数键消失(长度/局部两键随体内拆分消失)。
|
||||
- [ ] 验证步骤:受涉套件窄确认全绿+直扫四文件——上述键全部消失。
|
||||
|
||||
### T10 读数对拍+撤销证明+产出物落位卡(≈0.55d,末卡)
|
||||
|
||||
- [ ] 改后 `python tools/gdstyle_gate.py` 对拍:基线外 NEW=0(含 8 新件——新件键账表逐件核验)、恶化=0、在案键计数较改前下降 86(86 键消失清单写进实现报告,零残留申报)。可核查结果:读数对拍表在案。
|
||||
- [ ] 逐 wr 行撤销证明(§8.1 末列——回退对应文件 hunk→gdstyle 直扫该键重现或改址断言红→还原复绿),记录进实现报告。
|
||||
- [ ] 写齐三份产出物(实现报告〔86 键清偿清单+新件键账表+五组改址计数实绩+读数对拍表+实机目检总清单——启动冒烟实机一屏登记(行为零变化批,登记不阻塞)〕/代拍板追认单/反哺点清单〔§6 逐条落点〕)。
|
||||
- [ ] 合并前置:独立验收审计(§8.3)逐行「通过」。
|
||||
|
||||
**估时合计 ≈7.9d**(区间 7.4–8.4:T0 0.3/T1 0.7/T2 0.7/T3 0.7/T4 0.35/T5 1.5/T6 0.7/T7 1.4/T8 0.4/T9 0.6/T10 0.55;扩容主因=K1′ 改址 ≈800 处〔T7〕、K2′ 拆件与改址 ≈450 处〔T5〕、K3′ 瘦身与投影改形〔T6〕、K4′ 拆段与 .tres 迁移〔T8〕、K6′ 束化〔T9〕——五组改址合计 ≈1330 处,机械替换+逐文件复核计价)。
|
||||
|
||||
### T 卡间接口
|
||||
|
||||
- **取用与先后**:T5 先于 T6(meta 瘦身的读写面以 MetaStateStore 在位为前件);T1–T4/T7/T8/T9 各自文件域独立、零相互取用(T7 与 T9 同触 minesweeper_rules.gd :495 仅 K5 改址一处——同卡内先 T7 后 T9 或一次性完成);T10 取用各卡读数记录。
|
||||
- **产出**:T5 产出 SlotStore/MetaStateStore 公开面与投影键构成(K3′/反哺点③改写依据);T6 产出 meta 封闭面 20 清单与 tree_can_buy 公开在位凭据;T7 产出三容器成员分组与 K1′ 归位映射落地形(反哺点③依据);T8 产出段路径形态(反哺点②依据);T9 产出 spawn 束键词表(卡①/卡③ T0 对齐依据)。
|
||||
|
||||
## 8. 验证闸
|
||||
|
||||
### 8.1 改动—验收对照表
|
||||
|
||||
| 需求点 | 改动(文件:行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销证明 |
|
||||
|---|---|---|---|---|---|
|
||||
| wr1 校验族大表组 17 键 | 五 schema validate 拆分 | data_config+core 受涉套件直跑全绿〔现役错误清单断言面=逐字等价载体〕+gdstyle 直扫五文件键消失 | 单元 | ConfigDb.load_tables 真实加载入口(套件经 _ready/load_tables 驱动) | 回退该文件 hunk→gdstyle 直扫该键重现→还原复绿 |
|
||||
| wr2 校验族小表组+跨表+解析 23 键 | 八文件拆分 | 同上形态(八文件受涉套件)+直扫键消失 | 单元 | 同上 | 同上 |
|
||||
| wr3 生成器族 17 键 | board 四域拆+_finalize 5 参+node 六阶段拆 | board_generator_test/board_gen_reward_test+node_map 三件全绿+同种子逐位一致(T0 基线对拍) | 单元+集成 | generate 真实调用(表驱动+rng_stream 注入)/generate(参数档, 种子) 纯函数入口 | 回退 hunk→同种子对拍失配或直扫键重现 |
|
||||
| wr4 effect_engine 8 键 | 三装载域+四算子域+两键域+elif 收口 | effect_words_t1/tree_rules_v11/counter_prefix_fatal/adventure_feats/round_flow_skill_pool 全绿(装载序/词表/计数器面现役断言) | 单元 | rebuild→dispatch 真实战斗链 | 回退 hunk→直扫键重现 |
|
||||
| wr5 save 读盘域+status/treasure 拆分 | _load_parsed/_peek_migrated 提取+apply_effect 收口+validate_use 拆三 | save_manager_domain/save_slot_summary/seal_polarity/roll_multiplier/damage_controller/system_contracts/treasure_items_test 全绿 | 单元 | autoload _ready+套件真实驱动 | 回退 hunk→直扫键重现 |
|
||||
| wr6 存档域拆件 K2′ | SlotStore/MetaStateStore 建件+save 52→7+状态分家+改址 ≈450 | save 断言面全套直跑全绿(**存档读写逐位断言**=save_rng_roundtrip roundtrip 键集逐位+save_manager_domain 写读回等价,改址后判据逐字)+**原子写/无激活态拒写/高版本拒读/激活回退四态**现役断言改址保持+grep 槽位族/元进度族方法名在 save_manager 零命中+直扫新件零 NEW | 单元+探针 | SaveManagerCore autoload _ready 真实装配+套件直构实例经 save.slots/save.meta_state 真链驱动 | 回退 hunk→改址断言红(save.slots 成员不存在=脚本错误被闸③捕获)或直扫键重现 |
|
||||
| wr7 meta_progression 瘦身 K3′ | 纯转发退役 2+内联 3+并组 3+私 3+留置 20 | tree_requires_level/meta_progression_forge 改址后全绿(**树购买真链断言**=tree_buy→set_tree_level→write_to_disk→重读读回真链)+hero_override 输出逐字断言绿+grep **纯转发零残留**(save.keystone_balance/save.item_unlocked 在本文件零命中)+直扫 31→20、tree_can_buy 返回键 ≤6 | 单元 | meta.tree_buy/forge_buy_level 真实购买链(camp 投影数据源同链) | 回退 hunk→改址断言红或直扫公开方法键回 31 |
|
||||
| wr8 config_db 归位+域容器 K1′ | 3 容器建件+33 归位+删 2 私 1+改址 ≈800 | data_config 八套件+core 直引 12 文件改址后全绿(**行数据逐字断言**=表值读数等价载体)+**消费改址断言**(config_db_test/forge_table_test/level_shop_economy/table_structure_guard/config_db_resolver_test 全绿)+grep 两删除名零命中+reload/EC8 门保留断言绿+直扫 44→8、25→9、新件零 NEW | 静态+单元 | load_tables 真实加载入口+resolve_rowset 消费链(unit_container spawn 前置) | 回退 hunk→改址断言红(db.combat 成员不存在)或直扫键回 44/25 |
|
||||
| wr9 adventure_table 拆段 K4′ | 3 段件+.tres 等值迁移+访问器改读段+4 处改址 | adventure_feats/pool_case_d/feat_vouchers/table_structure_guard 全绿+**deck_total()=102 结构锚+表值逐字**(T0 留档全组合读数零差异)+validate 绿+直扫 44→12、段件零 NEW | 单元 | 表加载→访问器读数真实链 | 回退 hunk(含 .tres)→改址断言红(段路径不存在)或直扫键回 44 |
|
||||
| wr10 散条组 K5+reward/minesweeper 拆分 | action 删并+两文件域拆 | minesweeper_rules_test/round_flow_skill_pool round_end 载荷/reward_roll 流序全绿 | 单元 | 各系统真实调用链 | 回退 hunk→对应断言红(last_round_end() 方法不存在/取号序失配/事件序失配)或直扫键重现 |
|
||||
| wr11 spawn 束化 K6′ | 签名 10→1+体内两域拆+调用点 11 处改址 | 前置五套件全绿+**调用点断言**(grep `\.spawn(` 全束形零旧签名残留)+直扫参数键消失 | 单元 | battle_orchestrator begin_battle 真实遭遇链 | 回退 hunk→调用点 grep 现旧形(断言红)或直扫键重现 |
|
||||
| wr12 读数对拍+产出物 | T10 | 读数对拍表+三份产出物件核〔wr12〕 | — | — | 缺项红 |
|
||||
|
||||
回归措辞:里程碑步(T 卡)出口跑一次全套闸(按本批改动域选档 `--code`);卡内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。本批零新增测试断言(现役断言面即验收载体;grep 形判据为静态在位核验,非新运行时断言)。
|
||||
|
||||
### 8.2 测试削弱申报
|
||||
|
||||
零(无断言删除、无阈值放宽、无扫描面缩小;全部测试改动=K1′–K6′ 列明的调用点改址与投影同值改形,断言语义与判据逐条保持——契约 2)。
|
||||
|
||||
### 8.3 独立验收审计
|
||||
|
||||
入口=未参与实现的会话或子代理;报告落 `reports/iter<N>-验收审计-<日期>.md`;抽查重点=①错误清单逐字等价(任选三 schema 改前改后坏表对拍读数)②生成器同种子逐位一致记录③效果引擎装载序与词表零 diff(git diff 查 EVENTS/EFFECT_KINDS/FACTS/OPS 四常量)④归位映射抽检(每容器 ≥3 处行数据逐字+K1′ 溶解/迁移/委托三形态各 ≥2 处)⑤拆件抽检(save roundtrip 逐位读数+激活回退四态断言+纯转发零残留 grep 复跑)⑥拆段表值逐字(全组合读数对拍)⑦新件键账零 NEW(gdstyle 直扫 8 新件)⑧S13 基线未改(git diff 查 `tools/gdstyle_baseline.txt` 零变化)⑨改址抽检(五组各 ≥3 处断言语义等价)⑩撤销证明复现⑪拆分边界抽检(契约 7:新件/段件/拆分族职责语句逐件在案,抽 3 件核「单一变化原因+集体身份」两判据,凑计数袋形态即红)。未过不得合并。
|
||||
|
||||
## 9. 异常分级
|
||||
|
||||
- **L1(自救)**:行号漂移(T0 重锚自核);私有 helper 与投影内部实现的命名与注释措辞(投影键构成与公开签名不属此列);拆分域边界微调(各件 ≤阈值前提下)。
|
||||
- **L2(记录继续)**:五组改址中发现清单外调用点(同法改址+计数记录进实现报告);束键解包的等价实现细节;段件/容器成员的 @export 形态细节(类型化成员语义不变前提下)。
|
||||
- **L3(停机呈报)**:任何断言红且非测试问题;拆分后错误清单与改前不等价;RNG 取号序失配;存档读写逐位不等价或原子性语义漂移;归位后表读取语义漂移(空表护栏/缺省兜底);发现触碰 GDD/owner 契约的病根(停卡呈报,禁内联求裁);新件或留置面超阈(封闭面破坏——契约 3);K 清单外须动公开面的场景(实现段零裁断——退回上游);拆分边界无职责语句可陈述或凑计数袋形态(契约 7——停卡呈报走豁免/还债通道)。
|
||||
|
||||
## 10. 代拍板白名单(超清单必呈报)
|
||||
|
||||
1. 私有 helper 的命名与注释措辞(语义不变前提下)。
|
||||
2. 拆分域边界的等价微调(各件 ≤阈值、错误序/RNG 序不变前提下)。
|
||||
3. 五组改址的等价调用写法(访问路径等价、断言语义不变前提下)。
|
||||
4. 归位方法在表类侧的等价命名微调(避开既有成员名、映射语义不变前提下)。
|
||||
5. 提交切分与 worktree 分支命名。
|
||||
|
||||
## 11. 待裁点(零待裁点)
|
||||
|
||||
**零待裁点(2026-10-27 用户裁决记录:①config_db 彻底清零=归位+域容器 ②save/meta 彻底清零=SlotStore/MetaStateStore 拆件)**。随裁记录全四项:③adventure_table 类变量 44 拆子 Resource 段(形态同 settlement_table 拆段);④unit_container spawn 参数签名引用束化。裁决落点:v1.0 裁点 1 的案 B 走向=归位+域容器 Resource(非词典化形态,D7);v1.0 裁点 2 的案 B 走向=域对象拆件经设计段先行定稿(架构 v1.19 :88/:89/:90/:126 四行登记)后扩入本卡。开工门=U0+复核门(§12)。
|
||||
|
||||
## 12. 自审六查与复核记录
|
||||
|
||||
**自审六查(2026-10-27 修订会话,grilling 自检一轮合并执行——对抗审点逐条过并就地折入)**:
|
||||
- ①规格覆盖:86 键逐文件→T1–T9(大表组/小表组/生成器/效果引擎/存档拆件/meta 瘦身/config_db 归位/拆段/散条与 spawn)→wr1–wr11,读数与产出物→T10/wr12;全清账目闭合(86=65 拆分+21 结构收敛;留置 8+归位 33+删 2+私 1=44、槽位 10+元进度 35+断点 4+IO 3=52、31−11+3=20);K1′–K6′ 公开面改动逐项有改法+映射+消费方影响面+封闭面预演值。**折入**:修订会话实查订正 v1.0 两处实查笔误——meta_progression 三件「内部零调用」实为 hero_override 单调用点(处置由删改内联、输出逐字)、adventure_table「37 个 @export」计法订正为 44(账目不变)。
|
||||
- ②步骤扫描:每步一动作一可核查结果(拆分步挂「受涉套件绿+直扫键消失」双结果;建件步挂「键账零 NEW+断言改址绿」双结果);无 TBD/酌情行;实现体零抄写(helper 只给签名与域边界)。
|
||||
- ③类型一致性:K1′ 归位映射表与 T7 步骤逐字一致;K2′ 两 store 公开面清单(13 写+6 投影/10 槽位)与 §3.5 预演值、T5 步骤逐字一致;K3′ 封闭面 20 清单与 T6 步骤逐字一致;K4′ 段件键名与宿主访问器签名逐字一致;K6′ 束键词表与 T9 步骤逐字一致;wr 行与 T 卡引用对得上;投影返回键构成在 K2′②/K3′ 两处表述同文。
|
||||
- ④审查焦点+改动覆盖:最可能坑到玩家的失败模式=①错误清单不等价(fail-fast 面变形)→ 现役 data_config 断言面逐字保留+审计①对拍;②RNG 取号序漂移 → 契约 1②+T3/T9 同种子对拍;③效果引擎装载序漂移 → 契约 1④+T4 调用序钉死+审计③四常量零 diff;④存档盘面语义漂移(原子写/回退/迁移链)→ 契约 1⑥+wr6 逐位与四态断言+审计⑤;⑤拆段 .tres 迁移值错位 → 等值迁移+deck_total=102+全组合读数对拍+审计⑥;⑥归位后空表护栏/缺省兜底漂移 → 契约 6 口径+K1′⑤ 注记+审计④。结构图中全部行为改动行=「非行为」并指到 wr 行——**查毕确认零行为改动、无未覆盖失败模式**。
|
||||
- ⑤篇幅比例:全文无函数体,helper 为签名+域边界;§3 现状表为键账载体非抄写;映射表为改址合同非代码罗列。
|
||||
- ⑥落位与复用:新件 8 逐件「为什么不能复用既有」有答(God Class 本体不可复用其内部结构——§7 预检)+架构 v1.19 行指针(:88/:89/:90+段件形态既裁);唯一面(新件类名 grep 零同名+跨文件同名私有方法类作用域不冲突)与分层面(零新跨层路径、零 autoload、S1–S6 逐项过)已答;K1′–K6′ 每项公开面改动可指到预检节条目;新件封闭面逐件给出与阈值的余量(19/20、10/20、7·7·5/15、13·13·9/15、留置 20/20——20/20 与 15/15 均循卡①「封闭面 15≤15」先例,架构 :126 对外暴露列即封闭依据)。
|
||||
|
||||
**grilling 自检一轮结论(写卡段内自检,独立复核门仍须在开工前由用户/独立会话执行)**:骨架成立——全清账目闭合、零待裁点、新件封闭面全部可达阈内、行为零变化契约族完备(含存档序列化第六款)。对抗审点七条全折入:①MetaStateStore 35 原语直收将出 NEW 键(35>20)→ 读投影 6+写原语 13=19 收敛(架构 :90「数据读写原语族+只读投影」即此形态,K2′②);②meta_progression 按 v1.0 K3 算法只到 24/25,到不了 20 → 并组 3 组+forge_route_unlocked 私有化补齐 20(消费面 grep 逐方法核验——生产零者才私);③tree_can_buy 按 v1.0 应私有、但 v1.19 :126 对外暴露列在册 → 留公开、测试 8 处零改址(随 K3′ 记录);④resolver 文件键函数禁搬移 → resolve 委托注入形态(文件零搬移、T2 照旧);⑤shop_table/forge_table 归位方法与既有属性同名冲突(routes/products 等)→ 映射表改名(gp_drop_row/route_rows/product_rows 等);⑥db.adventure 表与容器命名的双层同名风险 → 容器名 combat/run/crossrun 三名全避让(成员名零碰撞——grep 零命中);⑦改址量重估:v1.0 口径 139 处 → 实查五组 ≈1330 处(估时 4.9→7.9d 如实上调)。遗留提示三件随卡在案:①估时超迭代冻结线——编入时循迭代 39 特批先例由用户裁;②本卡与卡③呈现侧改址行同文件触碰——编排错波;③main.save_manager 句柄面改址不新增句柄成员——:183 豁免面不扩大(审计⑧随核)。
|
||||
|
||||
## 13. 禁为机检文本保留无效成员(重构类必填条款)
|
||||
|
||||
禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名/死存储/转发壳:本批删除的 `_next_round_mode` 死存储与 K1′ 两访问器、K3′ 两纯转发即该契约的执行例——不得以「基线计数」「兼容过渡」「调试便利」等理由保留任何在删清单成员、新增同种件或在退役点留同名转发;新件公开面=K 清单封闭面(MetaStateStore 19/SlotStore 10/meta_progression 20/config_db 8),禁为凑数或过渡加别名与委托壳;机检键与卡片契约互斥时实现段一律停卡呈报,不得自造第三条路(code-conventions §1.1 同款)。
|
||||
+3
-6
@@ -5,8 +5,8 @@
|
||||
## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照)
|
||||
|
||||
- **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。
|
||||
- **迭代位**:迭代 1–41 全部已完成——迭代 41 两卡(核心数据面结构收敛批+呈现层结构收敛批)2026-10-29 合回(合并提交 eb9bb537,测试特许移交+用户裁直接合回),同日完成批后收尾(反哺点落文+产出物退役+账面换代)。
|
||||
- **下一步**:待编池:营地交互重做卡⑤(排卡④之后)、卡④(已退回美术设计段,美术设计闭合后重立卡)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(2026-10-17 已剔出迭代 30 规划、退回待设计,待美术/设计定稿后重新立卡)。批后可裁事项:gdstyle 基线 152 死键 refresh 清账(`python tools/gdstyle_gate.py --refresh`,待办清单在册)——用户发令时机。
|
||||
- **迭代位**:迭代 1–40 全部已完成——迭代 40 两卡 2026-10-28 合回(合并提交 514457d1,用户特许免闸直合),同日完成批后收尾(反哺落文 13 条+产出物退役+账面换代)。
|
||||
- **下一步**:迭代 41 已编两卡(核心数据面结构收敛批+呈现层结构收敛批,≈13.15 个工作日〔用户特批 2026-10-27 超 10 个工作日〕)——待开工,实现段由用户以 /iter 41 发令(开工前固定动作波 0 gdstyle 基线刷新已于 2026-10-28 执行销号)。待编池:营地交互重做卡⑤(排卡④之后)、卡④(已退回美术设计段,美术设计闭合后重立卡)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(2026-10-17 已剔出迭代 30 规划、退回待设计,待美术/设计定稿后重新立卡)。
|
||||
|
||||
## 里程碑时间线
|
||||
|
||||
@@ -74,14 +74,11 @@
|
||||
| 迭代 38 | 已完成(2026-10-26) | 已退役(git 历史可考) | 2026-10-26 | ≈5.225 个工作日 | 已退役(git 历史可考) |
|
||||
| 迭代 39 | 已完成(2026-10-27) | 已退役(git 历史可考) | 2026-10-26 | ≈10.15 个工作日〔用户特批 2026-10-26 超 10 个工作日〕 | 已退役(git 历史可考) |
|
||||
| 迭代 40 | 已完成(2026-10-28) | 已退役(git 历史可考) | 2026-10-27 | ≈6.375 个工作日 | 已退役(git 历史可考) |
|
||||
| 迭代 41 | 已完成(2026-10-29) | 已退役(git 历史可考) | 2026-10-27 | ≈13.15 个工作日〔用户特批 2026-10-27 超 10 个工作日〕 | 已退役(git 历史可考) |
|
||||
| 迭代 42 | 待开工 | reports/需求卡片-gdstyle尾波清偿批-2026-10-29.md<br>reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md | 2026-10-29 | ≈5.375 个工作日 | — |
|
||||
| 迭代 43 | 待开工 | reports/需求卡片-战斗一屏样张批-2026-10-28.md | 2026-10-29 | ≈6.5 个工作日 | — |
|
||||
| 迭代 41 | 待开工 | reports/需求卡片-核心数据面结构收敛批-2026-10-27.md<br>reports/需求卡片-呈现层结构收敛批-2026-10-27.md | 2026-10-27 | ≈13.15 个工作日〔用户特批 2026-10-27 超 10 个工作日〕 | — |
|
||||
|
||||
- 迭代 38 收口为带红合并〔用户特批 2026-10-26〕:09 静态扫描 S13 gdstyle 恶化 2 条经批准记入基线存量红(git 提交 c4c69701),卡② 停卡退上游,处方已于 2026-10-26 修订定稿 v1.3(git 提交 b3ea7532),随「gdstyle 存量债全量清偿」条目波 7 待编排。
|
||||
- 迭代 39 收口为带红合并〔用户特批 2026-10-27〕:02 EV 锚 goblin 0.9148∉[1.00,1.20](触发器批有意行为改动,fp f74b9a48ef4a)已随 EV 锚重锚批换带归绿(git 提交 ba5105aa);08d 生涯.md:55 行号漂移已随 2026-10-28 批后收尾反哺落文修复归绿。三卡拆分后终局 gdstyle 恶化 2 条(battle_orchestrator max-file-length、level_map_screen max-class-variables)归迭代 40 卡①还债与迭代 41 存量债序列。
|
||||
- 迭代 40 收口为用户特许免闸直合〔2026-10-28〕:全量域验收回执未取得(回执环节断于用户特许,验收审计报告如实记档不作绿报;独立审计结论=通过,F1 一行修 iter40 8a319369 先行入库)。卡① 契约 2 宿主行数残余债(实测 1036 行,合并适配带入 36 行)经用户裁登记归后续批清偿(待办清单「战斗域结构深拆批」条目承载);09 存量红剩 level_map_screen 类变量一条归迭代 41 卡③。
|
||||
- 迭代 41 收口为测试特许移交+用户裁直接合回〔2026-10-28/2026-10-29〕:全部套件与闸停跑(gdstyle 结构闸除外——开发期读数反馈在跑),验收断言、golden 对拍与独立验收审计一并移交用户执行,2026-10-29 用户裁直接合回(合并提交 eb9bb537);golden 改前锚未建让步与四项实机目检已迁体验验证清单 ㊵;gdstyle 基线 152 死键 refresh 待用户发令(待办清单在册)。
|
||||
- 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。
|
||||
- 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。
|
||||
- 新迭代行的编排与各列判据见 doc-conventions §12.2 与 iter-plan 技能,由流水线闸(`tools/pipeline_gate.py`)机检。
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
r"""capability_audit.py — 能力清单、覆盖域表与 GDD 纯度机检(文档域闸件)
|
||||
|
||||
职责(test-conventions §8.9 三层模型的机检半边;规则正文=test-conventions §8.3+§8.9+doc-conventions §5):
|
||||
A 文档纯度:design/gdd 全树现行文档禁写实现细节——代码路径(.gd/.py/.sh)、测试文件名、断言名、
|
||||
反引号包裹的调用形态(`名字(...)`);唯一例外=配置文件索引(.tres 表路径与表名)。围栏代码块内不扫。
|
||||
B 验收标准:design/gdd/systems/** 每篇须有非空的「## 验收标准」节(豁免件具名在册,附理由)。
|
||||
C 能力行结构:game/tests/README.md 能力表四列齐、逐行四格非空。
|
||||
D 代表用例可核(双通道):能力行「代表用例」的每条 `文件:函数`——代码在(文件在 run_all.gd 套件
|
||||
manifest 内且该文件有 `func 函数名(`)或卡在(该文件名或函数名能在 reports/需求卡片*.md 中找到,
|
||||
供写卡时当场入表的计划用例锚定);两头都无=红(清单挂了无凭证义务)。
|
||||
E 真实入口可核(双通道):能力行「真实入口」的每个 `类.方法()`——产品码(game/ 除 tests//probe//sim/)
|
||||
有 `func 方法(`,或该方法名能在 reports/需求卡片*.md 中找到(计划入口同 D 口径);两头都无=红。
|
||||
F 覆盖域表:systems 每篇一行;状态∈{已覆盖,部分覆盖,未覆盖};非未覆盖行的「能力行」非空且每项都能
|
||||
对上能力表里的行名;部分/未覆盖行的缺口非空且指待办清单。
|
||||
条件闸行豁免(代表用例含「条件闸」字样)不参与 D/E。
|
||||
|
||||
自检四道(防扫描面空转假绿):系统文档数、能力行数、manifest 套件数、覆盖表行数任一为零 ⇒ exit 2。
|
||||
|
||||
用法:
|
||||
python tools/capability_audit.py # 报告模式(红项只打印,不改退出码)
|
||||
python tools/capability_audit.py --strict # 有红项时 exit 1(供门禁)
|
||||
exit:0=绿/1=有红项(--strict)/2=扫描面异常
|
||||
"""
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parents[1]
|
||||
GDD_DIR = REPO / "design" / "gdd"
|
||||
SYS_DIR = GDD_DIR / "systems"
|
||||
README = REPO / "game" / "tests" / "README.md"
|
||||
RUN_ALL = REPO / "game" / "tests" / "run_all.gd"
|
||||
CARDS_DIR = REPO / "reports"
|
||||
|
||||
PURITY_RE = re.compile(r"\.(gd|py|sh)\b")
|
||||
ASSERT_RE = re.compile(r"check_quiet\s*\(|\bcheck\s*\(")
|
||||
CALL_FORM_RE = re.compile(r"`[A-Za-z_][A-Za-z0-9_.]*\s*\([^`]*\)`")
|
||||
FENCE_RE = re.compile(r"^\s*```")
|
||||
|
||||
CAP_COLS = ("能力", "系统", "真实入口", "代表用例")
|
||||
COV_COLS = ("系统文档", "能力行", "状态", "缺口")
|
||||
STATUS_VALUES = ("已覆盖", "部分覆盖", "未覆盖")
|
||||
|
||||
# 验收标准节豁免:无可写验收面的在册件(逐件附理由;新豁免须经用户裁)
|
||||
ACCEPT_EXEMPT = {
|
||||
"锻造工坊.md": "工程化系统,验收面由天赋树与元进度两篇承接,本批迁移实现事实后复核",
|
||||
"生涯.md": "P6 后置未实装,无现成可观测面;实装批补验收标准节",
|
||||
}
|
||||
|
||||
CASE_RE = re.compile(r"([A-Za-z0-9_\-]+\.gd):([A-Za-z_][A-Za-z0-9_]*)")
|
||||
ENTRY_RE = re.compile(r"([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)\s*\(\)")
|
||||
|
||||
reds = []
|
||||
selfcheck = []
|
||||
|
||||
|
||||
def red(path, line, check, msg):
|
||||
reds.append((str(path), line, check, msg))
|
||||
|
||||
|
||||
def read(path):
|
||||
return path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def cells(raw):
|
||||
return [c.strip() for c in raw.strip().strip("|").split("|")]
|
||||
|
||||
|
||||
def is_sep(cs):
|
||||
return all(set(c) <= set(":- ") for c in cs if c)
|
||||
|
||||
|
||||
def tables(lines, required):
|
||||
"""产出国标表格:(header_cells, [(源行号, cells)]),表头须含 required 全部列关键词。"""
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
if lines[i].strip().startswith("|"):
|
||||
block = []
|
||||
j = i
|
||||
while j < len(lines) and lines[j].strip().startswith("|"):
|
||||
block.append((j + 1, lines[j]))
|
||||
j += 1
|
||||
if len(block) >= 2:
|
||||
header = cells(block[0][1])
|
||||
if all(any(req in c for c in header) for req in required):
|
||||
rows = []
|
||||
for no, raw in block[1:]:
|
||||
cs = cells(raw)
|
||||
if is_sep(cs):
|
||||
continue
|
||||
rows.append((no, cs))
|
||||
yield header, rows
|
||||
i = j
|
||||
else:
|
||||
i += 1
|
||||
|
||||
|
||||
def col(header, key):
|
||||
return next((k for k, c in enumerate(header) if key in c), None)
|
||||
|
||||
|
||||
def strip_fences(text):
|
||||
out, inside = [], False
|
||||
for ln in text.splitlines():
|
||||
if FENCE_RE.match(ln):
|
||||
inside = not inside
|
||||
out.append("")
|
||||
continue
|
||||
out.append("" if inside else ln)
|
||||
return out
|
||||
|
||||
|
||||
def system_docs():
|
||||
return sorted(SYS_DIR.rglob("*.md"))
|
||||
|
||||
|
||||
def manifest():
|
||||
return re.findall(r'"path":\s*"res://tests/([^"]+)"', read(RUN_ALL))
|
||||
|
||||
|
||||
def product_funcs():
|
||||
names = set()
|
||||
for p in (REPO / "game").rglob("*.gd"):
|
||||
rel = p.relative_to(REPO).as_posix()
|
||||
if rel.startswith(("game/tests/", "game/probe/", "game/sim/")):
|
||||
continue
|
||||
names.update(re.findall(r"^(?:static\s+)?func\s+([A-Za-z_]\w*)\s*\(", read(p), re.M))
|
||||
return names
|
||||
|
||||
|
||||
def cards_corpus():
|
||||
"""reports/需求卡片*.md 全文拼接(双通道的「卡在」锚面);无卡返回空串。"""
|
||||
if not CARDS_DIR.is_dir():
|
||||
return ""
|
||||
return "\n".join(read(p) for p in sorted(CARDS_DIR.glob("需求卡片-*.md")))
|
||||
|
||||
|
||||
def check_purity():
|
||||
docs = sorted(GDD_DIR.rglob("*.md"))
|
||||
if not docs:
|
||||
selfcheck.append("design/gdd 下无文档")
|
||||
return
|
||||
for doc in docs:
|
||||
for no, ln in enumerate(strip_fences(read(doc)), 1):
|
||||
for m in PURITY_RE.finditer(ln):
|
||||
red(doc.relative_to(REPO), no, "纯度", "代码路径 `%s`(禁写实现细节)" % m.group(0))
|
||||
m = ASSERT_RE.search(ln)
|
||||
if m:
|
||||
red(doc.relative_to(REPO), no, "纯度", "断言名 `%s`(禁写实现细节)" % m.group(1))
|
||||
m = CALL_FORM_RE.search(ln)
|
||||
if m:
|
||||
red(doc.relative_to(REPO), no, "纯度", "反引号调用形态 %s(禁写实现细节)" % m.group(0))
|
||||
|
||||
|
||||
def check_accept_sections():
|
||||
for doc in system_docs():
|
||||
text = read(doc)
|
||||
m = re.search(r"^## 验收标准[^\n]*\n(.*?)(?=^## |\Z)", text, re.M | re.S)
|
||||
body = (m.group(1).strip() if m else "")
|
||||
if not body and doc.name not in ACCEPT_EXEMPT:
|
||||
red(doc.relative_to(REPO), 1, "验收标准",
|
||||
"缺非空「## 验收标准」节" if not m else "「## 验收标准」节为空")
|
||||
elif doc.name in ACCEPT_EXEMPT and body:
|
||||
red(doc.relative_to(REPO), 1, "验收标准", "豁免件已有验收标准节,请移除豁免")
|
||||
|
||||
|
||||
def capability_rows():
|
||||
if not README.exists():
|
||||
selfcheck.append("game/tests/README.md 缺失")
|
||||
return [], []
|
||||
lines = read(README).splitlines()
|
||||
cap_tables = list(tables(lines, ("真实入口", "代表用例")))
|
||||
cov_tables = list(tables(lines, ("系统文档", "能力行", "状态")))
|
||||
if not cap_tables:
|
||||
selfcheck.append("README 能力表未找到")
|
||||
if not cov_tables:
|
||||
selfcheck.append("README 覆盖域表未找到")
|
||||
return cap_tables, cov_tables
|
||||
|
||||
|
||||
def check_capability_rows(cap_tables, suites, funcs, cards):
|
||||
total = 0
|
||||
names = []
|
||||
suite_by_base = {}
|
||||
for rel in suites:
|
||||
suite_by_base.setdefault(Path(rel).name, []).append(rel)
|
||||
for header, rows in cap_tables:
|
||||
idx = {}
|
||||
for key in CAP_COLS:
|
||||
k = col(header, key)
|
||||
if k is None:
|
||||
red(README.relative_to(REPO), 1, "能力行结构", "缺「%s」列" % key)
|
||||
break
|
||||
idx[key] = k
|
||||
else:
|
||||
for no, cs in rows:
|
||||
total += 1
|
||||
short = lambda k: (cs[idx[k]] if idx[k] < len(cs) else "")
|
||||
name = short("能力").strip("`")
|
||||
names.append(name)
|
||||
empty = [k for k in CAP_COLS if not short(k)]
|
||||
if len(cs) < max(idx.values()) + 1 or empty:
|
||||
red(README.relative_to(REPO), no, "能力行结构",
|
||||
"「%s」行格数不足或空列(%s)" % (name[:16], "/".join(empty) or "列数"))
|
||||
continue
|
||||
if "条件闸" in short("代表用例"):
|
||||
continue
|
||||
check_cases(no, name, short("代表用例"), suite_by_base, funcs, cards)
|
||||
check_entry(no, name, short("真实入口"), funcs, cards)
|
||||
if total == 0:
|
||||
selfcheck.append("能力表零数据行")
|
||||
return names
|
||||
|
||||
|
||||
def check_cases(no, name, cell, suite_by_base, funcs, cards):
|
||||
chunks = [c.strip().strip("`") for c in re.split(r"[;;]", cell) if c.strip()]
|
||||
if not chunks:
|
||||
red(README.relative_to(REPO), no, "代表用例", "「%s」无代表用例" % name[:16])
|
||||
return
|
||||
for chunk in chunks:
|
||||
m = CASE_RE.search(chunk)
|
||||
if not m:
|
||||
red(README.relative_to(REPO), no, "代表用例",
|
||||
"「%s」格格式应为 `文件.gd:函数`:%s" % (name[:16], chunk[:40]))
|
||||
continue
|
||||
fname, fn = m.groups()
|
||||
# 双通道(test-conventions §8.9):代码在(套件 manifest 内且 func 在文件里)
|
||||
# 或卡在(文件名/函数名见于 reports/需求卡片*.md——写卡时当场入表的计划用例)。
|
||||
hits = suite_by_base.get(fname, [])
|
||||
code_ok = bool(hits) and any(
|
||||
re.search(r"^(?:static\s+)?func\s+%s\s*\(" % re.escape(fn), read(RUN_ALL.parent / rel), re.M)
|
||||
for rel in hits)
|
||||
card_ok = bool(cards) and (fname in cards or fn in cards)
|
||||
if not code_ok and not card_ok:
|
||||
red(README.relative_to(REPO), no, "代表用例",
|
||||
"「%s」%s 无凭证——代码面(manifest+func)与需求卡片均未锚定" % (name[:16], chunk[:40]))
|
||||
|
||||
|
||||
def check_entry(no, name, cell, funcs, cards):
|
||||
tokens = ENTRY_RE.findall(cell)
|
||||
if not tokens:
|
||||
red(README.relative_to(REPO), no, "真实入口", "「%s」无可核的 `类.方法()`" % name[:16])
|
||||
return
|
||||
for _, method in tokens:
|
||||
if method not in funcs and not (cards and method in cards):
|
||||
red(README.relative_to(REPO), no, "真实入口",
|
||||
"「%s」方法 %s() 无凭证——产品码无定义且需求卡片未载" % (name[:16], method))
|
||||
|
||||
|
||||
def check_coverage(cov_tables, names):
|
||||
want = {d.name for d in system_docs()}
|
||||
if not want:
|
||||
selfcheck.append("systems 下无系统文档")
|
||||
return
|
||||
total, seen = 0, {}
|
||||
for header, rows in cov_tables:
|
||||
idx = {}
|
||||
ok = True
|
||||
for key in COV_COLS:
|
||||
k = col(header, key)
|
||||
if k is None:
|
||||
red(README.relative_to(REPO), 1, "覆盖域表", "缺「%s」列" % key)
|
||||
ok = False
|
||||
break
|
||||
idx[key] = k
|
||||
if not ok:
|
||||
continue
|
||||
for no, cs in rows:
|
||||
total += 1
|
||||
short = lambda k: (cs[idx[k]] if idx[k] < len(cs) else "")
|
||||
doc = Path(short("系统文档").strip("`").strip()).name
|
||||
if not doc:
|
||||
red(README.relative_to(REPO), no, "覆盖域表", "系统文档格为空")
|
||||
continue
|
||||
if doc in seen:
|
||||
red(README.relative_to(REPO), no, "覆盖域表", "%s 重复登记(见行 %d)" % (doc, seen[doc]))
|
||||
seen[doc] = no
|
||||
status = short("状态").strip("`").strip()
|
||||
if status not in STATUS_VALUES:
|
||||
red(README.relative_to(REPO), no, "覆盖域表",
|
||||
"%s 状态须为 已覆盖/部分覆盖/未覆盖:%s" % (doc, status[:16]))
|
||||
continue
|
||||
caps = [c.strip() for c in re.split(r"[、;;]", short("能力行")) if c.strip()]
|
||||
gap = short("缺口").strip()
|
||||
if status != "未覆盖" and not caps:
|
||||
red(README.relative_to(REPO), no, "覆盖域表", "%s 非未覆盖但能力行为空" % doc)
|
||||
for cap in caps:
|
||||
cap = cap.strip("`")
|
||||
if cap in ("—", "-"):
|
||||
continue
|
||||
if not any(cap in n or n in cap for n in names):
|
||||
red(README.relative_to(REPO), no, "覆盖域表",
|
||||
"%s 的能力行「%s」在能力表中不存在" % (doc, cap[:20]))
|
||||
if status != "已覆盖" and (not gap or "待办清单" not in gap):
|
||||
red(README.relative_to(REPO), no, "覆盖域表",
|
||||
"%s 为%s,缺口须非空并指待办清单" % (doc, status))
|
||||
if total == 0:
|
||||
selfcheck.append("覆盖域表零数据行")
|
||||
for doc in sorted(want - set(seen)):
|
||||
red(README.relative_to(REPO), 1, "覆盖域表", "%s 未在覆盖域表登记" % doc)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--strict", action="store_true")
|
||||
args = ap.parse_args()
|
||||
|
||||
check_purity()
|
||||
check_accept_sections()
|
||||
cap_tables, cov_tables = capability_rows()
|
||||
suites = manifest()
|
||||
if not suites:
|
||||
selfcheck.append("run_all.gd manifest 零套件")
|
||||
funcs = product_funcs()
|
||||
if not funcs:
|
||||
selfcheck.append("产品码零 `func`")
|
||||
names = check_capability_rows(cap_tables, suites, funcs, cards_corpus())
|
||||
check_coverage(cov_tables, names)
|
||||
|
||||
if selfcheck:
|
||||
print("capability_audit 扫描面异常:")
|
||||
for s in selfcheck:
|
||||
print(" ! " + s)
|
||||
|
||||
print("| ── 能力审计:系统文档 %d 篇 · 能力行 %d · 套件 %d · 覆盖域表 %d 行 · 红项 %d"
|
||||
% (len(system_docs()), len(names), len(suites),
|
||||
sum(len(r) for _, r in cov_tables), len(reds)))
|
||||
for path, line, check, msg in reds:
|
||||
print(" ✗ [%s] %s:%d %s" % (check, path, line, msg))
|
||||
if selfcheck:
|
||||
return 2
|
||||
if reds and args.strict:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
+155
-3
@@ -5,19 +5,171 @@
|
||||
# 判定=键不在基线红(NEW)、同键数值较登记值恶化红(WORSENED)、改小/持平不红。
|
||||
# 重生成=人工专用:python tools/gdstyle_gate.py --refresh(禁清基线换绿;改规则口径/工具升级须随批
|
||||
# 重生成;新键数较旧基线少逾 10% 须加 --force 显式确认)。
|
||||
game/core/action_economy.gd|quality/max-class-variables = 18
|
||||
game/core/adventure_runner.gd|quality/max-class-variables = 28
|
||||
game/core/battle_orchestrator.gd|quality/max-class-variables = 38
|
||||
game/core/battle_orchestrator.gd|quality/max-file-length = 1035
|
||||
game/core/battle_orchestrator.gd|quality/max-file-length = 1037
|
||||
game/core/board_generator.gd|quality/max-branches|measure_inferability = 12
|
||||
game/core/board_generator.gd|quality/max-function-length|_attempt = 51
|
||||
game/core/board_generator.gd|quality/max-function-length|generate = 62
|
||||
game/core/board_generator.gd|quality/max-function-length|measure_inferability = 64
|
||||
game/core/board_generator.gd|quality/max-local-variables|generate = 14
|
||||
game/core/board_generator.gd|quality/max-local-variables|measure_inferability = 13
|
||||
game/core/board_generator.gd|quality/max-nesting-depth|measure_inferability = 5
|
||||
game/core/board_generator.gd|quality/max-parameters|_finalize = 6
|
||||
game/core/config_db.gd|quality/max-class-variables = 25
|
||||
game/core/config_db.gd|quality/max-public-methods = 44
|
||||
game/core/config_db_cross_validator.gd|quality/max-branches|cross_validate = 21
|
||||
game/core/config_db_cross_validator.gd|quality/max-function-length|cross_validate = 107
|
||||
game/core/config_db_cross_validator.gd|quality/max-local-variables|cross_validate = 24
|
||||
game/core/config_db_cross_validator.gd|quality/max-nesting-depth|cross_validate = 5
|
||||
game/core/config_db_resolver.gd|quality/max-branches|_resolve_progress = 16
|
||||
game/core/config_db_resolver.gd|quality/max-branches|resolve_enemy_rowset = 12
|
||||
game/core/config_db_resolver.gd|quality/max-function-length|_resolve_progress = 52
|
||||
game/core/config_db_resolver.gd|quality/max-local-variables|_resolve_progress = 11
|
||||
game/core/effect_engine.gd|quality/max-branches|validate_trigger_row = 14
|
||||
game/core/effect_engine.gd|quality/max-function-length|_cond_ok = 52
|
||||
game/core/effect_engine.gd|quality/max-function-length|rebuild = 55
|
||||
game/core/effect_engine.gd|quality/max-local-variables|validate_trigger_row = 11
|
||||
game/core/effect_engine.gd|quality/max-nesting-depth|_cond_ok = 5
|
||||
game/core/effect_engine.gd|quality/max-nesting-depth|rebuild = 5
|
||||
game/core/effect_engine.gd|quality/max-returns|_cond_ok = 19
|
||||
game/core/effect_engine.gd|quality/no-else-return|unnecessary 'elif' after 'return'
|
||||
game/core/level_runner.gd|quality/max-class-variables = 30
|
||||
game/core/level_runner.gd|quality/max-public-methods = 50
|
||||
game/core/level_runner.gd|quality/max-returns|_enter_node = 7
|
||||
game/core/meta_progression.gd|quality/max-public-methods = 31
|
||||
game/core/meta_progression.gd|quality/max-returns|tree_can_buy = 8
|
||||
game/core/minesweeper_rules.gd|quality/max-function-length|_do_dig = 53
|
||||
game/core/node_map_generator.gd|quality/max-branches|_assign_types = 11
|
||||
game/core/node_map_generator.gd|quality/max-branches|check_params = 12
|
||||
game/core/node_map_generator.gd|quality/max-branches|validate_output = 34
|
||||
game/core/node_map_generator.gd|quality/max-function-length|validate_output = 132
|
||||
game/core/node_map_generator.gd|quality/max-local-variables|_add_forks = 12
|
||||
game/core/node_map_generator.gd|quality/max-local-variables|_build = 15
|
||||
game/core/node_map_generator.gd|quality/max-local-variables|validate_output = 22
|
||||
game/core/node_map_generator.gd|quality/max-nesting-depth|_check_fork_rules = 5
|
||||
game/core/node_map_generator.gd|quality/max-returns|validate_output = 7
|
||||
game/core/reward_economy.gd|quality/max-function-length|roll_board = 52
|
||||
game/core/reward_economy.gd|quality/max-local-variables|_skewed_cell_rows = 13
|
||||
game/core/reward_economy.gd|quality/max-local-variables|roll_board = 11
|
||||
game/core/save_manager.gd|quality/max-public-methods = 52
|
||||
game/core/save_manager.gd|quality/max-returns|_peek_summary_at = 7
|
||||
game/core/save_manager.gd|quality/max-returns|load_from_disk = 8
|
||||
game/core/status_container.gd|quality/max-nesting-depth|apply_effect = 5
|
||||
game/core/status_container.gd|quality/max-parameters|_new_instance = 7
|
||||
game/core/status_container.gd|quality/max-returns|apply_effect = 9
|
||||
game/core/treasure_items.gd|quality/max-branches|validate_use = 11
|
||||
game/core/treasure_items.gd|quality/max-nesting-depth|validate_use = 5
|
||||
game/core/unit_container.gd|quality/max-function-length|spawn = 68
|
||||
game/core/unit_container.gd|quality/max-local-variables|spawn = 16
|
||||
game/core/unit_container.gd|quality/max-parameters|spawn = 10
|
||||
game/data/schemas/adventure_table.gd|quality/max-class-variables = 44
|
||||
game/data/schemas/board_gen_table.gd|quality/max-branches|validate = 20
|
||||
game/data/schemas/board_gen_table.gd|quality/max-function-length|validate = 67
|
||||
game/data/schemas/board_gen_table.gd|quality/max-local-variables|validate = 16
|
||||
game/data/schemas/enemy_table.gd|quality/max-branches|validate = 30
|
||||
game/data/schemas/enemy_table.gd|quality/max-function-length|validate = 110
|
||||
game/data/schemas/enemy_table.gd|quality/max-local-variables|validate = 28
|
||||
game/data/schemas/forge_table.gd|quality/max-branches|validate = 30
|
||||
game/data/schemas/forge_table.gd|quality/max-function-length|validate = 95
|
||||
game/data/schemas/forge_table.gd|quality/max-local-variables|validate = 20
|
||||
game/data/schemas/level_gen_params.gd|quality/max-branches|validate = 15
|
||||
game/data/schemas/level_gen_params.gd|quality/max-function-length|validate = 59
|
||||
game/data/schemas/level_gen_params.gd|quality/max-local-variables|validate = 18
|
||||
game/data/schemas/meta_table.gd|quality/max-branches|validate = 14
|
||||
game/data/schemas/meta_table.gd|quality/max-function-length|validate = 60
|
||||
game/data/schemas/meta_table.gd|quality/max-local-variables|validate = 14
|
||||
game/data/schemas/meta_tree_table.gd|quality/max-branches|validate = 26
|
||||
game/data/schemas/meta_tree_table.gd|quality/max-function-length|validate = 86
|
||||
game/data/schemas/meta_tree_table.gd|quality/max-local-variables|validate = 13
|
||||
game/data/schemas/meta_tree_table.gd|quality/max-nesting-depth|validate = 5
|
||||
game/data/schemas/reward_table.gd|quality/max-branches|validate = 30
|
||||
game/data/schemas/reward_table.gd|quality/max-function-length|validate = 99
|
||||
game/data/schemas/reward_table.gd|quality/max-local-variables|validate = 20
|
||||
game/data/schemas/skill_table.gd|quality/max-branches|validate = 26
|
||||
game/data/schemas/skill_table.gd|quality/max-function-length|validate = 76
|
||||
game/data/schemas/status_effect_table.gd|quality/max-branches|validate = 12
|
||||
game/data/schemas/treasure_item_table.gd|quality/max-branches|validate = 44
|
||||
game/data/schemas/treasure_item_table.gd|quality/max-function-length|validate = 147
|
||||
game/data/schemas/treasure_item_table.gd|quality/max-local-variables|validate = 26
|
||||
game/data/schemas/treasure_item_table.gd|quality/max-nesting-depth|validate = 6
|
||||
game/data/schemas/variation_table.gd|quality/max-branches|validate = 20
|
||||
game/data/schemas/variation_table.gd|quality/max-function-length|validate = 58
|
||||
game/presentation/battle_narrator.gd|quality/max-returns|bonus_card_text = 9
|
||||
game/presentation/camp_flow_context.gd|quality/max-parameters|_init = 12
|
||||
game/presentation/curio_flow_context.gd|quality/max-class-variables = 16
|
||||
game/presentation/curio_flow_context.gd|quality/max-parameters|_init = 16
|
||||
game/presentation/curio_interact_controller.gd|quality/max-class-variables = 18
|
||||
game/presentation/hud_presenter.gd|quality/max-parameters|_refresh_out_of_battle = 6
|
||||
game/presentation/hud_presenter.gd|quality/max-parameters|refresh = 8
|
||||
game/presentation/hud_presenter.gd|quality/max-parameters|tune_sim_report = 10
|
||||
game/presentation/main.gd|quality/max-class-variables = 49
|
||||
game/presentation/playtest_logger.gd|quality/no-debug-print|debug 'print()' call found
|
||||
game/presentation/tune_sim_controller.gd|quality/await-in-loop|'await' used inside a loop
|
||||
game/presentation/views/board_cell_unit.gd|quality/max-class-variables = 30
|
||||
game/presentation/tune_sim_controller.gd|quality/max-local-variables|run = 11
|
||||
game/presentation/tune_sim_controller.gd|quality/no-debug-print|debug 'print()' call found
|
||||
game/presentation/ui_assembler.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/ui_assembler.gd|quality/max-function-length|build_start_overlay = 83
|
||||
game/presentation/ui_assembler.gd|quality/max-local-variables|build_start_overlay = 16
|
||||
game/presentation/views/ap_bar_view.gd|quality/max-function-length|_init = 69
|
||||
game/presentation/views/battle_end_overlay.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/battle_end_overlay.gd|quality/max-class-variables = 20
|
||||
game/presentation/views/battle_end_overlay.gd|quality/max-function-length|_init = 81
|
||||
game/presentation/views/battle_end_overlay.gd|quality/max-parameters|open_victory = 8
|
||||
game/presentation/views/battle_log_view.gd|quality/max-branches|_format_row = 9
|
||||
game/presentation/views/battle_log_view.gd|quality/max-function-length|_format_row = 68
|
||||
game/presentation/views/battle_log_view.gd|quality/max-local-variables|_format_row = 21
|
||||
game/presentation/views/battle_log_view.gd|quality/max-returns|_format_row = 13
|
||||
game/presentation/views/battle_stage_view.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/battle_stage_view.gd|quality/max-function-length|_init = 97
|
||||
game/presentation/views/battle_stage_view.gd|quality/max-returns|_enemy_portrait_tex = 9
|
||||
game/presentation/views/board_cell_unit.gd|quality/max-branches|_draw = 29
|
||||
game/presentation/views/board_cell_unit.gd|quality/max-class-variables = 31
|
||||
game/presentation/views/board_cell_unit.gd|quality/max-function-length|_draw = 147
|
||||
game/presentation/views/board_cell_unit.gd|quality/max-local-variables|_draw = 19
|
||||
game/presentation/views/board_fx_view.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/board_view.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/board_view.gd|quality/max-branches|_paint_cell = 24
|
||||
game/presentation/views/board_view.gd|quality/max-class-variables = 32
|
||||
game/presentation/views/board_view.gd|quality/max-function-length|_paint_cell = 139
|
||||
game/presentation/views/board_view.gd|quality/max-local-variables|_paint_cell = 22
|
||||
game/presentation/views/board_view.gd|quality/max-public-methods = 27
|
||||
game/presentation/views/standee_body.gd|quality/max-class-variables = 19
|
||||
game/presentation/views/board_zone_view.gd|quality/max-function-length|_init = 59
|
||||
game/presentation/views/camp_overlay_view.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-class-variables = 19
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-function-length|_init = 149
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-function-length|_rebuild_forge = 72
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-function-length|_rebuild_tree = 61
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-function-length|refresh_camp = 61
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-local-variables|_init = 28
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-local-variables|_rebuild_forge = 20
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-local-variables|_rebuild_tree = 21
|
||||
game/presentation/views/camp_overlay_view.gd|quality/max-local-variables|refresh_camp = 17
|
||||
game/presentation/views/curio_pick_overlay.gd|quality/max-function-length|_init = 52
|
||||
game/presentation/views/curio_pick_overlay.gd|quality/max-returns|_icon_for_id = 7
|
||||
game/presentation/views/debug_overlay.gd|quality/max-class-variables = 17
|
||||
game/presentation/views/debug_overlay.gd|quality/max-function-length|_build = 124
|
||||
game/presentation/views/debug_overlay.gd|quality/max-local-variables|_build = 22
|
||||
game/presentation/views/hero_info_panel_view.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/hero_info_panel_view.gd|quality/max-function-length|_init = 74
|
||||
game/presentation/views/hero_info_panel_view.gd|quality/max-function-length|set_treasure_inventory = 57
|
||||
game/presentation/views/hero_info_panel_view.gd|quality/max-local-variables|set_treasure_inventory = 13
|
||||
game/presentation/views/legend_overlay.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/level_map_screen.gd|quality/max-branches|_draw_graph = 9
|
||||
game/presentation/views/level_map_screen.gd|quality/max-class-variables = 21
|
||||
game/presentation/views/level_map_screen.gd|quality/max-function-length|_draw_graph = 78
|
||||
game/presentation/views/level_map_screen.gd|quality/max-function-length|_init = 135
|
||||
game/presentation/views/level_map_screen.gd|quality/max-local-variables|_draw_graph = 27
|
||||
game/presentation/views/level_map_screen.gd|quality/max-local-variables|_init = 21
|
||||
game/presentation/views/settings_overlay.gd|quality/max-function-length|_build = 77
|
||||
game/presentation/views/settings_overlay.gd|quality/max-local-variables|_build = 13
|
||||
game/presentation/views/standee_body.gd|quality/allocation-in-loop|object allocation '.new()' inside a loop
|
||||
game/presentation/views/standee_body.gd|quality/max-class-variables = 29
|
||||
game/presentation/views/standee_body.gd|quality/max-function-length|_draw = 84
|
||||
game/presentation/views/standee_body.gd|quality/max-local-variables|_draw = 26
|
||||
game/presentation/views/ui_kit.gd|quality/max-local-variables|beams_rect = 13
|
||||
game/presentation/views/ui_kit.gd|quality/max-parameters|_init = 6
|
||||
game/presentation/views/ui_kit.gd|quality/max-parameters|bcard = 6
|
||||
game/presentation/views/ui_kit.gd|quality/max-parameters|modal_shell = 6
|
||||
game/presentation/views/ui_kit.gd|quality/max-public-methods = 26
|
||||
+3
-64
@@ -55,9 +55,6 @@ LEDGER_PROOF_MARKS = ("撤销", "证明")
|
||||
BINDING_RULE_DATE = (2026, 10, 28) # req-card §8:换代为判据绑定面列,撤销/变异证明列同日禁列
|
||||
BANNED_PROOF_MARKS = ("撤销证明", "变异证明")
|
||||
AUDIT_MARK = "验收审计"
|
||||
CAP_ROW_RULE_DATE = (2026, 10, 29) # req-card §8:每行标能力归属(对齐 test-conventions §8.9 三层模型)
|
||||
CAP_ROW_RE = re.compile(r"^(既有|新增)\s*[::]\s*(.+)$")
|
||||
CAP_README = Path("game/tests/README.md")
|
||||
|
||||
DATE_RE = re.compile(r"\d{4}-\d{2}-\d{2}")
|
||||
VER_RE = re.compile(r"[vV]\d+(?:\.\d+)*")
|
||||
@@ -456,30 +453,7 @@ def card_date(path):
|
||||
return tuple(int(x) for x in found[-1].split("-"))
|
||||
|
||||
|
||||
def capability_names(root):
|
||||
"""game/tests/README.md 能力表首列行名集合;文件或表缺失返回空集(调用方据此判红)。"""
|
||||
p = root / CAP_README
|
||||
if not p.is_file():
|
||||
return set()
|
||||
names = set()
|
||||
header = None
|
||||
for raw in p.read_text(encoding="utf-8").splitlines():
|
||||
s = raw.strip()
|
||||
if not s.startswith("|"):
|
||||
header = None
|
||||
continue
|
||||
cells = row_cells(s)
|
||||
if header is None:
|
||||
header = cells
|
||||
continue
|
||||
if SEP_ROW_RE.match(s):
|
||||
continue
|
||||
if any("代表用例" in c for c in header) and cells:
|
||||
names.add(cells[0].strip("`").strip())
|
||||
return names
|
||||
|
||||
|
||||
def check_ledger(text, path, when, issues, root):
|
||||
def check_ledger(text, path, when, issues):
|
||||
"""C3 改动—验收对照表结构检查(生效 2026-10-21)。
|
||||
|
||||
只查:对照表节在不在、表头有没有五个必需列、有没有数据行、必填格空不空。
|
||||
@@ -543,18 +517,6 @@ def check_ledger(text, path, when, issues, root):
|
||||
return
|
||||
idx["证明"] = proof_hit
|
||||
|
||||
cap_hit = None
|
||||
cap_names = None
|
||||
if when >= CAP_ROW_RULE_DATE:
|
||||
cap_hit = next((k for k, cell in enumerate(header) if "能力行" in cell), None)
|
||||
if cap_hit is None:
|
||||
issues.append((str(path), header_line, "验收对照表缺列",
|
||||
"缺「能力行」列(2026-10-29 起:每行写 既有:<能力名> 或 "
|
||||
"新增:<能力名>,对齐能力清单)"))
|
||||
return
|
||||
idx["能力行"] = cap_hit
|
||||
cap_names = capability_names(root)
|
||||
|
||||
rows = 0
|
||||
for i in range(header_line, len(lines)):
|
||||
s = lines[i].strip()
|
||||
@@ -574,27 +536,6 @@ def check_ledger(text, path, when, issues, root):
|
||||
if k >= len(cells) or not cells[k].strip():
|
||||
issues.append((str(path), i + 1, "验收对照表空格",
|
||||
"「%s」列为空" % name))
|
||||
if cap_hit is not None:
|
||||
cap_cell = cells[cap_hit] if cap_hit < len(cells) else ""
|
||||
for seg in [x.strip() for x in re.split(r"[;;]", cap_cell) if x.strip()]:
|
||||
m = CAP_ROW_RE.match(seg)
|
||||
if not m:
|
||||
issues.append((str(path), i + 1, "能力行格式",
|
||||
"「能力行」格须写 既有:<能力名>/新增:<能力名>:%s"
|
||||
% seg[:24]))
|
||||
continue
|
||||
# 2026-10-29 能力清单改版:写卡与入表同 commit——「新增:」同样要求该能力行
|
||||
# 已在 game/tests/README.md 能力表在场(写卡时当场入表,test-conventions §8.3)。
|
||||
cap_name = m.group(2).strip("`").strip()
|
||||
if cap_name not in cap_names:
|
||||
if m.group(1) == "新增":
|
||||
issues.append((str(path), i + 1, "新增能力未入表",
|
||||
"新增能力「%s」不在 game/tests/README.md 能力表——"
|
||||
"写卡须同批把能力行写入能力清单" % cap_name[:24]))
|
||||
else:
|
||||
issues.append((str(path), i + 1, "能力行不可核",
|
||||
"既有能力「%s」不在 game/tests/README.md 能力表"
|
||||
% cap_name[:24]))
|
||||
if rows == 0:
|
||||
issues.append((str(path), header_line, "验收对照表零行",
|
||||
"表内没有数据行"))
|
||||
@@ -610,9 +551,7 @@ def check_cards(root, issues):
|
||||
C2 判据:全文既无「设计事实源」也无「唯一事实源」者红(两种写法都与库内实态对齐)。
|
||||
C3 判据:有「改动—验收对照表」节;表头含需求点/改动/验收测试/真实入口+证明列
|
||||
(2026-10-28 起换代为「判据绑定面」列,并禁「撤销证明/变异证明」列);
|
||||
能力行列(2026-10-29 起)既有与新增的名称都须在 game/tests/README.md 能力表在场
|
||||
(新增=写卡同批入表,test-conventions §8.3);至少一行;必填格非空;全文含「验收审计」声明。
|
||||
语义覆盖不在此判。
|
||||
至少一行;必填格非空;全文含「验收审计」声明。语义覆盖不在此判。
|
||||
"""
|
||||
dirn = root / CARD_DIR
|
||||
if not dirn.is_dir():
|
||||
@@ -630,7 +569,7 @@ def check_cards(root, issues):
|
||||
"须含「设计事实源」或「唯一事实源」声明句(req-card §2 三选一,"
|
||||
"GDD 节+版本号/样张+art-bible 版本/工程形态证据指认)"))
|
||||
if when >= LEDGER_RULE_DATE:
|
||||
check_ledger(text, path, when, issues, root)
|
||||
check_ledger(text, path, when, issues)
|
||||
if AUDIT_MARK not in text:
|
||||
issues.append((str(path), 1, "独立验收审计未声明",
|
||||
"须在卡内写明独立验收审计入口与报告文件(2026-10-21 起,"
|
||||
|
||||
+35
-163
@@ -14,13 +14,10 @@
|
||||
# --code 只跑代码域闸(00 冒烟测试/01 系统测试/02 单元与集成测试/03 探针 --click/
|
||||
# 04 探针 --full/05 渲染闸/09 静态扫描/11 回放确定性对拍+10 熵增闸)
|
||||
# ——本批改动含 game/ 下非 .md 的行为载体(代码/测试脚本/探针/场景/数据表/素材)时用。
|
||||
# 关联档选闸(2026-10-29 用户裁,推广自 2026-10-28 影响面选闸):00 冒烟/01 系统测试/
|
||||
# 09 静态扫描三件保险恒跑不降;03/04 探针与 05 渲染闸维持影响面口径(本批 game/ 改动
|
||||
# 全在测量面 game/tests、game/sim 时记 SKIP);02 单元与集成改「选套件跑」——套件集=
|
||||
# 需求卡片申报 ∪ diff 推导并集(算法与套件族映射表见脚本中部),横切面(公共件/数据表/
|
||||
# autoload/数值·存档·RNG·结算触面)回落全套件;回执 scope 字段记 full|related。
|
||||
# --docs 只跑文档域闸(06 gdd_lint/07 doc_link/08 doc_term/08c 流水线闸/08d 引用可核/
|
||||
# 08e 能力审计+10 熵增闸)
|
||||
# 影响面选闸:本批 game/ 改动全在测量面(game/tests、game/sim)时,00/03/04/05 记
|
||||
# SKIP(测量面不触开机路径/场景树/渲染输出;映射定义在脚本中部,判定保守)。
|
||||
# --docs 只跑文档域闸(06 gdd_lint/07 doc_link/08 doc_term/08c 流水线闸/08d 引用可核
|
||||
# +10 熵增闸)
|
||||
# ——本批改动只有文档件时用:game/ 内的 .md(README、生成清单)、design/、根规则文件、
|
||||
# tools/ 工具脚本、.zcode/ 配置等一切非代码面改动。
|
||||
# --quick 全量档的中段自检形态:跳过渲染闸(窗口化,需开显示器)与静态扫描;完成出库禁用。
|
||||
@@ -157,83 +154,12 @@ fi
|
||||
declare -a NAMES=() EXITS=() LOGS=()
|
||||
FAILED=0
|
||||
|
||||
# PARITY 触面表——gate 11 数值·存档·RNG·结算触面判定与关联档横切判定共用同一清单(单点定义,勿在别处复制)。
|
||||
PARITY_TOUCH_FACES="
|
||||
game/data/tables/
|
||||
game/core/rng_service.gd
|
||||
game/core/save_manager.gd
|
||||
game/core/meta_progression.gd
|
||||
game/core/settlement/
|
||||
game/core/damage_math.gd
|
||||
game/core/damage_controller.gd
|
||||
game/core/battle_orchestrator.gd
|
||||
game/sim/adventure_monte_carlo.gd
|
||||
"
|
||||
|
||||
# ── 套件族映射表(关联档·推导半边的唯一事实源)──
|
||||
# game/ 代码面文件 → tests/ 套件族词(--only 子串词,词=套件目录名)。机械近似:同族内
|
||||
# 套件覆盖面仍可能宽于被测文件,保守方向=宁多勿漏。横切判定(公共件前缀/project.godot/
|
||||
# PARITY 触面表)先于本表执行,故表中不收 damage_math/damage_controller/battle_orchestrator/
|
||||
# settlement/** 等数值·存档·RNG·结算触面文件——它们恒走横切回落全量。映射不到的文件返回空=横切处理。
|
||||
suite_terms_for() { # suite_terms_for <仓库相对路径> → stdout: 套件族词(空格分隔,可空)
|
||||
case "$1" in
|
||||
# 战斗结算域
|
||||
game/core/action_economy.gd|game/core/battle_fx_host.gd|game/core/effect_context.gd|\
|
||||
game/core/effect_engine.gd|game/core/gain_journal.gd|game/core/skill_lottery.gd)
|
||||
echo "battle_settlement" ;;
|
||||
game/core/reward_economy.gd|game/core/reward_grant.gd)
|
||||
echo "battle_settlement core" ;;
|
||||
game/core/status_container.gd)
|
||||
echo "battle_settlement contracts" ;;
|
||||
game/core/unit_container.gd)
|
||||
echo "battle_settlement data_config" ;;
|
||||
# 排雷/棋盘域(封印与极性行为跨战斗结算族)
|
||||
game/core/board_data.gd|game/core/minesweeper_rules.gd)
|
||||
echo "core battle_settlement" ;;
|
||||
game/core/board_generator.gd|game/core/node_map_generator.gd|game/core/hero_stats.gd|\
|
||||
game/core/curio_deck.gd|game/core/curio_stop.gd|game/core/refresh_bank.gd|\
|
||||
game/core/treasure_items.gd|game/core/attune_loadout.gd|game/core/attunement.gd|\
|
||||
game/core/meta_state_store.gd|game/core/slot_store.gd|game/core/gp_wallet.gd|\
|
||||
game/core/shop_session.gd)
|
||||
echo "core" ;;
|
||||
# 冒险结构×存档断点×关卡推进(core 族+跨系统集成族)
|
||||
game/core/adventure_runner.gd|game/core/level_runner.gd)
|
||||
echo "core integration" ;;
|
||||
# 配置域表类(autoload 本体与解析器/跨表校验器走横切,不入本表)
|
||||
game/core/config_domain_*.gd)
|
||||
echo "data_config core" ;;
|
||||
# 数据 schema(data_config 族守卫+core 族消费侧校验与跨表校验)
|
||||
game/data/schemas/*)
|
||||
echo "data_config core" ;;
|
||||
# 呈现域
|
||||
game/presentation/*)
|
||||
echo "presentation" ;;
|
||||
# 素材(字体/地形/主题类断言在 presentation 族;探针与渲染闸另有行为面闸管)
|
||||
game/assets/*)
|
||||
echo "presentation" ;;
|
||||
*)
|
||||
echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ── 关联档选闸(2026-10-29 用户裁,推广自 2026-10-28 影响面选闸)──
|
||||
# 三件保险恒跑不降:00 冒烟/01 系统测试/09 静态扫描(10 熵增闸照旧两域都跑,11 数值·存档·RNG·结算触面判定照旧)。
|
||||
# 03/04 探针与 05 渲染闸维持影响面口径:本批 diff 相对 master 分叉点的 game/ 改动若全部落在
|
||||
# 测量面(game/tests/**、game/sim/**——测试与模拟驱动件,不触场景树与渲染输出)则记 SKIP。
|
||||
# 02 单元与集成改「选套件跑」:套件集=申报 ∪ 推导 取并集——
|
||||
# 申报:在册需求卡片(本批 diff 触及的 reports/需求卡片*.md ∪ roadmap「进行中」迭代行登记的
|
||||
# 卡片)对照表「验收测试」列提到的测试文件名,按文件名作为 --only 子串词归套件;
|
||||
# 找不到在册卡片则申报集为空并输出注明。
|
||||
# 推导:按下方套件族映射表把 game/ 代码面文件(非 .md、非测量面)归到套件族;
|
||||
# 映射不到的文件一律按横切处理。
|
||||
# 横切回落全量:diff 命中 game/data/tables/**、公共件前缀(config_db*/rng_service*/
|
||||
# save_manager*/meta_progression*/main*——main* 覆盖组合根拆件与主场景)、
|
||||
# autoload 注册面(game/project.godot)、或下方 PARITY 触面表任一 → 02 跑全部套件。
|
||||
# 测量面批(game/ 改动全在 tests/sim):02 照旧全套件跑(不加过滤)。
|
||||
# 回执 scope 字段:full|related(02 跑子集=related);映射表只在本脚本一处定义。
|
||||
# ── 影响面选闸(2026-10-28 用户裁):本批 diff 相对 master 分叉点的 game/ 改动若全部落在
|
||||
# 测量面(game/tests/**、game/sim/**——测试与模拟驱动件,不触开机路径、场景树与渲染
|
||||
# 输出),则 00 冒烟/03/04 探针/05 渲染闸记 SKIP。判定保守取向:diff 含任一行为面
|
||||
# 文件即全部实跑;01/02/09 恒跑(测试宿主与静态扫描正是测量面改动的验证载体)。
|
||||
# 触发面映射只在本脚本一处定义;SKIP 与 --quick 同构,回执记 not_run,不作闸况变化。
|
||||
NONBEHAVIOR=0
|
||||
SCOPE="full"
|
||||
ONLY_TERMS=""
|
||||
if in_domain code; then
|
||||
_base="$(git -C "$REPO" merge-base master HEAD 2>/dev/null || true)"
|
||||
_gfiles="$(git -C "$REPO" -c core.quotepath=false diff --name-only "${_base:-HEAD}" HEAD -- game/ 2>/dev/null || true)"
|
||||
@@ -241,62 +167,7 @@ if in_domain code; then
|
||||
_behavior="$(echo "$_gfiles" | grep -vE '^(game/tests/|game/sim/)' || true)"
|
||||
if [ -n "$_gfiles" ] && [ -z "$_behavior" ]; then
|
||||
NONBEHAVIOR=1
|
||||
echo "[gates] 影响面选闸:game/ 改动全在测量面(tests/sim)——03/04 探针/05 渲染闸 → SKIP(00/01/09 三件保险恒跑)"
|
||||
fi
|
||||
# ── 02 选套件推导(只对行为面代码文件做——测量面文件不进推导,其验证就是 02/09 自身)──
|
||||
_codefiles="$(echo "$_gfiles" | grep -viE '\.md$' | grep -vE '^(game/tests/|game/sim/)' || true)"
|
||||
if [ -n "$_codefiles" ]; then
|
||||
CROSSCUT=0
|
||||
_family_terms=""
|
||||
# 逐文件判定:横切命中即整批回落全量;否则按映射表归族。
|
||||
while IFS= read -r _f; do
|
||||
[ -z "$_f" ] && continue
|
||||
_b="$(basename "$_f")"
|
||||
case "$_b" in
|
||||
config_db*|rng_service*|save_manager*|meta_progression*|main*)
|
||||
CROSSCUT=1; break ;;
|
||||
esac
|
||||
[ "$_f" = "game/project.godot" ] && { CROSSCUT=1; break; } # autoload 注册面
|
||||
for _pat in $PARITY_TOUCH_FACES; do
|
||||
case "$_f" in
|
||||
"$_pat"*) CROSSCUT=1; break 2 ;;
|
||||
esac
|
||||
done
|
||||
_t="$(suite_terms_for "$_f")"
|
||||
[ -n "$_t" ] && _family_terms="$_family_terms $_t"
|
||||
done <<<"$_codefiles"
|
||||
# 申报半边:在册需求卡片对照表「验收测试」列的测试文件名(卡片=本批 diff 触及 ∪ roadmap 进行中行登记)。
|
||||
_cards="$(git -C "$REPO" -c core.quotepath=false diff --name-only "${_base:-HEAD}" HEAD -- 'reports/' 2>/dev/null | grep '需求卡片.*\.md$' || true)"
|
||||
_roadmap_cards="$(grep '| 进行中 |' "$REPO/roadmap.md" 2>/dev/null | grep -oE 'reports/需求卡片[^|]*\.md' || true)"
|
||||
_declared_names=""
|
||||
_card_seen=0
|
||||
for _c in $_cards $_roadmap_cards; do
|
||||
_card_seen=1
|
||||
_cf="$REPO/$_c"
|
||||
[ -f "$_cf" ] || continue
|
||||
_names="$(grep -ohE '[a-z0-9_]+_test\.gd' "$_cf" 2>/dev/null | sort -u || true)"
|
||||
[ -n "$_names" ] && _declared_names="$_declared_names $_names"
|
||||
done
|
||||
if [ "$CROSSCUT" -eq 1 ]; then
|
||||
SCOPE="full"
|
||||
echo "[gates] 关联档选闸:diff 命中横切面(公共件/数据表/autoload/数值·存档·RNG·结算触面)——02 回落全部套件"
|
||||
else
|
||||
# 并集去重:推导族词 ∪ 申报测试文件名;并集非空才过滤(映射表保证族词非空,此处双保险)。
|
||||
_union="$(printf '%s\n' $_family_terms $_declared_names | sed '/^$/d' | sort -u | tr '\n' ' ' || true)"
|
||||
_union="$(echo "$_union" | xargs 2>/dev/null || true)"
|
||||
if [ -n "$_union" ]; then
|
||||
SCOPE="related"
|
||||
ONLY_TERMS="$_union"
|
||||
else
|
||||
SCOPE="full"
|
||||
fi
|
||||
fi
|
||||
if [ "$_card_seen" -eq 0 ]; then
|
||||
echo "[gates] 关联档选闸·申报:未找到在册需求卡片(diff 与 roadmap 进行中行均无),申报集为空——仅按 diff 推导"
|
||||
fi
|
||||
if [ "$SCOPE" = related ]; then
|
||||
echo "[gates] 关联档选闸:02 选套件跑(--only=$ONLY_TERMS)"
|
||||
fi
|
||||
echo "[gates] 影响面选闸:game/ 改动全在测量面(tests/sim)——00 冒烟/03/04 探针/05 渲染闸 → SKIP"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -324,20 +195,11 @@ gate() { # gate <名称> <日志名> <命令...>
|
||||
|
||||
gate_unit() { # run_all 是 --script 模式,退出码为唯一判据
|
||||
local name="02 单元与集成测试"
|
||||
# 关联档选跑:把套件词列表经 --only= 传给 run_all(闸机来源标记 --only-source=gates,
|
||||
# 入口据此打关联档横幅、不落「仅供开发期」免责句);全量态不传任何选跑参数。
|
||||
local -a _user_args=()
|
||||
if [ "$SCOPE" = related ] && [ -n "$ONLY_TERMS" ]; then
|
||||
_user_args=(-- "--only=${ONLY_TERMS// /,}" --only-source=gates)
|
||||
fi
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════"
|
||||
echo " $name(--script 模式,退出码为唯一判据)"
|
||||
if [ "$SCOPE" = related ] && [ -n "$ONLY_TERMS" ]; then
|
||||
echo " 关联档选跑:--only=$ONLY_TERMS"
|
||||
fi
|
||||
echo "════════════════════════════════════════════"
|
||||
( cd "$REPO" && "$GODOT" --headless --path "$(cygpath -m "$GAME")" --script res://tests/run_all.gd "${_user_args[@]}" ) \
|
||||
( cd "$REPO" && "$GODOT" --headless --path "$(cygpath -m "$GAME")" --script res://tests/run_all.gd ) \
|
||||
>"$STAMP_DIR/unit.log" 2>&1
|
||||
local rc=$?
|
||||
# 三硬闸之二(脚本错误扫描):子套件的 SCRIPT ERROR/Parse Error 只写 stderr,入口内收不到,
|
||||
@@ -354,8 +216,12 @@ gate_unit() { # run_all 是 --script 模式,退出码为唯一判据
|
||||
# ══ 代码域(0–5)══
|
||||
if in_domain code; then
|
||||
# ── 0. 冒烟测试(极小启动场景:真实开机路径存活检查,零逻辑判定,秒级)──
|
||||
# 三件保险之一(00/01/09):恒跑不降——测量面批也不免(关联档选闸,2026-10-29 用户裁)。
|
||||
gate "00 冒烟测试" "smoke_boot.log" "$PY" "$REPO/tools/run_smoke.py"
|
||||
if [ $NONBEHAVIOR -eq 1 ]; then
|
||||
NAMES+=("00 冒烟测试"); EXITS+=("SKIP"); LOGS+=("")
|
||||
echo ""; echo "[gates] 00 冒烟测试 → SKIP(影响面选闸:测量面改动不触开机路径)"
|
||||
else
|
||||
gate "00 冒烟测试" "smoke_boot.log" "$PY" "$REPO/tools/run_smoke.py"
|
||||
fi
|
||||
# ── 1. 系统测试(真实玩法路径断言面;宿主=game/tests/system_test.gd,缺省 --script 由 run_system_test.py 持有)──
|
||||
gate "01 系统测试" "system_test.log" "$PY" "$REPO/tools/run_system_test.py"
|
||||
# ── 2. 单元与集成测试 ──
|
||||
@@ -389,15 +255,24 @@ gate "08 doc_term" "doc_term.log" "$PY" "$REPO/tools/doc_term_audit.py" --strict
|
||||
gate "08c 流水线闸" "pipeline.log" "$PY" "$REPO/tools/pipeline_gate.py"
|
||||
# ── 8d. 引用可核(现行文档里「文件:行号」指针的目标存在性与行界,判据=件头注)──
|
||||
gate "08d 引用可核" "doc_ref.log" "$PY" "$REPO/tools/doc_ref_audit.py" --strict
|
||||
# ── 8e. 能力审计(GDD 纯度+能力清单与覆盖域表结构,判据=test-conventions §8.9+doc-conventions §5)──
|
||||
gate "08e 能力审计" "capability.log" "$PY" "$REPO/tools/capability_audit.py" --strict
|
||||
fi
|
||||
# ── 6c. 回放确定性对拍(条件闸件;属代码域)──
|
||||
if in_domain code; then
|
||||
# 触面判定:本批 diff 相对 master 分叉点,命中 PARITY_TOUCH_FACES(脚本上部单点定义)之一即「触面」。
|
||||
# 触面判定:本批 diff 相对 master 分叉点,命中下列路径面之一即「触面」。
|
||||
# 触面也**不自动跑**——对拍调的是 MC 脚本,属「MC/统计类跑批发起前须用户批准」红线管辖;
|
||||
# 闸只负责每次跑批都把触面判定做一遍并显式要求批准,杜绝「该跑却没人记得」。
|
||||
# 用户批准后设 PARITY_APPROVED=1 重跑本脚本即实跑三变体对拍。
|
||||
PARITY_TOUCH_FACES="
|
||||
game/data/tables/
|
||||
game/core/rng_service.gd
|
||||
game/core/save_manager.gd
|
||||
game/core/meta_progression.gd
|
||||
game/core/settlement/
|
||||
game/core/damage_math.gd
|
||||
game/core/damage_controller.gd
|
||||
game/core/battle_orchestrator.gd
|
||||
game/sim/adventure_monte_carlo.gd
|
||||
"
|
||||
_base="$(git -C "$REPO" merge-base master HEAD 2>/dev/null || true)"
|
||||
_changed_files="$(git -C "$REPO" diff --name-only "${_base:-HEAD}" HEAD 2>/dev/null || true)"
|
||||
_touch_hit=0
|
||||
@@ -438,11 +313,11 @@ else
|
||||
fi
|
||||
|
||||
# ── 与存量基线比对 ──
|
||||
"$PY" - "$BASELINE" "$RECEIPT" "$QUICK" "$DOMAIN" "$REPO" "$DIRTY_GAME" "$SCOPE" "$ONLY_TERMS" "${NAMES[@]}" -- "${EXITS[@]}" -- "${LOGS[@]}" <<'PYEOF'
|
||||
import hashlib, json, os, re, subprocess, sys
|
||||
"$PY" - "$BASELINE" "$RECEIPT" "$QUICK" "$DOMAIN" "$REPO" "$DIRTY_GAME" "${NAMES[@]}" -- "${EXITS[@]}" -- "${LOGS[@]}" <<'PYEOF'
|
||||
import hashlib, json, os, subprocess, sys
|
||||
|
||||
baseline_path, receipt_path, quick, domain, repo, dirty_game, scope, only_terms = sys.argv[1:9]
|
||||
rest = sys.argv[9:]
|
||||
baseline_path, receipt_path, quick, domain, repo, dirty_game = sys.argv[1:7]
|
||||
rest = sys.argv[7:]
|
||||
sep = rest.index("--")
|
||||
names = rest[:sep]
|
||||
tail = rest[sep + 1:]
|
||||
@@ -468,8 +343,7 @@ def tree_hash():
|
||||
return "unknown"
|
||||
|
||||
def fingerprint(exit_code, log):
|
||||
"""红项指纹:只取 exit!=0 时的 FAIL 关键行集合,忽略时序/耗时噪声
|
||||
(超时挂死行的 pid=NNN 随跑批变化,归一化为 pid=N 后再入哈希——否则存量红指纹逐轮漂移)。
|
||||
"""红项指纹:只取 exit!=0 时的 FAIL 关键行集合,忽略时序/耗时噪声。
|
||||
绿闸一律记 'green'——绿闸日志里的「零红」「全绿」等字样不是红项,采进来只会造噪声。"""
|
||||
# SKIP / NEED-APPROVAL 都属「本闸未实跑」状态,指纹一律记 skip——
|
||||
# 两者互变不是闸况变化(同是没跑),只有「未跑 → 跑出结果」或「绿 → 红」才算变化。
|
||||
@@ -486,7 +360,7 @@ def fingerprint(exit_code, log):
|
||||
s = line.strip()
|
||||
if not s or "FAIL" not in s:
|
||||
continue
|
||||
keys.append(re.sub(r"pid=\d+", "pid=N", s)[:160])
|
||||
keys.append(s[:160])
|
||||
if not keys:
|
||||
return "red-nokeys"
|
||||
return hashlib.sha1("\n".join(sorted(set(keys))).encode("utf-8")).hexdigest()[:12]
|
||||
@@ -538,8 +412,6 @@ with open(receipt_path, "w", encoding="utf-8") as f:
|
||||
"timestamp": subprocess.run(["date", "-Iseconds"], capture_output=True, text=True).stdout.strip(),
|
||||
"quick_mode": quick == "1",
|
||||
"domain": domain,
|
||||
"scope": scope,
|
||||
"scope_terms": [t for t in only_terms.split() if t],
|
||||
"dirty_game": dirty_game == "1",
|
||||
"first_baseline_run": first_run,
|
||||
"gates": [{"name": n, "exit": e, "fingerprint": now[n]["fp"]} for n, e in zip(names, exits)],
|
||||
|
||||
@@ -466,16 +466,3 @@
|
||||
| 2 | 战斗会话更替状态行(删动效+常态两档) | 两档下新开一场战斗后上一场遗留状态行已清、新会话首行即时显示(wr4 会话 flush) |
|
||||
- **红灯信号**:弹窗关闭后底层未恢复或残留残影、新战斗开始后旧状态行未清即报缺陷。
|
||||
- **结论回流**:呈现缺陷归待办清单登记新条目。
|
||||
|
||||
## ㊵ 迭代 41——结构收敛两卡实机目检(2026-10-29 随批后收尾登记)
|
||||
|
||||
> 两卡合回(2026-10-29,git 提交 eb9bb537):卡① 核心数据面结构收敛批(config_db 三域容器+存档拆件 SlotStore/MetaStateStore+adventure_table 拆段三段件+meta_progression 瘦身+spawn 束化)+卡② 呈现层结构收敛批(视图拆私有族+六状态件+ui_kit 收敛+print 删)。行为零变化批,判读口径全部=「与改前一致」;本批测试经用户特许(2026-10-28)全数移交未跑,呈现等价的其余证据承载=现役探针/单元测试断言面。登记不阻塞(2026-10-12 真人检测立规)。
|
||||
|
||||
| # | 目检项 | 判据 |
|
||||
|---|---|---|
|
||||
| 1 | 启动冒烟实机一屏 | 正常进主菜单并开一局,无错误无缺图(行为零变化批总入口) |
|
||||
| 2 | 三屏开合观感:营地/设置/战斗 | 三屏开合正常、布局与改前一致,无私有函数族拆分引入的错位或残影 |
|
||||
| 3 | 四浮层开合观感:战末结算/三选一/图例/调试浮窗 | 四浮层开合正常、遮挡关系正确、文案与改前一致(print 删除不影响呈现) |
|
||||
| 4 | 营地三柜台与同调交互回归 | 树淬炼/锻造工坊/秘宝匣三柜台可购可交互,同调充能与改前一致 |
|
||||
- **红灯信号**:任一屏/浮层布局错位、交互无响应或读数与改前不一致即报缺陷。
|
||||
- **结论回流**:呈现缺陷归待办清单登记新条目。
|
||||
@@ -2,34 +2,9 @@
|
||||
|
||||
本清单是流水线的唯一登记处:要做的事先在此登记一条,随流水线段推进改状态,做完整条删除;各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据含可选优先级,正文=实况/缺口/改动面/状态四属性)与状态机以 [doc-conventions §12.1](design/engineering/doc-conventions.md) 为权威。
|
||||
|
||||
#### 架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批(2026-10-29 登记,来源=审计发现)
|
||||
|
||||
**实况**:2026-10-29 全库架构静态审计完成,读数见 reports/审计-全库架构审查-2026-10-29.md(七节:总评/健康面/P0/P1/P2/待裁点/取证口径;零测试执行零引擎运行,全部结论带 文件:行号)。健康面已逐条核干净:Core 零 UI 八项判据全零命中、core 内 RNG 单点 100% 成立、字符串式信号连接全库 0 处、core 层零超长函数、19 表 ↔ 19 schema 一一对应、无循环 preload。问题集中在三条「写了没闸守」的纪律被实际破坏:①数值单一事实源被 18 处硬编码击穿,最危险两处是 `presentation/main.gd:787` 与 `:790` 把 `rap_refresh_cost=8` 与 `refresh_cap_per_round=2` 写死进提示文案(紧邻 783 行是正确读表的),表改文案不改、玩家直接受错误数字;另有 4 组代码自标「机制结构常量/产出约束」的字面量(`node_map_generator.gd:12` `MAX_WIDTH`、`action_economy.gd:14` `CHARGE_LAYER_CAP`、`board_data.gd:9` `SPAWN_AREA_CELLS`、`node_map_generator.gd:83-94` 域字面量)是否入表待裁。②`game/sim/` 与 `game/core/` 四组平行实现——扫雷推理引擎双份(`board_generator.gd` `measure_inferability` 族 vs `auto_player.gd` `_deduce` 族,输入集口径不同:前者含 safe_set oracle、后者 no-peek)、伤害掷点期望重算(`damage_probe.gd:196-201`)、档位排序与驱动循环双份(`level_autoplay.gd` vs `treasure_item_table.gd:44` 与 `battle_driver.gd:17`)、FakeDB 伪造表喂生成器——直接威胁「模拟读数 = 游戏真实数值」这一数值验证前提。③RNG 单点纪律在 core 外失守(sim 4 处/probe 1 处/tests 3 处自建 `RandomNumberGenerator`,均显式定种、确定性尚存),而 `static_scan.sh` 的 S1/S2 扫描面只含 `DIR_CORE` + `DIR_PRES`。守卫面另有三缺口:S8 是 9 文件显式清单(新增结算文件忘登记=静默不扫,缺位自检只防删改不防增)、S9 类型闸与 S13 质量闸扫描面止步于 core+data+presentation(sim/probe/tests 三层除 S11/S12 外零闸)、S13 三处豁免常态化到最大户文件(`battle_orchestrator`/`main.gd`/`tune_sim_controller`);另有四个 core 文件零测试点名(`attune_loadout`/`battle_fx_host`/`meta_state_store`/`slot_store`)。P2 级:`core/settlement/` 五段类直读写编排器私有成员 20+ 处(`oc._damage.*`/`oc._enemy_system.*`,GDScript 无编译期检查、改名静默断裂);架构文档三处漂移(`architecture.md:110` 登记的 `core/hero_ledger.gd` 盘上不存在且 `hero_ledger_test.gd:171` 显式断言它必须不存在、`:135` 行数过期、EC8 热重载门后 `ConfigDb.reload()` 零调用方且走 `load()` 拿不到磁盘新值);class_name 级双向依赖(`core/config_db` → `data/schemas/board_gen_table` → `core/board_data.SPAWN_AREA_CELLS`)与 `NODE_TYPES` 词表双份;`MetaProgression` 是唯一用 `get_node("/root/...")` 取依赖、唯一跨 Autoload 直调的单例。
|
||||
|
||||
**缺口**:审计只出读数不出方案,报告第六节 7 条待裁点全部未裁——①A 类硬编码 18 处的修复通道归属(core/presentation 侧属需求改动须写卡+编排,sim 侧属工程改动,两类不能混一批);②B 类结构常量是否入表(`SPAWN_AREA_CELLS` 已被 data 侧校验反向引用,边界需明确);③sim 四组平行实现收敛到 core 还是承认双口径并显式登记;④闸面缺口补不补(S1/S2/S9/S13 是否纳 sim 入扫描面、S8 是否改目录域);⑤S13 三处豁免收回还是登记长期例外;⑥零测试点名四件补测试还是登记豁免;⑦文档漂移三处是否先按 doc-design 落回 `architecture.md`。讨论段须逐条裁决并定整改分批(哪些进需求卡片、哪些走工程直改、哪些纯文档),产出=各条处置决定与批次归属;裁决落完本条方可转写卡或直改。
|
||||
|
||||
**改动面**:文档+游戏代码+工具代码
|
||||
|
||||
**状态**:待文档设计
|
||||
|
||||
#### 三关色相 × 五组微光互辨抽测——三关图类型色板终值冻结的前置抽测(2026-10-28 登记,来源=会话提及)
|
||||
|
||||
**实况**:三关图类型色板(`tile_closed` 与 `wall_ambient` 两槽)的终值冻结前,须先跑一次「三关色相 × 五组类型微光」互辨抽测——格底与类型微光同在未开格面上,邻近色相有吞没风险。`design/art/art-bible.md` §6.3 共同纪律已把该抽测立为终值取值程序的第一条:先抽测、再按 §4.3 现行规则重跑 §1.4 格子样张冻结,色值不代填。三关方向候选现行=暖石棕/灰白蓝/灰黑+矿脉金属色;五组微光色带=芥末黄/黄绿/青/紫罗兰/绯红(§4.2),抽测要把这两组逐一交叉比对。本条由 2026-10-28 战斗一屏样张目标规格设计轮的 A-3 定值派生——该轮裁定不沿用方向候选直接定终值,先跑抽测。
|
||||
|
||||
关联文档清单:
|
||||
- 相关文档 [美术圣经](design/art/art-bible.md) v3.22(2026-10-28)——§6.3 终值取值程序登记行(本抽测的挂点)与三关方向候选行、§4.2「类型微光色带」条(五组色相 + 明度双码)、§4.3 图类型四槽与不变槽、§1.4 格子样张(终值冻结闸)
|
||||
- 设计轮依据:2026-10-28 战斗一屏样张目标规格设计轮 §8.1 A-3 条(该轮过程稿已按「吸收即死」删除、不入库,定值与推导沿革见 commit 50702ea5)
|
||||
- 抽测方案(过程稿):reports/提案-三关色相互辨抽测方案-2026-10-29.md(2026-10-29,取样面/互辨判据/产物形态三件定值与执行步骤 S1–S7)
|
||||
|
||||
**2026-10-29 美术设计段闭合**:三件缺口全部定稿,待裁点 0 条。①取样面=3 关 × 5 组=15 对,每对铺 3 格(素砖底/装饰变体 A/装饰变体 B)=45 取样格,另每关每底型 1 格无微光基准=9 格,合计 54 格;画布 640×1120,正图段+灰度副本段;装饰变体底**带**、迷雾记忆态底**不带**(§4.2/§4.6.3/§6.5 三者合起来永不同格)。②判据=目检四条+机检四条并用,沿 §1.4 已立闸形「目检先行、机检冻结」;机检阈值全部取自本作在役值(合成对比 ≥1.20、格底-微光三通道差不得全部 <8/255、样图读数与合成模型差 ≤±2/255、铺底值准入 L≥0.30/饱和 ≤0.55/避 300°–345°),**色相通道刻意不设机检阈值**(圣经无色相差门槛条文,自造等于把观感问题伪装成可机检问题)。③产物形态=**两者兼有**(并列样图承担目检、逐对读数表承担机检与回归),故改动面须补「美术素材」与「工具代码」两档。新增色值 **0 枚**——`tile_closed`/`wall_ambient` 属 §4.1 分层②场景环境子板,**不占 48 token 额度**,故「额度用尽」不构成阻塞;三关瓦片色表已在役(`tools/recolor_terrain_tiles.py` 的 `PALETTES`,每套 23 色 ≤32),终值从墙顶受光档槽取即可。执行前提已核:三关瓦片现件(dungeon/underdark/deep_underdark 三套)在本机 `game/assets/art/board/` 齐备,可开跑。
|
||||
|
||||
**改动面**:文档+美术素材+工具代码
|
||||
|
||||
**状态**:美术设计已闭合+待执行
|
||||
|
||||
#### 验证与清单体系整改——四方向分阶段推进(2026-10-28 登记,来源=会话提及)
|
||||
|
||||
**实况**:用户裁「验证及清单不合理」,经调研定四方向全做、分阶段推进:A 粒度整改(清单从断言级升到能力/行为级,逐断言账本退役)→ B 精简裁断(在新粒度上规则驱动删并)→ C 流程风险分级(P0/P1/P2 验收强度、审计抽样)→ D 文档减肥(待办条目限长、历史归 git);测试有效性度量暂不处理。阶段 0 盘点已毕:验证集清单零机器闸依赖(run_all_gates/hooks/五技能均不引用,仅 test-conventions §8.3 维护锚+2 份过程报告引用),退役无闸改动;但测试名尾缀仅覆盖 28/47 个有断言文件(19 个零尾缀,含 seal_polarity 69 条、variant_placement 42 条、roll_multiplier 35 条),故能力清单只能按「能力→代表用例」建,不要求逐断言尾缀。对照表列改动触 pipeline_gate+req-card/iter 两技能;待办正文压缩不触机检(无长度判据)。盘点明细见 reports/盘点-验证与清单体系-2026-10-28.md。**阶段 1 设计已闭合(2026-10-28 用户四裁点)**:能力清单 v1 落 `game/tests/README.md`——按系统归属与玩家旅程排序,首期核心四域(存档与随机、冒险循环、战斗结算、奖励与经济)29 行+跨域条件闸 1 行,共 30 行,每行真实入口+2–3 个代表用例(`文件:函数`),维护规则为每批收口核对本批受影响行并刷新「最后验证批次」;`design/engineering/test-conventions.md` §8.3 维护锚改写为「验证集清单整册冻结、能力清单承接覆盖索引、阶段 2 精简后删除」;`game/tests/验证集清单.md` 头注同步冻结声明,冻结快照(基点 `b9260138`/1587 条)留作阶段 2 对账基准;`tools/extract_checks.py` 保留为审计工具,不再承担常态同步。**阶段 2 已执行闭合(2026-10-28 C 档合回)**:存量断言精简 C 档 6 组手写断言族并为 7 个表驱动站点(33→7),冻结清单对账 1587→1561,验证集清单随阶段 2 完成退役(覆盖索引归能力清单,维护锚 test-conventions §8.3),删并申报与件核见 reports/工程改动报告-存量断言精简C档-2026-10-28.md;阶段 3–4 待各自设计推进:风险分级与审计抽样规则、条目限长是否入 pipeline_gate 均未定。**2026-10-29 阶段 1 落地定稿(用户三裁)**:①能力清单与覆盖域表落 `game/tests/README.md`,独立成表、不与 GDD 验收标准合并;②GDD 纯度判红——系统与概念文档全文禁写实现细节(代码路径/测试文件名/断言名),唯一例外=配置文件索引(`game/data/tables/*.tres` 表路径与表名);③能力清单维护归写卡段——写需求卡片时增删能力行并刷新「最后验证批次」,实现批禁写该文件(清单按规则滞后一个迭代,属设计后果)。三层模型(验收意图/覆盖索引/执行证据)与四法则落 test-conventions §8.9;落地分五批:①三份规约+AGENTS.md 红线+本条实况(本批);②README 覆盖域表+三域能力行补齐;③`tools/capability_audit.py` 文档域新闸(3a 普通工具入库/3b 接闸+基线,worktree);④pipeline_gate 对照表加「能力行」列+req-card/iter 两技能同步;⑤GDD 存量实现细节清理(28 篇约 98 处,逐处去向表过用户目后落笔)。**2026-10-29 阶段 1 五批全部落地**:①032d923c;②5377b2ce;③`tools/capability_audit.py` 入库 ae3c99e3+接闸上电 915222fa(文档域闸 08e 能力审计,纯度红清零后才上电);④f3263444;⑤GDD 清理 00312e12(30 篇去 124 处实现指证,纯度红 124→0)。阶段 1 收口;阶段 3–4 待各自设计推进。
|
||||
**实况**:用户裁「验证及清单不合理」,经调研定四方向全做、分阶段推进:A 粒度整改(清单从断言级升到能力/行为级,逐断言账本退役)→ B 精简裁断(在新粒度上规则驱动删并)→ C 流程风险分级(P0/P1/P2 验收强度、审计抽样)→ D 文档减肥(待办条目限长、历史归 git);测试有效性度量暂不处理。阶段 0 盘点已毕:验证集清单零机器闸依赖(run_all_gates/hooks/五技能均不引用,仅 test-conventions §8.3 维护锚+2 份过程报告引用),退役无闸改动;但测试名尾缀仅覆盖 28/47 个有断言文件(19 个零尾缀,含 seal_polarity 69 条、variant_placement 42 条、roll_multiplier 35 条),故能力清单只能按「能力→代表用例」建,不要求逐断言尾缀。对照表列改动触 pipeline_gate+req-card/iter 两技能;待办正文压缩不触机检(无长度判据)。盘点明细见 reports/盘点-验证与清单体系-2026-10-28.md。**阶段 1 设计已闭合(2026-10-28 用户四裁点)**:能力清单 v1 落 `game/tests/README.md`——按系统归属与玩家旅程排序,首期核心四域(存档与随机、冒险循环、战斗结算、奖励与经济)29 行+跨域条件闸 1 行,共 30 行,每行真实入口+2–3 个代表用例(`文件:函数`),维护规则为每批收口核对本批受影响行并刷新「最后验证批次」;`design/engineering/test-conventions.md` §8.3 维护锚改写为「验证集清单整册冻结、能力清单承接覆盖索引、阶段 2 精简后删除」;`game/tests/验证集清单.md` 头注同步冻结声明,冻结快照(基点 `b9260138`/1587 条)留作阶段 2 对账基准;`tools/extract_checks.py` 保留为审计工具,不再承担常态同步。**阶段 2 已执行闭合(2026-10-28 C 档合回)**:存量断言精简 C 档 6 组手写断言族并为 7 个表驱动站点(33→7),冻结清单对账 1587→1561,验证集清单随阶段 2 完成退役(覆盖索引归能力清单,维护锚 test-conventions §8.3),删并申报与件核见 reports/工程改动报告-存量断言精简C档-2026-10-28.md;阶段 3–4 待各自设计推进:风险分级与审计抽样规则、条目限长是否入 pipeline_gate 均未定。
|
||||
|
||||
**改动面**:文档+游戏代码+工具代码
|
||||
|
||||
@@ -51,29 +26,22 @@
|
||||
|
||||
**状态**:待执行
|
||||
|
||||
#### 能力清单覆盖缺口补齐——六类无断言面或设计未定项(2026-10-29 登记,来源=会话提及)
|
||||
#### gdstyle 存量债全量清偿——216 键按病根分波整改(2026-10-26 登记,来源=会话提及,优先级=P0)
|
||||
|
||||
**实况**:证据=`game/tests/README.md` 覆盖域表 25 篇对照行(2026-10-29 立)。以下部分覆盖/未覆盖项作为缺口指针,逐项:①增益状态——只验契约词表与布尔受理,叠层/衰减/清除结算链无断言;②设置与本地化——减动效开关本体仅系统测试与冒烟覆盖、无单元/集成断言,多语言切换面未建;③音频——MVP 无音频,P1 后置无断言面;④战斗表现——死亡灰化与减动效演出档只有探针与人工目检;⑤难度曲线与Boss——难度曲线整链与 Boss 出场门控无专项断言;⑥锻造工坊——价格梯仅长剑路线逐级验,GDD 无验收标准节(`capability_audit` 验收标准豁免在册)。教学引导与生涯两篇的缺口归各自在册条目(「教学形态未定」「「生涯」界面——冒险中数据回看的唯一承接处」),不在本条。补齐时同批刷新覆盖域表与能力行,新增断言按 test-conventions §8.4 绑真实入口。
|
||||
**实况**:S13 闸实测存量债 216 键/60 文件(2026-10-26,master f3b148ce,gdstyle v0.4.0 默认阈值;基线登记 234 键=实存 216+陈旧 18)。全量清单、波次方案与纪律见清点报告(本条目裁决源)。2026-10-26 用户裁:撤销「一条总账」与「按病根拆多条」两案,并为本条单账(存量债全部清除,紧急优先级);原「gdstyle 基线陈旧键待人工清理」条目并入波 0(基线对账刷新),原「结构审查未立项小件候审」条目并入波 7(卡已写;iter38 施工停卡后经用户裁于 2026-10-26 修订定稿 v1.3,待编排)。**2026-10-26 设计段闭合(逐波裁定全数落定)**:①段组织=逐波开设计段,纯代码波(波 0/2/3/4/5/6/8)写卡前确认零设计改动+按当时 master 重测读数即可写卡;②波 2 各文件内部拆、波 6 视图内部拆私有函数、波 8 config_db 纯代码收敛(三处零设计改动);③波 1 拆件定稿=轴甲两件——battle_orchestrator 拆出 BattleFxHost(效果引擎宿主域)+RewardGrant(奖励授予域),宿主保留状态机/facts 缓冲/订阅/段驱动/行发射基建/呈现投影,attune 族原位保留(迭代 39 副卡语义领地),emit 经 bind 注入 Callable,行数恶化债(c4c69701 挂账)本波还债归绿,残留债「改善非清零」口径预计 8–10 键;定稿落文 architecture.md v1.18(功能层两新件行+「战斗编排域拆件定稿」节);**同日独立审查折入**(grilling+godot-master 双子代理并行、双判回炉补裁级——骨架成立、接线未闭合):阻断 8 条去重 6 组+建议 5 条全数折入 v1.18——跨件单向接线裁死(RewardGrant 持 fx 件引用/fx 兑付走注入 Callable,禁 RefCounted 环)、settlement/ 段类随动(直持三引用封转发壳)、12 随迁键卡内收敛义务(禁波 0 refresh 吸收)、两新件消费依赖列补全+引用束注入、treasure_interact_controller 三触点分家(现值回调双取值面)、_fx_revealing 再入闸归 fx 件(裁定全文见清点报告 §六第 6 条);④全部波不改游戏规则与玩家可见行为,design/gdd/systems/ 零修订预期;波 5 已实查落定纯代码(open_ticket 12 参=单据声明形态)。波 7 的 wr5/wr6 验收载体重裁为写卡段用户裁点(卡 v1.2 在册,写卡补呈报)。裁定全文见清点报告 §六。**2026-10-28 迭代 40 合回出账(波 1+波 7 闭合,合并提交 514457d1)**:卡①(波 1)45 键清 44、宿主类变量键豁免第三条顺带落 architecture v1.22 S13 豁免登记,行数恶化债还清(实测 1036≤登记 1302;契约 2 残余 36 行系合并适配承接 master 迭代 39 内容带入,用户裁登记残余债归后续批);卡②(波 7)六件定点修+运行期违约通道负面套件(run_time_fatal_test)落地合回。余波 2/4/6/8 归迭代 41 两卡(在册)。
|
||||
|
||||
**改动面**:游戏代码
|
||||
关联文档清单:
|
||||
- 清点报告 reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md(2026-10-26,216 键全量清单+波次方案+纪律+设计段裁定记录 §六含整合裁定第 7 条)
|
||||
- 设计定稿 design/engineering/architecture/architecture.md v1.19(2026-10-27:波 1 拆件定稿 v1.18 节+全清设计补课——ConfigDB 访问器归位与域容器持有+SlotStore/MetaStateStore 两新件行+组合根句柄面/测量面两处 S13 豁免登记)
|
||||
- 需求卡片 B1 战斗域拆件批卡(2026-10-27 v1.1 全清口径修订后编入;已随迭代 40 实现批合回退役,git 历史可考——合并提交 514457d1)
|
||||
- 需求卡片 reports/需求卡片-核心数据面结构收敛批-2026-10-27.md(v1.2=v1.1 全清口径修订〔2026-10-27〕+拆分边界纪律契约 7 落卡〔2026-10-28 用户裁 DDD/高内聚〕;config_db 访问器归位+三域容器+SlotStore/MetaStateStore 拆件+adventure_table 拆段+spawn 束化;估时 ≈7.9d;零待裁点)
|
||||
- 需求卡片 reports/需求卡片-呈现层结构收敛批-2026-10-27.md(v1.2=v1.1 全清口径修订〔2026-10-27〕+拆分边界纪律契约 9 与 u1 子域拆件改法落卡〔2026-10-28 用户裁 DDD/高内聚〕;print 删除+七件绘制态内部收拢+main/await 两键按 v1.19 豁免申报;估时 ≈5.3d;零待裁点)
|
||||
- 三宿主主副卡(已随迭代 39 实现批合回退役,git 历史可考——合并提交 ffb0ac15;原「规避指向:本事项禁触三宿主」随三宿主债清偿完成历史使命,残留归尾波)
|
||||
- 需求卡片 结构小件定点修批卡(波 7 现成卡:iter38 卡②停卡退回上游后经 v1.3→v1.4 修订定稿编入;已随迭代 40 实现批合回退役,git 历史可考——合并提交 514457d1)
|
||||
|
||||
**状态**:待执行
|
||||
**改动面**:游戏代码+工具代码
|
||||
|
||||
#### 迭代 41 测试债修复——9 个套件失败与静态扫描三项红(2026-10-29 登记,来源=批次移交)
|
||||
|
||||
**实况**:证据=能力审计上电批(worktree 分支 `capgate-20261029`,提交 48e6e551)全量闸复跑,首次实测迭代 41 两卡合回(合并提交 eb9bb537,测试特许移交+直接合回,见 roadmap 收口注脚)后的代码面真实状态:①02 单元与集成测试 9 套件失败——`config_db_test`(`if` 块内声明的变量在块外引用,解析错误)、`config_db_fatal_oob_test`(退出码 2≠期望 1)、`table_structure_guard_test`(`_TreeSaveMock` 缺 `meta_state`)、`treasure_items_test`(`StubDB` 缺 `crossrun`)、`standee_fx_sweep_test`(`set_trans` 空引用)、`forge_workbench_test`(120 秒超时挂死)、`tree_requires_level_test`(`row_by_id` 在空基址)、`save_manager_domain_test`(缺 `_migrate_legacy_save`)、`theme_projection_test`(`CampOverlay` 缺 `_recent_list`);②09 静态扫描红项清单与基线不一致——S9 类型闸 24 处(迭代 41 拆出的新件缺 `# type-hint: ignore` 注解与参数类型)、S10 文件头 4 处(`config_db` 与三个域容器头注日期)、S11 注释禁用词 1 处(`adventure_table.gd:55`),而 gdstyle 与 S13 已随迭代 41 还清(基线两条存量红已过期,须随修复实测重生成)。本条目只修测试与注解债、不改游戏行为。本批合入经用户 2026-10-29 裁带红合并:能力审计上电批只动闸件与规约(代码域零新增红),代码域现存红全部由本条目承接。**2026-10-29 用户裁(「表结构版本」数值冲突甲案+孤儿常量可删)**:文档侧已随文档域直改落地——数据配置.md 删「表结构版本」调参行、依赖表与验收项中的版本常量表述,存档序列化.md 迁移链「表结构版本对齐」改「随表结构变化」,architecture.md 两处常量名改现役 `SAVE_FORMAT_VERSION`;代码侧 `game/core/config_db.gd` 的死常量 `SCHEMA_VERSION`(全仓零引用,值为 1,与文档原载 2 无对应)随本批删除。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:待执行
|
||||
|
||||
#### gdstyle 尾波清偿批——基线余量 11 键定向整改(2026-10-29 登记,来源=审计发现)
|
||||
|
||||
**实况**:证据=`tools/gdstyle_baseline.txt`(2026-10-29 人工重锚后余量 16 键)+reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md(§三波次方案与 §六文档设计段裁定记录,裁定全部继续有效)。迭代 39/40/41 三批清偿后余 16 键:本批承接 11 键——board_view 6(_paint_cell 长度 139/分支 24/局部 22、循环内 new、类变量 32、公开方法 27)/level_runner 3(公开方法 50、类变量 30、_enter_node 返回 7)/battle_orchestrator 文件长 1035/adventure_runner 类变量 28;另 5 键走豁免通道另行讨论不在本批(main.gd 类变量 49、tune_sim_controller 循环内 await、board_cell_unit 类变量 30、standee_body 类变量 19、battle_orchestrator 类变量 38——其中三条已有架构豁免登记)。需求卡片 v2.0 定稿(零待裁点):reports/需求卡片-gdstyle尾波清偿批-2026-10-29.md 设计段裁决 2026-10-29 用户裁闭合(D1 装板域拆新件 BoardInstaller 两修正·architecture v1.24 轴丙已落文/D2 悬停域不拆/D3 商店域候选 A/D4 断点域不拆/D5 五降值键豁免终局/D6 商店域并排编队——执行合同=并排卡「level_runner 商店委托层拆除」v1.1,本卡不重复执行),零待裁点。预期两档:归绿 6 键(_paint_cell×3、循环内 new、_enter_node、文件长);豁免终局 5 键(board_view 32/27、level_runner 50→33/30、adventure 28——批末按实测值落 architecture 豁免登记,键 7 实测值视并排卡时序)。本卡估时 3–4.25 工作日(并排卡 ≈1.5 工作日另计)。MC/数值零触碰(结构整改不改数值与 RNG 消费序);battle_orchestrator 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚。S13 键账对账在批末,基线重锚由用户发令人工 --refresh(预期降幅逾 10% 须 --force)。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:文档设计已闭合+已写卡+已编迭代 42
|
||||
**状态**:文档设计已闭合+已写卡+已编迭代 41
|
||||
|
||||
#### 数值标定窗口总挂账——原九条数值类条目合并(2026-10-28 登记,来源=会话提及)
|
||||
|
||||
@@ -105,11 +73,11 @@
|
||||
|
||||
#### level_runner 商店委托层拆除——迭代 37 冻结契约期过渡件(2026-10-26 登记,来源=批次移交)
|
||||
|
||||
**实况**:证据=迭代 37 卡④ ShopSession 拆分时立「冻结公开面」契约,level_runner 保留 buy_product/shop_refresh 等同签名委托方法(架构模块表登记为「外部调用面由宿主同签名委托承载」)。2026-10-26 AdventureRunner 真拆分设计会话裁定新原则:纯转传委托=Middle Man 反模式,新件一律调用方直连不留壳(godot-master 技能库审查同判);本批不动该委托层(真拆分条目范围仅撤 8 条白盒转发属性),其拆除与调用文件改址由本条承接。需求卡片:reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md(v1.1,2026-10-29,复核门通过零待裁点)。
|
||||
**实况**:证据=迭代 37 卡④ ShopSession 拆分时立「冻结公开面」契约,level_runner 保留 buy_product/shop_refresh 等同签名委托方法(架构模块表登记为「外部调用面由宿主同签名委托承载」)。2026-10-26 AdventureRunner 真拆分设计会话裁定新原则:纯转传委托=Middle Man 反模式,新件一律调用方直连不留壳(godot-master 技能库审查同判);本批不动该委托层(真拆分条目范围仅撤 8 条白盒转发属性),其拆除与调用文件改址由本条承接。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:已写卡+已编迭代 42
|
||||
**状态**:待写卡
|
||||
|
||||
#### 超预算图策略升级路径——等比缩放与滚动视口两案待裁(2026-10-24 登记,来源=批次移交)
|
||||
|
||||
@@ -150,18 +118,12 @@
|
||||
|
||||
**实况**:[美术圣经](design/art/art-bible.md) §7.1 明文写着"程序化占位=临时态,任何屏的终稿闸=§1.4 整屏样张过闸;占位态禁止跨里程碑"。而 [美术素材状态清单](design/art/art-status-checklist.md) 把「战斗一屏样张」这件最高优先级的素材标的是**未开始**——也就是说,**判定界面美术算不算过关的那把尺子到现在还没造出来**。2026-10-16 曾编入迭代 30 卡②(UI 呈现三卡批序位②),2026-10-17 用户裁定不满足「迭代=代码实现批」的开发条件、剔除回待设计(理由=样张交付物本身就是设计规格,正式字体与素材均未定稿;同日样张批开工已被用户终止)。v1.4 旧卡留 reports/需求卡片-战斗一屏样张批-2026-10-16.md 作素材,非已写卡状态,重启不得直接开工。Alpha 出口裁决:列入 Alpha 硬前置——站桩帧动画的定版前置与主角+三 Boss 重产都依赖它。
|
||||
|
||||
**2026-10-28 美术设计段闭合**:差的那轮「设计讨论→需求澄清→美术定稿」已完成并落文——样张即设计目标图,五张规格表(尺寸档/色板/明度档/字号档/素材清单)全定、样张构图与内容清单全定、验收判据清单全定、16 条待裁点全数清零(最后一条 B-1 色板第二道门口径经 2026-10-28 用户裁取乙案宽松口径);样张的产出手段与素材输入级别已定,样张开工门复判 PASS。原缺口三件的前两件(目标规格清单、屏内素材规格)由此闭合,第三件(重启须重新立卡)转为本条的下一动作。
|
||||
|
||||
关联文档清单:
|
||||
- 美术线闭合凭据(art-bible 条款版本):[美术圣经](design/art/art-bible.md) v3.22(2026-10-28)——§1.4 样张产出手段与素材输入级别登记句、§2 世界底层两子带、§4.1 第二道门口径改写与色板转正/换色合并登记、§4.2 血条填充显式句与蓝族违例值退役、§6.1 舞台背景路径订正与近景地台独立件、§6.3 三关色板终值取值程序、§7.2 文字禁直接压地台、§7.4 顺位徽标不增列与字重重开钩子注销、§7.6(三) 氛围两派维持不统一、§8.2 护甲图标与地台件规格与棋盘小人 32px 源档终值、§8.4 方向集口径追认
|
||||
- 美术线设计轮定值与依据:2026-10-28 设计轮(过程稿已按「吸收即死」删除、不入库,结论已吸收进上一条,推导沿革见 commit 50702ea5 与 10d7c82b)
|
||||
- 配套资产登记:[美术资源依赖清单](design/art/art-assets-checklist.md)(2026-10-28,§3.7 护甲类型图标三枚与 §4 舞台背景/地台件两行)· [素材路径分工约定](design/art/asset-path-map.md)(2026-10-28,`scene/` 子目录现役列)
|
||||
- 相关文档:美术线(战斗一屏样张的验收标准归 [战斗表现](design/gdd/systems/战斗循环/战斗表现.md) 与 [美术圣经](design/art/art-bible.md) §1.4 共裁)
|
||||
- 需求卡片:reports/需求卡片-战斗一屏样张批-2026-10-28.md(2026-10-28 重新立卡,十二节齐备,旧卡 v1.4 已作废;待编入迭代,编入后由编排段记「已编迭代 N」)
|
||||
**缺口**:还差「设计讨论→需求澄清→美术定稿」一轮设计(样张即设计目标图,产出尺寸档/色板/明度档清单反向给素材批),定稿后重新立卡方可开发。旧卡 v1.4(reports/需求卡片-战斗一屏样张批-2026-10-16.md)在册但非已写卡状态,其前置未完成三件:①这一轮设计未做,样张的目标规格清单没有来源;②战斗一屏所需素材未定稿(前置里的正式字体半边已定稿——2026-10-24 用户裁 Fusion Pixel 单套即终稿,见 [美术圣经](design/art/art-bible.md) §7.4);③2026-10-17 用户已终止该批开工,重启须重新立卡。
|
||||
- 相关文档:美术线(战斗一屏样张的验收标准归 [战斗表现](design/gdd/systems/战斗循环/战斗表现.md) 与 [美术圣经](design/art/art-bible.md) §5.1 共裁)
|
||||
|
||||
**改动面**:美术素材
|
||||
|
||||
**状态**:已写卡+已编迭代 43
|
||||
**状态**:待美术设计
|
||||
|
||||
#### UI 氛围层与九宫格切片观感修——光柱硬边与面板切片错位(2026-10-13 登记,来源=审计发现)
|
||||
|
||||
@@ -440,6 +402,14 @@
|
||||
|
||||
**状态**:待写卡(备选)
|
||||
|
||||
#### tests/README manifest 计数行漂移订正——「64 条」对实际 65 条(2026-10-28 登记,来源=批次移交)
|
||||
|
||||
**实况**:证据=单元闸挂死守护批收尾实数(合并提交 4afe6c47,报告 reports/工程改动报告-单元闸挂死守护-2026-10-28.md)——`game/tests/run_all.gd` manifest 实为 65 条(62 单元+3 集成,grep '{"path"' 计数),`game/tests/README.md`「套件 manifest 现况」行仍记「64 条(61 单元+3 集成,2026-10-28 实数)」。漂移先于该批存在(主区与任务分支同值),该批未动套件数不属其 scope,登记归文档批订正。
|
||||
|
||||
**改动面**:文档
|
||||
|
||||
**状态**:待执行
|
||||
|
||||
#### 主角棋盘小人像素管线重产——原「美术资产链路审计两项 P0」之 P0②(2026-10-09 登记,来源=审计发现)
|
||||
|
||||
**实况**:主角棋盘小人未走像素管线(插值糊图),重产事项未在任何登记处在册;审计报告 HTML 件从未进版本库、现已删除,现状以本条正文为准。2026-10-13 用户令随「UI 美化三层诊断」登记:本条属第三层「观感提升」,Alpha 阶段需完成。原 P0①(文档面:两处引用已丢失的冻结样张路径)2026-10-28 按用户裁乙销号——art-bible §1.4 冻结记录与 art-status-checklist P0 样张行删路径、留「产物原件已丢失」,机检报告凭据(git 提交 7a847c7)保留。
|
||||
|
||||
Reference in new issue
Block a user