merge: 奇物概念收口与词族对齐(迭代15②号卡·文档与数据层)
概念层由用户逐轮裁定定稿(《奇物》v1.0→v2.7),本批只做落地对齐。 主要内容: - 新建 design/gdd/systems/冒险循环/奇物.md v2.7(本概念唯一定义文档) - 新建 design/research/任务书-奇物词族对齐与渠道分离批-2026-10-05.md (loop engineering 八件成文 + 12 条批末验收断言 + 11 条设计契约含 6 条停机级) - 代码词族对齐:feature_* → FEATURE_KINDS/feature_quota_*/feature_value_* (adventure_table.gd 24 字段 + 方法 + 常量,adventure.tres 21 键,值零变更) - 三个 schema 补概念指路注释;relic_table.gd / adventure_table.gd 概念注释指向奇物.md - ux/battle.md、level-map.md、HUD框架.md、06-待办清单.md、02-系统清单.md、 registry/entities.yaml 同步称谓与元信息 六处冲突解法: - 02-系统清单.md:版本历史整段重编(master v0.1-v1.3 原号复原,奇物系列从 v1.4 起) - ux/battle.md:取分支侧新称谓,但「魔法道具槽」须写「秘宝槽」(master v1.3 已更名) - adventure_table.gd:合成并集(取本批改名 + 保留 master SR-1 商店刷新三字段) - level_map_screen.gd:块1 取 master M5 底栏结构,块2 取本批配色与称谓 - registry/entities.yaml:7 处三方混战,块1-5/7 取 master,块6 取本批 - roadmap.md:迭代 15 两卡并存(①调试 已落籍 / ②奇物 待开工) 合并后自查修正: - 批量替换误伤 70 处(清图奖励/安全格奖励/关卡大奖励/奖励身份预读 等 属地图战斗资源域;「奖励道具经济」旧文件名与「迭代 10 奖励重构」属历史留痕)→ 全部回退 - battle.md 历史修订行误改 → 恢复 master 原文 - 奇物.md 5 处死链(../ux/ 少一层、魔法道具.md 已更名)→ 修 - registry 条目 markdown 链接 → 改纯路径(同文件惯例) - 奇物.md R1 散文段 656 字 → 拆段,现在零结构性告警 验证读数(合并后主区全量复跑): - 冒烟 755 项 / 0 失败,三闸全过 - ui_input_probe 十六断言全绿 - ui_layout_probe 四区尺寸逐位吻合 battle.md 规格 - doc_link 死链 0;doc_term 与基线同;gdd_lint 零新增 - 旧标识符残留全 0;_status_box 未成死代码,四个投喂键齐全
This commit is contained in:
commit
c571af226f
32 files changed
+1171
-209
No files matched your search
+10
-2
@@ -45,6 +45,7 @@
|
||||
| `关卡节点图生成.md` | 单关节点图的逐局随机来源:图模板池、抽签与实例化(实施排队 ADR-0007 裁决后) | 设计草案·拍板点全落文 |
|
||||
| `冒险结构.md` | 整局冒险的关卡序列、失败与大奖励 | 已定稿·自旧体系迁移 |
|
||||
| `难度曲线与Boss.md` | 难度曲线、期望值带与 Boss 设计 | 已定稿·自旧体系迁移 |
|
||||
| `奇物.md` | 一次冒险内各渠道给予玩家的增益总称(三个分类:专长 / 属性值提升 / 资源 × 三条渠道:奖励节点 / 商店 / 关底 Boss 击败) | 已实现·2026-10-05 新立定义·v2.0 改名并重构为两根轴 |
|
||||
|
||||
### 跨局循环(`systems/跨局循环/`)
|
||||
|
||||
@@ -96,6 +97,7 @@
|
||||
| 冒险循环 | 关卡节点图生成 | `NODE_MAP_GENERATION` | —(新立无旧代号) |
|
||||
| 冒险循环 | 冒险结构 | `ADVENTURE_STRUCTURE` | c2 |
|
||||
| 冒险循环 | 难度曲线与Boss | `DIFFICULTY_CURVE` | c3 |
|
||||
| 冒险循环 | 奇物 | `ADVENTURE_CURIO` | `ADVENTURE_FEATURE`(v1.0)→ `ADVENTURE_REWARD`(v2.0,v2.4 退役) |
|
||||
| 跨局循环 | 元进度 | `META_PROGRESS` | c4 |
|
||||
| 表现与支撑 | HUD框架 | `HUD_FRAMEWORK` | d1 |
|
||||
| 表现与支撑 | 数据配置 | `DATA_CONFIG` | d2 |
|
||||
@@ -114,8 +116,6 @@
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 改动 |
|
||||
|---|---|---|
|
||||
| v0.1 | 2026-09-15 | 根索引随新骨架建立:循环 × 子系统总表 + 子系统命名对照表 |
|
||||
| v0.2 | 2026-09-15 | 雾格残留清理:`地形变异.md` 概要行去掉"雾格已从设计中移除"的迁移期注记(移除事实以[不做清单](05-不做清单.md)为单一出处)。文档树形状不变 |
|
||||
| v0.3 | 2026-09-16 | 更名批(用户拍板 2026-09-16):两个系统中文规范名更名——"奖励道具经济"→"地图战斗资源"、"辅助道具"→"魔法道具";循环表文件行与命名对照表中文规范名同步(文件重命名 地图战斗资源.md / 魔法道具.md);英文代号暂沿用更名前名称,对齐另批 |
|
||||
@@ -129,3 +129,11 @@
|
||||
| v1.1 | 2026-09-27 | 关卡画面 UX spec 建档(关卡画面 UX 批):`ux/` 表补 `level-map.md` 行——选路枢纽三停点布局、GP 常驻徽章、交互映射与 AC 成文,三项设计提案挂 06 待拍板 |
|
||||
| v1.2 | 2026-10-03 | R3 清账批(gdd_lint 分域随批):四处状态单元格日期批注迁出——敌人系统行事件见敌人系统.md 版本历史 v0.5(技能池批);元进度行见本表 v0.8;camp/shop 行=两文 v1.0 落文(2026-09-30 三裁决执行批);语义零变更 |
|
||||
| v1.3 | 2026-10-05 | **消歧更名批(用户拍板 2026-10-05)**:a5 行中文规范名「魔法道具」→「**秘宝**」,文档树文件名同步(systems/排雷循环/魔法道具.md → 秘宝.md);英文代号 `AUXILIARY_ITEMS` 沿用不变(代码标识符不同步属已知欠债,另批);旧代号列不变(a5 仍指 2026-09-14 归档快照)。更名理由为「魔法」一词已被本作征用为敌方侧伤害/护甲语汇(`魔法矢`/`魔法族`/`魔法护甲`),详见[秘宝](systems/排雷循环/秘宝.md) v0.9。历史定稿文档(research/qa/archive)原样保留 |
|
||||
| v1.4 | 2026-10-05 | 立《特性》:一次冒险内角色自身得到的提升——此前按内部分类被叫成三个名字(规则类称"流派件"、属性类称"数值件"、界面称"本关强化"),现收敛为一个对象的两种形态枚举;文档树冒险循环补行 + 命名对照表补 `ADVENTURE_FEATURE` 行 |
|
||||
| v1.5 | 2026-10-05 | 《特性》v1.1 分类重构:两类由"规则改写型 / 属性加成型"改为"属性提升(ASI)/ 专长(Feat)",属性提升内部再分纯属性组与特殊组;获取途径由两口共用池改为三条分工渠道(专长走特定节点、属性提升走奖励节点与商店)+罕见旁路"专长获取" |
|
||||
| v1.6 | 2026-10-05 | 《特性》改名为《奖励》并升 v2.0:顶层概念改为"一次冒险内各渠道给予玩家的增益总称",边界判据由"自身提升 vs 持有物"改为生命周期(当局清零的是奖励,跨局带走的是魔法道具);分类由两类扩为三个枚举(专长 / 属性值提升 / 资源与机会类),并新增分类 × 渠道交叉开关表——两根轴互不决定。文档树冒险循环行改名 + 命名对照表 `ADVENTURE_FEATURE` → `ADVENTURE_REWARD` |
|
||||
| v1.7 | 2026-10-05 | 《奖励》v2.1 交叉表收口:Boss 渠道只出专长(终局 Boss 不给),另两类在此不出现;新增「计价物不自售」规则处理金币不进商店——不拆第四个分类、不开特例,而是两轴交叉处的一条约束 |
|
||||
| v1.8 | 2026-10-05 | 《奖励》v2.2:专长在非 Boss 渠道改为「专长获取」门票形式(不直接给专长);渠道约束重构为三层(分类白名单/可计算谓词/显式例外清单),并承认「计价物不自售」形式上是白名单外的一道过滤、与死特判的区别在可计算;立默认原则——除已登记规则外分类内的都要在池子里,据此回复应在商店内(现行货架缺它,须补) |
|
||||
| v1.9 | 2026-10-05 | 《奖励》改名为《奇物》并升 v2.4:顶层定名 Wondrous Item(DND 魔法物品九分类中的兜底杂类,官方中文译名「奇物」)。文档树冒险循环行改名;命名对照表 `ADVENTURE_REWARD` → `ADVENTURE_CURIO`(**不用 `reward_*`**——`reward_pick` 流 / `reward_node` context / `reward_preview` kind 已占用该词族) |
|
||||
| v1.10 | 2026-10-05 | 《奇物》v2.5:第三类定名「资源」(资源偏泛,故在命名出处节写死判据句——给的是可消耗或可重掷的余量,不是属性永久抬升);回复归属定案留在本类不拆第四类;修复 1.5 段末与渠道轴标题粘连 |
|
||||
| v1.11 | 2026-10-05 | 《奇物》v2.7 三个子节点正式定名:专长(Feat)/ 属性值提升(ASI)/ 资源——去「类」字后缀,此前是描述式叫法不是专名;新增 1.6 节「三层结构与命名」,定玩家可见的三层(奇物 / 三个分类 / 具体单件),并明确命名与呈现是两件事 |
|
||||
+66
-7
@@ -25,19 +25,68 @@
|
||||
|
||||
**设计知识存续口径**:七流派完整件表/逐项反例条件表/天赋树后备语言(哈迪斯 2 预算制扩容/邻接树改型/GP 价格通胀防线)存整合定稿,随实施批文档吸收迁入各 GDD 正主(元进度/node-reward/战斗结算/地形变异/行动经济/秘宝边界句/商店 spec)——**吸收完成前定稿不删**;喂雷流待办见上条遗留登记。
|
||||
|
||||
#### 冒险 BD 两类加强物品获取同渠道、纯概率差(用户口径:获取途径须区分开,2026-10-04 提问登记)
|
||||
#### 冒险 BD 各分类获取同渠道、纯概率差——渠道分工目标态(2026-10-04 提问登记;2026-10-05 用户定分工)
|
||||
|
||||
**现状**:BD 分层口径(用户定):基础 BD(账号级,局外天赋树+同调装配)与冒险 BD(局内一次冒险的构筑)两层;冒险 BD 的加强物品两类——**流派件**(机制件,改规则、带流派标签与档位激活,构筑核心,真正改变局内强度)与**数值件**(属性加成,UI 呈现名「本关强化」,写统一加算区;账本实为冒险域、关间不清零)。现行两类**共用同一获取渠道**:三选一(奖励节点+通关)+ 商店货架 + 格面令牌同属 98 张固定配额池(普通 70/稀有 25/罕见 3),流派件只占稀有/罕见档(与数值大件混编),商店仅「货架零流派件挤掉一张普通卡」保底——获取途径与条件完全相同、仅概率不同,构筑核心的获取节奏纯看脸。
|
||||
**现状**:BD 分层口径(用户定):基础 BD(账号级,局外天赋树+同调装配)与冒险 BD(局内一次冒险的构筑)两层;冒险 BD 的加强物 = **奇物**(2026-10-05 定名,v2.4 由「奖励」改名、v2.0 由「特性」改名,定义见 [奇物](systems/冒险循环/奇物.md)),下分**三个枚举分类**:**专长**(专长——改规则、带流派标签与档位激活,构筑核心)、**属性值提升**(生命/AC/攻击三轴,写统一加算区;账本实为冒险域、关间不清零)、**资源**(行动点上限·刷新次数·金币·回复——给"可用的量",命名待定)。旧称「流派件 / 数值件 / 本关强化」一律作废;v1.0 的「规则改写型 / 属性加成型」与 v1.1 的两分类亦作废。现行三个分类**共用同一获取渠道**:三选一(奖励节点+通关)+ 商店货架 + 格面令牌同属 98 张固定配额池(普通 70/稀有 25/罕见 3),专长只占稀有/罕见档(与属性大件混编),商店仅「货架零专长挤掉一张普通卡」保底——获取途径与条件完全相同、仅概率不同,构筑核心的获取节奏纯看脸。
|
||||
|
||||
**用户期望改动**:将两类的获取途径区分开,流派件获取节奏不依赖纯概率。已呈四备选(均未拍板):① Boss/精英击杀后流派件**专属三选一**,流派件整体退出共享池〔我方推荐:确定性最高,杀戮尖塔/以撒/哈迪斯参照系全支持,与钥石逐杀 Boss 节奏同构;代价=令牌池配额回收+商店保底改向+MC 锚换代〕;② 行为条件投放(累计玩法行为定向出件,防滚雪球工程量大);③ 计步保底(每 N 奖励面必含流派件,改动最小只缓解不根除);④ 双池分离(每面必见流派件,决策密度过强,不推荐)。
|
||||
**用户定案(2026-10-05,v2.1 收口)**:分类 × 渠道交叉开关表——
|
||||
|
||||
**归属**:[node-reward](ux/node-reward.md)(令牌池与奖励面)+ [冒险结构](systems/冒险循环/冒险结构.md)(商店货架保底);与上条「双层 BD 延期与备选内容总登记」二期件组相关但不同面。
|
||||
| 分类 \ 渠道 | 奖励节点 | 商店 | 关底 Boss 击败=通过这一关(末关不给) |
|
||||
|---|---|---|---|
|
||||
| 专长 | **门票形式** | **门票形式** | **直接给**(唯一直接渠道) |
|
||||
| 属性值提升 | 出 | 出(训练) | 不出现 |
|
||||
| 资源 | 出 | 出(金币除外;**回复在内**) | 不出现 |
|
||||
|
||||
**状态**:待讨论(2026-10-04 用户提问登记,后续展开)
|
||||
**Boss 渠道是专长的独占渠道,也是唯一直接给专长的渠道**——另两类都不走这里;奖励节点与商店不直接给专长,而是给一个**「专长获取」道具(门票)**,拿到后开专长三选一。形状是"一块独占 + 两块并行",不是三块平分。**末关的 Boss 击败后不给**(打赢时冒险已结束,无后续关卡可消费),兑付只发生在还有下一关可去的那些关底 Boss 身上。用户原话:"我在获取特性的时候,可以有些比较罕见的道具,让我立马得到一个专长,就给它一点不确定性,一点随机性"。**确定性优先**:专长不因没 roll 到就构筑不起来。用户同时明确:先定大意念再分小类,渠道与分类是两根互不决定的轴。
|
||||
**兑付频率(2026-10-05 用户纠错后写死)**:这条渠道的触发点是**关底 Boss 被击败**,而按 [冒险结构](systems/冒险循环/冒险结构.md) 的定义,**打掉关底 Boss 恰好就等于"通过这一关"**——两者是同一个时刻,不是一条链上的两步。**奇物不是打一场战斗给一份**:关内普通战斗节点打完了什么也不给,一关之内奇物只兑付一次。(此前《奇物》文档的"核心循环位置"图把"战斗结算 → 通关 → 得到一份奇物"画成一条链,读起来像每场战斗通关都给一份——已于 v2.6 修正为分支图并加此口径,勿再改回链式。)
|
||||
|
||||
#### 内部分类禁写入玩家可见面——流派件呈现三处违规待改(2026-10-04 用户立意登记)
|
||||
**门票归专长,不归资源**:它给的不是"余量"而是"一件你以前不会的事",只是把选择推迟到一次三选一。**为什么只给门票**:若商店能直接买到指定专长,玩家就能用金币把构筑买出来,Boss 渠道"打赢才拿到"就失去意义;门票保留惊喜(开出的是三选一不是指定),但不让钱定点购买。
|
||||
|
||||
**现状**:用户立意(方向已明确):流派/数值等内部分类**不得写进玩家可见的道具名称、介绍词或界面**——玩家可根据效果自行推断类别,游戏不得直接点破。查证实态:26 件流派件 display_name 全风味名(奥术余烬/贯穿射击/矿工的执拗等,合规,符合 2026-09-29 playnote 既有批评);**违规三处**(均系迭代 12 呈现补齐批所落,承载用户「局内奖励选了什么看不到」反馈——缺口承载需求仍成立,撤的只是分类字样):① 三选一+商店流派件卡面第二行印流派名(`battle_narrator.gd` relic_card_text,「奥术余烬 · 魔法」式);② 战斗屏 C 区列表标题「流派件」+逐流派聚合行「魔法 ×2 · 档一」(`hero_info_panel_view.gd` + `hud_presenter.gd` relic_holdings_lines);③ 关卡选择页复用同一聚合文案(`level_map_screen.gd`)。**边界**:效果摘要行(「普攻附加必中伤害」)保留——那是件本身在做什么,是玩家推断归类的依据。
|
||||
**门票机制四条(用户 2026-10-05 定)**:① **拿到即开、不可囤积**——不进持有集,选中或买下同一时刻就开专长三选一(可囤积会让玩家把关键决策无限推迟,且把持有物语义从后门放回来;"道具"只是卡面表现)。② **罕见只在概率,不在价格**——货架价与其他商品相当,不靠高价劝退。③ **一局限购一次**(现行口径)。④ **计步保底**——连续 5 次三选一展示未出现门票,第 6 次展示必定出现;计数对象=**展示次数**(刷新后的重新展示计入,用户明定含刷新),计数范围=奖励节点与商店**共享**,触发后清零,**限购用满后保底不再触发**。
|
||||
|
||||
**渠道定位 vs 默认原则(两句,别混)**:**渠道出哪些分类,是渠道轴自己的定位决定,不是例外**——Boss 渠道只出专长,另两类"不出现"是它的同义表述,不需另外找理由(v2.2 曾把它误当成缺理由的缺格,v2.3 修正)。**默认原则只管分类内部**:一个渠道一旦确定要出某个分类,该分类的成员就都要在它的池子里,缺席须有已登记的规则。
|
||||
|
||||
原四备选(① 专长专属三选一 ② 行为条件投放 ③ 计步保底 ④ 双池分离)已被上述定案覆盖——定案≈备选①的确定性路线,余三备选不再单独推进。**节点类型不扩类**:专长挂在 Boss 节点兑付面上(击败后追加一次专长三选一),[关卡节点地图](systems/冒险循环/关卡节点地图.md) 的节点类型仍为封闭枚举五种——此前的"是否新增节点类型"悬案由此收口。
|
||||
|
||||
**gp/heal 已安置,不再走迁移**:v2.0 把它们放进资源(用户 2026-10-05 选"暂不处置"=不做结构性迁移、不动配额),并在该类内显式登记异质性——**金币与回复是即时兑付,不进持有集、不持续生效**,与行动点上限/刷新次数(进持有账本、当局持续有效)生命周期不同。这条异质性必须留在文档里,防止后续把它们当持续生效的东西去结算。
|
||||
|
||||
**渠道约束分三层(v2.2,用户质疑后重构)**:用户问"计价物不自售不就是特判吗"。**诚实结论:形式上是的**——它确实是在分类白名单之外加的一道过滤,不是从分类推出来的。但和死特判有实质区别:
|
||||
|
||||
| 层 | 是什么 | 新增渠道/奇物时 |
|
||||
|---|---|---|
|
||||
| 一层 分类白名单 | 分类轴决定渠道 | 新分类按判据归类,自动继承 |
|
||||
| 二层 **可计算谓词** | 渠道与奇物的**结构性**关系 | **自动判定,不用改表** |
|
||||
| 三层 显式例外清单 | 人为设计选择,无内在理由 | **只能逐条加,每条须写理由** |
|
||||
|
||||
死特判="GP 不进商店"(一条记录,每多一个例外加一条,靠记忆维护);谓词="X 是渠道 C 的计价物 → X 不进 C"(一个函数,自动判定)。**它没有消除"在白名单外加过滤",只是把它从枚举例变成了计算谓词。** 判据:结构性原因(计价物/即时兑付/先决条件)可写成谓词;设计性原因只能进三层清单。**要害不是有没有例外,而是例外能不能被算出来。**
|
||||
|
||||
三方案代价并列(不藏折中):甲=GP 单独立第四个分类(例外 0,但用渠道轴切分类轴、两轴缠回、一项一类失衡);**乙=可计算谓词(现行,1 条谓词)**;丙=死特判清单(1 条记录,靠记忆维护)。
|
||||
|
||||
**在册约束就两条**:① 金币不进商店(二层·谓词,理由=计价物不自售);② 专长在非 Boss 渠道只给门票(一层·分类自身形态,理由=防用钱定点买构筑)。
|
||||
|
||||
**回复应在商店内**(用户 2026-10-05 定):回复不是计价物,套不上「计价物不自售」,按默认原则它应当在商店出现。现行 `shop.tres` 货架只有 attack / max_hp / armor / ap 四项,**现状与表格不对齐,须在实施批补上**。
|
||||
|
||||
**待拍板/待观察两项**:① ~~资源的命名~~ 与 ~~回复是否属该类~~ **已定(v2.5)=资源,回复留在其中不拆第四类**(它与金币同为即时兑付、判据同源;拆出去第四类只剩两项)。② **专长门票尚未入表**:出现概率 / 配额 / 全局限量三个参数都没有事实源,入池同样受档位结构锚约束。③ **专长总量与档位阈值的匹配——延后复裁**(用户 2026-10-05 定"先不调整"):终局 Boss 不给已定,一局确定性专长次数=终局前 Boss 个数;**三关结构下是两次,加门票最多三次**,而档位阈值是同标签 ≥2 档一 / ≥4 档二——**档二(完全体)在三关结构下几乎不可达**。用户决定不动,理由是**后续会有第四关**,且届时可能另做获取侧调整。**复裁触发:第四关内容批落地后实测,配合仍太少再调。** 先不调≠不成问题,登记于此防忘。
|
||||
④ **charge 标签件数不足(数据缺陷,独立登记,勿被上条盖掉)**:档二要求同标签 ≥4 件,而 `relics.tres` 里 charge 标签**只有 3 件**——即使获取次数无限,charge 流派也永远达不到档二。这与渠道结构无关,是数据层缺陷。
|
||||
⑤ ~~顶层命名待定~~ **已定(v2.4)=「奇物」Wondrous Item**:DND 魔法物品九分类中的兜底杂类,官方中文译名即「奇物」,专装"不好归类但有奇效之物"——正好对应三个互不相干的分类。落选:Treasure(偏财物,装不下专长)、Relic(品类惯例,用户否决「遗物」)、全部自造词(进益/造化/机缘/遇获)。**代码词族随之定为 `curio_*` / `ADVENTURE_CURIO`**——原计划的 `feature_* → reward_*` 对齐**作废**:`reward_pick` 流 / `reward_node` context / `reward_preview` kind 已占用 reward 词族,照做会撞车。
|
||||
|
||||
**归属**:[奇物](systems/冒险循环/奇物.md)(定义与交叉开关表)+ [node-reward](ux/node-reward.md)(令牌池与奖励面)+ [冒险结构](systems/冒险循环/冒险结构.md)(商店货架保底与货架过滤)+ [关卡节点地图](systems/冒险循环/关卡节点地图.md)(节点类型词表);与上条「双层 BD 延期与备选内容总登记」二期件组相关但不同面。
|
||||
|
||||
**状态**:分工已定,**实施待排批**;两项待拍板/待观察(2026-10-05 v2.1 更新)
|
||||
|
||||
#### 资源两个新种类入池——刷新次数、专长获取(2026-10-05 立)
|
||||
|
||||
**现状**:[奇物](systems/冒险循环/奇物.md) v2.0 立了资源四项,其中**行动点上限**已在池(罕见档)、**金币与回复**已在池,**刷新次数与专长获取两项尚未入表**。注意与既有「商店独立刷新机制」条分清:那条是进店后的免费次数 + GP 刷新(商店自身的服务),本条指的是**作为奖励授予的**重抽次数,两者不是一回事,入池前须先划清边界。
|
||||
|
||||
**连带约束**:`FEATURE_KINDS` 词表封闭(断点附随件与牌库剔除态依赖它),扩种类须走 `adventure_table.gd` + registry 同步修订;档位配额是**结构锚**(普通 70 / 稀有 25 / 罕见 3 = 98 张,入 schema validate 硬断言),新种类入池要占配额——**改总量须重裁而非调参**。专长获取须带全局限量(一局内可获得次数上限)。
|
||||
|
||||
**归属**:[奇物](systems/冒险循环/奇物.md) 调参表 + [冒险结构](systems/冒险循环/冒险结构.md) 共享池账本节;数值所有权归 [难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md)
|
||||
|
||||
**状态**:待排批——须在可跑冒烟的迭代批次内完成
|
||||
|
||||
#### 内部分类禁写入玩家可见面——奇物呈现三处违规待改(2026-10-04 用户立意登记)
|
||||
|
||||
**现状**:用户立意(方向已明确):形态(规则改写型/属性加成型)等内部分类**不得写进玩家可见的名称、介绍词或界面**——玩家可根据效果自行推断类别,游戏不得直接点破。查证实态:26 项专长奖励的 display_name 全风味名(奥术余烬/贯穿射击/矿工的执拗等,合规,符合 2026-09-29 playnote 既有批评);**违规三处**(均系迭代 12 呈现补齐批所落,承载用户「局内奖励选了什么看不到」反馈——缺口承载需求仍成立,撤的只是分类字样):① 三选一+商店特性卡面第二行印流派名(`battle_narrator.gd` relic_card_text,「奥术余烬 · 魔法」式);② 战斗屏 C 区列表标题(现为「特性」)+逐流派聚合行「魔法 ×2 · 档一」(`hero_info_panel_view.gd` + `hud_presenter.gd` relic_holdings_lines);③ 关卡选择页复用同一聚合文案(`level_map_screen.gd`)。**边界**:效果摘要行(「普攻附加必中伤害」)保留——那是件本身在做什么,是玩家推断归类的依据。
|
||||
|
||||
**连带裁点**:档位激活(同标签 2 件档一/4 件档二)若完全不呈现,玩家只能靠悟——三路待裁:甲=纯隐藏、机制照跑(以撒套装式,最贴用户「流派是玩家挖掘出来的」原则);乙=档位达成那一刻给一次性风味反馈、不点破流派名;丙=连档位机制一起退役。
|
||||
|
||||
@@ -45,6 +94,16 @@
|
||||
|
||||
**状态**:方向已明确(禁写类别),违规改法与档位呈现三路待讨论(2026-10-04 登记,后续展开)
|
||||
|
||||
#### 奇物命名统一后续——代码标识符与文件名的对齐(2026-10-05 立)
|
||||
|
||||
**现状**:概念已统一为「奇物」(2026-10-05 v2.4 由「奖励」改名、v2.0 由「特性」改名,定义见 [奇物](systems/冒险循环/奇物.md))。已完成三件——① 定义文档落位(`design/gdd/systems/冒险循环/奇物.md`);② 称谓统一(代码注释与玩家可见文案,94 处+design/ 侧随改名批同步);③ 数据层标识符统一(`adventure_table.gd` / `adventure.tres` 的常量与字段整体换到 `feature_*` 词族,112 处,值零变更)。
|
||||
|
||||
**未完四件**:⓪ **`feature_*` 词族随顶层改名再换到 `curio_*`**(2026-10-05 v2.0 新增、v2.4 改目标词族)——`FEATURE_KINDS` → `CURIO_KINDS` / `feature_quota()` → `curio_quota()` / `feature_value()` → `curio_value()` / `feature_candidate_count` → `curio_candidate_count` / `feature_quota_*` / `feature_value_*`,涉及 `adventure_table.gd` + `adventure.tres` 键名 + registry。**注意两点**:其一,**目标词族是 `curio_*` 不是 `reward_*`**——`reward_pick`(rng 封闭流 scope)/ `reward_node`(`grant_aux_item` context)/ `reward_preview`(道具 kind)已占用 reward 词族,照 `reward_*` 对齐会撞车;其二,`adventure.tres` 的键名是存档外的表数据,换名只动键不减值,但 `FEATURE_KINDS` 是封闭词表、断点附随件与牌库剔除态依赖它,须走本表 + registry 同步修订。① 专长那套的 relic 词族(RelicTable / relics.tres / relic_id / _relics)与统一词族对齐——文件名与 class_name 改名须同步 Godot `.uid` 与 `.tscn` 引用,非文本层可自证;② 运行层标识符(`_bonus_deck` / `bonus` 加算区 / `_bonus_taken` / `pick_bonus` / BonusInteractController / BonusPickOverlay)换名;③ 断点与存档键(`bonus_deck` / `bonus_taken` / `bonus_pending` / `bonus_result` / `bonus_aux_carry`)为存档兼容沿用历史名,是否随存档版本迁移一并换名待定。
|
||||
|
||||
**次序建议**:⓪ 与 ① 同为"词族对不齐",可同批;② 涉及运行层最广,单批;③ 须与存档版本迁移一起裁。**顶层已改名而代码仍是 `feature_*`,属"文档与代码分开"的临时态**,应在下一个可跑冒烟的批次内收口。
|
||||
|
||||
**状态**:待实施——须在可跑冒烟的迭代批次内完成(本会话按测试执行两入口铁规零测试,改名无法自证)
|
||||
|
||||
#### 棋盘战斗键盘/手柄输入(2026-10-04 用户提问登记,排期 Beta)
|
||||
|
||||
**现状**:战斗棋盘操作现行唯一输入 = 鼠标——左键已开格 = 移动 / 未开格 = 挖掘,右键 = 封印(旗一次性承诺,无拔旗),悬停承载合法性反馈(可挖域微光 + BFS 路径点迹);全仓无 InputEventKey/JoypadButton 处理,project.godot 无自定义 InputMap 动作。**可行性已核(2026-10-04):可做**——分发接缝现成,board_view `action_requested(cell, kind)`(kind ∈ {dig, move, flag_place, flag_pull})是唯一出口,键盘/手柄作第二输入前端产出同款信号即可,规则引擎合法性校验零改动(非法目标两条路径同拦);Godot InputMap 原生支持键盘与手柄(十字键/摇杆)绑定同一动作,与鼠标并存不冲突。用户期望操作形态:十字方向移动;挖掘/封印各一独立键;方向控制选定 8 向挖掘或封印目标(斜向 = 双方向键组合)——8 向恰与现行可挖域(8 向相邻未开格)同集,十字移动与立绘 4 向既有裁决一致;键盘移动语义 = 逐格步进(现行点击 = 任意已开格 BFS 全程,逐格为等价交互变体)。连带设计点(实施批先裁):① 键盘模式需屏上光标格承载现行悬停反馈(无鼠标 hover,合法性指示改挂光标);② 键盘默认键位与手柄键位映射待定;③ 弹层界面(结算/三选一/商店/设置等)现行全鼠标,手柄全覆盖需焦点导航——本条范围 = 棋盘战斗操作,界面焦点导航是否同批待裁;④ 键位自定义是否进设置面待裁。
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
# 奇物(Wondrous Item)
|
||||
|
||||
> 一次冒险之内,通过各渠道给予玩家的**增益总称**——奖励节点给的、商店里买的、打赢关底 Boss 给的,都是奇物。它装的是"这一局你捞到了什么",不管从哪个渠道来。
|
||||
>
|
||||
> 它是一个概念,不是一套东西。下面有**两根互不相干的轴**:
|
||||
>
|
||||
> - **分类轴**回答"给的是什么"——三个枚举:专长 / 属性值提升 / 资源;
|
||||
> - **渠道轴**回答"从哪来"——奖励节点 / 商店 / 关底 Boss 击败(即通过这一关)。
|
||||
>
|
||||
> 一个奇物属于哪个分类,不决定它从哪个渠道来;反过来也一样。两者的交叉由第 2 节那张开关表定死。
|
||||
>
|
||||
> **兑付频率(先看这条,它是三条渠道的共同前提)**:奇物**不是打一场战斗给一份**。关内的普通战斗节点打完了什么也不给;一关之内奇物**只兑付一次**,触发点是**关底 Boss 被击败**——而按 [冒险结构](冒险结构.md) 的定义,打掉关底 Boss 恰好就等于"通过这一关",这两件事是同一个时刻,不是一条链上的两步。
|
||||
>
|
||||
> 状态:**已实现**(2026-10-04 双层 BD 实施批落地)。本文件是奇物的唯一定义文档。
|
||||
>
|
||||
> 数值纪律:本文件只写概念、取值域与指路;每件给多少、效果是什么一律不进正文,事实源是 `game/data/tables/relics.tres` 与 `game/data/tables/adventure.tres`。
|
||||
|
||||
## 设计目的
|
||||
|
||||
一次冒险要走三关,如果走完时角色和开局毫无区别,中途的每一次取舍就都不算数了。奇物就是那个把"这一局玩成了什么样"落下来的东西:让玩家在冒险过程中不断变强,且每一局变强的方向不同。
|
||||
|
||||
它同时要和跨冒险的成长隔开:永久保留的东西是[魔法道具](../排雷循环/魔法道具.md)(带在身上的物品)与[元进度](../跨局循环/元进度.md)(账号级的树),奇物只在当局存在,冒险收束即清零——它不是"你的存档变强了",而是"这一次下矿的你变强了"。
|
||||
|
||||
**边界判据(一句话)**:**一次冒险内获得、冒险收束即清零的,是奇物;跨冒险跟着你走的,是魔法道具。**
|
||||
|
||||
这条判据走的是生命周期,不走"是不是物品"。原因:奇物这个筐里既装"角色自身的变化",也装金币这类一次性兑付物——用"拿在手里 vs 带在身上"去切,切不开它们,但用"当局清零 vs 跨局保留"能一刀切开,且对筐里所有东西都成立。
|
||||
|
||||
## 系统范围
|
||||
|
||||
| 负责 | 不负责 |
|
||||
|---|---|
|
||||
| 奇物的定义、三个分类、以及分类与渠道的交叉开关 | 每件效果怎么接入结算——归挂点所属文档([战斗结算](../战斗循环/战斗结算.md)、[行动经济](../排雷循环/行动经济.md)、[地形变异](../排雷循环/地形变异.md)) |
|
||||
| 生命周期边界:何时出现、何时生效、何时清零 | 卡面排版与界面呈现细则——见 [HUD框架](../表现与支撑/HUD框架.md) |
|
||||
| 获取渠道的口径与约束 | 魔法道具与元进度——归上表两份文档 |
|
||||
| 与相邻概念的边界 | 格面资源、关卡节点、商店本身的规则——归各自所属文档 |
|
||||
|
||||
## 在核心循环中的位置
|
||||
|
||||
```
|
||||
一次冒险 = 若干关卡串联,每关 = 一条节点链 + 一个关底 Boss
|
||||
|
||||
关内普通战斗节点 ──▶ 打完不给奇物,继续往下走
|
||||
│
|
||||
├─ 奖励节点 ──▶ 一次三选一(属性值提升 / 资源,罕见门票)
|
||||
├─ 商店 ──▶ 花钱买(属性值提升 / 资源,罕见门票)
|
||||
│
|
||||
关底 Boss 击败 ═══╗ ← 打掉关底 Boss 就是「通过这一关」,同一件事
|
||||
╰──────────╬──▶ 一次专长三选一(专长)
|
||||
╰──▶ 通关回血 ──▶ 进下一关,带着它继续
|
||||
```
|
||||
|
||||
**关键:一关只兑付一次,不是一场战斗给一份。** 触发点是**关底 Boss 被击败**,而这恰好就等于"通过这一关"([冒险结构](冒险结构.md) 定义:通关一关 = 该关关底 Boss 被击杀)——**这两件事是同一个时刻,不是一条链上的两步**。关内普通战斗节点打完了什么也不给,直接往下走。
|
||||
|
||||
奇物处在「一次冒险」这一层:它不是一场战斗里的临时状态,也不跨冒险留存。上游是三条渠道,下游是之后所有关卡的排雷与结算——拿到了,下一关就开始生效。
|
||||
|
||||
## 核心规则
|
||||
|
||||
### 1. 分类轴:三个枚举
|
||||
|
||||
奇物只有一个名词,但它下面分三类。**这三类各有自己的专名,不是描述**——文档正文、代码词族、帮助与百科页面都用这三个词指代它们。
|
||||
|
||||
| 分类 | 它给的是什么 | 落点 | 事实源 |
|
||||
|---|---|---|---|
|
||||
| **专长**(Feat) | 给规则。在结算管线某个挂点上给自己加一条规则;同一标签的持有件数达阈值时质变 | 各结算段挂点;标签与档位由求值服务统一算 | `relics.tres`(逐项定义) |
|
||||
| **属性值提升**(ASI) | 给数字。抬高角色某项战斗属性的基础值 | 冒险加算区的生命上限 / AC / 攻击三轴 | `adventure.tres`(种类配额与值) |
|
||||
| **资源** | 给"可用的量"。不抬高战斗属性,也不改规则,而是扩充你能调动的余量与机会 | 行动经济、三选一界面、局内钱包;**不进加算区、多数不进持有集** | `adventure.tres`(种类配额与值) |
|
||||
|
||||
三类的共性:都在当局获得、都在当局消费完或随冒险收束清零;都不写账号进度——出现与否由抽取决定,玩家的账号强弱不影响它出现在哪一局。
|
||||
|
||||
#### 1.1 专长:规则改写
|
||||
|
||||
专长改的是规则而不是数字——它给自己加一条"在某种条件下,本来不会发生的事现在会发生"的规则。它不是任何一条属性轴的延伸,玩家也无法用"加了多少"来衡量它。
|
||||
|
||||
专长带流派标签,同一标签的持有件数达到阈值时发生质变(档位机制归 [战斗结算](../战斗循环/战斗结算.md),本文件不展开)。这是它和另两类最直观的体感差别:属性提升是"我更耐打了",专长是"我现在会一件以前不会的事"。
|
||||
|
||||
**专长门票也归专长**:非 Boss 渠道不直接给专长,而是给一张名为「专长获取」的门票——拿到后立刻开一次专长 N 选一。它给的是"一件你以前不会的事"(只是把选择推迟到一次三选一),按 1.4 的判据归专长,不归资源。详见 2.2。
|
||||
|
||||
#### 1.2 属性值提升:纯属性三项
|
||||
|
||||
三项,各改一条战斗属性轴:
|
||||
|
||||
| 项 | 改什么 |
|
||||
|---|---|
|
||||
| 生命上限 | 抬高角色的生命上限 |
|
||||
| AC(护甲) | 抬高角色的护甲 |
|
||||
| 攻击 | 抬高角色的攻击 |
|
||||
|
||||
三项都直接进冒险加算区,跨关携带且关间不清零。这一类是封闭的:只有这三项,多一项就要走文档修订。
|
||||
|
||||
#### 1.3 资源:四项
|
||||
|
||||
资源这一类装的是"不抬高战斗属性、也不改规则,但让你更有余地"的东西:
|
||||
|
||||
| 项 | 给什么 | 备注 |
|
||||
|---|---|---|
|
||||
| 行动点上限 | 每场战斗首轮可用的行动点更多 | 罕见档 |
|
||||
| 刷新次数 | 三选一界面可重抽的次数更多 | **作用对象是选择界面,不是角色**——见第 3 节的例外登记;奖励节点与商店两个渠道都可出现 |
|
||||
| 金币(GP) | 局内钱包进账 | 进钱包即花掉,不进持有集、不持续生效;**不进商店**(计价物不自售,见 2.4) |
|
||||
| 回复 | 当即回血 | 即时兑付,不进持有集、不持续生效;**在商店内**(见 2.4 的默认原则) |
|
||||
|
||||
**资源为什么单独成一类**:它的成员不满足"抬高战斗属性"(那归属性值提升),也不满足"改写规则"(那归专长),但玩家拿到时的感受是一致的——"我能做的事变多了"。把它们跟属性提升混在一起,会让"加了多少攻击"这种可度量的提升和"多一次重抽"这种不可度量的余地摆在同一张候选卡上,玩家没法比。
|
||||
|
||||
**判据句("资源"这个词太泛,这句是唯一的收口凭据)**:资源给的是**可以调动、可以花掉的余量**,不是角色基础属性的永久抬升。"资源"是常用词,能力资源、财富资源都叫资源——所以判据必须写死:拿不准一项该归哪类时,问它**会不会进角色自己的属性数值**。会进的归属性值提升,不会进、而是变成你手里多出来的次数或多出来的钱的,归资源。
|
||||
|
||||
**资源类内部的异质性(要诚实登记)**:金币与回复是**即时兑付**——拿到就消失,不进持有集,也没有"持有→生效→清零"的过程;行动点上限与刷新次数则进持有账本、当局持续有效。它们被归在同一类是因为"给的是余量"这个共同性质,不是因为生命周期相同。这条异质性在此显式登记,防止后续把金币当成会持续生效的东西去结算。
|
||||
|
||||
#### 1.4 分类判据
|
||||
|
||||
**给规则的是专长,给数字的是属性值提升,给余量的是资源。**
|
||||
|
||||
拿不准的项按这条判:去掉它之后,角色是"某件以前不会的事做不到了"(专长)、"某个数字少了一截"(属性值提升)、还是"能调动的余地变小了"(资源)。
|
||||
|
||||
#### 1.5 命名出处
|
||||
|
||||
专长与属性值提升都取自 DND 规则书的既有名词:专长对应 Feat,属性值提升对应 Ability Score Improvement(ASI)。**顶层「奇物」取自 DND 魔法物品的九分类之一 Wondrous Item——官方中文译名就是「奇物」,是那个专门装不好归类但有奇效的东西的兜底杂类。** 用它做顶层名的理由:地下城里挖到的、商店里能买到的、能把你变强的、又确实贵重的东西,在 DND 里没有别的总称,只有 Treasure 和 Wondrous Item 两个候选,而 Treasure 偏向财物,装不下专长这种你会了件以前不会的事。奇物天生是杂类兜底,正好对应本概念下三个互不相干的分类(专长改规则 / 属性值提升改数字 / 资源给余量)——它们本来就没有共同点,能拢在一起的只有一个不好归类但有用的名字。**资源取"资源"这个常用词**(用户 2026-10-05 定)——行动点上限、刷新次数、金币、回复都是可以调动、可以花掉的余量。它确实偏泛(能力资源、财富资源都叫资源),所以这一类的判据句必须写死:**给的是可消耗或可重掷的余量,不是角色基础属性的永久抬升**——这一句是把"资源"从泛用词收回到本类定义里的唯一凭据,不能省。**三个分类的专名在 v2.7 去掉了「类」字后缀**——此前写作「机制类 / 属性提升类 / 资源类」,那是描述不是专名;去掉后缀后三个词各自都能独立成词、与 DND 官方中文一致,理由与逐条依据见 1.6 节。玩家可见文案只写效果,不出现任何分类名。
|
||||
|
||||
### 1.6 三层结构与命名(本概念的完整层级)
|
||||
|
||||
奇物这个概念只有三层,任何一处提到它都属于其中一层:
|
||||
|
||||
| 层 | 名称 | 例子 | 谁看得到 |
|
||||
|---|---|---|---|
|
||||
| 一层 总称 | **奇物**(Wondrous Item) | 「这一局你捞到的全部奇物」 | 全部玩家可见面 |
|
||||
| 二层 分类 | **专长** / **属性值提升** / **资源** | 「这四件是属性值提升」 | 帮百科与成就页可见;卡面与详情页**不出现** |
|
||||
| 三层 单件 | 具体那一件的名称 | 奥术余烬、贯穿射击、小幅提升生命上限 | 全部玩家可见面 |
|
||||
|
||||
**两层是两件事,别混**:
|
||||
|
||||
- **命名是本节的规矩**——三个分类各有一个专名,文档、代码词族、帮百科一律用它。指代某个分类时直接说「专长」,不说「机制类」「专长那一类」。
|
||||
- **呈现是另一件事**(归 [battle](../ux/battle.md) 与 [node-reward](../ux/node-reward.md),本节不裁决):玩家看到某件奇物时,卡面只写**这件东西的名字与效果**,不附带它的分类。玩家可以从效果反推它属于哪一类,但界面不替他说破。
|
||||
|
||||
**为什么两层都要有**:分类名在卡面上不出现,不等于玩家对它没有概念——帮助手册、百科条目、成就名称三处一定会用到它(「首次集齐 4 件专长」「三件属性值提升」),效果描述里出现指代时也需要名字(「本项属专长,同标签达到 4 件时质变」)。所以它必须是一个**玩家读得懂、读一遍就懂**的正式名词,不能是内部描述或自造词。
|
||||
|
||||
**代码侧词族对应**(本批只做命名对齐,代码改动见任务书):顶层 `curio_*`(奇物总称)/ 专长 `feat_*` / 属性值提升 `asi_*` / 资源 `res_*`。`reward_*` 已被既有标识符占用(`reward_pick` / `reward_node` / `reward_preview`),**不得使用**。
|
||||
|
||||
### 2. 渠道轴:与分类的交叉
|
||||
|
||||
三个渠道各只取走分类的一部分。这张表是奇物概念的第二个维度——它和分类轴互不决定,改其中一根不必动另一根。
|
||||
|
||||
| 分类 \ 渠道 | 奖励节点 | 商店 | 关底 Boss 击败=通过这一关(见 2.1) |
|
||||
|---|---|---|---|
|
||||
| **专长**(专长) | 门票形式(见 2.2) | 门票形式(见 2.2) | **直接给**(唯一的直接渠道) |
|
||||
| **属性值提升** | 出 | 出(口径「训练」) | 不出现 |
|
||||
| **资源** | 出 | 出(**金币除外**,见 2.4) | 不出现 |
|
||||
|
||||
**这张表的形状**:Boss 渠道是**专长的独占渠道**,也是唯一**直接**给专长的渠道;奖励节点与商店不直接给专长,但会出现通往专长的**门票**。另两类不走 Boss 渠道,只在奖励节点与商店两个并行出口出现。三条渠道的分工因此是"一块独占 + 两块并行",不是三块平分。这条形状本身要记住:它意味着专长的获取节奏与其他奇物的获取节奏**由完全不同的机制决定**——前者靠打赢,后者靠抽取与购买。
|
||||
|
||||
**渠道定位 vs 默认原则(两句,别混)**:
|
||||
|
||||
- **渠道出哪些分类,是渠道轴自己的定位决定,不是例外**——Boss 渠道只出专长,所以另两类在此"不出现",这是"Boss 是专长独占渠道"的同义表述,不需要另外找理由。
|
||||
- **默认原则只管分类内部**(用户 2026-10-05 定):一个渠道一旦确定要出某个分类,**该分类的成员就都要在这个渠道的池子里**。它的默认值是"出",任何成员缺席都必须有已登记的规则,没有理由的缺席是缺陷不是设计。
|
||||
|
||||
两条的管辖范围不同:前者决定"这张表的格子填不填",后者决定"填了的格子里装不装得全"。
|
||||
|
||||
#### 2.1 专长的主渠道:关底 Boss 击败(即通过这一关)
|
||||
|
||||
专长的专属渠道,时机确定——打赢就有,不需要看脸。构筑的节奏由此可预期:玩家能规划"第几关拿到第一个专长"。品类原型是杀戮尖塔(每层 Boss 后必给遗物)与哈迪斯(Boss 后必给恩赐)——打赢了一定拿到东西,是这类游戏的通例。
|
||||
|
||||
**这个渠道的触发点就是「关底 Boss 被击败」**——而按 [冒险结构](冒险结构.md) 的定义,打掉关底 Boss 恰好就等于"通过这一关"。所以这条渠道的全名是**关底 Boss 击败(即通过这一关)**:它不是"战斗结算之后再来一次奖励"的独立步骤,而**就是关卡推进本身那一刻**。关内的普通战斗节点打完了什么也不给;一关之内奇物只兑付这一次。
|
||||
|
||||
**终局那关的 Boss 击败后不给**:兑付只发生在**还有下一关可去**的那些关底 Boss 身上——打赢最终 Boss 时冒险已经结束,没有后续关卡可消费,给了也无处生效。三关结构下,一局的确定性专长兑付次数由此确定(每个终局前 Boss 一次)。
|
||||
|
||||
**不新增节点类型**:专长挂在 Boss 节点的兑付面上(击败后追加一次专长三选一),[关卡节点地图](关卡节点地图.md) 的节点类型仍是封闭枚举五种(战斗 / Boss / 奖励 / 恢复 / 商店),词表零扩类。此前"要不要为专长新设一类节点"的悬案由此收口。
|
||||
|
||||
#### 2.2 专长门票:非 Boss 渠道怎么给专长
|
||||
|
||||
奖励节点与商店**不直接给专长**——它们给的是一张**门票**:一个名为「专长获取」的奇物项,选中或买下之后,**立刻**开一次专长 N 选一(N 与 Boss 渠道的候选数同源)。
|
||||
|
||||
**它归专长,不归资源**:它给的不是"余量",而是"一件你以前不会的事"——只是把选择推迟到一次三选一。按 1.4 的分类判据(去掉它之后角色少了什么),它属于专长。所以在交叉表上,专长在非 Boss 渠道的表现是**只以门票形式出现**,不是"不出现"。
|
||||
|
||||
**为什么非 Boss 渠道只给门票**:如果商店也能直接买到一个指定的专长,玩家就能用金币把构筑买出来,Boss 渠道的"打赢才拿到"就失去意义了。门票保留了惊喜(开出来的还是三选一,不是指定),但不让玩家用钱直接定点购买。
|
||||
|
||||
##### 门票的三个性质
|
||||
|
||||
- **拿到即开,不可囤积**(用户 2026-10-05 定):门票不进持有集,选中或买下的同一时刻就开专长三选一。玩家不能攒几张一次连开——可囤积会让玩家把关键决策无限推迟到最优时机,破坏 Boss 渠道的节奏感;而且"攥着一张票"就是把持有物语义从后门放回来了。它叫"道具"只是卡面表现,不是持有物。
|
||||
- **不推翻确定性**:专长的主渠道仍然是 Boss 击败后,玩家不会因为没抽到门票就构筑不起来。
|
||||
- **罕见只在概率,不在价格**:门票的"罕见"**只体现在它出现的概率上**——它在货架上的价格与其他商品相当,不靠高价劝退。一局内**限购一次**(现行口径)。
|
||||
|
||||
##### 保底:第 6 次必出
|
||||
|
||||
光靠概率,运气差的玩家可能整局都见不到门票——那就等于这个机制对他不存在。所以门票带一条**计步保底**:
|
||||
|
||||
> 连续 5 次三选一展示中没有出现门票,**第 6 次展示必定出现**。
|
||||
|
||||
| 项 | 口径 |
|
||||
|---|---|
|
||||
| 计数对象 | 三选一的**展示次数**,不是"节点次数"——**刷新后的重新展示计入次数**(用户 2026-10-05 明定含刷新) |
|
||||
| 计数范围 | 奖励节点与商店**共享同一计数**,不各算各的 |
|
||||
| 触发后 | 计数清零,重新累计 |
|
||||
| 与限购的关系 | 一局限购一次;**已经买过(限购用满)之后,保底不再触发**——门票已经用掉了,没有再给的理由 |
|
||||
|
||||
**为什么是"展示次数"而不是"节点次数"**:保底要保的是"玩家看到的脸",刷新本来就是让玩家多一次看脸的机会,若刷新不计入,保底与刷新两套机制会打架——玩家可以用刷新绕开保底的计数语义。
|
||||
|
||||
玩家视角它长这样:在普通的三选一奇物或商店货架里,偶尔会冒出一张不一样的卡——拿到它,立刻再开一次专长选择。它是奇物面里的惊喜,不是奇物面的常态;而连续几次没见到之后,它一定会来一次。
|
||||
|
||||
#### 2.3 商店口径:训练
|
||||
|
||||
商店这一侧走的叙事是「**训练**」——花代价向某位师父学习、借某种卷轴修炼、或把战斗攒下的钱换成一身本领。它不是买一个东西回来,而是把钱换成自己的本领,所以落到命名空间上和奖励节点那一侧完全相同:都是往同一个持有集里加一项奇物。
|
||||
|
||||
#### 2.4 渠道约束分三层:白名单 / 可计算谓词 / 显式例外
|
||||
|
||||
一个"某分类在某渠道出不出现"的判断,实际由三层叠起来决定:
|
||||
|
||||
| 层 | 是什么 | 判据来源 | 新增渠道或奇物时 |
|
||||
|---|---|---|---|
|
||||
| **一层 分类白名单** | 分类轴决定渠道——专长走 Boss、另两类走奖励节点与商店 | 分类本身 | 新分类按 1.4 判据归类,自动继承该类的渠道 |
|
||||
| **二层 可计算谓词** | 渠道与奇物之间的**结构性**关系,能算出来 | 对象与渠道的内在关系 | **自动适用,不用改表** |
|
||||
| **三层 显式例外清单** | 人为的设计选择,没有内在理由可推 | 设计决定 | **只能逐条加,每条必须写理由** |
|
||||
|
||||
**先诚实回答"计价物不自售不就是特判吗"**:**形式上是的**——它确实是在分类白名单之外又加了一道过滤,不是从分类推出来的。但它和三层那种"死特判"有实质区别:
|
||||
|
||||
| | 写法 | 新增渠道/奇物时 | 维护方式 |
|
||||
|---|---|---|---|
|
||||
| 死特判 | "GP 不进商店"(一条记录) | 每多一个例外加一条记录 | 靠人记住,容易漏 |
|
||||
| **可计算谓词** | "X 是渠道 C 的计价物 → X 不进 C"(一个函数) | **自动判定,不用改表** | 判据在对象属性上,不会漏 |
|
||||
|
||||
所以准确的说法是:**它没有消除"在白名单外加过滤"这件事,但把过滤从"枚举例外"变成了"计算谓词"**。以后新增渠道或奇物,只要"不出现"的原因是**结构性**的——来自奇物与渠道的内在关系(计价物、即时兑付、需要先决条件等)——就能写成谓词自动算;如果原因是**设计性**的("我就是想让它在这一关不出"),那就只能进三层清单。
|
||||
|
||||
**所以要害不是"有没有例外",而是"例外能不能被算出来"**。三层清单不是不能用,但每一条都必须写出理由;一条写不出理由的例外,就是坏味道,应该回头质疑分类是不是分错了。
|
||||
|
||||
**为什么不干脆拆成第四个分类(零例外的那条路)**:分类轴回答的是"给的是什么",金币给的是余量,和行动点上限、刷新次数同类。按"能不能进商店"去反推分类,等于**用渠道轴的性质去切分类轴**,两根轴又缠回一起了——这是本文件 v2.0 专门拆开的东西,不能为了消灭一条例外再缠回去。而且为一个只有一项的分类立枚举,读者会以为它和另三类是同一重量级的划分,实际它只是某一项恰好踩到了一条经济规则。
|
||||
|
||||
三个方案的真实代价,摆出来不藏:
|
||||
|
||||
| 方案 | 例外数 | 代价 |
|
||||
|---|---|---|
|
||||
| 甲:GP 单独立第四个分类 | 0 | 用渠道轴切分类轴,两轴缠回;一项一类,分类失衡 |
|
||||
| **乙:可计算谓词(现行)** | **1 条谓词** | **分类干净,但"白名单外加过滤"这件事没消失,只是自动化了** |
|
||||
| 丙:死特判清单 | 1 条记录 | 每加一个例外加一条,靠记忆维护 |
|
||||
|
||||
**回复在商店内**(用户 2026-10-05 定):回复不是计价物,套不上「计价物不自售」,按默认原则(除登记的特殊规则外,分类内的都要在池子里)**它应当在商店中出现**。现行 `shop.tres` 的货架只有攻击 / 生命上限 / 护甲 / 行动点四项,回复不在其中——这是**现状与表格不对齐**,须在实施批补上,登记在 [06-待办清单](../../06-待办清单.md)。
|
||||
|
||||
**当前在册的约束清单**(就这么两条,都要有理由):
|
||||
|
||||
| 约束 | 层 | 理由 |
|
||||
|---|---|---|
|
||||
| 金币不进商店 | 二层·谓词 | 计价物不自售——商店的计价物是 GP |
|
||||
| 专长在非 Boss 渠道只给门票 | 一层·分类自身的形态 | 见 2.2——防止用钱定点买构筑 |
|
||||
| 属性值提升与资源不出现在 Boss 渠道 | **不是约束** | 见 2.1——这是渠道轴的定位(Boss 是专长独占渠道),不属默认原则管辖 |
|
||||
|
||||
#### 2.5 在册事项
|
||||
|
||||
现行实现里**三条渠道完全共用同一个候选池**,三个分类出现条件一样、只有出现概率不同——上表的渠道分工是**目标状态,尚未实施**。相关的实施批次登记在 [06-待办清单](../../06-待办清单.md) 的 BD 分层条目下,本文件不复制。
|
||||
|
||||
### 3. 作用对象与范围
|
||||
|
||||
- **作用对象**:角色本人,以及角色参与的结算过程。奇物不改敌人、不改棋盘生成、不改关卡内容。
|
||||
- **刷新次数的例外**:它作用在三选一界面上,改的是"这一局里你能重选几次",而不是角色身上的任何数字。它是资源里唯一一条作用对象不是角色的项——留在这里是因为它满足另外三条:当局获得、当局有效、进同一份持有账本。这条例外在此显式登记,避免后续把它当成角色属性去结算。
|
||||
- **时间范围**:整局冒险。专长与属性值提升自获得起对本局剩余所有关卡生效,跨关携带且关间不清零;资源里的金币与回复是即时兑付,拿到即消费完。
|
||||
- **归属范围**:不进账号永久进度,不带到下一次冒险。
|
||||
|
||||
### 4. 生命周期
|
||||
|
||||
```
|
||||
未获得 → 进入候选池 → 作为候选出现 → 选定 → 持有/兑付 → 生效 →(冒险收束)清零
|
||||
↑ ↓
|
||||
断点恢复 持有集持续累积
|
||||
```
|
||||
|
||||
| 阶段 | 说明 |
|
||||
|---|---|
|
||||
| 候选池构建 | 冒险开局时一次建成。三个分类的候选**现同处一个令牌池**:属性值提升与资源按配额铺开,专长按定义表的有效行铺开。 |
|
||||
| 出现 | 玩家在渠道上看到若干候选(三选一的形式),看不到整个池。 |
|
||||
| 选定 | 玩家选定一项后,它从池中剔除,此后任何渠道都不会再见。选到「专长获取」时,立刻再开一次专长 N 选一——这次选择走专长的渠道语义,不占用原本的渠道。 |
|
||||
| 持有与兑付 | 专长与属性值提升进入持有集后立即生效,跨关携带;专长按同一标签的持有项数决定处于哪一档。金币与回复即时兑付,不入持有集。 |
|
||||
| 清零 | 冒险以任一结局收束时整集清空;下次开局重建。 |
|
||||
| 断点恢复 | 进行中的冒险把持有集与剩余候选池一并写入断点,续玩后恢复到同一状态(断点里的键名沿用历史形态,不随本次改名变动)。 |
|
||||
|
||||
### 5. 关联与边界
|
||||
|
||||
| 相邻概念 | 关系(只写关系,不写对方的规则) |
|
||||
|---|---|
|
||||
| [魔法道具](../排雷循环/魔法道具.md) | 最需要分清的一对,判据是生命周期:**奇物当局清零,魔法道具跨冒险保留**。两者互不相通——奇物永不进同调位,魔法道具永不进当局随机渠道。 |
|
||||
| [元进度](../跨局循环/元进度.md)(树) | 树管账号永久的规则与容量,奇物管当局构筑,两层互不代替。 |
|
||||
| [战斗结算](../战斗循环/战斗结算.md) | 专长的挂点位于结算管线的各段;挂点清单与语义归结算文档。 |
|
||||
| [行动经济](../排雷循环/行动经济.md)、[地形变异](../排雷循环/地形变异.md) | 部分挂点落在行动点结转与地形处理上,语义归各自文档。 |
|
||||
| [关卡节点地图](关卡节点地图.md) | 是渠道的载体,不是奇物的属性。专长挂在 Boss 节点兑付面上,节点类型词表零扩类。 |
|
||||
| [地图战斗资源](../战斗循环/地图战斗资源.md)(格面资源) | 无关:格面资源是单格的一次性产出,不进持有集,也不是渠道给的。 |
|
||||
| [存档序列化](../表现与支撑/存档序列化.md) | 断点负载记录持有集与剩余候选池;键名与版本迁移策略归存档文档。 |
|
||||
|
||||
## 依赖与输出
|
||||
|
||||
| 类型 | 内容 |
|
||||
|---|---|
|
||||
| 依赖(概念) | 角色、结算管线、行动点、地形、关卡节点地图、局内金币钱包、三选一界面 |
|
||||
| 依赖(数据) | `relics.tres`(专长定义行)、`adventure.tres`(属性值提升与资源的种类配额与值)、`shop.tres`(货架取舍) |
|
||||
| 输出(对外) | 持有集、生效中的分类投影、剩余候选池、档位求值结果、可用重抽次数 |
|
||||
| 明确边界 | 不写账号进度、不改敌人与关卡内容、不承载具体数值 |
|
||||
|
||||
## P0 最小闭环 / P1・P2 后置
|
||||
|
||||
- **P0(已实现)**:三个分类可定义 → 进入候选池 → 在渠道上被选中 → 当局生效 → 收束清零。
|
||||
- **P1 后置**:三条渠道按第 2 节分工;刷新次数与专长获取两项入池;两项合成高阶项;同一标签收集到四项以上的后期表达。
|
||||
- **P2 后置**:商店里的攻击类型转换服务;喂雷流派是否保留(尚未拍板,登记在 [06-待办清单](../../06-待办清单.md))。
|
||||
|
||||
## 调参表
|
||||
|
||||
数值所有权归 [难度曲线与Boss](难度曲线与Boss.md);本文件只列参数与取值域,**不列现行值**。
|
||||
|
||||
| 参数 | 取值域 | 事实源 |
|
||||
|---|---|---|
|
||||
| 专长定义行(标识 / 显示名 / 稀有度 / 标签 / 挂点 / 效果字典) | 各字段封闭枚举,行键白名单封闭 | `game/data/tables/relics.tres` |
|
||||
| 专长门票(出现概率 / 配额 / 全局限量) | 整数 | **尚未入表**,见待办 |
|
||||
| 属性值提升种类 | 封闭三项:生命上限 / AC / 攻击,扩项走文档修订 | `game/data/schemas/adventure_table.gd` |
|
||||
| 资源种类 | 行动点上限 / 金币 / 回复(**刷新次数与专长获取两项尚未入表**,见待办) | 同上 |
|
||||
| 稀有度档位 | 封闭三档(普通 / 稀有 / 罕见);三档配额是结构锚,改总量须重新拍板而非调参 | 同上 |
|
||||
| 各分类种类 × 档位的配额与值 | 整数 | `game/data/tables/adventure.tres` |
|
||||
| 专长获取的全局限量 | 整数(一局内可获得的次数上限) | 同上 |
|
||||
| 一次三选一的候选展示数 | [1,6] | 同上 |
|
||||
|
||||
## 验收标准
|
||||
|
||||
1. 三个分类走同一套获取流程,代码里只有一个表示"已持有奇物"的集合。
|
||||
2. 一次冒险内获得的奇物在之后任何关卡都生效;开新冒险后持有集为空。
|
||||
3. 一项被选定的奇物不再出现在任何后续渠道。
|
||||
4. 每个流派标签至少有一项挂在排雷侧的结算触发点上(防止专长沦为纯战斗数值)。
|
||||
5. 玩家可见的文案不出现分类名与内部分组标签——只写效果,归类让玩家自己推断。
|
||||
6. 文档与代码里提到它时只有"奇物"这一个名字;需要区分时用"专长/属性值提升/资源"描述,不得另造称呼。
|
||||
7. 刷新次数不进角色加算区——它只改三选一界面的可用重抽次数。
|
||||
8. 金币与回复不进持有集——它们是即时兑付,拿到即消费完。
|
||||
9. 金币不出现在商店货架上——这是「计价物不自售」谓词算出来的结果,不是给金币单独立的一个分类;它确实是在分类白名单之外加的一道过滤,只是这道过滤可自动计算而非靠枚举。
|
||||
10. 一个渠道一旦确定要出某个分类,该分类的成员就都在它的池子里——"渠道出哪些分类"不受这条约束,那是渠道轴的定位。
|
||||
11. 门票拿到即开,不进持有集,玩家无法囤积——选中或买下的同一时刻就开专长三选一。
|
||||
12. 门票带有计步保底:连续 5 次三选一展示未出现则第 6 次必出;计数跨奖励节点与商店共享,刷新后的重新展示计入次数,限购用满后保底不再触发。
|
||||
|
||||
## 待办
|
||||
|
||||
全部待办单点登记于 [06-待办清单](../../06-待办清单.md)(BD 分层条目、命名统一后续条目),本节不复制。
|
||||
|
||||
本节只点出四条由本版新立、尚未登记的判断来源:
|
||||
|
||||
- **回复归属已定(v2.5)**:留在资源,不独立成第四类。理由是它与金币同为**即时兑付**、都给的是可花掉的余量,拆出去之后第四类只有两项、且与资源的判据完全同源——分类的价值在于判据能一刀切得开,拆一个判据同源的类只会让读者多查一张表。
|
||||
- **专长门票尚未入表**:出现概率、配额、限购次数、保底计数阈值四个参数都没有事实源;入池时同样受档位结构锚约束(改总量须重裁而非调参)。
|
||||
- **专长总量与档位阈值的匹配——延后复裁(用户 2026-10-05 定"先不调整")**:终局 Boss 不给已定,一局确定性专长次数=终局前 Boss 的个数。三关结构下是两次,加上门票最多三次,而档位阈值是同标签 ≥2 档一 / ≥4 档二——**档二(完全体)在三关结构下几乎不可达**。用户决定不动,理由是后续会有第四关,且届时可能另做获取侧的调整。**复裁触发条件:第四关内容批落地后实测,若配合仍太少再调**。登记于此防止它被忘掉。
|
||||
- **charge 标签件数不足(数据缺陷,独立登记)**:档二要求同标签 ≥4 件,而 `relics.tres` 里 charge 标签**只有 3 件**——即使获取次数无限,charge 流派也永远达不到档二。这与渠道结构无关,是数据层缺陷,随上一条一并延后,但不要被上一条盖掉。
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 变更 |
|
||||
|---|---|---|
|
||||
| v1.0 | 2026-10-05 | 以「特性」为名首次为本概念立定义文档。此前它按内部分类被叫成三个名字(规则类称「流派件」、属性类称「数值件」、界面称「本关强化」),现收敛为一个对象下的分类;性质定为「角色自身得到提升」而非「获得物品」。 |
|
||||
| v1.1 | 2026-10-05 | 分类重构:两类由「规则改写型 / 属性加成型」改为「属性提升 / 专长」。 |
|
||||
| v1.2 | 2026-10-05 | 专长渠道落定:关底 Boss 击败后兑付,不新增节点类型;罕见旁路明确为"普通奖励里的专长 N 选一"。 |
|
||||
| **v2.0** | 2026-10-05 | **顶层改名为「奖励」并重构为两根轴**。改名动因:筐里既装"角色自身的变化"也装金币这类一次性兑付物,用"自身提升 vs 持有物"已切不开,边界判据改由生命周期承担——**当局清零的是奖励,跨局带走的是魔法道具**。分类由两类改为**三个枚举**(当时的写法是「机制类 / 属性提升类 / 资源与机会类」,v2.7 才定名为专长 / 属性值提升 / 资源):专长 / 属性值提升(生命·AC·攻击)/ 资源(行动点上限·刷新次数·金币·回复)。新增第 2 节分类 × 渠道交叉开关表,明确两根轴互不决定;金币与回复不再被当作"该移出去的脏东西",而是安置在资源里,同时把它们的即时兑付性质显式登记为类内异质性。 |
|
||||
| v2.1 | 2026-10-05 | **交叉表收口(用户拍板)**:Boss 渠道**只出专长**,属性值提升与资源在此均不出现——三条渠道的形状定为"一块独占 + 两块并行",专长靠打赢、其余靠抽取与购买。Boss 兑付明确为**终局前**的 Boss,终局 Boss 不给(无后续关卡可消费)。新增 2.4 节**「计价物不自售」规则**:金币不进商店既不拆分类也不开特例,而是写成两轴交叉处的一条约束——商店的计价物是金币,故金币不进商店;按"能不能进商店"反推分类等于用渠道轴去切分类轴,两根轴会缠回去。 |
|
||||
| v2.2 | 2026-10-05 | **门票形态 + 约束分层 + 默认原则**。① 用户明确:奖励节点与商店不直接给专长,而是给一个**「专长获取」道具**,拿到后开专长三选一——交叉表专长在两渠道由"不出现"改为"**门票形式**";门票归专长(给的是一件以前不会的事,只是把选择推迟),理由是防止用钱定点买构筑。② 用户质疑「计价物不自售」本质是特判——**承认成立**:它确实是在分类白名单之外加的一道过滤,与死特判的区别在于把"枚举例外"变成"**可计算谓词**"(新渠道/新奖励自动判定)。2.4 改写为**三层约束**(分类白名单 / 可计算谓词 / 显式例外清单),并给出判断标准:结构性原因可写成谓词,设计性原因只能进清单且每条须写理由;三个方案(单独分类 / 谓词 / 死特判)的代价并列摆出,不藏折中。③ 用户定**默认原则**:除已登记的特殊规则外,分类内的东西都要在池子里——据此**回复应在商店内**,现行 shop.tres 货架缺它是"现状与表格不对齐",须在实施批补上。 |
|
||||
| v2.3 | 2026-10-05 | **门票机制细化 + 默认原则表述修正**。① 门票**拿到即开、不可囤积**(用户定)——不进持有集,防止玩家把关键决策无限推迟,也防持有物语义从后门回来。② 门票的"罕见"**只在概率不在价格**,一局限购一次,并加**计步保底**:连续 5 次三选一展示未出现则第 6 次必出;计数跨奖励节点与商店共享、**刷新后的重新展示计入**(用户明定含刷新),限购用满后保底不再触发。③ **修正 v2.2 的误读**:把"分类在某渠道不出现"当成需要理由的缺格是错的——渠道出哪些分类是渠道轴的定位(Boss 只出专长),不是例外;默认原则只管**分类内部**的成员齐不齐。④ 专长总量与档位阈值的匹配按用户决定**延后**(待第四关内容批后实测复裁),另单独登记 charge 标签仅 3 件、永远达不到档二的数据缺陷。 |
|
||||
| **v2.7** | 2026-10-05 | **三个子节点正式定名(用户拍板:去「类」字后缀)**。此前三个分类只有带后缀的描述(机制类 / 属性提升类 / 资源类),是文档层临时叫法,既非专名也非玩家可读的词。现定专名:**专长**(Feat)/ **属性值提升**(ASI)/ **资源**。定名依据:前两个是 DND 规则书官方中文,且与用户 v1.1 原话一致(当时原话就是「属性提升(ASI)」与「专长」,v1.1 落文时被加了「类」字后缀而退化成描述)。「机制类」这个叫法本身还有硬伤——它的 28 个成员里没有一件是"机制",实际是"在结算挂点上改一条规则",读者看到会误解为游戏机制。
|
||||
**新增 1.6 节「三层结构与命名」**(用户 2026-10-05 拍板做玩家可见的三层):奇物(总称)/三个分类/具体单件。明确**命名是本节规矩、呈现是另一件事**——分类名在卡面不出现(归 battle.md / node-reward.md 裁决),但帮百科、成就名、效果描述的指代三处都要用,所以它必须是玩家读一遍就懂的正式名词。连带:修掉批量替换撞出的五处「专长(专长)」类自撞、v2.0 历史行内的自撞并标注当时的旧称、registry 的「资源(命名待定)」过期标注。
|
||||
| **v2.6** | 2026-10-05 | **修正核心循环位置图:奇物不是打一场战斗给一份**(用户纠错)。原图把"关内 排雷推理 → 战斗结算 → 通关 → 得到一份奇物"画成一条链,读起来就是每场战斗通关都给一份——**错在把关内普通战斗的通关与关底 Boss 的通关混为一谈**。按 [冒险结构](冒险结构.md) 的定义,**通关一关 = 该关关底 Boss 被击杀**,所以"击败 Boss"与"通过这一关"是同一个时刻、不是一条链上的两步。改法:① 图改为分支结构(普通战斗节点→不给、往下走;关底 Boss 击败→专长三选一+通关回血);② **一关只兑付一次**写成显式口径;③ 2.1 节渠道名由"终局前 Boss 击败后"改为"关底 Boss 击败(即通过这一关)",并写明触发点就是关卡推进本身那一刻;④ 文首引言加"兑付频率"条,交叉表渠道名与 registry 同步;⑤ 连带修掉一处污染——节点类型封闭枚举五种里的"奖励"曾被 v2.4 批量替换误伤成"奇物"(节点类型里没有奇物这一类),已复原。 |
|
||||
|
||||
| **v2.5** | 2026-10-05 | **第三类定名「资源」**(用户拍板,父节点定为「奇物」后解锁)。定名依据:行动点上限 / 刷新次数 / 金币 / 回复都是可以调动、可以花掉的余量。「资源」偏泛(能力资源、财富资源都叫资源),因此在 1.5 写死判据句——**给的是可消耗或可重掷的余量,不是角色基础属性的永久抬升**,这一句是把泛用词收回本类定义的唯一凭据。**回复归属同时定案:留在资源,不独立成第四类**——它与金币同为即时兑付、判据同源,拆出去第四类只剩两项且与本类判据重合。附带修复:1.5 段末与「### 2. 渠道轴」标题粘连(缺换行)。 |
|
||||
| **v2.4** | 2026-10-05 | **顶层由「奖励」改名为「奇物」(Wondrous Item)**。用户否决了「奖励」「收益」与全部自造词(进益/造化/机缘/遇获),要求回到 DND/西幻既有名词。定名依据:DMG 魔法物品九分类中的 Wondrous Item,官方中文译名即「奇物」,是专装不好归类但有奇效之物的兜底杂类——正好对应本概念下三个互不相干的分类。此前考虑过的 Treasure(宝物)因偏财物、装不下专长而落选;roguelike 品类惯例 Relic 因用户否决遗物落选。**代码词族定为 `curio_*`、`ADVENTURE_CURIO`**(`reward_*` 已被 `reward_pick` / `reward_node` / `reward_preview` 占用,不能对齐)。 |
|
||||
@@ -216,7 +216,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| [地图战斗资源](../战斗循环/地图战斗资源.md) | 已开格的奖励身份常读;未开格类型微光(英雄周围 8 格内的未开格显示资源类型——概念定义见本篇「未开格类型微光」节) |
|
||||
| [秘宝](../排雷循环/秘宝.md) | 库存条常读;使用交互与目标拾取;板级叠加层信息呈现 |
|
||||
| [棋盘生成](../排雷循环/棋盘生成.md) | 零合法板的诚实告知(数据面经战斗结算上抛,本系统只管提示形态) |
|
||||
| [地形变异](../排雷循环/地形变异.md) | 全局作用域型三层预告(2026-10-04 首发批——语义正主=地形变异 §全局作用域型):①开战横幅一行(板级变异非空时显示;减动效=静态驻留,轮横幅先例同款双态)②HUD 常驻角标(C 区战斗全程可见防中局遗忘,空态整节隐藏=流派件段先例;摆位 provisional)③帮助手册一行(零交互教学,承载=玩法帮助文案块);数据面经呈现快照 board_variants 投影(核心→呈现唯一读取面),普通图三层恒空态零打扰 |
|
||||
| [地形变异](../排雷循环/地形变异.md) | 全局作用域型三层预告(2026-10-04 首发批——语义正主=地形变异 §全局作用域型):①开战横幅一行(板级变异非空时显示;减动效=静态驻留,轮横幅先例同款双态)②HUD 常驻角标(C 区战斗全程可见防中局遗忘,空态整节隐藏=奇物段先例;摆位 provisional)③帮助手册一行(零交互教学,承载=玩法帮助文案块);数据面经呈现快照 board_variants 投影(核心→呈现唯一读取面),普通图三层恒空态零打扰 |
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
@@ -300,6 +300,6 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| v0.10 | 2026-09-26 | 渲染技术注记(战斗舞台 Node2D 迁移批 Phase B,代码实装同批;上位裁决 ADR-0006):B 区战斗舞台 Node2D 化——BattleStageView 内部由 PanelContainer+Control 站桩改为 Control 壳 + SubViewportContainer + SubViewport + Node2D 世界(StageWorld/StandeeBody),类名/setter 面/公共方法契约不变、调用点零改造;状态图标行与悬停 tooltip 保留 Control 载体挂壳层(伴随件);C6 字体注入挂点复用(set_world_font);三区布局与性能预算(同屏 draw calls < 200)不变;占位表现等价平移(时序常量逐字对照——等价证明=git 提交 7f24b64,文件已按生命周期条款退役) |
|
||||
| v0.11 | 2026-09-27 | 关卡画面 UX spec 建档([level-map](../../ux/level-map.md),关卡画面 UX 批——用户拍板立项):义务清单「关卡节点地图」行挂屏级 spec 指针;屏级权威行与不负责表改按屏分治口径(战斗屏 = battle.md / 关卡画面 = level-map.md)。文档面零机制改动 |
|
||||
| v0.12 | 2026-09-30 | **未开格类型微光概念收口批(用户裁决落位)**:新增「未开格类型微光」节=全项目唯一正主定义(五要素——作用对象=英雄周围 8 格内的未开格〔与可挖域同圈〕/信息内容=只类型不泄雷安/生命周期=入圈亮出圈灭开格灭/关联边界/实装状态=契约定稿〔样张 v2〕游戏内待实施批);核心规则章六节改七节;呈现义务来源清单「地图战斗资源」行补微光指路;验收标准补微光呈现线。背景:该概念此前只活在 06 登记与 art-bible 复述,「常显/全部未开格」无范围表述酿成理解事故(2026-09-30 用户纠正口径),本批落位正主、他文只许指路 |
|
||||
| v0.13 | 2026-10-04 | **地形变异三层预告义务批(全局作用域变异首发批——迭代 14 ③号卡,代码同批)**:呈现义务来源清单补「地形变异」行(开战横幅一行〔减动效=静态驻留,轮横幅先例同款双态〕+ C 区常驻角标〔空态整节隐藏=流派件段先例,摆位 provisional〕+ 帮助手册一行〔零交互教学〕);验收标准补三层预告线(普通图恒空态零打扰);数据面走呈现快照 board_variants 投影(核心→呈现唯一读取面)。语义正主=地形变异.md §全局作用域型,本文只锁呈现承载 |
|
||||
| v0.13 | 2026-10-04 | **地形变异三层预告义务批(全局作用域变异首发批——迭代 14 ③号卡,代码同批)**:呈现义务来源清单补「地形变异」行(开战横幅一行〔减动效=静态驻留,轮横幅先例同款双态〕+ C 区常驻角标〔空态整节隐藏=奇物段先例,摆位 provisional〕+ 帮助手册一行〔零交互教学〕);验收标准补三层预告线(普通图恒空态零打扰);数据面走呈现快照 board_variants 投影(核心→呈现唯一读取面)。语义正主=地形变异.md §全局作用域型,本文只锁呈现承载 |
|
||||
| v0.14 | 2026-10-03 | **视野迷雾实施批落籍注记(迭代 11 第④批)**:迷雾节补「实施状态」注记(四裁决逐条对账:纯呈现两态逐位一致/暗淡记忆态灰显可读/LIGHT_RADIUS=8 参数化〔提灯 +2 插值位预留未接〕/类型微光仍贴身 8 邻格);实装状态行「待实施批」改「已实装」;验收标准迷雾行去「待实施批落地后验收」括注转正式验收。机制定义零改动(定义一句话/作用范围/生命周期/关联边界/配套拍板全段原样);黑暗区域渲染规格落 art-bible §6.5(v3.5) |
|
||||
| v0.13 | 2026-09-30 | **视野迷雾概念落位批(用户拍板立项)**:新增「视野迷雾」节=正主定义(菱形灯光区+黑暗边界;区外已开格=暗淡记忆态灰显可读、区外未开格=全黑;灯光半径起步=微光环 8 格同圈;纯呈现层,与已退役雾格无关);验收标准补迷雾线;配套拍板随节登记(魔法提灯灯甲外扩 +2 格、类型微光不随视野扩、初始展开收窄后置 Alpha 差异化批)。实施待主线编卡 |
|
||||
@@ -105,7 +105,7 @@
|
||||
- 攻击值 + 修正来源角标(战斗在消费、且站桩上无展示)
|
||||
- 护甲 AC(2026-09-26 二轮拍板补入——我方 AC 的唯一展示面;掷点判定轴,受击侧可读性)
|
||||
- 秘宝槽(**已实装**:四槽两步交互,详见 [node-reward.md](node-reward.md)——随身战斗用道具的唯一展示面)
|
||||
- 本关强化列表(**预留**——锻造/大奖励/关卡奖励节点获得的属性提升;与战斗内状态效果分区呈现,防「战斗结束被清」误读)
|
||||
- 奇物列表(**预留**——锻造/大奖励/关卡奖励节点获得的属性提升;与战斗内状态效果分区呈现,防「战斗结束被清」误读)
|
||||
- **D 区扫雷图 · AP 条**
|
||||
- AP 点阵 + 停手按钮(现行)
|
||||
- **RAP 读数(点阵+数字)**——自 C 区迁入,置于弃图刷新按钮旁(2026-09-26 拍板:RAP 唯一消费口 = 弃图刷新,资源数字贴消费按钮)
|
||||
@@ -120,7 +120,7 @@
|
||||
| 区 | 位置与尺寸 | 内容 |
|
||||
|---|---|---|
|
||||
| **B 战斗画面** | 全宽 × 252px | 主角站桩立绘(左)+ 兑现演出区(中)+ 敌人站桩立绘 ×1–3(右)——**全站桩形态(2026-09-20 用户拍板,敌人卡形态待办裁决收口):主角与敌人均为无框立绘+底座,零卡片**;主角与敌人站桩 = **HP 与状态效果的唯一展示面(2026-09-26 信息归属拍板)**;底部结算明细带(24px 摘要 / 结算期 84px 实时流);顶部中央轮次·阶段指示 |
|
||||
| **C 角色信息** | 左下 240px × 548px | 攻击值(含修正显示)、护甲 AC;秘宝槽(预留)、本关强化列表(预留)——HP 条/RAP 池/状态效果槽/立绘占位/钱包行退役(2026-09-26 信息归属拍板:HP 与状态唯一展示面 = B 区站桩;RAP 迁 D 区 AP 条;GP/钥石迁出战斗屏) |
|
||||
| **C 角色信息** | 左下 240px × 548px | 攻击值(含修正显示)、护甲 AC;秘宝槽(预留)、奇物列表(预留)——HP 条/RAP 池/状态效果槽/立绘占位/钱包行退役(2026-09-26 信息归属拍板:HP 与状态唯一展示面 = B 区站桩;RAP 迁 D 区 AP 条;GP/钥石迁出战斗屏) |
|
||||
| **D 扫雷图** | 中下 ~1036px × 548px(原右下面板删除后横向加宽,吸收其宽度) | 顶部 AP 条(44px:左——AP 点阵 + 停手按钮;中——RAP 点阵+数字〔自 C 区迁入,贴弃图刷新按钮,2026-09-26 拍板〕;右——图例按钮 + 弃图刷新按钮〔雷图右上角,2026-09-12 拍板〕);棋盘主体(居中,格 36–45px 见方);toast 槽(上缘内侧) |
|
||||
|
||||
> 布局为 B/C/D 三区——关卡进度条不在战斗屏(节点链进度常驻关卡画面,见 Navigation Position;字母不重编沿用 B/C/D)。
|
||||
@@ -147,7 +147,7 @@
|
||||
| B | 结算明细回看 | 模态 overlay | 完整流水逐行(现行 9 类行协议;未生效类行聚合计数) | 关闭 | battle_log_view.gd 改造 |
|
||||
| C | 攻击数据框 | 直角细线数据框 | 攻击值 + 修正来源角标 + 护甲 AC(AC 二轮拍板 2026-09-26 补入——我方 AC 唯一展示面;原「HP/攻击/RAP 显示」——HP 与 RAP 随信息归属拍板迁出本组件) | 只读 | HUDView 拆分 |
|
||||
| C | 秘宝槽(已实装:四槽两步交互,详见 [node-reward.md](node-reward.md)) | 图标槽 ×4 | 随身战斗用道具的唯一展示面;库存已随迭代 7 落地(C 区四槽+关卡域库存),清库反馈呈现待批 | 悬停 tooltip(道具语义) | 新建(随秘宝批,已落地) |
|
||||
| C | 本关强化列表(预留) | 列表/图标行 | 锻造/大奖励/关卡奖励节点获得的属性提升——中循环数据,因改变战斗数学且无其他展示面准入战斗屏;与战斗内状态效果(B 区站桩)分区,防「战斗结束被清」误读 | 只读 | 新建 |
|
||||
| C | 奇物列表(预留) | 列表/图标行 | 锻造/大奖励/关卡奖励节点获得的属性提升——中循环数据,因改变战斗数学且无其他展示面准入战斗屏;与战斗内状态效果(B 区站桩)分区,防「战斗结束被清」误读 | 只读 | 新建 |
|
||||
| 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③) |
|
||||
@@ -204,7 +204,7 @@
|
||||
│ │ 秘宝槽(预留) │ │ │ │AP不足·剩0点 │ 12 12 1 ░ 2 ▓▓ ▓▓ │ │
|
||||
│ │ ◇ ◇ ◇ ◇ │ │ │ └──────────────────┘ 12 █ 1 1 2 ▓▓ ▓▓ │ │
|
||||
│ ├──────────────────┤ │ │ 1 2 2 🚩 █ 2 1 1 ▓▓ 👫 1 1 ░ │ │
|
||||
│ │ 本关强化(预留) │ │ │ ░ 1 ▓▓ 👫 1 1 ░ ▓▓ 1 1 ░ ░ 2 │ │
|
||||
│ │ 奇物列表(预留) │ │ │ ░ 1 ▓▓ 👫 1 1 ░ ▓▓ 1 1 ░ ░ 2 │ │
|
||||
│ │ 锻造+2攻 │ │ │ ▓▓ 1 1 ░ ░ 2 ▓▓ │ │
|
||||
│ │ (空态=隐藏) │ │ │ ( █=可挖域微光 👫=小人) │ │
|
||||
│ └──────────────────┘ │ └─────────────────────────────────────────────────┘ │
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
**布局决策 3 —— 放弃冒险二次确认(2026-09-27 拍板)**:放弃 = 整局冒险终结,不可逆(pattern 7 破坏性确认)。首击转入确认态(按钮文案变「再点一次确认放弃——不可逆」,危险红边框脉冲约 3 秒,超时回落),二击才提交。代价语义(已获大奖励保留、同失败结算)常驻按钮文案。
|
||||
|
||||
**布局决策 4 —— 底部状态栏(2026-09-27 拍板,原提案为顶栏 HP 读数)**:底栏作为状态展示——生命、属性、本关已选加成三项常读;顶栏保持关卡名 + GP 两件。单一展示面注记:与 [battle.md](battle.md) C 区「本关强化列表(预留)」为不同屏的不同展示面——两屏循环口径各自独立(选路规划消费 vs 战斗内决策消费),不构成同屏重复。
|
||||
**布局决策 4 —— 底部状态栏(2026-09-27 拍板,原提案为顶栏 HP 读数)**:底栏作为状态展示——生命、属性、本关已选加成三项常读;顶栏保持关卡名 + GP 两件。单一展示面注记:与 [battle.md](battle.md) C 区「奇物列表(预留)」为不同屏的不同展示面——两屏循环口径各自独立(选路规划消费 vs 战斗内决策消费),不构成同屏重复。
|
||||
|
||||
### ASCII Wireframe
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ entities:
|
||||
table: RewardTable(数据配置 承载,键 = reward_id;地图战斗资源 回填 owner;**2026-09-15 格面资源批结构性重写**——旧 category / use_timing / 库存 / 供给轴随可选类删除整批下线,五型 × 极性字典取代〔历史结构见底部修订记录〕)
|
||||
fields:
|
||||
reward_id: String(表内主键)
|
||||
cell_type: enum {attack, defense, heal, blast, weaken, pierce, magic, action, gp}——九型封闭(2026-09-18 伤害道具批五→七、2026-09-20 格面资源八型批七→八 +action、同日 GP+商店房批八→九 +gp;格面资源类型身份;CELL_TYPE_KEYS 词表十八格 = 九型 × 正负,表里出现清单外值加载拒绝 fail-fast) # 2026-09-15 新增,取代 category;2026-09-18 扩七型;2026-09-20 八型批扩八型;同日 GP+商店房批扩九型
|
||||
cell_type: enum {attack, defense, heal, blast, weaken, pierce, magic, action, gp}——九型封闭(2026-09-18 伤害道具批五→七、2026-09-20 格面资源八型批七→八 +action、同日 GP+商店房批八→九 +gp;格面资源型身份;CELL_TYPE_KEYS 词表十八格 = 九型 × 正负,表里出现清单外值加载拒绝 fail-fast) # 2026-09-15 新增,取代 category;2026-09-18 扩七型;2026-09-20 八型批扩八型;同日 GP+商店房批扩九型
|
||||
polarity: enum {positive, negative}——同型两行:正向行参与摇号(权重 = 类型频次),负向行纯兑付字典、不消费权重 # 2026-09-15 新增
|
||||
effect_id: String 可空——percent 类行(attack/defense/weaken 正负两向)必填(StatusEffectTable 精确引用,悬空校验已激活);flat 直付行(直伤/群伤/治疗)恒空
|
||||
stacks: int [1,16] 可省——多层授予行(原 blast 负向 ambush_double ×2 层——该行随 2026-09-20 八型批退役,现行表无 stacks 行、字段保留 schema 位);缺省 1
|
||||
@@ -582,9 +582,27 @@ entities:
|
||||
nodes: 节点图结构——节点数组 + 连线(node_kind ∈ {battle, reward, rest, boss, shop},切片字段名 type;+shop 随 2026-09-20 GP+商店房批——商店房兑付 = 打开商店覆盖层、离开后确认回选路,不携带战斗行〔零敌人、零棋盘配置行〕;每节点领关卡内唯一**节点编号**,battle/boss 数据键 node_depth 沿用〔v1.0 语义升级:深度 → 节点编号〕;连线 = 出边节点编号表,只朝前进方向、无回头路);单链特例 = 隐式后继(数组序即链,切片现行形态零漂移)
|
||||
rowset_rule: 图合法性校验(2026-09-17 关卡节点地图 v1.0)——节点编号关卡内唯一、入口唯一、Boss 恒唯一终点(编号最大,Dmax 语义平移)、连线无环、所有节点沿连线可达 Boss,违规加载期致命;实现批(2026-09-17 分支节点图批):校验落 LevelTable.validate(单链形态经同一套算法——编号解析单链 = 数组下标 / 图 = node_depth),L1 单链与 L2 图双行集加载全绿断言;商店房编排(每关恰 1、Boss 前一位必经位)由冒烟断言承载、非加载校验——图合法性六检零新增(GP+商店房批 2026-09-20,关卡节点地图 v1.1)
|
||||
cross_table_validation: battle/boss 节点 (L,D) 在 board_gen/enemy 两表存在精确行(数据配置 跨表校验⑧复用 + 冒险结构 AC-7 冒烟断言——序列关数 ⊆ 内容覆盖,越界关卡 = 内容生产缺口)
|
||||
mvp_content: L1 全行(切片转正——7 节点链〔单链特例,合法图形态〕、rest_heal_pct=30);L2 全行已落地(2026-09-17 分支节点图批——首张分支图:9 节点〔入口 0 → 中间三层 2/3/2 → Boss 8〕、真实岔路 4 处、奖励点+恢复点各 1、战斗节点 6 + Boss;行值 provisional 归 难度曲线与Boss v0.7;首页直入口已退役〔2026-09-23 用户拍板〕);**L3 全行已落地(2026-09-20 第三关内容批——「第三层 · 灰矮人矿城」:九节点图复用 L2 同模板〔6 战 + Boss + 奖励 + 恢复、真实岔路 4 处〕,行值全 provisional 归 难度曲线与Boss;测试直入口已退役〔2026-09-23〕)**;2026-09-20 GP+商店房批 rewiring:L2/L3 图版 Boss 重编号 8→9、各新增 (8, shop, next[9]) 商店房节点(Boss 前一位必经位),L1 零改动,图合法性六检零新增——必经位由冒烟断言承载;**2026-09-21 冒险结构实现批:三关正式序列生效**(首页「开始冒险」= L1→L2→L3 连探,AdventureRunner 编排——大奖励/生命账本/GP 冒险账本/主种子归冒险结构层,冒烟断言在案)**
|
||||
mvp_content: L1 全行(切片转正——7 节点链〔单链特例,合法图形态〕、rest_heal_pct=30);L2 全行已落地(2026-09-17 分支节点图批——首张分支图:9 节点〔入口 0 → 中间三层 2/3/2 → Boss 8〕、真实岔路 4 处、奖励点+恢复点各 1、战斗节点 6 + Boss;行值 provisional 归 难度曲线与Boss v0.7;首页直入口已退役〔2026-09-23 用户拍板〕);**L3 全行已落地(2026-09-20 第三关内容批——「第三层 · 灰矮人矿城」:九节点图复用 L2 同模板〔6 战 + Boss + 奖励 + 恢复、真实岔路 4 处〕,行值全 provisional 归 难度曲线与Boss;测试直入口已退役〔2026-09-23〕)**;2026-09-20 GP+商店房批 rewiring:L2/L3 图版 Boss 重编号 8→9、各新增 (8, shop, next[9]) 商店房节点(Boss 前一位必经位),L1 零改动,图合法性六检零新增——必经位由冒烟断言承载;**2026-09-21 冒险结构实现批:三关正式序列生效**(首页「开始冒险」= L1→L2→L3 连探,AdventureRunner 编排——大奇物/生命账本/GP 冒险账本/主种子归冒险结构层,冒烟断言在案)**
|
||||
referenced_by: [冒险结构, 关卡节点地图, 难度曲线与Boss, 棋盘生成, 数据配置]
|
||||
|
||||
- name: curio
|
||||
type: concept
|
||||
owner: design/gdd/systems/冒险循环/奇物.md
|
||||
attributes:
|
||||
definition: 一次冒险之内通过各渠道给予玩家的增益总称——奖励节点给的、商店买的、打赢关底 Boss 给的,都是奇物。装的是"这一局你捞到了什么",不管从哪个渠道来
|
||||
channel_constraint_layers: 渠道约束分三层——一层 分类白名单(分类轴决定渠道);二层 可计算谓词(渠道与奇物的结构性关系,如「计价物不自售」:X 是渠道 C 的计价物 → X 不进 C;新渠道/新奇物自动判定,不用改表);三层 显式例外清单(人为设计选择,只能逐条加,每条须写理由)。要害不是有没有例外,而是例外能不能被算出来——结构性原因写成谓词,设计性原因进清单。在册约束两条:①金币不进商店(二层·谓词)②专长在非 Boss 渠道只给门票(一层·分类形态)。**注意**:属性值提升/资源不出现在 Boss 渠道**不是约束**——那是渠道轴的定位(Boss 是专长独占渠道),不属默认原则管辖。**「计价物不自售」形式上确是在白名单外加的一道过滤(用户质疑成立),与死特判的区别在于把枚举例外变成计算谓词**
|
||||
axes: 两根互不决定的轴——**分类轴**(给的是什么)与**渠道轴**(从哪来)。一个奇物属于哪个分类不决定它从哪个渠道来;交叉关系由 design/gdd/systems/冒险循环/奇物.md 第 2 节开关表定死
|
||||
categories: 封闭三类 {专长 Feat, 属性值提升 ASI, 资源}(v2.7 定名,**去「类」字后缀**——此前为描述式叫法「机制类 / 属性提升类 / 资源类」,非专名;用户 v1.1 原话即「属性提升(ASI)」与「专长」,v1.1 落文时被加后缀而退化。v2.0 起为三类、v1.1 曾用两类、v1.0 曾用 {rule, stat},均已作废)。
|
||||
hierarchy: 玩家可见的三层(用户 2026-10-05 拍板)——一层总称「奇物」/二层三个分类/三层具体单件(如 奥术余烬、贯穿射击)。**命名与呈现是两件事**:分类各有一个正式专名,文档、代码词族、帮百科/成就名/效果描述的指代一律用它;但卡面与详情页只写单件名与效果、不附带分类(呈现面归 battle.md / node-reward.md 裁决,本条目不预断)专长(Feat)——在结算管线某个挂点上给自己加一条规则,同标签持有项数达阈值时质变,事实源 relics.tres;属性值提升(ASI)——抬高生命上限 / AC / 攻击三轴基础值,进冒险加算区,事实源 adventure.tres;资源——给"可用的量",不抬高战斗属性也不改规则:行动点上限 / 刷新次数 / 金币 / 回复,不进加算区、多数不进持有集,事实源 adventure.tres
|
||||
scope: 作用对象 = 角色本人与其参与的结算(不改敌人、不改棋盘生成、不改关卡内容);**例外**——刷新次数作用在三选一界面而非角色身上,不进加算区;时间范围 = 整局冒险,专长与属性值提升跨关携带、关间不清零,金币与回复即时兑付;归属范围 = 不进账号永久进度,不带到下一次冒险
|
||||
lifecycle: 候选池构建(冒险开局一次)→ 在渠道上出现(三选一形式)→ 选定(自池中剔除不再复现;选到「专长获取」时立刻再开一次专长 N 选一)→ 持有生效或即时兑付 → 冒险以任一结局收束时整集清零;断点记录持有集与剩余候选池
|
||||
acquisition: 三条渠道的**目标分工(交叉开关,v2.2 收口)**——专长:主渠道=**关底 Boss 击败=通过这一关**(**唯一直接给的渠道**;不新增节点类型、挂 Boss 节点兑付面;末关的 Boss 击败后不给——无后续关卡可消费)。**兑付频率**:奇物不是打一场战斗给一份,关内普通战斗节点不给任何奇物,一关之内只兑付一次(奖励节点与商店同理,各节点各自兑付),奖励节点与商店**只给「专长获取」门票**——**拿到即开、不可囤积**,不进持有集(选中/买下同一时刻开专长三选一;可囤积会让玩家无限推迟关键决策,且把持有物语义从后门放回)。门票归专长(给的是一件以前不会的事,只是把选择推迟)。罕见**只在概率不在价格**,一局限购一次,**计步保底**:连续 5 次三选一展示未出现→第 6 次必出(计数=展示次数、刷新重展计入、奖励节点与商店共享、触发清零、限购用满后不再触发);属性值提升:奖励节点 + 商店(口径「训练」);资源:奖励节点 + 商店(**金币除外、回复在内**);后两类均不出现在 Boss 渠道。形状=「一块独占 + 两块并行」,专长靠打赢、其余靠抽取与购买。**默认原则**:除已登记的特殊规则外,分类内的东西都要在它该出现的渠道池子里——任何不出现都须登记理由**现行实现三渠道共用同一候选池、三类混编**,分工尚未实施,登记于 06-待办清单 BD 分层条目
|
||||
boundary: 判据走生命周期——**一次冒险内获得、冒险收束即清零的是奇物;跨冒险跟着你走的是魔法道具**。奇物永不进同调位,魔法道具永不进当局随机渠道;与元进度天赋树两层互不代位
|
||||
data_sources: relics.tres(专长定义行)/ adventure.tres(属性值提升与资源的种类配额与值)/ shop.tres(货架取舍)
|
||||
open_questions: ①类内异质性已登记——金币与回复是即时兑付、不进持有集不持续生效,与行动点上限/刷新次数生命周期不同,靠这条描述把"资源"从泛用词收回到本类定义内;②专长门票尚未入表(出现概率/配额/限购次数/保底阈值四参数均无事实源);③确定性渠道一局两次专长 vs 档位阈值(同标签 ≥2 档一 / ≥4 档二)——**档二在三关结构下几乎不可达**,用户定延后复裁(触发=第四关内容批后实测);④charge 标签仅 3 件、永远达不到档二(数据层缺陷,独立登记,勿被上条盖掉);⑤断点存档键 5 个(bonus_deck / bonus_taken / bonus_pending / bonus_result / bonus_aux_carry)是否随存档版本迁移换名待裁
|
||||
naming_note: 2026-10-05 命名统一 + 两次重构——此前按内部分类被叫成三个名字(规则类称「流派件」、属性类称「数值件」、界面称「本关强化」),v1.0 统一为「特性」,v2.0 改名为「奖励」,v2.4 定名为「奇物」(因筐里也装金币这类一次性兑付物,"自身提升 vs 持有物"已切不开,判据改由生命周期承担)。v2.5 第三类定名为「资源」(用户拍板)。**v2.7 三个子节点全部正式定名、去「类」字后缀**:专长(Feat)/ 属性值提升(ASI)/ 资源——此前是描述式叫法不是专名。**代码侧三套词族均尚未对齐**:`feature_*` → `curio_*`(103 处,顶层总称)、`relic_*` → `feat_*`(162 处,专长分类的词族——v2.7 定名后顶层与内层分类各有各的词族)、运行层 `bonus_*` → `curio_*`(160 处),属临时态,登记于 06-待办清单,须在可跑冒烟批次收口
|
||||
referenced_by: [冒险结构, 关卡节点地图, 战斗结算, 行动经济, 地形变异, HUD框架, 魔法道具, 元进度, 数据配置]
|
||||
|
||||
- name: adventure_table
|
||||
type: schema_data
|
||||
owner: design/gdd/systems/冒险循环/冒险结构.md
|
||||
@@ -593,11 +611,12 @@ entities:
|
||||
fields: |
|
||||
退役两字段(迭代 10 奖励重构批,2026-09-30 用户拍板):level_clear_hp_bonus(「血回满+上限提升」件随大奖励三件套退役——回血改 clear_heal_pct 部分回血、上限提升改三选一件值列)、keystone_per_level(钥石退役出大奖励改 Boss/精英击杀掉落)。
|
||||
clear_heal_pct: int [0,100](knob 默认 20——非末关通关部分回血回复生效上限的百分比,封顶上限不回满、满血回 0 合法;难度上压方向,带重扫义务归 难度曲线与Boss)
|
||||
bonus_attack_flat / bonus_max_hp_flat / bonus_armor_flat: int [0,999](三选一属性件兑付值——加算区攻击/生命上限/护甲轴累加,经覆盖值通道;值锚与上调约束归 难度曲线与Boss)
|
||||
bonus_gp_amount: int [0,999](GP 袋件定额入钱包);bonus_ap_flat: int [0,10](AP 件每场战斗首轮行动点基线增量);bonus_aux_item_count: int [1,9](秘宝件授予件数)
|
||||
**2026-10-05 命名统一批**:本表的属性值提升奇物字段与常量整体换名(旧 → 新)——BONUS_IDS → FEATURE_KINDS、bonus_token_count() → feature_quota()、bonus_value() → feature_value()、bonus_candidate_count → feature_candidate_count、token_{kind}_{tier} → feature_quota_{kind}_{tier}、bonus_*_flat/_amount(_large) → feature_value_{kind}_{tier};值零变更(句柄改称不改数),断点附随键名沿用历史形态不动(存档兼容)。换名动因见 curio 条目(v2.0 顶层改名为「奇物」)。
|
||||
feature_value_attack_common / feature_value_max_hp_common / feature_value_armor_common: int [0,999](三选一属性值提升奇物兑付值——加算区攻击/生命上限/护甲轴累加,经覆盖值通道;值锚与上调约束归 难度曲线与Boss)
|
||||
feature_value_gp_common: int [0,999](GP 袋件定额入钱包);feature_value_ap_rarest: int [0,10](AP 件每场战斗首轮行动点基线增量);bonus_aux_item_count: int [1,9](魔法道具件授予件数)
|
||||
~~bonus_weight_*(E-S 加权洗牌权重族)~~ / ~~bonus_cap_*(种类次数上限族)~~:**v2.2 令牌池换代退役(迭代 12 TP0——2026-10-03 追认 b 实施批;洗牌改令牌 Fisher-Yates、池消耗即上限)**
|
||||
token_{kind}_{tier}: int [0,99](**TP0 令牌配额族**——kind×tier 计数:attack 18/5 · max_hp 17/5 · armor 17/5 · gp 18/5 · heal 0/5 · ap 0/0/3〔common/rare/rarest〕;未列组合=0;档位结构锚 70/25/3=98 张入 schema validate 硬断言〔罕见档原列「道具件 2」随 aux_item 池种退役收窄——台账自决披露项〕)
|
||||
bonus_attack_flat_large / bonus_max_hp_flat_large / bonus_armor_flat_large / bonus_gp_amount_large: int [0,999](稀有档大数值对——+2/+10/+2/50);bonus_heal_flat: int [0,999](恢复件 +6 当即回血——新入池种类 rare 档);MC 策略 316-f(autoplay 1 级最稀有/2 级最左)随批落地
|
||||
feature_quota_{kind}_{tier}: int [0,99](**TP0 令牌配额族**——kind×tier 计数:attack 18/5 · max_hp 17/5 · armor 17/5 · gp 18/5 · heal 0/5 · ap 0/0/3〔common/rare/rarest〕;未列组合=0;档位结构锚 70/25/3=98 张入 schema validate 硬断言〔罕见档原列「道具件 2」随 aux_item 池种退役收窄——台账自决披露项〕)
|
||||
feature_value_attack_rare / feature_value_max_hp_rare / feature_value_armor_rare / feature_value_gp_rare: int [0,999](稀有档大数值对——+2/+10/+2/50);feature_value_heal_rare: int [0,999](恢复件 +6 当即回血——新入池种类 rare 档);MC 策略 316-f(autoplay 1 级最稀有/2 级最左)随批落地
|
||||
transitional_sync_slots: int [0,9](同调位过渡读数源,默认 1——道具持有上限;正主 = attunement_growth.tres 里程碑谓词表,同调实施批落地后切换读数源)
|
||||
mvp_content: 单行全局默认值即 MVP 行(provisional 归 曲线调参批——迭代 10 扩列批注)
|
||||
extension_reserve: 大奖励形态扩列位已消费(迭代 10 奖励重构批落地三选一/攻击型——本键使命完成退役;冒险结构 OQ2 收口)
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
# 任务书:奇物概念收口与词族对齐批(迭代 15)
|
||||
|
||||
- 日期:2026-10-05
|
||||
- 设计事实源:[奇物.md](../gdd/systems/冒险循环/奇物.md) v2.6(概念唯一定义,2026-10-05 用户逐轮裁定)
|
||||
- 登记台账:[06-待办清单](../gdd/06-待办清单.md) 三条目(渠道分工目标态 / 资源两个新种类入池 / 奇物命名统一后续)
|
||||
- 实体登记:[entities.yaml](../registry/entities.yaml) `curio` 条目
|
||||
- 状态:**定稿待发令**——用户 2026-10-05 令:本批只改文档,代码与配置改动整理成任务书编入迭代 15
|
||||
- **loop 计划书八件对照**:①目标与完成定义=§一 ②现状事实(代码级,开工自行复核)=§二 ③设计契约(🔴 触碰=L3 停机)=§三 ④范围边界=§四 ⑤任务卡 T0..Tn=§五 ⑥验证闸=§六 ⑦异常分级=§七 ⑧代拍板白名单=§八
|
||||
- **本任务书已有约束**:范式为"设计契约先行、代码后跟"——概念已由用户逐轮裁定定稿(v1.0→v2.6 共 6 轮),本批不做二次设计,只做**落地对齐**。任何在执行中冒出的"要不要改设计"念头,一律记 06 不在本批解决
|
||||
- 数值全 provisional:本批只改标识符与结构,**不调任何平衡数值**;档位配额 70/25/3=98 是结构锚(schema validate 硬断言),本批零改动
|
||||
|
||||
---
|
||||
|
||||
## 一、目标与完成定义
|
||||
|
||||
一句话目标:把 v2.6 已定稿的「奇物」概念从**文档层**贯彻到**代码层与数据层**——三套旧词族(`feature_*` / `relic_*` / 运行层 `bonus_*`)全部对齐到统一词族,渠道分工与两个新种类入表,使代码与文档不再各说一套。
|
||||
|
||||
**为什么现在做**:用户 2026-10-05 的原始诉求是"这导致我们的代码实现和文档描述是分开的"。概念层已裁定完(6 轮),但代码层仍是三个旧词族 + 渠道未分离,**债已经欠了 9 次提交**。顶层已改名「奇物」而代码仍叫 `feature_*`,正是用户最初抱怨的"文档与代码分开"的临时态。
|
||||
|
||||
完成定义(逐条可验):
|
||||
|
||||
1. **词族对齐完成**:`feature_*` → `curio_*`(103 处 / 7 文件)、`relic_*` → `curio_*` 或 `feat_*`(162 处 / 12 文件)、运行层 `bonus_*` → `curio_*`(160 处 / 8 文件)全部改完,`game/` 下 `grep -c "feature_\|relic_\|_bonus_\|pick_bonus\|BonusInteract\|BonusPick"` 归零(存档键 5 个除外,见 T2 裁点)
|
||||
2. **渠道分工落地**:三条渠道按分类分离——关底 Boss 击败=通过这一关 → 只出专长;奖励节点 / 商店 → 只出属性值提升 + 资源,专长在此只以门票形式出现;三渠道不再共用同一个池
|
||||
3. **两个新种类入表**:刷新次数、专长获取门票进入 `adventure.tres`,各自带全参数
|
||||
4. **商店货架补回复**:按默认原则,回复必须在商店货架内(现行缺)
|
||||
5. **数据缺陷修复**:`relics.tres` 的 charge 标签补至 ≥4 件(档二要求同标签 ≥4,现仅 3 件,永远达不到)
|
||||
6. **冒烟与三闸全绿**:批末 run_smoke 全量 + 三探针 + doc 三闸对基线**零新增** + 熵增闸 PASS
|
||||
7. **断点存档往返幂等**:改词族不破存档——旧档能读、新档能续(若 T2 裁点选"换名+迁移",须验 v→v+1 往返)
|
||||
|
||||
## 二、现状事实(代码级,T0 开工须自行复核)
|
||||
|
||||
> 以下是 2026-10-05 读出的事实。开工时按 loop 规范 T0 复核,不以本节为准。
|
||||
|
||||
### 2.1 词族占用实况
|
||||
|
||||
| 词族 | 处数 | 文件数 | 主要落点 |
|
||||
|---|---|---|---|
|
||||
| `feature_*` | 103 | 7 | `adventure_table.gd` / `adventure.tres` / `adventure_runner.gd` / `level_runner.gd` / `config_db_cross_validator.gd` / `bonus_interact_controller.gd` / `smoke_all.gd` |
|
||||
| `relic_*` | 162 | 12 | `relic_table.gd`(+`.uid`)/ `relics.tres` / `relics_engine.gd` / `config_db.gd` / `battle_orchestrator.gd` / `damage_controller.gd` / `action_economy.gd` / `level_runner.gd` / `battle_narrator.gd` / `adventure_runner.gd` 等 |
|
||||
| 运行层 `bonus_*` | 160 | 8 | `_bonus_deck` / `_bonus_taken` / `pick_bonus` / `BonusInteractController` / `BonusPickOverlay` / `bonus_interact_controller.gd` / `level_autoplay.gd` / `breakpoint_resume_test.gd` 等 |
|
||||
|
||||
**🔴 硬约束(不可撞车)**:`reward` 词族**已被占用**——`reward_pick`(rng 封闭流 scope)/ `reward_node`(`grant_aux_item` 的 context 字符串)/ `reward_preview`(道具效果 kind)。**统一词族不得使用 `reward_*`**,本批定为 `curio_*`(`treasure` / `trove` / `curio` / `haul` 零占用,2026-10-05 查证)。
|
||||
|
||||
### 2.2 封闭词表与结构锚(改动即触碰红线)
|
||||
|
||||
- `AdventureTable.FEATURE_KINDS: Array[String]` = `["attack", "max_hp", "armor", "gp", "ap", "heal"]`——**封闭六项**。断点附随件与牌库剔除态依赖它,扩种类须走 schema + registry 同步修订
|
||||
- `AdventureTable.TIER_QUOTAS := {"common": 70, "rare": 25, "rarest": 3}`(合计 98)——**结构锚**,schema `validate()` 内有硬断言:"档位配额结构失锚……改总量须重裁"。本批**入新种类须占配额**,若配额总量不够,**只能在本批内重裁并说明**,不得调参绕过
|
||||
- `adventure.tres` 现有 22 个键与 schema 的 22 个 `@export` 一一对应(2026-10-05 脚本校验通过),改名须同步两侧
|
||||
- 节点类型是**封闭枚举五种**(战斗 / Boss / 奖励 / 恢复 / 商店)——本批**零扩类**(专长挂 Boss 节点兑付面)
|
||||
|
||||
### 2.3 渠道与池的现状
|
||||
|
||||
- 现行**三渠道共用同一个 98 张固定配额令牌池**(普通 70 / 稀有 25 / 罕见 3),三类混编
|
||||
- 专长只占稀有/罕见档,与属性大件混编;商店货架靠"零专长挤掉一张普通卡"保底
|
||||
- 商店货架 = 池 ∖ {GP 袋}(`shop.tres` 的 `pool_shelf` 行族,现为 attack / max_hp / armor_class / ap 四项,**缺回复**)
|
||||
- 奖励节点与通关三选一**共享同一池、同权重同上限**(`node-reward` v2.4)
|
||||
|
||||
### 2.4 数据缺陷(独立于渠道结构,须单独修)
|
||||
|
||||
- `relics.tres` 的 **charge 标签只有 3 件**,而档位激活要求同标签 ≥4 件——**charge 流派永远达不到档二**,即使获取次数无限
|
||||
- 一局确定性专长兑付次数 = 终局前 Boss 个数(三关 = 2 次),而档一阈值是同标签 ≥2——档一刚好够,档二(≥4)须靠门票补齐。**此项用户已定延后复裁**(触发=第四关内容批落地后实测),本批只登记不改
|
||||
|
||||
### 2.5 断点与存档键(5 个)
|
||||
|
||||
`bonus_deck` / `bonus_taken` / `bonus_pending` / `bonus_result` / `bonus_aux_carry`——为存档兼容沿用历史名。`adventure_runner.gd` 内同时有 `_node_bonus_pending`(奖励节点停点态)。**是否随存档版本迁移换名须本批裁**(见 T2)。
|
||||
|
||||
## 三、设计契约(违反即返工,🔴 触碰 = L3 停机)
|
||||
|
||||
1. 🔴 **兑付频率不可改**:奇物**不是打一场战斗给一份**。关内普通战斗节点打完不给任何奇物;一关之内只兑付一次,触发点是**关底 Boss 被击败**——按 [冒险结构](../gdd/systems/冒险循环/冒险结构.md) 定义"通关一关 = 该关关底 Boss 被击杀",**这两件事是同一个时刻,不是一条链上的两步**。任何把专长挂到"战斗结算后"的实现即为 L3
|
||||
2. 🔴 **两条轴互不决定**:分类轴(给的是什么:专长 / 属性值提升 / 资源)与渠道轴(从哪来:奖励节点 / 商店 / 关底 Boss 击败)**不得互相推导**。禁止"因为它要进商店所以另立一分类"这类反向推导(= 06 已登记的"两轴缠回去")
|
||||
3. 🔴 **Boss 渠道独占专长**:关底 Boss 击败=通过这一关**只出专长**,属性值提升与资源在此不出现。这是渠道轴的定位决定,不是例外,不需另找理由。末关的 Boss 击败后不给(无后续关卡可消费)
|
||||
4. 🔴 **专长门票四条口径不可改**:①**拿到即开、不可囤积**(不进持有集,选中/买下同一时刻开专长三选一);②**罕见只在概率、不在价格**(货架价与其他商品相当);③**一局限购一次**;④**计步保底**——连续 5 次三选一展示未出现 → 第 6 次必定出现(计数=**展示次数**,刷新后的重展计入,奖励节点与商店共享计数,触发后清零,限购用满后不再触发)
|
||||
5. 🔴 **统一词族不得用 `reward_*`**(已被 `reward_pick` / `reward_node` / `reward_preview` 占用,见 §2.1)
|
||||
6. 🔴 **档位配额结构锚不可绕过**:`TIER_QUOTAS` 的 70/25/3 有 validate 硬断言。改总量须重裁并留说明,不得调参绕过
|
||||
7. 🔴 **不新增节点类型**:`关卡节点地图` 的节点类型封闭枚举五种不变,专长挂 Boss 节点兑付面
|
||||
8. 🔴 **魔法道具边界不位移**:奇物**当局清零、跨局带走的是魔法道具**(判据走生命周期,不走"带在身上")。本批任何改动不得让奇物进同调位,也不得让魔法道具进当局随机渠道
|
||||
9. 🔴 **层级纪律**:奇物只走当局随机渠道(奖励节点 / 商店 / Boss 兑付),不进元进度天赋树
|
||||
10. **本批不改平衡数值**:所有 `feature_value_*` / `feature_quota_*` 的**值零变更**。入新种类属结构改动(占配额),非调参
|
||||
11. **零战斗期新动词**:专长表达全部经"扫雷决策 → 自动结算"间接生效,不新增手动闪避 / 主动施法
|
||||
|
||||
## 四、范围边界(以下均不在本批,收到即停、不顺手做)
|
||||
|
||||
- **任何平衡数值的调参**——档位阈值、门票四参数的具体取值(概率 / 配额 / 限购次数 / 保底步数)、token 配额重裁方案。门票四参数本批只**建结构与字段**,取值走 provisional + 曲线调参批
|
||||
- **第四关内容**——用户已定"后续还会有第四关,到时候试完觉得配合太少再调整"。档二可达性复裁触发条件是第四关落地后实测
|
||||
- **charge 补件的内容设计**——本批只把 charge 补到 ≥4 件以打开档二通路,**补哪几件是内容裁决**,走独立内容批;本批若判断内容不可自决,则只做"档二对 charge 不可达"的显式登记(数据缺陷留痕),不硬补
|
||||
- **玩家可见面违规改法**(06 独立条目:内部分类禁写入玩家可见面 + 档位呈现三路待裁)——属呈现面设计裁决,须用户拍板,本批不碰
|
||||
- **教学引导相关**——用户 2026-10-04 裁改排 Beta
|
||||
- **资源配比预设 / 判式换代 / 全局变异等 M-4 在途批**——与本批词族改名**撞同一批文件**(`adventure_table.gd` / `level_runner.gd` / `adventure.tres`),**须在 roadmap 排期上确认不与在途批并行**,本批开工门 = 相关在途批出口或用户明示插队
|
||||
- **存档键换名的迁移实现**(若 T2 裁"换名")——须与存档版本迁移单独裁定,本批可只做"代码侧改名 + 兼容读旧键",迁移写 v+1 归存档批
|
||||
|
||||
## 五、任务卡(T0..T8 逐卡估时)
|
||||
|
||||
> **估时合计**(provisional,工作日)≈ 4.5 日,在 ≤3 日软时间盒边缘。**切分预案**:T0-T3 一段(词族对齐)≈ 2 日;T4-T8 二段(渠道分离 + 入表)≈ 2.5 日。切分点 = T3 出口。超限即按 loop 规范切迭代(L3 汇报)。
|
||||
|
||||
### T0 开工(≈0.3d)
|
||||
|
||||
- 建 worktree(分支名建议 `curio-wordfamily-20261005`),**主工作区只作合并落点**
|
||||
- 基线复读记档:冒烟全量数字 / 三探针(`ui_input_probe` 十一断言)/ doc 三闸 / MC 对拍基准 / `git status` 归属核对(并行遗留只标旗不碰)
|
||||
- **复核 §2 全部事实**(词族处数、封闭词表、配额锚、存档键清单),与本节不符以实测为准并回写本任务书
|
||||
- 输出:worktree 名 + 基线数字 + 事实复核差异表
|
||||
|
||||
### T1 词族对齐第一批:`feature_*` → `curio_*`(≈0.7d)
|
||||
|
||||
- 范围:`FEATURE_KINDS` → `CURIO_KINDS`、`feature_quota()` → `curio_quota()`、`feature_value()` → `curio_value()`、`feature_candidate_count` → `curio_candidate_count`、`feature_quota_{kind}_{tier}` → `curio_quota_*`、`feature_value_{kind}_{tier}` → `curio_value_*`
|
||||
- 涉及:`adventure_table.gd` + `adventure.tres`(键名)+ 6 个引用文件
|
||||
- **值零变更**(只改键名与常量名)
|
||||
- ⚠️ `FEATURE_KINDS` 是封闭词表、断点附随件与牌库剔除态依赖它 → 改名须与 `entities.yaml` 同批同步
|
||||
- 轻闸:冒烟全量绿 + 存档往返测试绿
|
||||
|
||||
### T2 词族对齐第二批:运行层 `bonus_*` + **存档键裁点**(≈0.7d)
|
||||
|
||||
- 范围:`_bonus_deck` / `_bonus_taken` / `pick_bonus` / `BonusInteractController` / `BonusPickOverlay` / `bonus_interact_controller.gd` / `level_autoplay.gd` / `breakpoint_resume_test.gd`
|
||||
- **文件改名须同步 Godot `.uid` 与 `.tscn` 引用**(非文本层,无法靠 grep 自证)
|
||||
- **裁点(本任务书内唯一待裁,批内自裁可行但须台账留痕)**:
|
||||
- 五个**断点存档键**(`bonus_deck` / `bonus_taken` / `bonus_pending` / `bonus_result` / `bonus_aux_carry`)换不换名?
|
||||
- 甲=**不换**(保存档兼容,仅改代码侧变量名)——推荐
|
||||
- 乙=换 + 兼容读旧键(旧键读入映射到新键,写出用新键)
|
||||
- 丙=换 + 存档版本迁移到 v+1(**范围外**,本批不做)
|
||||
- 建议甲或乙;若判断丙才对,回写本任务书并转 06
|
||||
- 轻闸:冒烟全量 + **断点存档往返测试绿** + `ui_click_probe`(触碰 presentation)
|
||||
|
||||
### T3 词族对齐第三批:`relic_*` → 专长(≈0.8d)
|
||||
|
||||
- 范围:`relic_table.gd`(+`.uid`)/ `relics.tres` / `relics_engine.gd` / 及 9 个引用文件
|
||||
- 目标词族:**`feat_*`**(专长 Feat)。**顶层与内层分类各有各的词族**(v2.7 定名后确立):`curio_*` 是总称「奇物」/`feat_*` 是专长/`asi_*` 是属性值提升/`res_*` 是资源
|
||||
- **文件名与 `class_name` 改名须同步 `.uid` 与 `.tscn`**(非文本层)
|
||||
- **不新增节点类型**;MINE_HOOKS 红线校验逻辑零改动
|
||||
- 轻闸:冒烟全量 + 全探针(三)
|
||||
- **T3 出口 = 切分点**:段落一(词族对齐)完成,出阶段报告
|
||||
|
||||
### T4 渠道分离:池的拆分(≈0.8d)
|
||||
|
||||
- 目标:三个渠道各按分类白名单取候选,不再共用同一个 98 张池
|
||||
- 关底 Boss 击败 → 只出专长
|
||||
- 奖励节点 / 商店 → 专长**只以门票形式出现** + 属性值提升 + 资源
|
||||
- ⚠️ **配额结构锚处置**:专长抽离共享池后,属性与资源的配额总量是否维持 98?**若须改 `TIER_QUOTAS` 总量,走重裁流程并在本任务书回写理由**(不得调参绕过 validate 硬断言)
|
||||
- 商店货架 = 池 ∖ {GP 袋}(**计价物不自售**规则:凡以某渠道计价物为内容的奖励不进该渠道货架)
|
||||
- 轻闸:冒烟全量 + 探针 + **MC 逐位对拍**(涉核心,必须)
|
||||
|
||||
### T5 专长门票入表(≈0.7d)
|
||||
|
||||
- 新增门票项到 `adventure.tres`,四参数全部建字段、**取值 provisional**:
|
||||
- 出现概率 / 配额 / 限购次数(=1)/ 保底步数(=5 展示)
|
||||
- 机制:**拿到即开、不可囤积**(不进持有集)→ 选中/买下同一时刻开专长三选一
|
||||
- **计步保底计数器**:计数=展示次数、刷新后重展计入、奖励节点与商店**共享**计数、触发后清零、限购用满后不触发
|
||||
- 稀有档处置须说明:门票进哪一档(罕见?),占多少配额
|
||||
- 轻闸:冒烟全量 + 探针 + MC 逐位对拍
|
||||
|
||||
### T6 刷新次数入表 + 商店补回复(≈0.5d)
|
||||
|
||||
- `FEATURE_KINDS` 扩项须走 schema + registry 同步修订(封闭词表,红线 §3.6)
|
||||
- ⚠️ **必须先划清边界**:既有「商店独立刷新机制」是**进店后的免费次数 + GP 刷新**(商店自身的服务),本项是**作为奇物授予的**重抽次数——**两者不是一回事**,入表前须在 registry 里把边界写死,防止后续混淆结算
|
||||
- 刷新次数的作用对象是**三选一界面而非角色**——不进加算区(§2.2 加算区四轴不含它)
|
||||
- 补 `shop.tres` 的 `pool_shelf` 货架含回复(按默认原则:除已登记规则外,分类内成员都要在它该出现的渠道池子里)
|
||||
- 轻闸:冒烟全量 + 探针 + MC 逐位对拍
|
||||
|
||||
### T7 档位通路与数据缺陷(≈0.4d)
|
||||
|
||||
- 复核 charge 标签件数。若本批能自决则补至 ≥4 件;若内容不可自决,则**只做显式登记**("档二对 charge 不可达,数据缺陷留痕,转内容批")——**不硬补、不塞占位件**
|
||||
- 档二可达性复裁:**本批只做静态推演与登记**,实测归第四关内容批(用户已定)
|
||||
- 轻闸:冒烟全量
|
||||
|
||||
### T8 批末闸与人闸材料(≈0.4d)
|
||||
|
||||
- 重闸:全量轻闸 + doc 三闸(对基线**零新增**)+ 熵增闸 + MC 逐位对拍(涉核心)+ 素材批机检断言(本批无素材则免)
|
||||
- 人闸材料包(`design/qa/`):真人目检清单(重点 = 奇物列表呈现、档位激活反馈、门票弹出三选一面)+ 代拍板追认清单 + 三渠道兑付点目检指引(**专长兑付发生在关底 Boss 击败那一刻,不是战斗结算后**——这条要单列一个检查项)
|
||||
- 收口五步:①`active.md` 快照 ②台账条目(查撞号)③里程碑移动更新 roadmap ④`stage.txt` 阶段变更 ⑤闸序列全绿留痕
|
||||
|
||||
## 六、验证闸
|
||||
|
||||
### 6.1 轻闸(每轮必跑,headless)
|
||||
|
||||
- `run_smoke` 全量
|
||||
- `ui_input_probe`(十一断言)
|
||||
- 触碰 presentation 时加跑 `ui_click_probe` + `ui_layout_probe`(T2 / T3 触碰)
|
||||
|
||||
### 6.2 重闸(批末 T8)
|
||||
|
||||
- 全量轻闸 + `doc_link` / `gdd_lint` / `doc_term` 三闸**对基线零新增**
|
||||
- 熵增闸 PASS
|
||||
- MC 逐位对拍(T4 / T5 / T6 涉核心,必须;T1-T3 纯改名可免但须在报告说明理由)
|
||||
|
||||
### 6.3 本批专属验收断言(概念与代码一致性)
|
||||
|
||||
| # | 断言 | 判据 |
|
||||
|---|---|---|
|
||||
| A1 | 词族归零 | `game/` 下 `feature_\|relic_\|_bonus_\|pick_bonus\|BonusInteract\|BonusPick` 命中数 = 0(存档键除外) |
|
||||
| A2 | 禁词未用 | `game/` 下无 `reward_pick` / `reward_node` / `reward_preview` **新增**(既有三处不动) |
|
||||
| A3 | 兑付频率正确 | 专长兑付点 = 关底 Boss 击败;**关内普通战斗节点不产奇物**(代码级断言 + 人闸目检双查) |
|
||||
| A4 | 渠道分离 | 三渠道候选池按分类白名单过滤;专长在非 Boss 渠道只以门票形态出现 |
|
||||
| A5 | 门票拿到即开 | 门票不进持有集;选中/买下同帧开专长三选一(断言:持有关卡推进后仍无门票残留) |
|
||||
| A6 | 保底计数 | 连续 5 次展示未出 → 第 6 次必出;刷新重展计入;限购用满后不触发 |
|
||||
| A7 | 值零变更 | T1-T3 全部改名的键,值与基线**逐位相等** |
|
||||
| A8 | 存档往返 | 旧断点可读、可续;存档键按 T2 裁点结论验证 |
|
||||
| A9 | 池配额锚 | `TIER_QUOTAS` validate 硬断言绿;若改总量须有重裁说明 |
|
||||
| A10 | 节点类型零扩类 | 节点类型仍为封闭枚举五种 |
|
||||
| A11 | 玩家可见面无分类名 | 奇物列表 / 三选一面 / 弹窗**不出现**"专长/属性值提升/资源"字样(与 06 独立条目协同,本批只做**断言检查**,不改法) |
|
||||
| A12 | 档二通路 | charge 标签 ≥4 件,或已有显式登记"不可达 + 转内容批" |
|
||||
|
||||
## 七、异常分级(loop 规范)
|
||||
|
||||
- **L1 自救**:一次重试(改名后编译错、`.uid` 未同步等机械错)
|
||||
- **L2 记录继续**:连续 3 次同红灯升级,写台账继续推进
|
||||
- **L3 停机写报告**:触碰 §3 任一 🔴 红线 / 配额结构锚无法自洽 / 发现概念层自相矛盾 / MC 逐位对拍出现无法归因的漂移
|
||||
|
||||
**本批预判的 L3 高风险点**:
|
||||
1. `relic_table.gd` 改名连带 `.uid` / `.tscn` 非文本层引用失败(T3)
|
||||
2. 专长抽离共享池后配额结构锚失锚,需重裁(T4)
|
||||
3. 存档键换名导致旧断点读不出(T2)
|
||||
|
||||
## 八、代拍板白名单(批内可自裁,台账留痕)
|
||||
|
||||
1. **词族细分名的具体拼写**——`curio_*` / `feat_*` / `asi_*` / `res_*` 的下划线与单复数形式,在不撞既有占用(`reward_*` 等)的前提下自定
|
||||
2. **重命名时的中间态命名**——允许分步改(先改引用再改定义),只要批末归零
|
||||
3. **T2 存档键裁点的甲/乙选择**(不选丙)
|
||||
4. **T7 charge 是否硬补**——若内容不可自决,走"只登记不硬补"(本任务书已授权此判断)
|
||||
5. **provisional 取值的第一版数字**——门票四参数、刷新次数件值,取 working value 即可,**须标 provisional 且归曲线调参批**,不进终值
|
||||
|
||||
## 九、待用户裁点(不在本批自裁范围)
|
||||
|
||||
| # | 待裁 | 阻塞面 | 建议 |
|
||||
|---|---|---|---|
|
||||
| C1 | 玩家可见面三处违规的改法 + 档位呈现三路 | 06 独立条目;A11 断言只检查不修 | 单独开呈现面批 |
|
||||
| C2 | 第四关内容与档二可达性复裁 | T7 实测、charge 补件 | 第四关内容批后 |
|
||||
| C3 | 门票四参数的终值 | T5 provisional 定稿 | 曲线调参批 + MC 采集 |
|
||||
| C4 | 存档键换名的正式迁移 | T2 裁点丙案 | 存档版本迁移批 |
|
||||
|
||||
---
|
||||
|
||||
## 附:本任务书引用的设计裁定链(v1.0 → v2.6,供执行者回溯)
|
||||
|
||||
| 版本 | 用户裁定要点 |
|
||||
|---|---|
|
||||
| v1.0 | 立《特性》:一次冒险内角色自身得到的提升;命名统一(此前三个名字:流派件 / 数值件 / 本关强化) |
|
||||
| v1.1 | 分类重构为「属性提升 ASI / 专长 Feat」;刷新次数作用对象是选择界面而非角色,作为例外登记 |
|
||||
| v1.2 | 专长渠道落定=关底 Boss 击败后;**不新增节点类型**(挂 Boss 节点兑付面) |
|
||||
| v2.0 | 顶层改名「奖励」;分类扩为三类;重构为**两根轴**(分类轴 × 渠道轴);边界判据改走**生命周期**(当局清零的是奖励,跨局带走的是魔法道具) |
|
||||
| v2.1 | Boss 渠道只出专长(独占);终局 Boss 不给;金币不进商店写成「计价物不自售」**规则**而非特例 |
|
||||
| v2.2 | 非 Boss 渠道给**门票**形式(拿到即开、不可囤积);渠道约束重构为**三层**(分类白名单 / 可计算谓词 / 显式例外清单);立**默认原则**——除已登记规则外分类内成员都要在池子里 |
|
||||
| v2.3 | 门票四条口径细化(含**计步保底**:连续 5 次展示未出第 6 次必出,刷新重展计入);修正默认原则表述——**只管分类内部**,"渠道出哪些分类"是渠道轴自己的定位决定 |
|
||||
| v2.4 | 顶层定名**「奇物」Wondrous Item**(DND 魔法物品九分类的兜底杂类);落选 Treasure(偏财物)/ Relic(用户否决)/ 全部自造词;**代码词族定为 `curio_*`**(`reward_*` 已被占用) |
|
||||
| v2.5 | 第三类定名**「资源」**(偏泛,故在 1.3 写死判据句);**回复留在资源**不拆第四类 |
|
||||
| v2.6 | **修正核心循环图**——奇物不是打一场战斗给一份;关底 Boss 击败=通过这一关是同一时刻;兑付频率写进文首 / 2.1 / 待办 / registry |
|
||||
@@ -0,0 +1,259 @@
|
||||
# 任务书:秘宝代码词族对齐批(v1.0 定稿,待发令开工)
|
||||
|
||||
> 成文 2026-10-05。**性质**:纯代码标识符改名 + 玩家可见文案清零,**零行为变更、零数值变更、零 schema 契约变更**。
|
||||
> 设计权威 = [秘宝 GDD](../gdd/systems/排雷循环/秘宝.md) v0.9 版本行(2026-10-05 用户拍板「魔法道具」→「秘宝」);[registry `aux_items` 条目](../registry/entities.yaml) 仍是条目键事实源(**本批不改条目键**,见 §4 范围边界)。
|
||||
> 归属迭代:**迭代 15 · 需求③**(迭代 15 现有 ① 调试功能整合批〔已落籍〕+ ② 奇物词族对齐与渠道分离批〔T0-T8 在册〕)。
|
||||
> 满足 loop engineering 八件(见 §9 逐条对照);本任务书 = 计划书八节的前五节落地,§6 任务卡为执行单元。
|
||||
> **用户三项拍板(2026-10-05)**:①编入迭代 15(追加)②**全族彻底改(含数据表)** ③**断点存档键一律保留**。
|
||||
|
||||
> 🔴 **撞批警示(与同迭代 ② 奇物批)**:本批与 `任务书-奇物词族对齐与渠道分离批-2026-10-05.md` **撞同一批文件**(`core/level_runner.gd` · `data/tables/adventure.tres` · `core/adventure_runner.gd` 断点区),且**双方都动断点存档键**(本批禁改、②批内有"存档键正式迁移"待裁点)。**两批不得并行开工**,须串行或用户明示插队——详见 §7 C3。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
### 1.1 一句话目标
|
||||
|
||||
把代码层 `aux_*` / `AuxItem*` 词族(**358 处 / 35 文件**)整体换词为「秘宝」词族,使**代码词根、中文规范名、玩家可见文案三者对齐**,消除「魔法道具」进入玩家视野的残余通道。
|
||||
|
||||
### 1.2 完成定义(出口判定清单——五条全满足才算本批落籍)
|
||||
|
||||
| # | 判定项 | 量化标准 |
|
||||
|---|---|---|
|
||||
| 1 | 词族换尽 | `game/` 下 `aux_*`/`AuxItem*`/`AUX_ITEM*` 出现处**仅剩 §4 白名单**(存档键 + 🔴 冲突面 + 历史留痕注释),其余全数换词 |
|
||||
| 2 | 玩家可见清零 | `grep -rn "魔法道具" game/` **零命中**(现状 3 处:`battle_narrator.gd:117-118`、`bonus_interact_controller.gd:76`) |
|
||||
| 3 | 重闸全绿 | 冒烟 **747/0**(现基线,迭代 15 前实测值)· 十一探针全绿 · MC 逐位对拍**零漂移** · doc 三闸**对基线零新增** · 熵增闸 PASS |
|
||||
| 4 | 人闸完成 | 目检清单过 + 代拍板追认清单过 + §8 白名单外无代拍板 |
|
||||
| 5 | 收口五步 | active.md 快照 / 台账条目 / roadmap 里程碑行 / stage.txt(如变)/ 闸序列留痕 |
|
||||
|
||||
> ⚠️ **基线纪律**:迭代 15 调试整合批已把冒烟推进到 **747 项**。本批开工前必须重测基线取实际值(本任务书不写死数字,T0 复核后回填),**禁止用本文档的历史数字当闸门**。
|
||||
|
||||
## 2. 现状事实(代码级,T0 须自行复核)
|
||||
|
||||
| # | 事实 | 读数 |
|
||||
|---|---|---|
|
||||
| F1 | `aux_*` / `AuxItem*` 词族规模 | **358 处 / 35 文件**(`game/` 下 `.gd` + `.tres`) |
|
||||
| F2 | 重灾文件 | `core/adventure_runner.gd`(79) · `core/level_runner.gd`(27) · `presentation/bonus_interact_controller.gd`(19) · `core/battle_orchestrator.gd`(18) · `smoke/smoke_all.gd`(14) · `presentation/aux_interact_controller.gd`(14) · `core/config_db.gd`(14) · `presentation/main.gd`(13) |
|
||||
| F3 | 玩家可见「魔法道具」文案 | **3 处**:`battle_narrator.gd:117` `battle_narrator.gd:118` `bonus_interact_controller.gd:76` |
|
||||
| F4 | 🔴 **`battle_narrator.gd` 同屏两义共现** | 117-118 行输出"魔法道具" ‖ 同文件 **139 行** `arch_names := {"magic": "魔法", ...}` = 敌方伤害语汇——同一 narrator 内两义并存,是歧义的**唯一真实暴露点** |
|
||||
| F5 | 断点存档键(**禁改**) | `bonus_aux_carry` · `aux_detail` · `aux_cleared` · `aux_cleared_last` · `aux_items`(断点快照数组)· `attunement_charges` —— **28 处引用**(读 28 / 内部变量 26) |
|
||||
| F6 | 🔴 **冲突面:`aux_items` 一名两义** | 既是**断点存档键**(`adventure_runner.gd:976` 写入 / `:951-953` 读取,跨局持久,改名即破档)**又是** registry 条目键与 ConfigDB 持有变量名(`config_db.gd:50` `var aux_items: AuxItemTable`)——**同一字符串,语义不同层** |
|
||||
| F7 | 🔴 **冲突面:`"aux_item"` 是加载期校验域串** | `reward_table.gd:15` `CELL_TYPES` 封闭枚举含 `"aux_item"`(十型之一)· `:16` `AUX_ITEM_TYPE` 常量 · `smoke_all.gd:3932-3933` **断言 `CELL_TYPES.size() == 10` 且 `has("aux_item")`** —— 改此串 = 改 schema 契约 + 改 .tres 数据行 + 改冒烟断言,**三重连锁** |
|
||||
| F8 | Godot 类名/文件名 | `AuxItemTable`(schema) · `aux_items.gd` · `aux_item_table.gd` · `aux_interact_controller.gd` —— 改名须同步 `.uid` + `.tscn` 引用(迭代 14.5 有实证先例:主区跑前须 `--import` 重刷类名缓存) |
|
||||
| F9 | 中文注释层现状 | 大量注释仍写"魔法道具"(如 `aux_items.gd:2` `aux_items_test.gd:2` `bonus_interact_controller.gd:92` `config_db.gd:27`)——**注释属本批清理对象**(与 §1.2 判定 2 同批) |
|
||||
| F10 | 文档侧已完成 | 2026-10-05 消歧更名批(`430419c` + `06e94b7`):26 个设计文档已改「秘宝」,`秘宝.md` 已重命名,registry 30 处已同步,owner 路径已指向新文件。**本批只做代码侧,文档侧除 §3 链接修复外不动** |
|
||||
|
||||
## 3. 改动清单(分五组,逐组独立可提交)
|
||||
|
||||
### 组 A · 玩家可见文案(**P0,最高优先**)
|
||||
|
||||
| 文件:行 | 现状 | 改为 |
|
||||
|---|---|---|
|
||||
| `presentation/battle_narrator.gd:117` | `return "魔法道具\n%s" % aux_line` | `return "秘宝\n%s" % aux_line` |
|
||||
| `presentation/battle_narrator.gd:118` | `return "魔法道具\n随机获得一件"` | `return "秘宝\n随机获得一件"` |
|
||||
| `presentation/bonus_interact_controller.gd:76` | `toast.show_toast("上关剩余 %d 件魔法道具已随关卡结束清空" ...)` | `"上关剩余 %d 件秘宝已随关卡结束清空"` |
|
||||
|
||||
> **组 A 独立成一个提交**——它是本批唯一有玩家可见效果的部分,先行落地上游台账可独立验收。**F4 两义共现随本组一并消解**(117-118 改后同屏不再出现两个"魔法")。
|
||||
|
||||
### 组 B · schema 与数据表文件(类名 + 文件名 + @export)
|
||||
|
||||
| 现状 | 改为 | 注意 |
|
||||
|---|---|---|
|
||||
| `data/schemas/aux_item_table.gd` | `treasure_item_table.gd` | 类名 `AuxItemTable` → `TreasureItemTable`;`@export` 字段名与 `item_id` 主键**不动** |
|
||||
| `data/tables/aux_items.tres` | `treasure_items.tres` | 表内行键(`item_id` 值 / `effect_kinds` / 效果字段)**全不动**;仅文件名与 `ext_resource` 路径改 |
|
||||
| `core/aux_items.gd` | `core/treasure_items.gd` | 类名 `AuxItems` → `TreasureItems`;`inventory_count` / `snapshot_inventory` / `validate_use` 等**方法名不动** |
|
||||
| `core/config_db.gd:50` | `var aux_items: AuxItemTable` | `var treasure_items: TreasureItemTable`(**变量名改**;⚠️ 与 F6 存档键冲突面相关,见 §7 C2) |
|
||||
| `core/config_db.gd:27` | `"aux_items": "aux_items.tres"` | `"treasure_items": "treasure_items.tres"`(注册表键) |
|
||||
| `core/config_db.gd` 访问器 | `aux_item_row()` / `aux_items_transitional_rows()` 等 | 统一换词;**调用方全量跟改**(`battle_orchestrator` / `level_runner` / `meta_progression` / 三个 presentation / `attunement`) |
|
||||
|
||||
> **`.uid` / `.tscn` 同步强制**:改名后须 `godot --headless --path game --import` 重刷类名缓存(迭代 14.5 实证:主区跑前不刷会命中旧类名缓存),并在 T0 记录导入前后 `.uid` 清单差异。
|
||||
|
||||
### 组 C · 文档链接修复(**仅链接,不改称谓**)
|
||||
|
||||
历史文档正文按换名先例原样保留旧名,但**指向旧文件名的活链接必须修**(重命名已使其失效):
|
||||
|
||||
| 文件:行 | 链接 | 修法 |
|
||||
|---|---|---|
|
||||
| `research/proposal-magic-item-attunement-2026-09-22.md:6` | 已于 `430419c` 修好 | ✅ 免 |
|
||||
| `research/调研-全局作用域变异设计空间-2026-10-04.md:322` | 已于 `430419c` 修好 | ✅ 免 |
|
||||
| `design/dev/architecture/architecture.md:113` | `../../design/gdd/...` 断链 | **既有欠债**(多一层 `design/`),本批顺带修(`../../gdd/...`) |
|
||||
| `design/dev/architecture/architecture.md:196` | 同上 | 同上 |
|
||||
|
||||
> 该断链**改动前即存在**(已用 `git show HEAD:` 复现验证),本批顺带清偿,不单独计工时。
|
||||
|
||||
### 组 D · 中文注释层(**与组 A 同批**)
|
||||
|
||||
`game/` 下所有注释中的「魔法道具」→「秘宝」。**注意区分不得改的两类**:
|
||||
|
||||
| 词 | 处置 |
|
||||
|---|---|
|
||||
| `魔法矢` / `魔法反噬` / `魔法族` / `魔法护甲` / `arch_names["magic"]` | 🔴 **敌方伤害/护甲语汇,一律不动** |
|
||||
| 格面类型微光色带描述(紫/穿刺蓝/…) | 不动(属 `magic` 格面家族) |
|
||||
| 「魔法道具」 | ✅ 改「秘宝」 |
|
||||
| 「道具工坊」 | 不动(营地柜台名,玩家可见面现名,本批不改) |
|
||||
|
||||
### 组 E · 测试文件名与内部变量(**最后做**)
|
||||
|
||||
| 类别 | 文件/标识符 | 改法 |
|
||||
|---|---|---|
|
||||
| 测试文件 | `tests/unit/core/aux_items_test.gd` · `tests/unit/data_config/aux_target_violation_test.gd` · `tests/unit/data_config/reward_dangling_aux_test.gd` | 文件名 + 内部 `AuxItemsScript` preload 路径 + 套件名(`tests/run_all.gd:35` 登记行同步) |
|
||||
| 内部变量 | `_last_aux_cleared` · `_bonus_aux_carry` · `_last_draw_aux` · `aux_inventory` · `aux_items`(局部) | ✅ 换词(**非存档键的**局部变量;存档键见 §4) |
|
||||
| 🔴 冒烟断言 | `smoke_all.gd:3932-3933` `CELL_TYPES.size() == 10 and has("aux_item")` | **见 §7 C1 裁决**——本批不动断言值即需同步改 .tres 与 enum,两条路由 C1 定 |
|
||||
|
||||
## 4. 范围边界(🔴 不可越界)
|
||||
|
||||
### 本批**不做**(硬边界,违反即 L3 停机)
|
||||
|
||||
| 禁项 | 理由 |
|
||||
|---|---|
|
||||
| **断点存档键一律保留** | 用户 2026-10-05 明令。`bonus_aux_carry` / `aux_detail` / `aux_cleared` / `aux_cleared_last` / `aux_items`(断点数组)/ `attunement_charges` **一字不改**——破档即玩家进度丢失 |
|
||||
| **registry 条目键 `aux_items` 不改** | 属数据契约键(`design/registry/entities.yaml`),与 06 更名批的"条目键沿用"口径一致 |
|
||||
| **数值零触碰** | 本批纯改名。`magnitude` / `charge_n` / `w` / `t` / 权重档位**一律不动** |
|
||||
| **行为零变更** | 不得借改名之机重构逻辑、调参数、改流程 |
|
||||
| **`magic` 格面族与 `ward` 护甲** | 敌方语汇,与本批无关(组 D 已锁) |
|
||||
| **Godot 类名/文件名改动须同步 `.uid`+`.tscn`** | 漏改 = 类名缓存错乱(迭代 14.5 实证坑) |
|
||||
| **不改 `game/README.md`** | 文档侧已由 `430419c` 收口,本批零文档债 |
|
||||
|
||||
### 降级面(可接受的**部分完成**形态)
|
||||
|
||||
若 T1 之后发现全族换词的连锁面超出预期,**允许降级**,但必须按序:
|
||||
|
||||
| 级 | 降级形态 | 代价 |
|
||||
|---|---|---|
|
||||
| G1 | 组 A + D 完成,组 B/C/E 留 backlog | 玩家可见歧义已消,代码词根仍不一致——**可接受终态** |
|
||||
| G2 | A+B+C+D 完成,组 E 留 backlog | 测试文件名/局部变量暂旧——**可接受终态**(测试仍跑得通) |
|
||||
| G3 | 仅组 A 完成 | 玩家歧义消但代码债留存——**下限,不可再降** |
|
||||
|
||||
> **降级总则**:一轮一降级;连续两卡降级 = L2 记录;🔴 契约项不可降级(存档键 / 数值 / schema 契约)。
|
||||
|
||||
## 5. 设计契约(🔴 触碰 = L3 停机)
|
||||
|
||||
| # | 契约 | 验证方式 |
|
||||
|---|---|---|
|
||||
| 🔴 R1 | **存档兼容零破坏** | 断点续玩回归:存 → 退 → 读 → 持有集/充能余量/候选详情逐项一致;`attunement_charges` 充能账本不丢 |
|
||||
| 🔴 R2 | **数值零漂移** | MC 逐位对拍(`adventure_monte_carlo.gd` 锚种子)输出**逐位相同**;冒烟数值断言全绿 |
|
||||
| 🔴 R3 | **schema 契约面零变更** | 加载期校验行为一致:格面十型封闭校验、悬空引用校验、跨表校验(`config_db_cross_validator.gd`)错误消息语义不变(**文案可变、行为不可变**) |
|
||||
| 🔴 R4 | **零 schema 字段更名** | `item_id` 主键 / `effect_kinds` 值域 / `form` 值域 / `slot_cost` 全部原样 |
|
||||
| 🔴 R5 | **零 await 保持** | 核心层(`core/`)不因改名引入 await/异步——破坏可回放性(MC 逐位对拍的前提) |
|
||||
|
||||
> R1–R5 任一破 = **L3 停机写报告**,不自行修复后继续。
|
||||
|
||||
## 6. 任务卡(逐卡一个 loop 轮次)
|
||||
|
||||
| 卡 | 内容 | 估时 | 轻闸 | 完成判据 |
|
||||
|---|---|---|---|---|
|
||||
| **T0** | 开工:worktree + 基线复读(冒烟实际值/十一探针/MC 基准/三闸)+ `git status` 归属核对 + 记录 `.uid` 清单 + **回填 §1.2 基线数字** | 0.5d | 全量冒烟基线 | 基线数字回填进本文档 §1.2 且全绿 |
|
||||
| **T1** | **组 A + D**(玩家可见文案 + 中文注释层) | 0.5d | 冒烟 + `grep "魔法道具" game/` 零命中 | 组 D 分色表零误改(`魔法矢`/`魔法护甲` 未被误改) |
|
||||
| **T2** | **组 C**(链接修复,含 architecture.md 既有断债清偿) | 0.25d | doc 三闸 | `doc_link` 对基线**零新增** |
|
||||
| **T3** | **组 B-1**(schema 文件名 + 类名 + `.uid` 同步 + `--import` 重刷) | 0.75d | 冒烟 + `--import` 后类名解析 | `TreasureItemTable` 加载零报错 |
|
||||
| **T4** | **组 B-2**(ConfigDB 持有变量 + 访问器 + 全部调用方跟改) | 0.75d | 冒烟 + MC 对拍 | 冒烟数值断言全绿(访问器链路完整) |
|
||||
| **T5** | **组 E-1**(测试文件名 + preload + run_all 登记) | 0.5d | 冒烟(十五套件全跑) | `run_all` 无 fixture 缺失 |
|
||||
| **T6** | **组 E-2**(内部变量换词) | 0.5d | 冒烟 + MC 对拍 | MC 逐位零漂移 |
|
||||
| **T7** | **重闸**:全量轻闸 + doc 三闸 + 熵增闸 + MC 逐位对拍 | 0.5d | 重闸全绿 | §1.2 判定 3 五项全绿 |
|
||||
| **T8** | **人闸**:目检清单 + 代拍板追认 + §7 冲突面裁决回报 | 0.5d | 目检过 | §1.2 判定 4 |
|
||||
| **T9** | **收口五步** | 0.25d | — | §1.2 判定 5 |
|
||||
|
||||
> 估时合计 ≈ **5.0 日**,**超 roadmap 软盒 3 日上限**。知情预挂:T7 后按 L3 呈报切点,不擅切(沿迭代 9 先例:估 4.5–6 日 vs 软盒 3 日,切点=段末闸后呈报)。或执行中触发 G1/G2 降级可压至 3 日内。
|
||||
|
||||
## 7. 待裁决冲突面(🔴 **T0 必须回报用户,不得自行决断**)
|
||||
|
||||
### C1 · `"aux_item"` 格面域串改不改?
|
||||
|
||||
**事实冲突**:用户拍板"全族彻底改(含数据表)",但该串是**加载期校验的域名字符串**,改动 = 三重连锁:改 `reward_table.gd:15` enum → 改 `reward.tres` 数据行 `cell_type` → 改 `smoke_all.gd:3932` 断言(`size()==10 and has("aux_item")`)。
|
||||
|
||||
| 方案 | 做法 | 风险 |
|
||||
|---|---|---|
|
||||
| **甲** | 全改(enum + .tres + 断言) | 🔴 **动 schema 契约 + 数据文件**;`reward.tres` 存量数据行须逐行改;`doc_term` 闸可能判新增术语债 |
|
||||
| **乙** | 保留 `"aux_item"` 域串为**已知欠债**,加注释说明它 = 秘宝 | 零风险;"全族彻底改"打折(但可解释为"域串非用户可见语义") |
|
||||
|
||||
> **我方倾向:乙**——该串是数据契约键而非玩家可见语汇,与 registry 条目键同性质(同"沿用不改"口径);且 `reward.tres` 是 MC 对拍的输入,动它会污染 R2 判定。**须用户拍板**。
|
||||
|
||||
### C2 · `aux_items` 一名两义拆不拆?
|
||||
|
||||
**事实**(F6):`config_db.gd:50` 的持有变量 `var aux_items: AuxItemTable`(可改)与断点存档键 `"aux_items"`(禁改)**字符串相同**。`adventure_runner.gd:951-976` 的断点数组读写用的正是这个键。
|
||||
|
||||
| 方案 | 做法 | 风险 |
|
||||
|---|---|---|
|
||||
| **甲** | 变量改 `treasure_items`、存档键留 `aux_items`(靠字面不同区分) | 🟡 **易误改**:同文件内 `bp.get("aux_items")` 与 `treasure_items` 混排,肉眼难辨 |
|
||||
| **乙** | 变量保持 `aux_items` 不改、只改类名与文件名 | 与"全族彻底改"打折,但零误改风险 |
|
||||
|
||||
> **我方倾向:甲 + 强制注释标记**——变量改词,存档键在代码旁加显式注释 `// 🔴 存档键,历史名,禁改(2026-10-05 用户拍板)`。**须用户拍板**。
|
||||
|
||||
### C3 · 与同迭代 ② 奇物批的串行次序(🔴 **开工前必须定**)
|
||||
|
||||
**事实冲突**:两批同属迭代 15、**撞同一批文件**、**双方都动断点存档键**。
|
||||
|
||||
| 撞点 | 本批(③秘宝) | ② 奇物批 | 冲突性质 |
|
||||
|---|---|---|---|
|
||||
| `core/level_runner.gd` | 改 `restore_aux_items` / `grant_aux_item` / `aux_inventory` 等 | 动 `feature_*` / `relic_*` / `bonus_*` 词族 | 🔴 **同文件不同词族**,机械替换易误伤 |
|
||||
| `data/tables/adventure.tres` | 只改注释(`aux_item` 池种退役注记) | 改数据行(`feature_*` → `curio_*` 键) | 🔴 同文件,数据 vs 注释混层 |
|
||||
| `core/adventure_runner.gd` 断点区 | **禁改**(`bonus_aux_carry` / `aux_items` 键) | 有"存档键正式迁移"待裁点 | 🔴 **若 ② 先迁移键名,本批的禁改清单失效** |
|
||||
| 冒烟基线 | 待 T0 取实际值 | 同样待取 | 🟡 两批先后跑,基线数字不同 |
|
||||
|
||||
| 方案 | 做法 | 风险 |
|
||||
|---|---|---|
|
||||
| **甲** | ② 先走完(其 T3 出口 = 切分点),③ 开工时**重新取基线**并复核本批事实表 F1–F10 | 🟢 串行无冲突;代价 = ③ 起点后移 |
|
||||
| **乙** | ③ 先走,② 延后 | 🟡 ③ 改动面小(5 组),先跑代价低;但 ② 的"存档键迁移"待裁点会因 ③ 的"禁改"约束而需重议 |
|
||||
| **丙** | 两批并行 | 🔴 **禁止**——同文件同区域机械替换,必生不可定位的冲突 |
|
||||
|
||||
> **我方倾向:甲(② 先走)**——② 的 T8 涉及"存档键正式迁移"这一未裁事项,若 ③ 先动完代码再由 ② 迁移键,等于让 ③ 的禁改清单被单方面作废。**须用户拍板并定次序**。
|
||||
|
||||
|
||||
## 8. 代拍板白名单
|
||||
|
||||
**白名单内**(执行会话可直接决断,commit 记录):
|
||||
- 内部变量/方法/文件/类的具体英文词形选择(`treasure_items` / `secret_treasure` 等,须语义贴"秘宝")
|
||||
- 新旧标识符在同一文件不同位置的**注释措辞**
|
||||
- 改名顺序与提交粒度(§3 五组可再细分)
|
||||
|
||||
**白名单外**(须回报用户):
|
||||
- §7 C1 / C2 两条冲突面的任何决断
|
||||
- 任何 🔴 R1–R5 契约的取舍
|
||||
- 降级级别选择(G1/G2/G3)
|
||||
- `.tres` 数据行 `cell_type` 值改与不改(C1 派生)
|
||||
- 冒烟基线数字与本文档不符时的取用
|
||||
|
||||
## 9. loop engineering 八件对照(合规自证)
|
||||
|
||||
| # | 八件要求 | 本文对应 | 状态 |
|
||||
|---|---|---|---|
|
||||
| 1 | 计划书八节(目标完成定义/现状事实/设计契约/范围边界/任务卡/验证闸/异常分级/代拍板白名单) | §1 目标与完成定义 · §2 现状事实 · §5 设计契约 · §4 范围边界 · §6 任务卡 · §6/§7 验证闸 · §10 异常分级 · §8 白名单 | ✅ 八节齐 |
|
||||
| 2 | T0 开工(worktree + 基线复读 + 归属核对) | §6 T0 卡 | ✅ |
|
||||
| 3 | 循环骨架(一轮一卡:读卡→对事实源→实装→轻闸→提交→台账) | §6 各卡 · 纪律见下 | ✅ |
|
||||
| 4 | 轻闸(冒烟 + 十一探针;触 presentation 加 click/layout) | §6 各卡轻闸列 | ✅ 组 A/B-2 触 presentation → 须加 `ui_click_probe` + `ui_layout_probe` |
|
||||
| 5 | 重闸(批末:全量轻闸 + doc 三闸 + 熵增闸 + MC 逐位对拍) | §6 T7 · §1.2 判定 3 | ✅ 本批涉 core → **MC 逐位对拍必跑** |
|
||||
| 6 | 人闸(目检 + 代拍板追认 + 异步终审) | §6 T8 | ✅ 本批无样张类 → 异步终审触点不适用(可省) |
|
||||
| 7 | 异常分级(L1 自救 / L2 记录 / L3 停机) | §10 | ✅ |
|
||||
| 8 | 收口五步 | §6 T9 | ✅ |
|
||||
|
||||
**执行纪律补充**(承 roadmap §执行纪律):
|
||||
- **一批一 loop**:本批单独成 loop,不与他批并行;单 worktree 多点提交一次合并
|
||||
- **worktree 铁律**:开工必建 worktree(`../g-plan2-iter15-code-align`),轮内禁开第二个
|
||||
- **测试执行两入口铁规**:改标识符后**无法靠文档层自证**,冒烟必须在 T1 之后每轮实跑
|
||||
- **归零式改名慎独**:358 处机械替换,**必须分组 + 分轮**,禁止一次性全仓 sed(否则断链与误改不可定位)
|
||||
- **提交粒度**:A/D 一组、B-1、B-2、E-1、E-2 各一提交,便于逐段回滚定位
|
||||
|
||||
## 10. 异常分级
|
||||
|
||||
| 级 | 触发 | 处置 |
|
||||
|---|---|---|
|
||||
| **L1** | 单点改名后冒烟红 | 一次重试(自查字面漏改/`.uid` 未刷);仍红 → L2 |
|
||||
| **L2** | 同类错误连续 3 轮 / 连锁面超预期 | 记录进本任务书 §4 降级面 + 台账,降级继续(不阻断全批) |
|
||||
| **L3** | 任一 🔴 R1–R5 破 / C1·C2 久决不下 / 需动数值或 schema 契约 | **停机写报告**(列事实+影响面+方案对比),等用户发令;**不自行决断** |
|
||||
|
||||
## 11. 现状留痕(供执行会话读序)
|
||||
|
||||
```
|
||||
1. 本文 §7 冲突面 C1/C2/C3 → 若用户未拍板,T0 后即停机呈报
|
||||
2. design/gdd/systems/排雷循环/秘宝.md v0.9(设计权威·换名理由与代码欠债登记)
|
||||
3. design/registry/entities.yaml(条目键 aux_items = 数据契约键,禁改依据)
|
||||
4. design/gdd/06-待办清单.md(「命名统一后续」条目 = 本批的 06 登记源)
|
||||
5. design/research/任务书-奇物词族对齐与渠道分离批-2026-10-05.md(同迭代 ②·撞批对象,见 §7 C3)
|
||||
6. .zcode/inflight-active-backup-*.md 台账 352(迭代 15 需求① 落籍态)
|
||||
```
|
||||
|
||||
> **注 1**:`entities.yaml` 无法被标准 YAML 解析器读取(项目把 `**粗体**` 当键名用,改动前即如此)——校验结构须用正则提取键集合比对,**勿用 `yaml.safe_load`**。
|
||||
>
|
||||
> **注 2**:局内「奇物」概念文档 = [奇物.md](../gdd/systems/冒险循环/奇物.md) v2.7(7 轮裁定定稿,2026-10-05 落文),任务书 = `任务书-奇物词族对齐与渠道分离批-2026-10-05.md`。**本批与它分属两套词族**(`aux_*` = 局外秘宝 / `feature_*`·`relic_*`·`bonus_*` = 局内奇物),但撞同一批文件——见 §7 C3。
|
||||
|
||||
@@ -80,8 +80,8 @@ var _save_manager = null # 断点承载注入(迭代 8 卡①
|
||||
var _resume_bp := {} # 续玩快照暂存(resume_adventure → _start_current_level 单跳传递)
|
||||
# ---- 三选一停点态(迭代 10 奖励重构批)----
|
||||
var _bonus_taken := {} # 件获取次数计数(kind 维度派生账本——断点附随件与摘要读数承载;池库存正主=_bonus_deck)
|
||||
var _bonus_deck: Array = [] # 令牌池(TP0 v2.2——持久多重集,元素 {"kind","tier"};洗牌抽候选/选中踢池未选回池/池耗即枯竭;商店货架同库共账;迭代 12 T1 起机制件带=relic 令牌随表追加)
|
||||
var _relics: Array[String] = [] # 流派件持有集(迭代 12 T1——局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树)
|
||||
var _bonus_deck: Array = [] # 令牌池(TP0 v2.2——持久多重集,元素 {"kind","tier"};洗牌抽候选/选中踢池未选回池/池耗即枯竭;商店货架同库共账;迭代 12 T1 起规则改写型特性带=relic 令牌随表追加)
|
||||
var _relics: Array[String] = [] # 特性持有集(迭代 12 T1——局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树)
|
||||
var _tree_rules: Array = [] # 树 rule 键集(迭代 12 T10——Fork 激活侧 effects 透传;下传 enc.tree_rules 消费面)
|
||||
var _bonus_pending := {} # 停点态:{"candidates": Array, "payload": Dictionary, "chosen"/"incoming": 替换在途}——空 = 无停点
|
||||
var _bonus_result := {} # 已兑付待推进态(bonus_resolved 载荷副本——中断续玩不重兑付)
|
||||
@@ -128,8 +128,8 @@ func start_adventure(seed_val: int, params: Dictionary = {}) -> bool:
|
||||
_attunement = params.get("attunement", []) if params.get("attunement", []) is Array else [] # additive(迭代 11 第①批 T5)
|
||||
_attune_refresh_y = maxi(0, int(params.get("attune_refresh_y", 0))) # additive(迭代 11 第①批 T5b——Y 冒险周期池)
|
||||
_seed_attune_charges() # 迭代 11 第①批 T6——冒险开始充能账本按装备主动件重置(每冒险充能语义)
|
||||
# 流派件开局注入(迭代 12 T7——MC 成型画像载体:params.relics_seed 非空=开局持有集〔七流派
|
||||
# 各 2 件档一成型——测量面专用;真实局流派件只走局内随机渠道,红线②层级纪律不破〕)
|
||||
# 特性开局注入(迭代 12 T7——MC 成型画像载体:params.relics_seed 非空=开局持有集〔七流派
|
||||
# 各 2 件档一成型——测量面专用;真实局规则改写型特性只走局内随机渠道,红线②层级纪律不破〕)
|
||||
var relic_seed: Array = params.get("relics_seed", []) if params.get("relics_seed", []) is Array else []
|
||||
_tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # 迭代 12 T10——A/B 面 rule 键集
|
||||
if not relic_seed.is_empty():
|
||||
@@ -190,7 +190,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
|
||||
rtok["relic_id"] = String(tok.get("relic_id", ""))
|
||||
restored.append(rtok)
|
||||
_bonus_deck = restored
|
||||
# 流派件持有集还原(迭代 12 T1——缺键 = 旧版断点防御空集)
|
||||
# 特性持有集还原(迭代 12 T1——缺键 = 旧版断点防御空集)
|
||||
_relics = []
|
||||
for r in (bp.get("relics", []) as Array):
|
||||
_relics.append(String(r))
|
||||
@@ -267,14 +267,14 @@ func _reset_bonus_state() -> void:
|
||||
_node_bonus_pending = {}
|
||||
|
||||
|
||||
# 令牌池构建(TP0 v2.2——按表 kind×tier 配额展开为持久多重集;构建序确定 = BONUS_IDS×TIERS 逐层,
|
||||
# 随机性只发生在洗牌消费 reward_pick 封闭流的时刻。迭代 12 T1:机制件带=relic 活行每件 1 张追加
|
||||
# 令牌池构建(TP0 v2.2——按表 kind×tier 配额展开为持久多重集;构建序确定 = FEATURE_KINDS×TIERS 逐层,
|
||||
# 随机性只发生在洗牌消费 reward_pick 封闭流的时刻。迭代 12 T1:规则改写型特性带=relic 活行每件 1 张追加
|
||||
# (rarity common/rare→稀有令牌档、rarest→罕见令牌档——relic 永不入普通档;空表=零追加零扰动))
|
||||
func _build_bonus_deck() -> Array:
|
||||
var deck: Array = []
|
||||
for kind in db.adventure.BONUS_IDS:
|
||||
for kind in db.adventure.FEATURE_KINDS:
|
||||
for tier in db.adventure.TIERS:
|
||||
for i in int(db.adventure.bonus_token_count(String(kind), String(tier))):
|
||||
for i in int(db.adventure.feature_quota(String(kind), String(tier))):
|
||||
deck.append({"kind": String(kind), "tier": String(tier)})
|
||||
for row in db.relic_rows():
|
||||
var rtier := "rarest" if String(row.get("rarity", "")) == "rarest" else "rare"
|
||||
@@ -282,7 +282,7 @@ func _build_bonus_deck() -> Array:
|
||||
return deck
|
||||
|
||||
|
||||
# 令牌唯一身份(抽签去重/兑付匹配共用——数值件=kind,机制件=relic_id;同档多张不同 relic 可同屏)
|
||||
# 令牌唯一身份(抽签去重/兑付匹配共用——属性加成型特性=kind,规则改写型特性=relic_id;同档多张不同 relic 可同屏)
|
||||
func _token_identity(tok: Dictionary) -> String:
|
||||
if String(tok.get("kind", "")) == "relic":
|
||||
return "relic:" + String(tok.get("relic_id", ""))
|
||||
@@ -337,7 +337,7 @@ func continue_to_next_level() -> bool:
|
||||
|
||||
# ---- 提升三选一(迭代 10 奖励重构批——选择停点零自动推进、重复兑付被拒;兑付恰一件、未选项零生效)----
|
||||
|
||||
# 候选令牌匹配(身份键恒等——数值件 kind+tier、机制件 relic_id;迭代 12 T1 机制件带)
|
||||
# 候选令牌匹配(身份键恒等——属性加成型特性 kind+tier、规则改写型特性 relic_id;迭代 12 T1 规则改写型特性带)
|
||||
func _find_token(candidates: Array, kind: String, tier: String, relic_id: String = "") -> Dictionary:
|
||||
for t in candidates:
|
||||
var tok: Dictionary = t as Dictionary
|
||||
@@ -351,7 +351,7 @@ func _find_token(candidates: Array, kind: String, tier: String, relic_id: String
|
||||
|
||||
# 玩家点选兑付(呈现层/冒烟/自动模拟确认入口):令牌 ∈ 停点候选(身份键精确匹配——relic 件
|
||||
# 另须 relic_id)。属性件写加算区、AP 件写第四轴、GP 件走钱包「奖励入账」入口、恢复件当即回血、
|
||||
# relic 件入流派件持有集(🔴 层级纪律:只走局内随机渠道)、道具件受同调位约束(随池种退役不可达)。
|
||||
# relic 件入特性持有集(🔴 层级纪律:只走局内随机渠道)、道具件受同调位约束(随池种退役不可达)。
|
||||
# 消费=选中令牌踢池(未选回池由「抽签不摘牌、兑付才摘牌」语义承载——TP0 v2.2)。
|
||||
func pick_bonus(kind: String, tier: String = "", relic_id: String = "") -> bool:
|
||||
if state != "running" or _bonus_pending.is_empty():
|
||||
@@ -361,7 +361,7 @@ func pick_bonus(kind: String, tier: String = "", relic_id: String = "") -> bool:
|
||||
if _find_token(candidates, kind, tier, relic_id).is_empty():
|
||||
push_error("[冒险结构] pick_bonus 拒绝——令牌不在候选: %s|%s|%s" % [kind, tier, relic_id])
|
||||
return false
|
||||
var value: int = int(db.adventure.bonus_value(kind, tier))
|
||||
var value: int = int(db.adventure.feature_value(kind, tier))
|
||||
var hp_before := int(ledger.get("hero_hp", 0))
|
||||
if kind == "aux_item":
|
||||
return _pick_aux_item(value) # 道具件分派通关渠道(持有容器 = 跨关携带——与节点渠道分轨;池种退役后不可达)
|
||||
@@ -435,7 +435,7 @@ func _consume_deck_token(kind: String, tier: String, relic_id: String = "") -> b
|
||||
return false
|
||||
|
||||
|
||||
# 流派件持有集读面(效果接线/求值/摘要唯一取数口——副本防外部改写)
|
||||
# 特性持有集读面(效果接线/求值/摘要唯一取数口——副本防外部改写)
|
||||
func relics_held() -> Array:
|
||||
return _relics.duplicate()
|
||||
|
||||
@@ -457,10 +457,10 @@ func pool_stock(kind: String) -> int:
|
||||
# 写加算区+账本+摘牌(与奖励三选一真单点——买一件=奖励面少一件的库存语义由同库成立)。
|
||||
# 未知 kind 拒绝(货架词表封闭的前置防御)。
|
||||
func _consume_pool_purchase(kind: String, tier: String) -> bool:
|
||||
if not db.adventure.BONUS_IDS.has(kind):
|
||||
if not db.adventure.FEATURE_KINDS.has(kind):
|
||||
push_error("[冒险结构] 商店购买消费拒绝——件不在池词表: %s" % kind)
|
||||
return false
|
||||
return _apply_bonus_pick(kind, tier, int(db.adventure.bonus_value(kind, tier)))
|
||||
return _apply_bonus_pick(kind, tier, int(db.adventure.feature_value(kind, tier)))
|
||||
|
||||
|
||||
# 终局池快照(_settle 清账前调用——_reset_bonus_state 会重置 _bonus_taken,摘要 additive 键
|
||||
@@ -552,7 +552,7 @@ func apply_node_bonus(kind: String, tier: String = "", relic_id: String = "") ->
|
||||
if _find_token(candidates, kind, tier, relic_id).is_empty():
|
||||
push_error("[冒险结构] apply_node_bonus 拒绝——令牌不在候选: %s|%s|%s" % [kind, tier, relic_id])
|
||||
return false
|
||||
var value: int = int(db.adventure.bonus_value(kind, tier))
|
||||
var value: int = int(db.adventure.feature_value(kind, tier))
|
||||
if kind == "aux_item":
|
||||
return _apply_node_aux(value) # 道具件分派节点渠道(持有容器 = 关卡域库存——与通关渠道分轨;池种退役后不可达)
|
||||
if not _apply_bonus_pick(kind, tier, value, relic_id):
|
||||
@@ -573,7 +573,7 @@ func _apply_node_aux(count: int) -> bool:
|
||||
var records: Array = []
|
||||
if _runner != null and _runner.aux_inventory != null:
|
||||
records = _runner.aux_inventory.holding_records()
|
||||
# 迭代 11 第①批 T7——守卫随过渡键退役拆除(BONUS_IDS 已除名 aux_item,本分支不可达;
|
||||
# 迭代 11 第①批 T7——守卫随过渡键退役拆除(FEATURE_KINDS 已除名 aux_item,本分支不可达;
|
||||
# 替换子交互路由随容量闸一并退役——能力件容量闸正主 = 营地装配面满位禁选)
|
||||
if _runner != null:
|
||||
for iid in picked:
|
||||
@@ -739,7 +739,7 @@ func _draw_bonus_candidates() -> Array:
|
||||
if ident.begins_with("relic:"):
|
||||
cand["relic_id"] = String((tok as Dictionary).get("relic_id", ""))
|
||||
out.append(cand)
|
||||
if out.size() >= int(db.adventure.bonus_candidate_count):
|
||||
if out.size() >= int(db.adventure.feature_candidate_count):
|
||||
break
|
||||
return out
|
||||
|
||||
@@ -828,7 +828,7 @@ func _start_current_level() -> bool:
|
||||
if ok:
|
||||
_runner.set_attunement(_attunement) # 迭代 11 第①批 T5——同调装配下传(enc 携带进战斗结算)
|
||||
_runner.set_attune_charges(attune_charges) # 迭代 11 第①批 T6——充能账本下传(能力件骑库存面注入)
|
||||
_runner.set_relics(_relics) # 迭代 12 T1——流派件持有集下传(begin_battle enc.relics 求值面)
|
||||
_runner.set_relics(_relics) # 迭代 12 T1——特性持有集下传(begin_battle enc.relics 求值面)
|
||||
_runner.set_tree_rules(_tree_rules) # 迭代 12 T10——树 rule 键集下传(A/B 面消费)
|
||||
if _shop_mode == "pool":
|
||||
# 商店共享池注入(迭代 11 第②批 T3——库存账本引用+消费 handler 双下传;legacy 模式零注入零扰动)
|
||||
@@ -908,7 +908,7 @@ func _settle(result: String) -> void:
|
||||
"aux_cleared_last": _last_aux_cleared, # additive 扩签(迭代 7 T4——末关清空反馈;非末关走 bonus 载荷)
|
||||
"keystone_drops": _keystone_drops.duplicate(true), # additive 扩签(迭代 10——逐杀掉落明细;settle 入账明细/复盘归因数据源)
|
||||
"pool_stock": _pool_stock_snapshot(), # additive 扩签(迭代 11 第②批 T5——终局池读数:清账前快照,商店买走 vs 奖励领走 vs 枯竭的终局面)
|
||||
"relics": _relics.duplicate(), # additive 扩签(迭代 12 T1——流派件终局持有集:清账前快照,成型判读取数面)
|
||||
"relics": _relics.duplicate(), # additive 扩签(迭代 12 T1——特性终局持有集:清账前快照,成型判读取数面)
|
||||
}
|
||||
# 败退明细(数值验证工具取数面 2026-09-22——tools/balance_verifier.py 止步节点分布数据源;
|
||||
# 仅失败局附加,键缺省 = 未败退,既有五件事消费方零感知)
|
||||
@@ -941,7 +941,7 @@ func _forward_choices_presented(candidates: Array) -> void:
|
||||
|
||||
|
||||
# ---- 断点快照(迭代 8 卡①——七字段拍板面+恢复必需附随件)----
|
||||
# 七字段(拍板面):关卡序号/节点位/生命/本关加成区/GP 钱包/商店已购档/已抽模板;
|
||||
# 七字段(拍板面):关卡序号/节点位/生命/属性加成区/GP 钱包/商店已购档/已抽模板;
|
||||
# 附随件(续玩正确性必需,随批注记):主种子+取数计数器(rng 快照契约回填——续接原时间线)、
|
||||
# 钥石累计(大奖励中途值——终局摘要五件事不失真)、已到节点序(呈现层图条重建)、道具库存
|
||||
# (奖励节点已选件——防静默丢失)。注入缺省 null = 整面静默(模拟/冒烟零扰动)。
|
||||
@@ -976,7 +976,7 @@ func _snapshot_breakpoint() -> void:
|
||||
"aux_items": aux_items,
|
||||
"bonus_taken": _bonus_taken.duplicate(true), # 三选一件获取次数(kind 维度派生账本——断点附随件与读数承载)
|
||||
"bonus_deck": _bonus_deck.duplicate(true), # 令牌池余库(TP0 v2.2——池消耗即上限,续玩余库逐枚还原)
|
||||
"relics": _relics.duplicate(), # 流派件持有集(迭代 12 T1——局内随机渠道获得态续玩防丢失)
|
||||
"relics": _relics.duplicate(), # 特性持有集(迭代 12 T1——局内随机渠道获得态续玩防丢失)
|
||||
"bonus_pending": _bonus_pending.duplicate(true), # 三选一停点态(空 = 无停点——选择停点可中断契约)
|
||||
"bonus_result": _bonus_result.duplicate(true), # 已兑付待推进态(空 = 无——中断续玩不重兑付)
|
||||
"bonus_aux_carry": _bonus_aux_carry.duplicate(true), # 道具件跨关携带(注入前中断防静默丢失)
|
||||
|
||||
@@ -72,7 +72,7 @@ var attunement: Array = [] # 装备中同调件 item_id 集
|
||||
var _attune_charges_ref: Dictionary = {} # 充能账本共享引用(迭代 11 第①批 T6——use_aux 消费直改)
|
||||
var _attune_bank := 0 # 掘进蓄能积点(battle 域——每 charge_n 安全格 +1 点)
|
||||
var _attune_safe_seen := 0 # 掘进蓄能 battle 域安全开格计数
|
||||
# 流派件运行态(迭代 12 T2——relic 持有集经 enc.relics 注入;求值旗注 damage_controller.relic_flags;
|
||||
# 特性运行态(迭代 12 T2——relic 持有集经 enc.relics 注入;求值旗注 damage_controller.relic_flags;
|
||||
# 魔矢每战首次计数 battle 域。空集=零扰动)
|
||||
var _relic_first_dig_used := false
|
||||
var _relic_combo := 0 # 矿脉直觉连击计数(battle 域——safe +1/mine 清零)
|
||||
@@ -94,7 +94,7 @@ func _attune_mag(item_id: String) -> int:
|
||||
return int(_attune_row(item_id).get("magnitude", 0))
|
||||
|
||||
|
||||
# 流派件求值(迭代 12 T2——持有集 × relic_table → damage_controller.relic_flags 注入面):
|
||||
# 特性求值(迭代 12 T2——持有集 × relic_table → damage_controller.relic_flags 注入面):
|
||||
# rider_flat = Σ rider 件 value(奥术余烬 +1 / 魔能共鸣 +2);magic 档一(≥2 件)rider +1、
|
||||
# 档二(≥4 件)rider 可暴击;clamp 两件直调键;first_dig_spell 旗(魔能共鸣第二效果——魔矢值
|
||||
# = 件 effects.value)。空集/空表 = 零旗零扰动。
|
||||
@@ -247,7 +247,7 @@ func begin_battle(enc: Dictionary) -> bool:
|
||||
_attune_safe_seen = 0
|
||||
_damage.attune_venom = _attune_mag("venom_edge") if _attune_has("venom_edge") else 0
|
||||
_reward_economy.luck_bias = _attune_mag("luck_coin") if _attune_has("luck_coin") else 0
|
||||
# 流派件运行态注入(迭代 12 T2 魔法流——enc.relics 携带持有集;RelicsEngine 求值后注伤害控制器
|
||||
# 特性运行态注入(迭代 12 T2 魔法流——enc.relics 携带持有集;RelicsEngine 求值后注伤害控制器
|
||||
# relic_flags;空集/空表=零扰动。魔矢每战首次开格计数同步归零)
|
||||
_relic_flags_for((enc.get("relics", []) as Array))
|
||||
_relic_first_dig_used = false
|
||||
@@ -680,7 +680,7 @@ func set_aux_unlocked(ids: Dictionary) -> void:
|
||||
|
||||
func _grant_routed(snap: Dictionary, polarity: String, source_class: String, cell: Vector2i, ri: int, highlight: String = "", label_suffix: String = "") -> bool:
|
||||
# 迭代 11 第①批 T7——aux 授予分支随掉落/停点渠道退役拆除(reward 词表第十型 aux_item 保留但零投放:
|
||||
# 无 aux 行入池、BONUS_IDS 词表已除名);剩余类型走极性字典路由。
|
||||
# 无 aux 行入池、FEATURE_KINDS 词表已除名);剩余类型走极性字典路由。
|
||||
var row: Dictionary = _reward_economy.polarity_row(String(snap.get("cell_type", "")), polarity)
|
||||
if row.is_empty():
|
||||
_fatal("极性字典缺行: %s %s" % [String(snap.get("cell_type", "")), polarity])
|
||||
|
||||
@@ -27,7 +27,7 @@ const TABLE_MANIFEST := {
|
||||
"aux_items": "aux_items.tres", # 迭代 7 T1 魔法道具内容批(AuxItemTable 六行——定义表 Rule 4 豁免;罗盘 retired/失义件 deferred 标记见 schema 头注)
|
||||
"adventure": "adventure.tres", # 冒险结构实现批 2026-09-21(AdventureTable 建表——大奖励与钥石行值单点)
|
||||
"attunement_growth": "attunement_growth.tres", # 迭代 11 第①批 同调实施批 T1(AttunementGrowthTable 单行全局——同调位里程碑谓词表;单行先例 Rule 4 豁免)
|
||||
"relics": "relics.tres", # 迭代 12 T1 双层 BD 机制件基建(RelicTable 定义表 Rule 4 豁免——AuxItemTable 先例;空表合法态=主时间线零扰动)
|
||||
"relics": "relics.tres", # 迭代 12 T1 双层 BD 规则改写型特性基建(RelicTable 定义表 Rule 4 豁免——AuxItemTable 先例;空表合法态=主时间线零扰动)
|
||||
}
|
||||
|
||||
var action_economy: ActionEconomyTable
|
||||
@@ -154,7 +154,7 @@ func relic_row(relic_id: String) -> Dictionary:
|
||||
return relics.row_by_id(relic_id) if relics != null else {}
|
||||
|
||||
|
||||
# 机制件带令牌构建源(池接线——adventure_runner._build_bonus_deck 消费;行 rarity→投放档映射)
|
||||
# 规则改写型特性带令牌构建源(池接线——adventure_runner._build_bonus_deck 消费;行 rarity→投放档映射)
|
||||
func relic_rows() -> Array:
|
||||
return relics.rows if relics != null else []
|
||||
|
||||
|
||||
@@ -99,18 +99,18 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void:
|
||||
for e in validate_skill_pool_links(skt, en, loaded.get("status_effects")):
|
||||
push_diag.call("error", e.category, e.message)
|
||||
# ⑥ 商店货架 × 冒险共享池跨表校验(M-4 迭代 11 第②批 T1——次数上限域):
|
||||
# pool_shelf kind 须命中 adventure.BONUS_IDS 且为有限库存种(cap ∈ [1,99]——gp 无上限种/牌库外种
|
||||
# 入货架 = 库存账本无锚,加载致命;gp 袋负交易切边/机制件三轴切边由 ShopTable 词表封闭另拦)
|
||||
# pool_shelf kind 须命中 adventure.FEATURE_KINDS 且为有限库存种(cap ∈ [1,99]——gp 无上限种/牌库外种
|
||||
# 入货架 = 库存账本无锚,加载致命;gp 袋负交易切边/规则改写型特性三轴切边由 ShopTable 词表封闭另拦)
|
||||
var adv = loaded.get("adventure")
|
||||
var shp = loaded.get("shop")
|
||||
if adv != null and shp != null:
|
||||
for row in shp.pool_shelf:
|
||||
var kind: String = String(row.get("kind_id", ""))
|
||||
if not adv.BONUS_IDS.has(kind):
|
||||
push_diag.call("error", "shelf_dangling_kind", "ShopTable.pool_shelf kind %s 不在 AdventureTable.BONUS_IDS(共享池牌库外种)" % kind)
|
||||
if not adv.FEATURE_KINDS.has(kind):
|
||||
push_diag.call("error", "shelf_dangling_kind", "ShopTable.pool_shelf kind %s 不在 AdventureTable.FEATURE_KINDS(共享池牌库外种)" % kind)
|
||||
continue
|
||||
# TP0 令牌池——货架件须为有限令牌种(配额 >0;种类次数上限退役后库存=剩余令牌数)
|
||||
var quota := int(adv.bonus_token_count(kind, adv.TIER_COMMON)) + int(adv.bonus_token_count(kind, adv.TIER_RARE)) + int(adv.bonus_token_count(kind, adv.TIER_RAREST))
|
||||
var quota := int(adv.feature_quota(kind, adv.TIER_COMMON)) + int(adv.feature_quota(kind, adv.TIER_RARE)) + int(adv.feature_quota(kind, adv.TIER_RAREST))
|
||||
if quota < 1:
|
||||
push_diag.call("error", "shelf_zero_quota", "ShopTable.pool_shelf kind %s 令牌配额为 0(牌库空种入货架 = 库存无锚)" % kind)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ var _outcomes := {} # ticket_id → "redeemed"/"zero"/"voided"(
|
||||
var _seq := 0 # 流水号
|
||||
var _halted := false # 主角倒下终止旗(死亡事件置位——flush 余单作废)
|
||||
var _hero_ac_override := -1 # 主角护甲等级合流入参(begin_battle 显式设定——-1 = 表值兜底,口径同战斗编排器)
|
||||
# 流派件求值旗(迭代 12 T2——begin_battle 编排器经 RelicsEngine 求值后注入;空字典=零扰动。
|
||||
# 特性求值旗(迭代 12 T2——begin_battle 编排器经 RelicsEngine 求值后注入;空字典=零扰动。
|
||||
# rider_flat=英雄侧必中附加值〔奥术余烬族〕/rider_crit=档二 rider 可暴击/first_dig_spell=每战首次
|
||||
# 开安全格追加魔法矢〔消费在编排器授予段〕/clamp_magic_light·clamp_magic_heavy=克制点直调)
|
||||
var relic_flags: Dictionary = {}
|
||||
@@ -418,7 +418,7 @@ func _counter_delta(attack_type: String, armor: String) -> int:
|
||||
return int(row.get(armor, 0))
|
||||
|
||||
|
||||
# 克制点直调(迭代 12 T2 魔法流/T4 穿刺流 clamp_modifier 件——克制矩阵查表值后的流派件调整;
|
||||
# 克制点直调(迭代 12 T2 魔法流/T4 穿刺流 clamp_modifier 件——克制矩阵查表值后的特性调整;
|
||||
# 空旗=0 零扰动):魔网织者=magic vs magic(矩阵罚 −1 → 0/正);湛蓝誓约=magic vs heavy(+1 → +2);
|
||||
# 猎手刺剑=pierce vs light(+1——对轻甲敌穿刺提升,对重甲无增益=正负双修)。hero_attack 与
|
||||
# board_typed 两消费面同享。
|
||||
|
||||
@@ -590,7 +590,7 @@ func set_attunement(ids: Array) -> void:
|
||||
_attunement = ids.duplicate()
|
||||
|
||||
|
||||
# 流派件持有集注入(迭代 12 T1——AdventureRunner._start_current_level 唯一调用方;begin_battle
|
||||
# 特性持有集注入(迭代 12 T1——AdventureRunner._start_current_level 唯一调用方;begin_battle
|
||||
# enc.relics 携带进战斗求值;**共享引用不复制**——关内奖励节点兑付的 relic 须当关后续战斗生效
|
||||
# (attune_charges 共享账本同款);空集=零扰动)
|
||||
var _relics: Array = []
|
||||
@@ -600,7 +600,7 @@ func set_relics(ids: Array) -> void:
|
||||
_relics = ids
|
||||
|
||||
|
||||
# 流派件持有集读面(迭代 12 呈现补齐——HUD C 区流派件段数据源)
|
||||
# 特性持有集读面(迭代 12 呈现补齐——HUD C 区特性段数据源)
|
||||
func relics_held() -> Array:
|
||||
return _relics.duplicate()
|
||||
|
||||
@@ -779,7 +779,7 @@ func _shop_draw_shelf() -> void:
|
||||
_shop_shelf.append(tok)
|
||||
if _shop_shelf.size() >= 3:
|
||||
break
|
||||
# 商店保底(迭代 12 T6——「本关变异交互件必刷」简化口径:货架零流派件时**挤掉最后一张普通卡**
|
||||
# 商店保底(迭代 12 T6——「本关变异交互件必刷」简化口径:货架零特性时**挤掉最后一张普通卡**
|
||||
# 换吞噬流件〔地形交互件广义映射——按关变异精细绑定归数值批,台账披露待追认〕;占位制货架恒
|
||||
# ≤3;池内无 devour 令牌=不保底合法态)
|
||||
var has_relic := false
|
||||
@@ -834,10 +834,10 @@ func shop_shelf() -> Array:
|
||||
var tier := String((tok as Dictionary).get("tier", ""))
|
||||
var row: Dictionary = db.shop_pool_row(kind)
|
||||
var display := String(row.get("display_name", kind))
|
||||
var value := int(db.adventure.bonus_value(kind, tier))
|
||||
var value := int(db.adventure.feature_value(kind, tier))
|
||||
if row.is_empty() and kind == "relic":
|
||||
var rrow: Dictionary = db.relic_row(String(tok.get("relic_id", "")))
|
||||
display = String(rrow.get("display_name", "流派件"))
|
||||
display = String(rrow.get("display_name", "特性"))
|
||||
value = 0
|
||||
out.append({
|
||||
"kind_id": kind,
|
||||
|
||||
@@ -13,9 +13,18 @@
|
||||
class_name AdventureTable
|
||||
extends Resource
|
||||
|
||||
## 概念指路:本表的属性值提升与资源,与 relics.tres 的专长,同属一个对象——
|
||||
## 「奇物」(一次冒险内各渠道给予玩家的增益总称)。定义见 design/gdd/systems/冒险循环/奇物.md。
|
||||
## 它们是它的分类轴上的枚举(专长 / 属性值提升 / 资源),不是三套系统;
|
||||
## 本表承载属性值提升与资源的种类配额与件值。
|
||||
## (2026-10-05 命名统一 + v2.0 改名:旧称「数值件」→ 属性提升;顶层「特性」→「奖励」→「奇物」。
|
||||
## 常量与字段随之前缀 feature_*,**尚未**随顶层改名换到 reward_*——见 06-待办清单。
|
||||
## 分类轴三个枚举:属性值提升〔生命上限 / AC / 攻击〕;资源〔行动点上限 /
|
||||
## 刷新次数 / 金币 / 回复,命名待定〕——本表两类混编;刷新次数与专长获取两项尚未入表。
|
||||
## 类内异质性:金币与回复是即时兑付,不进持有集、不持续生效。)
|
||||
## 三选一提升池 kind 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。
|
||||
## aux_item 池种退役(迭代 11 第①批 T7——同调批出池);heal 恢复件新入池(v2.2 令牌池追认 b)。
|
||||
const BONUS_IDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap", "heal"]
|
||||
const FEATURE_KINDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap", "heal"]
|
||||
## 令牌档位词表(v2.2 三档位——稀有度命名对齐 MC 策略判读序 316-f:1 级最稀有=rarest 优先)
|
||||
const TIERS: Array[String] = ["common", "rare", "rarest"]
|
||||
const TIER_COMMON := "common"
|
||||
@@ -30,65 +39,65 @@ const TIER_QUOTAS := {"common": 70, "rare": 25, "rarest": 3}
|
||||
@export var clear_heal_pct: int = 20 # [0,100] knob——回复生效上限的百分比,封顶上限不回满
|
||||
|
||||
# —— 三选一候选数(2026-10-02 修复批 T2 魔法数结构化)——
|
||||
@export var bonus_candidate_count: int = 3 # [1,6] knob——令牌洗牌不放回抽取张数上界
|
||||
@export var feature_candidate_count: int = 3 # [1,6] knob——令牌洗牌不放回抽取张数上界
|
||||
@export var shop_refresh_free: int = 0 # [0,9] knob(MC-1 provisional——进店免费刷新次数;基础 0=Q2 裁,天赋增益位预留)
|
||||
@export var shop_refresh_cost_base: int = 20 # [1,999] knob(MC-1 provisional——GP 刷新基价)
|
||||
@export var shop_refresh_cost_curve: float = 1.8 # [1.0,4.0] knob(MC-1 provisional——按已付费刷新数幂曲线,A 链同族)
|
||||
|
||||
# —— 令牌配额(kind × tier 计数;未列组合 = 0——heal 只入稀有/ap 只入罕见,v2.2 档位构成)——
|
||||
@export var token_attack_common: int = 18 # [0,99]
|
||||
@export var token_attack_rare: int = 5 # [0,99]
|
||||
@export var token_max_hp_common: int = 17 # [0,99]
|
||||
@export var token_max_hp_rare: int = 5 # [0,99]
|
||||
@export var token_armor_common: int = 17 # [0,99]
|
||||
@export var token_armor_rare: int = 5 # [0,99]
|
||||
@export var token_gp_common: int = 18 # [0,99]
|
||||
@export var token_gp_rare: int = 5 # [0,99]
|
||||
@export var token_heal_rare: int = 5 # [0,99]——恢复件(新入池种类,当即回血)
|
||||
@export var token_ap_rarest: int = 3 # [0,99]——AP 件(罕见档;道具件 2 席位随池种退役收窄)
|
||||
@export var feature_quota_attack_common: int = 18 # [0,99]
|
||||
@export var feature_quota_attack_rare: int = 5 # [0,99]
|
||||
@export var feature_quota_max_hp_common: int = 17 # [0,99]
|
||||
@export var feature_quota_max_hp_rare: int = 5 # [0,99]
|
||||
@export var feature_quota_armor_common: int = 17 # [0,99]
|
||||
@export var feature_quota_armor_rare: int = 5 # [0,99]
|
||||
@export var feature_quota_gp_common: int = 18 # [0,99]
|
||||
@export var feature_quota_gp_rare: int = 5 # [0,99]
|
||||
@export var feature_quota_heal_rare: int = 5 # [0,99]——恢复件(新入池种类,当即回血)
|
||||
@export var feature_quota_ap_rarest: int = 3 # [0,99]——AP 件(罕见档;道具件 2 席位随池种退役收窄)
|
||||
|
||||
# —— 令牌件值(小/大数值对——v2.2 追认 b 定稿:20/50、+1/+2、+1/+2、+5/+10、恢复+6、AP+1)——
|
||||
@export var bonus_attack_flat: int = 1 # [0,999] knob——小增伤
|
||||
@export var bonus_attack_flat_large: int = 2 # [0,999] knob——大增伤
|
||||
@export var bonus_max_hp_flat: int = 5 # [0,999] knob——小生命
|
||||
@export var bonus_max_hp_flat_large: int = 10 # [0,999] knob——大生命
|
||||
@export var bonus_armor_flat: int = 1 # [0,999] knob——小护甲
|
||||
@export var bonus_armor_flat_large: int = 2 # [0,999] knob——大护甲
|
||||
@export var bonus_gp_amount: int = 20 # [0,999] knob——小GP
|
||||
@export var bonus_gp_amount_large: int = 50 # [0,999] knob——大GP
|
||||
@export var bonus_heal_flat: int = 6 # [0,999] knob——恢复(当即回血,封顶生效上限)
|
||||
@export var bonus_ap_flat: int = 1 # [0,10] knob——AP 件每场战斗首轮行动点基线增量
|
||||
@export var feature_value_attack_common: int = 1 # [0,999] knob——小增伤
|
||||
@export var feature_value_attack_rare: int = 2 # [0,999] knob——大增伤
|
||||
@export var feature_value_max_hp_common: int = 5 # [0,999] knob——小生命
|
||||
@export var feature_value_max_hp_rare: int = 10 # [0,999] knob——大生命
|
||||
@export var feature_value_armor_common: int = 1 # [0,999] knob——小护甲
|
||||
@export var feature_value_armor_rare: int = 2 # [0,999] knob——大护甲
|
||||
@export var feature_value_gp_common: int = 20 # [0,999] knob——小GP
|
||||
@export var feature_value_gp_rare: int = 50 # [0,999] knob——大GP
|
||||
@export var feature_value_heal_rare: int = 6 # [0,999] knob——恢复(当即回血,封顶生效上限)
|
||||
@export var feature_value_ap_rarest: int = 1 # [0,10] knob——AP 件每场战斗首轮行动点基线增量
|
||||
|
||||
|
||||
## 令牌配额读数(未列 kind×tier 组合 = 0——heal 无普通档/ap 无普通稀有档按 v2.2 构成)
|
||||
func bonus_token_count(kind: String, tier: String) -> int:
|
||||
func feature_quota(kind: String, tier: String) -> int:
|
||||
match [kind, tier]:
|
||||
["attack", TIER_COMMON]: return token_attack_common
|
||||
["attack", TIER_RARE]: return token_attack_rare
|
||||
["max_hp", TIER_COMMON]: return token_max_hp_common
|
||||
["max_hp", TIER_RARE]: return token_max_hp_rare
|
||||
["armor", TIER_COMMON]: return token_armor_common
|
||||
["armor", TIER_RARE]: return token_armor_rare
|
||||
["gp", TIER_COMMON]: return token_gp_common
|
||||
["gp", TIER_RARE]: return token_gp_rare
|
||||
["heal", TIER_RARE]: return token_heal_rare
|
||||
["ap", TIER_RAREST]: return token_ap_rarest
|
||||
["attack", TIER_COMMON]: return feature_quota_attack_common
|
||||
["attack", TIER_RARE]: return feature_quota_attack_rare
|
||||
["max_hp", TIER_COMMON]: return feature_quota_max_hp_common
|
||||
["max_hp", TIER_RARE]: return feature_quota_max_hp_rare
|
||||
["armor", TIER_COMMON]: return feature_quota_armor_common
|
||||
["armor", TIER_RARE]: return feature_quota_armor_rare
|
||||
["gp", TIER_COMMON]: return feature_quota_gp_common
|
||||
["gp", TIER_RARE]: return feature_quota_gp_rare
|
||||
["heal", TIER_RARE]: return feature_quota_heal_rare
|
||||
["ap", TIER_RAREST]: return feature_quota_ap_rarest
|
||||
return 0
|
||||
|
||||
|
||||
## 令牌件值(kind × tier;v2.2 数值对——小/大两档)
|
||||
func bonus_value(kind: String, tier: String = TIER_COMMON) -> int:
|
||||
func feature_value(kind: String, tier: String = TIER_COMMON) -> int:
|
||||
match [kind, tier]:
|
||||
["attack", TIER_COMMON]: return bonus_attack_flat
|
||||
["attack", TIER_RARE]: return bonus_attack_flat_large
|
||||
["max_hp", TIER_COMMON]: return bonus_max_hp_flat
|
||||
["max_hp", TIER_RARE]: return bonus_max_hp_flat_large
|
||||
["armor", TIER_COMMON]: return bonus_armor_flat
|
||||
["armor", TIER_RARE]: return bonus_armor_flat_large
|
||||
["gp", TIER_COMMON]: return bonus_gp_amount
|
||||
["gp", TIER_RARE]: return bonus_gp_amount_large
|
||||
["heal", TIER_RARE]: return bonus_heal_flat
|
||||
["ap", TIER_RAREST]: return bonus_ap_flat
|
||||
["attack", TIER_COMMON]: return feature_value_attack_common
|
||||
["attack", TIER_RARE]: return feature_value_attack_rare
|
||||
["max_hp", TIER_COMMON]: return feature_value_max_hp_common
|
||||
["max_hp", TIER_RARE]: return feature_value_max_hp_rare
|
||||
["armor", TIER_COMMON]: return feature_value_armor_common
|
||||
["armor", TIER_RARE]: return feature_value_armor_rare
|
||||
["gp", TIER_COMMON]: return feature_value_gp_common
|
||||
["gp", TIER_RARE]: return feature_value_gp_rare
|
||||
["heal", TIER_RARE]: return feature_value_heal_rare
|
||||
["ap", TIER_RAREST]: return feature_value_ap_rarest
|
||||
return 0
|
||||
|
||||
|
||||
@@ -104,8 +113,8 @@ func tier_rank(tier: String) -> int:
|
||||
## 档位令牌总数(货架/校验读面)
|
||||
func tier_total(tier: String) -> int:
|
||||
var total := 0
|
||||
for kind in BONUS_IDS:
|
||||
total += bonus_token_count(kind, tier)
|
||||
for kind in FEATURE_KINDS:
|
||||
total += feature_quota(kind, tier)
|
||||
return total
|
||||
|
||||
|
||||
@@ -118,18 +127,18 @@ func validate() -> Array:
|
||||
var errs: Array[Dictionary] = []
|
||||
if clear_heal_pct < 0 or clear_heal_pct > 100:
|
||||
errs.append({"category": "domain", "message": "clear_heal_pct 越域 [0,100]: %d" % clear_heal_pct})
|
||||
for kind in BONUS_IDS:
|
||||
for kind in FEATURE_KINDS:
|
||||
for tier in TIERS:
|
||||
var c := bonus_token_count(kind, tier)
|
||||
var c := feature_quota(kind, tier)
|
||||
if c < 0 or c > 99:
|
||||
errs.append({"category": "domain", "message": "token_count(%s,%s) 越域 [0,99]: %d" % [kind, tier, c]})
|
||||
var v := bonus_value(kind, tier)
|
||||
var v := feature_value(kind, tier)
|
||||
if v < 0 or v > 999:
|
||||
errs.append({"category": "domain", "message": "bonus_value(%s,%s) 越域 [0,999]: %d" % [kind, tier, v]})
|
||||
errs.append({"category": "domain", "message": "feature_value(%s,%s) 越域 [0,999]: %d" % [kind, tier, v]})
|
||||
for tier in TIERS:
|
||||
var total := tier_total(tier)
|
||||
if total != int(TIER_QUOTAS.get(tier, -1)):
|
||||
errs.append({"category": "domain", "message": "档位配额结构失锚(v2.2 追认 b——%s 应=%d 实=%d;改总量须重裁)" % [tier, int(TIER_QUOTAS.get(tier, -1)), total]})
|
||||
if bonus_candidate_count < 1 or bonus_candidate_count > 6:
|
||||
errs.append({"category": "domain", "message": "bonus_candidate_count 越域 [1,6]: %d" % bonus_candidate_count})
|
||||
if feature_candidate_count < 1 or feature_candidate_count > 6:
|
||||
errs.append({"category": "domain", "message": "feature_candidate_count 越域 [1,6]: %d" % feature_candidate_count})
|
||||
return errs
|
||||
@@ -13,8 +13,8 @@
|
||||
# requires Array[node_id](显式前置——父开子脉内链)/ effects Dictionary(stat 四线 flat:
|
||||
# atk/max_hp/hit/armor_class;rule 键封闭 RULE_KEYS)/ fork_group/fork_side(a/b——同组互斥、
|
||||
# 营地免费切换)。
|
||||
# 🔴 层级纪律(任务书红线 2):局外树只放全局规则件——effects 禁流派标签(relic 流派件永不入树,
|
||||
# archetype 键出域=加载致命);流派件只走局内随机渠道。
|
||||
# 🔴 层级纪律(任务书红线 2):局外树只放全局规则件——effects 禁流派标签(relic 特性永不入树,
|
||||
# archetype 键出域=加载致命);规则改写型特性只走局内随机渠道。
|
||||
# A/B 只放规则面(定稿 1.3——全树互斥面 ≤10-15% 首期 4 组);两侧「不同强非强弱」MC 验差 <~3pp(T10)。
|
||||
# 彩蛋 ≤3(定稿 1.4——点满某脉某排免费觉醒;发现率 <5% 改灰色预告——T10 追认单呈报)。
|
||||
class_name MetaTreeTable
|
||||
@@ -76,9 +76,9 @@ func validate() -> Array:
|
||||
for ek in fx.keys():
|
||||
if not (STAT_KEYS.has(String(ek)) or RULE_KEYS.has(String(ek))):
|
||||
errs.append({"category": "zero_flat", "message": "%s effects 键出域(四线/rule 词表封闭): %s" % [nid, String(ek)]})
|
||||
# 🔴 层级纪律:局外树禁流派件(archetype 键出域=加载致命)
|
||||
# 🔴 层级纪律:局外树禁规则改写型特性(archetype 键出域=加载致命)
|
||||
if fx.has("archetype"):
|
||||
errs.append({"category": "load_bearing", "message": "%s effects 含 archetype(🔴 层级纪律——流派件禁入局外树)" % nid})
|
||||
errs.append({"category": "load_bearing", "message": "%s effects 含 archetype(🔴 层级纪律——特性禁入局外树)" % nid})
|
||||
# A/B 互斥对结构:fork 行必带 fork_group+side;同组恰 a/b 各一
|
||||
if kind == "fork":
|
||||
var fg := String(row.get("fork_group", ""))
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# Validation Question: 七核心流派各 ≥3 件入局内随机渠道后,标签+档位激活引擎能否机械判「成型」、
|
||||
# 机制件带能否挂进令牌池稀有/罕见档随机投放(P0——迭代 12 双层 BD 实施批 T1)
|
||||
# 专长带能否挂进令牌池稀有/罕见档随机投放(P0——迭代 12 双层 BD 实施批 T1)
|
||||
# Date: 2026-10-04(双层 BD 实施批 T1——任务书五裁定稿;设计权威 双层BD体系-整合定稿-2026-10-03 v3)
|
||||
# 数据配置 RelicTable schema(双层BD/机制件 回填 owner 批末落文;行 = Dictionary 键 relic_id,Rule 4 豁免
|
||||
# 概念指路:本表的专长,与 adventure.tres 的属性值提升、资源,同属一个对象——
|
||||
# 「奇物」(一次冒险内各渠道给予玩家的增益总称)。定义见 design/gdd/systems/冒险循环/奇物.md。
|
||||
# 它们是它分类轴上的枚举(专长 / 属性值提升 / 资源),不是三套系统;本表承载「专长」(专长 Feat)的逐项定义。
|
||||
# (2026-10-05 命名统一 + 分类重构:旧称「流派件」→「规则改写型特性」→ 现定名「专长」;
|
||||
# 表名与 relic_id 沿用历史命名,与统一词族对齐归后续批次——见 06-待办清单「命名统一」条目。
|
||||
# 目标渠道:专长走关底 Boss 击败后专属三选一(不新增节点类型),见奇物文档 2.1 节。)
|
||||
# 数据配置 RelicTable schema(奇物·专长定义表;行 = Dictionary 键 relic_id,Rule 4 豁免
|
||||
# 定义表——AuxItemTable 先例)。
|
||||
# 行字段:relic_id 主键 / display_name / rarity ∈ {common, rare, rarest}(对齐令牌池三档命名——
|
||||
# 投放档映射:common/rare→稀有令牌档、rarest→罕见令牌档;relic 令牌永不入普通档=「挂稀有/罕见档」
|
||||
@@ -12,7 +18,7 @@
|
||||
# 仅校验键域不禁纯增益(专项论证件以 positive_only 批注登记,人工清单呈报)。
|
||||
# 档位激活(整合定稿 设计工具 1——以撒套装/小骨铭文):同标签计数 ≥2→档一(流派核心规则)/≥4→档二
|
||||
# (完全体);散件单体保底=每件效果独立生效,档位只做质变(反例 B-2)——引擎纯函数 RelicsEngine。
|
||||
# 🔴 层级纪律(任务书红线 2):流派件只走局内随机渠道(三选一/商店/格面)——本表行永不入同调位
|
||||
# 🔴 层级纪律(任务书红线 2):专长只走局内随机渠道(三选一/商店/格面)——本表行永不入同调位
|
||||
# (aux_items 表)/局外树(T8 节点表);扫雷触发点铁律:每流派 ≥1 行 hook ∈ MINE_HOOKS(加载校验,
|
||||
# 违反=红线①触碰面)。
|
||||
class_name RelicTable
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# 现价公式 = base_price + price_level_bonus(关卡) + price_increment × 该商品已购档数(已购档数在 冒险结构)。
|
||||
# price_level_bonus = 关级定价加值行(level_index 连续从 1 递增)。
|
||||
# pool_shelf = 共享池货架行(M-4 迭代 11 第②批 T1——任务书 v1.3 P1 共享池/P4 ceil):键 kind_id 词表
|
||||
# 封闭 = 四切边后种(SHELF_KINDS:attack/max_hp/armor/ap——GP 袋负交易切边、机制件三轴 doctrine 切边);
|
||||
# 封闭 = 四切边后种(SHELF_KINDS:attack/max_hp/armor/ap——GP 袋负交易切边、规则改写型特性三轴 doctrine 切边);
|
||||
# 库存=上限即库存(账本在 冒险结构 _bonus_taken 单点共享,行族不记库存);price_a/price_b = 乘法价格
|
||||
# 因子(公式 ceil(base × b^(关序−1) × A^(本次进店已购次数)),provisional 投值——P5 甲研究拍板后置追认)。
|
||||
# products 行族 + 加法定价随 legacy 模式(shop=off 对照承载)保留,退役归 off 锚换代批。
|
||||
|
||||
@@ -5,27 +5,27 @@
|
||||
[resource]
|
||||
script = ExtResource("1")
|
||||
clear_heal_pct = 20
|
||||
bonus_candidate_count = 3
|
||||
token_attack_common = 18
|
||||
token_attack_rare = 5
|
||||
token_max_hp_common = 17
|
||||
token_max_hp_rare = 5
|
||||
token_armor_common = 17
|
||||
token_armor_rare = 5
|
||||
token_gp_common = 18
|
||||
token_gp_rare = 5
|
||||
token_heal_rare = 5
|
||||
token_ap_rarest = 3
|
||||
bonus_attack_flat = 1
|
||||
bonus_attack_flat_large = 2
|
||||
bonus_max_hp_flat = 5
|
||||
bonus_max_hp_flat_large = 10
|
||||
bonus_armor_flat = 1
|
||||
bonus_armor_flat_large = 2
|
||||
bonus_gp_amount = 20
|
||||
bonus_gp_amount_large = 50
|
||||
bonus_heal_flat = 6
|
||||
bonus_ap_flat = 1
|
||||
feature_candidate_count = 3
|
||||
feature_quota_attack_common = 18
|
||||
feature_quota_attack_rare = 5
|
||||
feature_quota_max_hp_common = 17
|
||||
feature_quota_max_hp_rare = 5
|
||||
feature_quota_armor_common = 17
|
||||
feature_quota_armor_rare = 5
|
||||
feature_quota_gp_common = 18
|
||||
feature_quota_gp_rare = 5
|
||||
feature_quota_heal_rare = 5
|
||||
feature_quota_ap_rarest = 3
|
||||
feature_value_attack_common = 1
|
||||
feature_value_attack_rare = 2
|
||||
feature_value_max_hp_common = 5
|
||||
feature_value_max_hp_rare = 10
|
||||
feature_value_armor_common = 1
|
||||
feature_value_armor_rare = 2
|
||||
feature_value_gp_common = 20
|
||||
feature_value_gp_rare = 50
|
||||
feature_value_heal_rare = 6
|
||||
feature_value_ap_rarest = 1
|
||||
|
||||
; TP0 令牌池换代(2026-10-03,node-reward v2.2 追认 b 落地):三选一池 = 固定配额令牌池——
|
||||
; 普通 70/稀有 25/罕见 3 = 98 张(罕见档原列「道具件 2」随 aux_item 池种退役收窄——台账自决披露项);
|
||||
|
||||
@@ -411,5 +411,5 @@ rows = [{
|
||||
; ≥ 4×(row−1));锻造脉 3 节点收编 forge_levels(钥石付价=现行迁移零痛);钥石脉=工坊解锁收编
|
||||
; (free 迁移点亮)+刷新升级移植;同调脉 socket 3(钥石=规则面首站)+Fork 4 对(A/B 集中同调脉
|
||||
; 营地免费切换——effects 首期两 rule 键真实接线余组 stat 面 provisional);彩蛋 1(锻造满排觉醒)。
|
||||
; 🔴 层级纪律:局外树只放全局规则件——零 archetype 键(schema 校验强制);流派件只走局内随机渠道。
|
||||
; 🔴 层级纪律:局外树只放全局规则件——零 archetype 键(schema 校验强制);规则改写型特性只走局内随机渠道。
|
||||
; 数值全 provisional 归 M-4 数值批;A/B 两侧差 <~3pp 验收=T10 MC。
|
||||
@@ -260,15 +260,15 @@ rows = [{
|
||||
}
|
||||
}]
|
||||
|
||||
; 双层 BD 实施批(2026-10-04):机制件表——行 = 流派件定义
|
||||
; 双层 BD 实施批(2026-10-04):规则改写型特性表——行 = 特性定义
|
||||
; (relic_id/display_name/rarity/archetype/hook/effects)。
|
||||
; T2 魔法流四件(整合定稿 §2.3 S1):奥术余烬〔普通·rider+1 必中附加〕/魔网织者〔稀有·magic vs
|
||||
; magic 克制罚修正〕/湛蓝誓约〔稀有·magic vs heavy 克制加成〕/魔能共鸣〔罕见锚点·rider+2+每战首次
|
||||
; 开格奥术矢——「每关首次」字面落地为「每战首次」台账披露待追认〕;magic 档一(≥2 件)rider+1 /
|
||||
; 档二(≥4 件)rider 可暴击——引擎 tiers_for 承载。T3-T6 逐流派续填(flag 4/pierce 4/normal 4/
|
||||
; dig 4/charge 3/devour 4——整合定稿 §2.3 七流派件面)。
|
||||
; dig 4/charge 3/devour 4——整合定稿 §2.3 七流派的件面)。
|
||||
; 稀有度→投放档映射:common/rare → 稀有令牌档、rarest → 罕见令牌档(relic 永不入普通令牌档
|
||||
; ——「机制件带挂稀有/罕见档」追认 b 接线口径,普通档 70 张纯数值维持)。
|
||||
; 🔴 层级纪律:本表行永不入同调位(aux_items)/局外树(T8 节点表)——流派件只走局内随机渠道。
|
||||
; ——「规则改写型特性带挂稀有/罕见档」追认 b 接线口径,普通档 70 张纯数值维持)。
|
||||
; 🔴 层级纪律:本表行永不入同调位(aux_items)/局外树(T8 节点表)——规则改写型特性只走局内随机渠道。
|
||||
; 数值全 provisional 归 M-4 数值批;effects 键白名单封闭(零裸 flat 同族护栏)。
|
||||
|
||||
@@ -94,7 +94,7 @@ price_b = 1.1
|
||||
;(用户拍板骨架先行、数值整体后置,行值归 难度曲线与Boss)。
|
||||
; GP 商店房重构批(M-4 迭代 11 第②批 T1,2026-10-03——任务书 v1.3 全裁 P1 共享池/P4 ceil/P5 甲):
|
||||
; pool_shelf 行族 = 共享池货架(kind_id 词表封闭四切边后种 attack/max_hp/armor/ap——GP 袋负交易切边、
|
||||
; 机制件三轴 doctrine 切边;库存=上限即库存,账本在 冒险结构 _bonus_taken 单点共享,行族不记库存);
|
||||
; 规则改写型特性三轴 doctrine 切边;库存=上限即库存,账本在 冒险结构 _bonus_taken 单点共享,行族不记库存);
|
||||
; 价格公式换代(pool 模式)= ceil(base_price × b^(关序−1) × A^(本次进店已购次数)),price_a=1.8/price_b=1.1
|
||||
; provisional 投值(零人工令改 provisional+后置追认,原 P5 甲研究拍板后置);products 行族 + 加法定价
|
||||
; 随 legacy 模式(shop=off 对照承载)保留不退役,退役归 off 锚换代批。货架行值全部 provisional 归
|
||||
|
||||
@@ -131,11 +131,11 @@ static func bonus_result_text(result: Dictionary) -> String:
|
||||
return "已选择:%s\n其余选项已丢弃(不可反悔)" % name
|
||||
|
||||
|
||||
# 流派件卡片文案(迭代 12 T1;2026-10-04 呈现补强——第三行=hook 效果摘要,用户反馈「不知道件是
|
||||
# 特性卡片文案(迭代 12 T1;2026-10-04 呈现补强——第三行=hook 效果摘要,用户反馈「不知道件是
|
||||
# 干嘛的」缺口承载;摘要=静态映射表 provisional 文案归代拍板白名单「件文案微调」)
|
||||
static func relic_card_text(row: Dictionary) -> String:
|
||||
if row.is_empty() or String(row.get("relic_id", "")) == "":
|
||||
return "流派件\n???"
|
||||
return "特性\n???"
|
||||
var arch_names := {"magic": "魔法", "pierce": "穿刺", "normal": "普攻", "dig": "开格",
|
||||
"flag": "标旗", "charge": "蓄力", "devour": "吞噬"}
|
||||
var arch := String(arch_names.get(String(row.get("archetype", "")), "流派"))
|
||||
@@ -167,7 +167,7 @@ static func relic_card_text(row: Dictionary) -> String:
|
||||
var summary := String(summaries.get(String(row.get("hook", "")), ""))
|
||||
if summary != "":
|
||||
return "%s · %s\n%s" % [String(row.get("display_name", row.get("relic_id", ""))), arch, summary]
|
||||
return "流派件 · %s\n%s" % [arch, String(row.get("display_name", row.get("relic_id", "")))]
|
||||
return "特性 · %s\n%s" % [arch, String(row.get("display_name", row.get("relic_id", "")))]
|
||||
|
||||
|
||||
# Boss 胜利战斗总结结算行(settlement-summary v1.1——钥石增量行;组合根拼 GP 行后追加)
|
||||
|
||||
@@ -127,9 +127,9 @@ func _bonus_card_texts(candidates: Array, aux_detail: Array = []) -> Array:
|
||||
elif kind == "aux_item":
|
||||
var iid := String(aux_detail[aux_i]) if aux_i < aux_detail.size() else ""
|
||||
aux_i += 1
|
||||
text = Narrator.bonus_card_text(kind, tier, int(db.adventure.bonus_value(kind, tier)), _aux_card_line(iid))
|
||||
text = Narrator.bonus_card_text(kind, tier, int(db.adventure.feature_value(kind, tier)), _aux_card_line(iid))
|
||||
else:
|
||||
text = Narrator.bonus_card_text(kind, tier, int(db.adventure.bonus_value(kind, tier)))
|
||||
text = Narrator.bonus_card_text(kind, tier, int(db.adventure.feature_value(kind, tier)))
|
||||
out.append({"id": cid, "text": text})
|
||||
return out
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ extends RefCounted
|
||||
# HP/状态效果单投喂 B 区站桩(原 B/C 双投喂为重复展示——信息归属拍板单一展示面原则)
|
||||
static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApBarView,
|
||||
settlement, runner, level_active: bool, db, refresh_remaining: int) -> void:
|
||||
# 本关强化列表(v3.5 迭代 9 卡⑫ 2026-09-30——runner 统一加算区投影:商店购买与关卡大奖励
|
||||
# 特性列表(v3.5 迭代 9 卡⑫ 2026-09-30——runner 统一加算区投影:商店购买与关卡大奖励
|
||||
# 共账本〔level_runner bonus{atk,max_hp,armor_class}〕;空加算=整节隐藏〔视图内空态纪律〕。
|
||||
# 呈现只读投影零核心触碰;行文格式=代拍板白名单项)
|
||||
if runner != null and level_active:
|
||||
@@ -34,7 +34,7 @@ static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApB
|
||||
info.set_level_bonuses(lines)
|
||||
else:
|
||||
info.set_level_bonuses([])
|
||||
# 流派件持有投影(迭代 12 呈现补齐 2026-10-04——用户反馈「局内奖励选了什么看不到」:
|
||||
# 特性持有投影(迭代 12 呈现补齐 2026-10-04——用户反馈「局内奖励选了什么看不到」:
|
||||
# 逐流派聚合行+成型档位;常驻可读+空态隐藏。档位求值=RelicsEngine 纯函数直调)
|
||||
if runner != null and level_active:
|
||||
info.set_relic_holdings(relic_holdings_lines(db, runner.relics_held()))
|
||||
@@ -46,7 +46,7 @@ static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApB
|
||||
return
|
||||
var s: Dictionary = settlement.presentation_snapshot()
|
||||
# 地形变异常驻角标投影(全局作用域变异首发批 2026-10-04——板级变异快照 → 文案行;
|
||||
# 空态隐藏=流派件段先例;战斗全程常驻防中局遗忘)
|
||||
# 空态隐藏=特性段先例;战斗全程常驻防中局遗忘)
|
||||
info.set_board_variants(board_variant_lines(db, s.get("board_variants", [])))
|
||||
var hero: Dictionary = s.hero
|
||||
if hero.is_empty() or not bool(hero.get("alive", false)):
|
||||
@@ -93,7 +93,7 @@ static func _refresh_economy(ap_bar: ApBarView, s: Dictionary, db, refresh_remai
|
||||
ap_bar.set_stop_enabled(bool(s.hero.get("alive", false)) and digging)
|
||||
|
||||
|
||||
# 流派件持有聚合文案(迭代 12 呈现补齐——战斗 C 区与关卡选择页两处共用;空持有=空数组)
|
||||
# 特性持有聚合文案(迭代 12 呈现补齐——战斗 C 区与关卡选择页两处共用;空持有=空数组)
|
||||
static func relic_holdings_lines(db, held: Array) -> Array[String]:
|
||||
var rlines: Array[String] = []
|
||||
if db == null or db.relics == null or (db.relics.rows as Array).is_empty() or held.is_empty():
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# 实现 GDD:design/ux/battle.md(C 区角色信息 240×548——2026-09-26 信息归属拍板精简:
|
||||
# 攻击(+修正来源角标)/护甲 AC 数据框 + 魔法道具槽(预留)+ 本关强化列表(预留)。
|
||||
# 攻击(+修正来源角标)/护甲 AC 数据框 + 魔法道具槽(预留)+ 特性列表(预留)。
|
||||
# HP 条/立绘占位/状态效果槽/RAP 池/GP/钥石退役——HP 与状态唯一展示面 = B 区站桩(同一数据
|
||||
# hud_presenter 双投喂 B/C 两区的重复展示);RAP 迁 D 区 AP 条(贴弃图刷新消费口);
|
||||
# GP(中循环)/钥石(大循环)迁出战斗屏)。
|
||||
@@ -19,9 +19,9 @@ var item_slots: HBoxContainer # 魔法道具槽(迭代 7 T4 接
|
||||
var _slot_panels: Array = [] # 槽 PanelContainer 引用(选中高亮/置灰重刷)
|
||||
var _selected_handle := 0 # 选中态(0=无;组合根回写维持单源)
|
||||
var _slot_handles: Array = [] # 槽位→handle 映射(set_aux_inventory 刷新)
|
||||
var _bonus_section: VBoxContainer # 本关强化(预留——空态隐藏,接线归大奖励/锻造呈现批)
|
||||
var _bonus_section: VBoxContainer # 特性(预留——空态隐藏,接线归大奖励/锻造呈现批)
|
||||
var _bonus_list: VBoxContainer
|
||||
var _relic_section: VBoxContainer # 流派件持有段(迭代 12 呈现补齐——空态隐藏)
|
||||
var _relic_section: VBoxContainer # 特性持有段(迭代 12 呈现补齐——空态隐藏)
|
||||
var _relic_list: VBoxContainer
|
||||
var _board_variant_section: VBoxContainer # 地形变异常驻角标(全局作用域变异首发批——空态隐藏)
|
||||
var _board_variant_list: VBoxContainer
|
||||
@@ -70,19 +70,19 @@ func _init() -> void:
|
||||
item_slots.add_child(slot)
|
||||
_slot_panels.append(slot)
|
||||
|
||||
# 流派件持有段(迭代 12 呈现补齐 2026-10-04——三选一流派件兑付后常驻可读:逐流派聚合行+成型档位;
|
||||
# 特性持有段(迭代 12 呈现补齐 2026-10-04——三选一特性兑付后常驻可读:逐流派聚合行+成型档位;
|
||||
# 空态整节隐藏。用户试玩反馈「局内奖励选了什么看不到」缺口承载;2026-10-04 二次反馈上移——
|
||||
# 构筑核心信息优先级高于临时强化,且防 C 区下部裁切不可见)
|
||||
_relic_section = VBoxContainer.new()
|
||||
_relic_section.add_theme_constant_override("separation", 4)
|
||||
_relic_section.visible = false
|
||||
col.add_child(_relic_section)
|
||||
_relic_section.add_child(UiKit.label("流派件", 16, true))
|
||||
_relic_section.add_child(UiKit.label("特性", 16, true))
|
||||
_relic_list = VBoxContainer.new()
|
||||
_relic_list.add_theme_constant_override("separation", 2)
|
||||
_relic_section.add_child(_relic_list)
|
||||
# 地形变异常驻角标(全局作用域变异首发批 2026-10-04——Boss 图整图型战斗全程可见防中局遗忘;
|
||||
# 空态整节隐藏=流派件段先例;摆位/文案 provisional 归 HUD 框架批与本地化批)
|
||||
# 空态整节隐藏=特性段先例;摆位/文案 provisional 归 HUD 框架批与本地化批)
|
||||
_board_variant_section = VBoxContainer.new()
|
||||
_board_variant_section.add_theme_constant_override("separation", 4)
|
||||
_board_variant_section.visible = false
|
||||
@@ -91,13 +91,13 @@ func _init() -> void:
|
||||
_board_variant_list = VBoxContainer.new()
|
||||
_board_variant_list.add_theme_constant_override("separation", 2)
|
||||
_board_variant_section.add_child(_board_variant_list)
|
||||
# 本关强化(预留):锻造/大奖励/关卡奖励节点的属性提升——中循环数据因改变战斗数学准入;
|
||||
# 特性(预留):锻造/大奖励/关卡奖励节点的属性提升——中循环数据因改变战斗数学准入;
|
||||
# 与战斗内状态效果(B 区站桩,随战斗消散)分区,防「战斗结束被清」误读;空态整节隐藏
|
||||
_bonus_section = VBoxContainer.new()
|
||||
_bonus_section.add_theme_constant_override("separation", 4)
|
||||
_bonus_section.visible = false
|
||||
col.add_child(_bonus_section)
|
||||
_bonus_section.add_child(UiKit.label("本关强化", 16, true))
|
||||
_bonus_section.add_child(UiKit.label("特性", 16, true))
|
||||
_bonus_list = VBoxContainer.new()
|
||||
_bonus_list.add_theme_constant_override("separation", 2)
|
||||
_bonus_section.add_child(_bonus_list)
|
||||
@@ -113,7 +113,7 @@ func set_armor(ac: int) -> void:
|
||||
_armor_label.text = "护甲 AC %d" % ac
|
||||
|
||||
|
||||
# 流派件持有段(迭代 12 呈现补齐):lines = 聚合文案行(「魔法 ×2 · 档一」式)——空数组 = 整节隐藏
|
||||
# 特性持有段(迭代 12 呈现补齐):lines = 聚合文案行(「魔法 ×2 · 档一」式)——空数组 = 整节隐藏
|
||||
func set_relic_holdings(lines: Array) -> void:
|
||||
for c2 in _relic_list.get_children():
|
||||
_relic_list.remove_child(c2)
|
||||
@@ -135,7 +135,7 @@ func set_board_variants(lines: Array) -> void:
|
||||
_board_variant_section.visible = not lines.is_empty()
|
||||
|
||||
|
||||
# 本关强化列表(预留接线面):lines = 文案行数组(如「锻造 +2 攻击」)——空数组 = 整节隐藏
|
||||
# 特性列表(预留接线面):lines = 文案行数组(如「锻造 +2 攻击」)——空数组 = 整节隐藏
|
||||
func set_level_bonuses(lines: Array) -> void:
|
||||
for c in _bonus_list.get_children():
|
||||
_bonus_list.remove_child(c)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# 悬停预承诺(描边加粗+指针)后点击提交;press_candidate 探针入口改走图上命中同路径
|
||||
# ③ 放弃冒险二次确认(布局决策 3)——首击转确认态(文案+危险红脉冲约 3 秒超时回落),二击提交
|
||||
# ④ 顶栏语境:关卡名(level_row.display_name)+ GP 常驻徽章(2026-09-26 二轮拍板去向落地面)
|
||||
# ⑤ 底部状态栏(布局决策 4):生命/属性/本关加成三组常读(零加成隐藏),放弃按钮右端异位
|
||||
# ⑤ 底部状态栏(布局决策 4):生命/属性/特性三组常读(零加成隐藏),放弃按钮右端异位
|
||||
# 关卡画面(独立屏,Level Map Screen——2026-09-28 形态升格批 M-2 迭代 3 T2:原 RouteOverlay 模态
|
||||
# 覆盖层升格独立屏,spec level-map.md 形态章节同批改写):全屏不透明独占呈现——激活期战斗屏宿主
|
||||
# 由组合根整体隐藏(非暗幕半透、零透出)。零自动推进的玩家停点语义不变:唯一前进通道 =
|
||||
@@ -57,7 +57,7 @@ var _hp_bar: Control
|
||||
var _attr_value: Label
|
||||
var _bonus_row: HBoxContainer
|
||||
var _bonus_value: Label
|
||||
var _relic_value: Label # 流派件持有行(迭代 12 呈现补齐——组合根投喂聚合文案)
|
||||
var _relic_value: Label # 特性持有行(迭代 12 呈现补齐——组合根投喂聚合文案)
|
||||
var _cand_ids: Array[int] = [] # 本停点候选 id 集(图上命中合法集)
|
||||
var _content_size := Vector2(620, 240) # 图内容包络(open_choices 按图拟合——画布 min 尺寸随它)
|
||||
var _hover_id := -1 # 悬停预承诺候选(-1 = 无)
|
||||
@@ -159,10 +159,14 @@ func _init() -> void:
|
||||
strip.add_child(_bonus_row)
|
||||
var bonus_box := VBoxContainer.new()
|
||||
_bonus_row.add_child(bonus_box)
|
||||
bonus_box.add_child(UiKit.label("本关加成", 11, false, Color8(110, 69, 52)))
|
||||
_bonus_value = UiKit.label("", 15, true, UiKit.INK_TITLE)
|
||||
bonus_box.add_child(_bonus_value)
|
||||
_relic_value = UiKit.label("", 12, false, Color8(110, 69, 52))
|
||||
var bonus_inner := VBoxContainer.new()
|
||||
bonus_box.add_child(bonus_inner)
|
||||
var bonus_cap := UiKit.label("特性", 12, false, UiKit.WARM_SOFT)
|
||||
bonus_inner.add_child(bonus_cap)
|
||||
_bonus_value = UiKit.label("", 15, true, UiKit.WARM)
|
||||
bonus_inner.add_child(_bonus_value)
|
||||
# 特性持有行(迭代 12 呈现补齐 2026-10-04——用户反馈关卡选择页看不到局内奖励;组合根投喂)
|
||||
_relic_value = UiKit.label("", 13, false, UiKit.WARM_SOFT)
|
||||
_relic_value.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
bonus_box.add_child(_relic_value)
|
||||
var spacer := Control.new()
|
||||
@@ -200,7 +204,7 @@ func _draw_hp_bar(bar: Control) -> void:
|
||||
|
||||
|
||||
# 放弃入口可见性(组合根在冒险启动时开、默认关——语义对象 = 整局冒险)
|
||||
# 流派件持有投影(迭代 12 呈现补齐——组合根投喂聚合文案;空文案=行隐藏)
|
||||
# 特性持有投影(迭代 12 呈现补齐——组合根投喂聚合文案;空文案=行隐藏)
|
||||
func set_relic_holdings(text: String) -> void:
|
||||
_relic_value.text = text
|
||||
|
||||
@@ -335,7 +339,7 @@ func _refresh_status() -> void:
|
||||
if ac_bonus > 0:
|
||||
parts.append("AC +%d" % ac_bonus)
|
||||
_bonus_value.text = " · ".join(parts)
|
||||
# 流派件持有行可见性(与加成行并框——任一非空整框显示;文案归组合根 set_relic_holdings)
|
||||
# 特性持有行可见性(与加成行并框——任一非空整框显示;文案归组合根 set_relic_holdings)
|
||||
_bonus_row.visible = not parts.is_empty() or _relic_value.text != ""
|
||||
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ func _initialize() -> void:
|
||||
var shop_mode := "off"
|
||||
if args.size() >= 6 and args[5] in ["off", "on"]:
|
||||
shop_mode = args[5]
|
||||
# 流派件/树分层开关(迭代 12 T7/T10——off=基线;formed=成型画像开局注入七流派各 2 件档一成型集
|
||||
# 〔测量面专用 params.relics_seed——真实局流派件只走局内随机渠道〕;ab_a/ab_b=Fork posture 两侧
|
||||
# 特性/树分层开关(迭代 12 T7/T10——off=基线;formed=成型画像开局注入七流派各 2 件档一成型集
|
||||
# 〔测量面专用 params.relics_seed——真实局规则改写型特性只走局内随机渠道〕;ab_a/ab_b=Fork posture 两侧
|
||||
# rule 键集——A/B 面两侧差 <~3pp 验收载体)
|
||||
var relic_mode := "off"
|
||||
if args.size() >= 7 and args[6] in ["off", "formed", "ab_a", "ab_b"]:
|
||||
|
||||
@@ -137,7 +137,7 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_
|
||||
"log_path": "", "policy": policy, "refreshes": 0, "mine_hits": 0, "mine_dmg": 0,
|
||||
"visited_ids": [], "choices": 0, "last_battle_enemies": [],
|
||||
"summary": {}, "wallet_events": [], "encounter_max_hp_seq": [], "reward_events": [],
|
||||
"relic_mode": String(relic.get("mode", "off")), # 流派件分层开关(迭代 12 T7——off=316-f 通用竞争/on=成型画像优先捕捞 relic)
|
||||
"relic_mode": String(relic.get("mode", "off")), # 特性分层开关(迭代 12 T7——off=316-f 通用竞争/on=成型画像优先捕捞 relic)
|
||||
"shop_gp_seq": [], # 商店房到达余额序(逐关 1 次——GP 跨关延续验收取数面)
|
||||
# 旗经济五字段(迭代14②判式换代批 T1——与 run_level 同口径,见彼处注释)
|
||||
"flag_placed": 0, "flag_hit": 0, "flag_miss": 0, "flag_hit_gain": 0, "flag_miss_penalty": 0,
|
||||
@@ -161,7 +161,7 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_
|
||||
if not attune.is_empty():
|
||||
adv_params["attunement"] = attune.get("equipped", [])
|
||||
adv_params["attune_refresh_y"] = int(attune.get("refresh_y", 0))
|
||||
# 流派件注入(迭代 12 T7——formed 画像=开局注入七流派各 2 件档一成型集;测量面专用)
|
||||
# 特性注入(迭代 12 T7——formed 画像=开局注入七流派各 2 件档一成型集;测量面专用)
|
||||
if relic.has("seed_ids"):
|
||||
adv_params["relics_seed"] = relic.get("seed_ids", [])
|
||||
# 树规则键注入(迭代 12 T10——A/B 面读数载体:fork 激活侧 effects rule 键集透传)
|
||||
@@ -190,7 +190,7 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_
|
||||
# 终局池读数(迭代 11 第②批 T5——摘要 additive 键 pool_stock:_settle 清账前快照,
|
||||
# 商店买走 vs 奖励领走 vs 枯竭的终局面;事后读 adr.pool_stock 会被收束清账重置=满库假象)
|
||||
st["pool_stock"] = (st.get("summary", {}).get("pool_stock", {}) as Dictionary).duplicate(true)
|
||||
st["relics"] = (st.get("summary", {}).get("relics", []) as Array).duplicate() # 流派件终局持有集(迭代 12 T1——摘要 additive 键清账前快照,同 pool_stock 模式)
|
||||
st["relics"] = (st.get("summary", {}).get("relics", []) as Array).duplicate() # 特性终局持有集(迭代 12 T1——摘要 additive 键清账前快照,同 pool_stock 模式)
|
||||
st.log_path = logger.log_path()
|
||||
if own_session:
|
||||
logger.close_session()
|
||||
@@ -273,7 +273,7 @@ static func _on_adventure_bonus(payload: Dictionary, st: Dictionary, adr) -> voi
|
||||
# 三选一确定性选件(TP0 316-f——1 级优先度=最稀有〔档位最高 rarest>rare>common〕、2 级=最左;
|
||||
# 候选并列同档取最左=稳定序保证。空候选/未知档位 = 回退最左防御口径。
|
||||
# 成型画像(迭代 12 T7——relic 模式 on:候选含 relic 令牌时优先在 relic 集内按 316-f 择一
|
||||
# 〔贪心捕捞→流派件入局→成型画像全流派覆盖——R3 乙单锚承载〕;off=relic 与数值件同规则竞争)
|
||||
# 〔贪心捕捞→特性入局→成型画像全流派覆盖——R3 乙单锚承载〕;off=relic 与属性加成型特性同规则竞争)
|
||||
static func _pick_token(candidates: Array, relic_mode: String = "off") -> Dictionary:
|
||||
var pool: Array = candidates
|
||||
if relic_mode == "on":
|
||||
|
||||
+25
-25
@@ -220,12 +220,12 @@ func _smoke_adventure_table() -> void:
|
||||
check(int(_db.adventure.tier_total(tier)) == int(_db.adventure.TIER_QUOTAS[tier]),
|
||||
"档位配额结构锚(v2.2 追认 b):%s = %d 张" % [tier, int(_db.adventure.TIER_QUOTAS[tier])])
|
||||
check(int(_db.adventure.deck_total()) == 98, "令牌池总量 = 98 张(普通 70/稀有 25/罕见 3——罕见档随道具件池种退役收窄)")
|
||||
check(int(_db.adventure.bonus_value("gp", "common")) == 20 and int(_db.adventure.bonus_value("gp", "rare")) == 50
|
||||
and int(_db.adventure.bonus_value("attack", "common")) == 1 and int(_db.adventure.bonus_value("attack", "rare")) == 2
|
||||
and int(_db.adventure.bonus_value("max_hp", "common")) == 5 and int(_db.adventure.bonus_value("max_hp", "rare")) == 10
|
||||
and int(_db.adventure.bonus_value("armor", "common")) == 1 and int(_db.adventure.bonus_value("armor", "rare")) == 2,
|
||||
check(int(_db.adventure.feature_value("gp", "common")) == 20 and int(_db.adventure.feature_value("gp", "rare")) == 50
|
||||
and int(_db.adventure.feature_value("attack", "common")) == 1 and int(_db.adventure.feature_value("attack", "rare")) == 2
|
||||
and int(_db.adventure.feature_value("max_hp", "common")) == 5 and int(_db.adventure.feature_value("max_hp", "rare")) == 10
|
||||
and int(_db.adventure.feature_value("armor", "common")) == 1 and int(_db.adventure.feature_value("armor", "rare")) == 2,
|
||||
"数值对(v2.2):小GP 20/大GP 50 · 小增伤 +1/大 +2 · 小生命 +5/大 +10 · 小护甲 +1/大 +2")
|
||||
check(int(_db.adventure.bonus_value("heal", "rare")) == 6 and int(_db.adventure.bonus_value("ap", "rarest")) == 1,
|
||||
check(int(_db.adventure.feature_value("heal", "rare")) == 6 and int(_db.adventure.feature_value("ap", "rarest")) == 1,
|
||||
"恢复件 +6 当即回血(新入池种类,rare 档)· AP +1(rarest 档)")
|
||||
check(_db.attunement_growth != null and int(_db.attunement_slot_cap()) == 3
|
||||
and Attunement.slots(_db, null) == 0,
|
||||
@@ -349,7 +349,7 @@ func _smoke_adventure() -> void:
|
||||
var cand_ok := picks.size() == 2
|
||||
var ks_gain_ok := picks.size() == 2
|
||||
var resolve_ok := level_resolves.size() == 2
|
||||
var max_flat := int(_db.adventure.bonus_max_hp_flat)
|
||||
var max_flat := int(_db.adventure.feature_value_max_hp_common)
|
||||
var heal_pct := int(_db.adventure.clear_heal_pct)
|
||||
var hp_acc := 0 # max_hp 件累加(回血封顶断言的生效上限推导——TP0 起按兑付令牌实值,大小档分别计)
|
||||
var ks_prefix := 0
|
||||
@@ -384,7 +384,7 @@ func _smoke_adventure() -> void:
|
||||
var r: Dictionary = level_resolves[i]
|
||||
var rk := String(r.get("picked", ""))
|
||||
var rt := String(r.get("tier", ""))
|
||||
if _smoke_find_token(p.get("candidates", []) as Array, rk, rt).is_empty() or int(r.get("value", -1)) != int(_db.adventure.bonus_value(rk, rt)):
|
||||
if _smoke_find_token(p.get("candidates", []) as Array, rk, rt).is_empty() or int(r.get("value", -1)) != int(_db.adventure.feature_value(rk, rt)):
|
||||
resolve_ok = false
|
||||
if rk == "max_hp":
|
||||
hp_acc += int(r.get("value", max_flat))
|
||||
@@ -397,7 +397,7 @@ func _smoke_adventure() -> void:
|
||||
var exp_base := maxi(1, int(round(float(int(_db.hero.max_hp)) * k)))
|
||||
# 模拟档 v3.4 商店贪心购血(数值修复批)合法抬升——上限窗口 = 基础 + 加算区 3 件 + 购血余量;
|
||||
# TP0 数值对后 max_hp 件有大生命 +10(rare 档)——上界按大件最坏构成 3×10+购血 15=+45(TP0 放宽)
|
||||
var hp_ceiling := maxi(1, int(round(float(int(_db.hero.max_hp) + 3 * int(_db.adventure.bonus_value("max_hp", "rare")) + 15) * k)))
|
||||
var hp_ceiling := maxi(1, int(round(float(int(_db.hero.max_hp) + 3 * int(_db.adventure.feature_value("max_hp", "rare")) + 15) * k)))
|
||||
var seq_ok := seq.size() > 0 and int(seq[0]) == exp_base
|
||||
for v in (seq as Array):
|
||||
if int(v) < exp_base or int(v) > hp_ceiling:
|
||||
@@ -592,22 +592,22 @@ func _smoke_adventure() -> void:
|
||||
a13.present_node_bonus(ncands13, ndraw.get("aux_detail", []) as Array)
|
||||
a13.present_node_bonus([{"kind": "gp", "tier": "common"}])
|
||||
var gp13 := int(a13.ledger.get("gp", 0))
|
||||
check(a13.apply_node_bonus("gp", "common") and int(a13.ledger.get("gp", 0)) == gp13 + int(_db.adventure.bonus_value("gp", "common")),
|
||||
"奖励节点 GP 件入账(钱包「奖励入账」收口——+%d)" % int(_db.adventure.bonus_value("gp", "common")))
|
||||
check(a13.apply_node_bonus("gp", "common") and int(a13.ledger.get("gp", 0)) == gp13 + int(_db.adventure.feature_value("gp", "common")),
|
||||
"奖励节点 GP 件入账(钱包「奖励入账」收口——+%d)" % int(_db.adventure.feature_value("gp", "common")))
|
||||
check(a13._node_bonus_pending.is_empty(), "节点停点态兑付后清零(恰一次语义同构)")
|
||||
var s10: Dictionary = a10.summary
|
||||
check(String(s10.get("result", "")) == "abandoned" and not bool(s10.get("cleared", true)),
|
||||
"放弃摘要:abandoned · 未打穿(已获大奖励不追回——同失败型结算)")
|
||||
|
||||
|
||||
# ---- 双层 BD 机制件基建冒烟(迭代 12 T1——relic_table/档位激活引擎/机制件带池接线)----
|
||||
# ---- 双层 BD 规则改写型特性基建冒烟(迭代 12 T1——relic_table/档位激活引擎/规则改写型特性带池接线)----
|
||||
|
||||
func _smoke_relics() -> void:
|
||||
print("--- 机制件基建(relic_table · 档位激活引擎 · 机制件带接线)---")
|
||||
print("--- 规则改写型特性基建(relic_table · 档位激活引擎 · 规则改写型特性带接线)---")
|
||||
# ① 现行表牌库构成:七流派 27 件全量入池——98 数值令牌+27 relic 令牌(批次一铺量完成)
|
||||
check(_db.relics != null and (_db.relics.rows as Array).size() == 27, "relic_table 已加载(七流派 27 件全量——批次一 T2-T6 铺量完成)")
|
||||
var a_r0 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(71))
|
||||
check(a_r0.start_adventure(71, {"first_script": true}), "机制件带场景:冒险启动(seed 71)")
|
||||
check(a_r0.start_adventure(71, {"first_script": true}), "规则改写型特性带场景:冒险启动(seed 71)")
|
||||
var relic_tokens := 0
|
||||
var rarest_tokens := 0
|
||||
for t in a_r0._bonus_deck:
|
||||
@@ -616,7 +616,7 @@ func _smoke_relics() -> void:
|
||||
if String((t as Dictionary).get("tier", "")) == "rarest":
|
||||
rarest_tokens += 1
|
||||
check(relic_tokens == 27 and rarest_tokens == 6 and a_r0._bonus_deck.size() == 125,
|
||||
"机制件带入池:27 件(rare 档 21 + rarest 锚点 6)——牌库 98+27=125")
|
||||
"规则改写型特性带入池:27 件(rare 档 21 + rarest 锚点 6)——牌库 98+27=125")
|
||||
check(_db.relics.validate().is_empty(), "relic_table.validate 零违例(有行流派扫雷端铁律——magic first_dig_spell 在案)")
|
||||
# ② 档位激活引擎(纯函数直测——构造表 4 件 magic + 1 件 flag + 1 件 rarest 锚点)
|
||||
var rt := RelicTable.new()
|
||||
@@ -638,17 +638,17 @@ func _smoke_relics() -> void:
|
||||
var hooks := RelicsEngine.hooks_for(["m1", "f1"], rt)
|
||||
check(hooks.size() == 2 and String(hooks[0].get("hook", "")) == "hero_attack_rider",
|
||||
"挂点投影:表序稳定(同集合→同投影)")
|
||||
# ③ 机制件带接线(临时表注入——relic 令牌入牌库/兑付入持有集/踢池/断点往返;测试尾还原现行表)
|
||||
# ③ 规则改写型特性带接线(临时表注入——relic 令牌入牌库/兑付入持有集/踢池/断点往返;测试尾还原现行表)
|
||||
var live_rows: RelicTable = _db.relics
|
||||
_db.relics = rt
|
||||
var a_r = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(72))
|
||||
check(a_r.start_adventure(72, {"first_script": true}), "机制件带场景:冒险启动(seed 72——注入 5 行临时表)")
|
||||
check(a_r.start_adventure(72, {"first_script": true}), "规则改写型特性带场景:冒险启动(seed 72——注入 5 行临时表)")
|
||||
var deck_relic := 0
|
||||
for t in a_r._bonus_deck:
|
||||
if String((t as Dictionary).get("kind", "")) == "relic":
|
||||
deck_relic += 1
|
||||
check(deck_relic == 5 and a_r._bonus_deck.size() == 103,
|
||||
"机制件带入池:5 行 relic 每件 1 张(common/rare→稀有档 rarest→罕见档)——牌库 98+5=103")
|
||||
"规则改写型特性带入池:5 行 relic 每件 1 张(common/rare→稀有档 rarest→罕见档)——牌库 98+5=103")
|
||||
var relic_seen: Dictionary = {}
|
||||
for i in 60:
|
||||
for t in a_r._draw_bonus_candidates():
|
||||
@@ -726,13 +726,13 @@ func _smoke_relics() -> void:
|
||||
"深挖钻头=开掘 +1 AP/每 4 格深层产出(R4 甲非信息税对价)· 蓄力三件=层值 1/减伤 1/层/满层 ×2")
|
||||
check(orch.action_economy.relic_ap_carry and orch.action_economy.relic_dig_extra == 1,
|
||||
"蓄力/钻头 action_economy 注入(ap_carry 改写停手转存 + 付费开掘对价注入——关着 false/0 零扰动)")
|
||||
# ⑦c 流派件持有呈现段(2026-10-04 用户反馈补齐——C 区「流派件」节:聚合行+成型档位;空态隐藏)
|
||||
# ⑦c 特性持有呈现段(2026-10-04 用户反馈补齐——C 区「特性」节:聚合行+成型档位;空态隐藏)
|
||||
var panel = load("res://presentation/views/hero_info_panel_view.gd").new()
|
||||
panel.set_relic_holdings([])
|
||||
check(not panel._relic_section.visible, "流派件段空态隐藏(视图空态纪律同本关强化段)")
|
||||
check(not panel._relic_section.visible, "特性段空态隐藏(视图空态纪律同特性段)")
|
||||
panel.set_relic_holdings(["魔法 ×2 · 档一", "开格 ×1 · 散件"])
|
||||
check(panel._relic_section.visible and panel._relic_list.get_child_count() == 2,
|
||||
"流派件段持有呈现(聚合行+成型档位常驻可读——「局内奖励选了什么看不到」缺口承载)")
|
||||
"特性段持有呈现(聚合行+成型档位常驻可读——「局内奖励选了什么看不到」缺口承载)")
|
||||
# ⑦b 深挖钻头付费开掘回归(2026-10-04 试玩缺陷修复——对价挂付费侧):AP=1 降级照常开格
|
||||
# (用户实测「AP=1 无法开格只能标旗」的回归闸);AP=2 付全价积付费计数(深层产出配额取数面)。
|
||||
var ae_dd = load("res://core/action_economy.gd").new(_db)
|
||||
@@ -3824,8 +3824,8 @@ func _smoke_shop_pool() -> void:
|
||||
var val0: int = int(a8.bonus.get(String(val_map[kind]), -999))
|
||||
check(r8.buy_pool_item(kind), "购买受理(pool 口——%s|%s)" % [kind, tier])
|
||||
check(int(r8.gp) == gp0 - int(buy_c.get("price", 0)), "钱包扣现价(%d → %d)" % [gp0, int(r8.gp)])
|
||||
check(int(a8.bonus.get(String(val_map[kind]), -999)) == val0 + int(_db.adventure.bonus_value(kind, tier)),
|
||||
"加算区 +令牌档位件值(池件=奖励件本体——%s|%s %+d)" % [kind, tier, int(_db.adventure.bonus_value(kind, tier))])
|
||||
check(int(a8.bonus.get(String(val_map[kind]), -999)) == val0 + int(_db.adventure.feature_value(kind, tier)),
|
||||
"加算区 +令牌档位件值(池件=奖励件本体——%s|%s %+d)" % [kind, tier, int(_db.adventure.feature_value(kind, tier))])
|
||||
check(int(a8._bonus_taken.get(kind, 0)) == taken0 + 1, "共享池账本 -1(跨渠道单点——taken %d → %d)" % [taken0, int(a8._bonus_taken.get(kind, 0))])
|
||||
# A 链:同visit 第二购现价 = ceil(base×b^(l2−1)×A^1)(货架已全重抽——新卡新价同公式)
|
||||
var second: Dictionary = {}
|
||||
@@ -3839,7 +3839,7 @@ func _smoke_shop_pool() -> void:
|
||||
check(int(second.get("price", -1)) == expect_p2,
|
||||
"A 链爬价 = ceil(base×b^(关序−1)×A^1)(进店第 2 购——%d)" % expect_p2)
|
||||
check(r8.buy_pool_item(String(second.get("kind_id", ""))), "同 visit 第二购受理(A 链软闸在价不在限)")
|
||||
# ④ 切边零入店(白-box 重抽 40 次——GP 袋/机制件永不在架;重抽消费 shop_draw 签,场景尾不回写主时间线)
|
||||
# ④ 切边零入店(白-box 重抽 40 次——GP 袋/规则改写型特性永不在架;重抽消费 shop_draw 签,场景尾不回写主时间线)
|
||||
var cut_seen := false
|
||||
for i in 40:
|
||||
r8._shop_draw_shelf()
|
||||
@@ -3890,7 +3890,7 @@ func _smoke_shop_pool() -> void:
|
||||
for k in ps.keys():
|
||||
var quota := 0
|
||||
for tier in _db.adventure.TIERS:
|
||||
quota += int(_db.adventure.bonus_token_count(String(k), tier))
|
||||
quota += int(_db.adventure.feature_quota(String(k), tier))
|
||||
if int(ps[k]) < 0 or int(ps[k]) > quota:
|
||||
ps_ok = false
|
||||
check(ps_ok, "终局池余量在域 [0,配额](%s)" % str(ps))
|
||||
@@ -4481,7 +4481,7 @@ func _smoke_save() -> void:
|
||||
and int(bp.get("hero_hp", -1)) == 13, "断点七字段往返:关卡序号/节点位/生命")
|
||||
var bp_bonus: Dictionary = bp.get("bonus", {})
|
||||
check(int(bp_bonus.get("atk", -1)) == 2 and int(bp_bonus.get("max_hp", -1)) == 5
|
||||
and int(bp_bonus.get("armor_class", -1)) == 1, "断点七字段往返:本关加成区")
|
||||
and int(bp_bonus.get("armor_class", -1)) == 1, "断点七字段往返:属性加成区")
|
||||
check(int(bp.get("gp", -1)) == 17, "断点七字段往返:GP 钱包")
|
||||
var bp_shop: Dictionary = bp.get("shop_purchased", {})
|
||||
check(int(bp_shop.get("hp_small", -1)) == 2 and int(bp_shop.get("atk_small", -1)) == 1,
|
||||
|
||||
+3
-1
@@ -60,7 +60,9 @@
|
||||
| 迭代 12 | **双层 BD 实施批(反制批位移承接——变异应对局内化在本批落地)**:**2026-10-03 用户五裁全落**=R1 甲(树形态融合案:主干脊柱 row-gating+三脉+彩蛋 ≤3+A/B 集中同调脉)/R2 乙(**两层全入本迭代**:批次一 T0-T7=机制件基建+七流派全量铺〔R3 乙〕+地形转化件+商店保底+MC 锚;批次二 T8-T10=天赋树+存档 v4+营地 UI 重构;超软时间盒切 12/12b,切分点=批次一出口)/R3 乙(七流派批次一全量铺)/R4 甲(**信息型永不对冲**+复查闸=T10 呈报信息型真人读数仅呈报不提案;净化工兵仅限伤害型、清除工具件族不做、深挖钻头改非信息税设计)/R5 甲(喂雷流不做,06 留正式待办+kill-switch 判据)。未落地备选内容已自包含迁 06「双层 BD 延期与备选内容总登记」。设计事实源=`design/research/双层BD体系-整合定稿-2026-10-03.md`(双模型并行调研仲裁版),任务书=`design/research/任务书-双层BD实施批-2026-10-03.md`(已定稿)。**✅ 已全批落籍(2026-10-04,台账 328-333)**:TP0 令牌池先行(normal 重锚)→批次一 T0-T7(27 件七流派+MC 成型锚 L1 5%→75% 分岔+红线自检①过)→批次二 T8-T10(天赋树 33 节点+存档 v5+营地树 UI+A/B 面 0.0pp)一次合并 e780063;试玩反馈四连修复(钻头 AP 锁死/v2 收益重投/流派件呈现双界面/清图奖励 toast)至 c43276d;批末冒烟 718/0+run_all 15+探针绿+doc 三闸基线同款+熵增 PASS;**出口人闸待用户**(人工检查清单=台账 328-333+design/qa/m4iter12 两报告);前置=迭代 11 三批出口+M-4 数值批令牌池落地+商店批共享池 | 迭代 11 出口 | T0-T10 两段式(任务书 §四) |
|
||||
| 迭代 13 | **工程债与测试基建批(含 D6 爆破工兵包实施)**:六条目=ui_click_probe 完整局适配(D1——分派链序修正+停点/锁期/重放三态断言)/探针只读出口(D2——六出口 26 直入清零)/ArmedTimer helper(D3——P4 乙三处计时收口缝零动)/main.gd 二期瘦身(D4——bonus_interact_controller+camp_shop_presenter 拆件 1370→1119,家族②契约3绑定面留置;~900±50 锚差=族级清单上限不自洽已归因)/aux 二期合并(T5 判不合收口)/杂项尾差四件(D5)/爆破工兵包中立移除雷格(D6——P1 甲邻接冻结/P2 甲退色降档,判定逻辑零改动,充能表驱动零新码)。**✅ 已落籍(2026-10-04,台账 342)**:worktree m4iter13-debt-20261004 八提交 cd7d3ea…2402877 合并 eff8cb8;闸=冒烟 718/0(断言数持平基线)+run_all 15+click 三种子绿+全探针绿+doc 三闸零新增+熵增 PASS+MC 零跑(静态零漂移证明);合并后主区全量复跑同绿 | 迭代 12 出口 | T0-T9 ≈4.8-5.3d(知情超限单批,实际单会话) |
|
||||
| 迭代 14 | **初始展开收窄批(2026-10-04 用户拍板甲乙混合立项)**:甲=先布后删剃雷域收窄至出生 3×3∪外扩 r 环(参数化半径,现值 r=1——开阔地均值从板面 66.5% 根因性降至约三成)+乙=生成重掷闸 R₀≤cap(合法性门序列、cap=板面 30% 锚〔10×10=30/12×12=43/13×13=51〕、重试耗尽走既有三分出口);**玩法侧零改动路线**(排雷玩法「初始展开恰等」验收原样为真,minesweeper_rules.gd 零 diff);裸数字截断路否决退役(可见 0 格+未开邻居=扫雷不可能态)。可行性报告=`design/research/研究-初始展开收窄可行性-2026-10-04.md`,任务书=`design/research/任务书-初始展开收窄批-2026-10-04.md`(T0-T8≈5.25d,读数批 T5-T6 可切独立后批;拍板点 P1-P3 全读数后置;停机点 S1 相变警戒/S2 带越界回调)。**②挖掘风险不等式判式换代批(2026-10-04 用户裁编入本迭代,作为迭代内需求)**:判式三层换代(条款2 标中旗锚/条款3 聚合健康式「(1−ρ̂)E_dig−ρ̂V_mine≥0」/旗边际引理+条件二旗溢价)+β 比值带判读 [1.2,2.5](u=3 登记态)+标中兑付溢价 δ=1.25(形态 a 兑付公式一处·雷安同池冻结不动)+runsum 旗行为五字段+audit 工具常量刷新(池 77/直伤 6-8-8/AP 8);裁决全落零新拍板点(方案报告=`design/research/方案-挖掘风险不等式修订-2026-10-04.md` §九),任务书=`.zcode/plans/mine-inequality-revision-miniloop-plan-2026-10-04.md`(T0-T5≈2.5d;条件二 T3 落文按登记已知破·T4 机制转绿;契约红线=DamageController 零改/直伤雷 6-8-8 与 p_perfect 不动——iter8 缺口四选一解绑独立在案;开工门=U0)。**✅ 实施批落地(2026-10-05,worktree m4iter14-mineq-20261005 台账 354)**:T0-T5 全落——audit 工具常量刷新(改前静态锚与方案报告 §四 逐位吻合)+runsum 五字段(行侧判据考证=授予行专带 highlight,87行==87插旗1:1)+F1 条款3 重立三层口径(v0.8)+战斗结算 v0.25+难度联动表+6 行+registry clause3_inequality 重立条(改前锚+P7 修正注记)+06 破线条收口+**T4 标中兑付溢价机制**(settlement.flag_hit_premium=125 provisional,grant 单点只挂 flag_hit 正向·percent 幅度贯穿应用与呈现,标空/挖格不乘,DamageController 零改/同池冻结)+smoke 750/0(+3 断言;max 路径种子 42→43 重采);判读三件=β 带 u=1/2 带内 u=3 登记态/δ 敏感度行为无感(η 位移 <1.4pp<5pp,保留+登记)/条件二判式口径等号压线转绿(整数量级实现 u=1/2 绿·u=3 微欠 −1.1% 登记面);改后锚换代 runsum_m4iter14mineq_post_n200_20261005(perfect 冒险通关 65.3%→72.0% 增强向位移,四带判读归 M-4);出口报告=design/qa/m4iter14-mineq-exit-report-2026-10-05.md(provisional 追认单 8 项+07⑫ 人工项);damage_probe A1 红灯=改前既有非本批新增(在册)。**③全局作用域变异首发批(2026-10-04 用户拍板立项——调研报告 P1-P8+盘问 Q1-Q4 全按推荐案落,批内序位待排)**:L2/L3 Boss 图恒定一型 scope=global 变异,首发型=**案A 资源面·微贫向偏斜**(正向格面池合计不变、进攻族 attack/blast/pierce/magic 权重上浮/生存族 heal/defense 明显下调、EV 微降 3-5% provisional、gp/action 白名单不动;v1.0「沃土+雷密对冲」形勘误作废——雷数为生成器事实、布置段不可加,改生成端=踩结构面否决理由);**替换制**(Boss 图不再布 region 片——L2 完美 Boss 承伤 55.8% 已越带不叠加;迭代 12 四件地形应对件在 Boss 图失效=知情代价,registry/调参日志随批登记);L1 Boss 免疫(带B [50,85] 教学保护);三层预告(开战横幅+HUD 常驻角标+帮助手册行);带A 判读后置 M-4(落地 off/on 对拍只测不判;off 基线=替换制后零变异 Boss 图,与现行带 region 片 Boss 图语义不同须注明);偏运硬币合成序=图级先件级后(代拍随批锚登记)。调研报告(事实源,v1.1 裁决落盘)=`design/research/调研-全局作用域变异设计空间-2026-10-04.md`,任务书=`design/research/任务书-全局作用域变异首发批-2026-10-04.md`(T0-T8≈5.75d,读数批 T7 可切独立后批→主体≈5.25d;零新拍板点·provisional 追认单随批;停机点 S1 普通图逐位漂移/S2 读数越带只呈报/S3 互锁误伤;开工门=U0;**⑥A4 批开工门含本批出口——本批落地图级偏斜投影点为⑥合成链中段**〔2026-10-05 注:⑥已移出迭代 14 挂起,此依赖句冻结待其重启〕)。与①②互不撞(收窄=普通图初始展开轴/判式=不等式判读口径/全局变异=Boss 图资源面轴),出口读数各自分开归因。**✅ 实施批落地(2026-10-04,worktree m4iter14-gvar-20261004 台账 345)**:T1-T8Line truncated
|
||||
| 迭代 15 | **调试功能整合批(2026-10-05 用户令自「14.5」临时卡改编入册——原周期外 0.5 卡,落地事实与验证读数零变化,只改编号归属)**:主菜单三调试散件(随机种子输入框/角色数值调整板/两层调试入口)收一张调试浮窗 DebugOverlay——入口=开始覆盖层右下角「调试」角标(与主按钮组非平级,DS_DEBUG=1 环境变量门控沿用迭代 8 卡④口径);浮窗=悬浮菜单之上 Dialog(不隐藏开始层,同确认弹窗形态;旧 TunePanel「与开始层互斥」形态与类整体吸收退役含 .uid);可扩展滚动列表页四区块(随机种子/数值调整/批量模拟/两层调试入口——后续调试项往下追加滚轮下探)。四拍板全落(2026-10-04 用户裁)=P1 甲 DS_DEBUG 门控/P2 乙全摊平/P3 仅开始菜单可开·对局不可达(_show_debug_overlay 门禁护栏+对局发起随开随收)/P4 可扩展列表。**✅ 已全批落籍(2026-10-05,worktree iter145-debug-hub 两提交 48c0b34/46dadbb,主区 merge --no-ff d0a3c6b/10c301b,台账 352)**:闸=冒烟 747/0+探针 ui_tune/ui_click/ui 三绿(worktree+主区双跑,主区跑前 --import 重刷类名缓存在册坑);遗留=实机目检归用户(DS_DEBUG=1 启动→右下角角标→浮窗四区块→两层调试入口) | 迭代 14 出口(注:本卡先于迭代 14 出口落籍——编入时点迭代 14 ③已闭/①②④⑤在飞/⑥挂起,门列仅记编入时点状态,不构成追溯闸) | 单批已落地(原估 0.5d,实际一次会话);后续扩调试项=debug_overlay.gd _build() 列表区追加区块(P4 扩展口径) |
|
||||
| 迭代 15 | **①调试功能整合批(2026-10-05 用户令自「14.5」临时卡改编入册——原周期外 0.5 卡,落地事实与验证读数零变化,只改编号归属)**:主菜单三调试散件(随机种子输入框/角色数值调整板/两层调试入口)收一张调试浮窗 DebugOverlay——入口=开始覆盖层右下角「调试」角标(与主按钮组非平级,DS_DEBUG=1 环境变量门控沿用迭代 8 卡④口径);浮窗=悬浮菜单之上 Dialog(不隐藏开始层,同确认弹窗形态;旧 TunePanel「与开始层互斥」形态与类整体吸收退役含 .uid);可扩展滚动列表页四区块(随机种子/数值调整/批量模拟/两层调试入口——后续调试项往下追加滚轮下探)。四拍板全落(2026-10-04 用户裁)=P1 甲 DS_DEBUG 门控/P2 乙全摊平/P3 仅开始菜单可开·对局不可达(_show_debug_overlay 门禁护栏+对局发起随开随收)/P4 可扩展列表。**✅ 已全批落籍(2026-10-05,worktree iter145-debug-hub 两提交 48c0b34/46dadbb,主区 merge --no-ff d0a3c6b/10c301b,台账 352)**:闸=冒烟 747/0+探针 ui_tune/ui_click/ui 三绿(worktree+主区双跑,主区跑前 --import 重刷类名缓存在册坑);遗留=实机目检归用户(DS_DEBUG=1 启动→右下角角标→浮窗四区块→两层调试入口) | 卡①门:迭代 14 出口(注:本卡先于迭代 14 出口落籍——编入时点迭代 14 ③已闭/①②④⑤在飞/⑥挂起,门列仅记编入时点状态,不构成追溯闸) | 单批已落地(原估 0.5d,实际一次会话);后续扩调试项=debug_overlay.gd _build() 列表区追加区块(P4 扩展口径) |
|
||||
| 迭代 15 | **②奇物概念收口与词族对齐批(2026-10-05 用户令编入本迭代)**:概念层已由用户逐轮裁定定稿(《奇物》v1.0→v2.7,7 轮),本批只做**落地对齐**、不做二次设计。三批内容:**①三套旧词族全面对齐**(顶层已改名「奇物」而代码仍叫旧名=用户最初抱怨的"文档与代码分开"):`feature_*`→`curio_*`(103 处/7 文件)、`relic_*`→`feat_*`(162 处/12 文件)、运行层 `bonus_*`→`curio_*`(160 处/8 文件)。**硬约束:`reward_*` 已被 `reward_pick`/`reward_node`/`reward_preview` 占用,统一词族不得使用**;`relic_table.gd` 与两个控制器类改名须同步 Godot `.uid`/`.tscn`(非文本层无法自证)。**②三条渠道按分类分离**(现行三渠道共用同一个 98 张池、三类混编):关底 Boss 击败=通过这一关→只出专长;奖励节点/商店→属性值提升+资源、专长在此**只以门票形式**出现。**兑付频率红线**:奇物不是打一场战斗给一份,关内普通战斗节点打完不给任何奇物,一关之内只兑付一次(用户 2026-10-05 纠错)。**③两个新种类入池**=刷新次数(须先与"商店独立刷新机制"划清边界)+ 专长获取门票(拿到即开不可囤积/罕见只在概率/一局限购一次/计步保底:连续 5 次三选一展示未出→第 6 次必出,刷新重展计入、奖励节点与商店共享计数);附带 `shop.tres` 补回复(默认原则要求分类内成员都在该出现的渠道池里)与 charge 标签补至 ≥4 件(现仅 3 件,档二永远达不到——数据缺陷)。设计事实源=`design/gdd/systems/冒险循环/奇物.md` v2.7,任务书=`design/research/任务书-奇物词族对齐与渠道分离批-2026-10-05.md`(T0-T8≈4.5d,两段切分预案在册〔段一词族 T0-T3≈2d/段二渠道+入表 T4-T8≈2.5d〕,切分点=T3 出口;11 条设计契约含 6 条 🔴 停机级;12 条批末验收断言;代拍板白名单 5 项;待用户裁点 4 项〔玩家可见面违规/第四关档二复裁/门票四参数终值/存档键正式迁移〕)。**开工门**:与在途 M-4 各批(判式换代/全局变异/配比预设)撞同一批文件(`adventure_table.gd`/`level_runner.gd`/`adventure.tres`),须确认不并行或用户明示插队 | 卡②门:迭代 14 出口 | 卡①已落籍(原估 0.5d);卡②T0-T8≈4.5d(可两段切分:词族对齐段 + 渠道入表段) |
|
||||
|
||||
## 执行纪律(2026-09-27 用户立规)
|
||||
|
||||
1. **一迭代一 loop**:所有更改任务(功能/文档/数值/素材接线)一律进本路线图的迭代,每迭代先立计划书再开工,一个迭代一次合并登记——**零散并行会话退场**(多会话并行 = 冲突源+介入成本;2026-09-27 起单迭代串行执行)。台账记「批」= 本文件记「迭代」,同物异名。
|
||||
|
||||
Reference in new issue
Block a user