Files
gplan-2/game/data/schemas/relic_table.gd
T
DKChan 128078780f 奇物 v2.5:第三类定名「资源类」+ 回复归属定案
父节点定为「奇物」后,Q6(第三类命名)解锁,本批收口。

一、第三类定名「资源类」(用户拍板)
四个成员——行动点上限 / 刷新次数 / 金币 / 回复——都是可以调动、可以
花掉的余量,故名资源类。「资源」偏泛(能力资源、财富资源都叫资源),
因此在两处写死判据句,这是把泛用词收回本类定义的唯一凭据:
- 1.3 节新增专属判据:**给的是可以调动、可以花掉的余量,不是角色基础
  属性的永久抬升**。拿不准时问一句:它会不会进角色自己的属性数值?
  会进的归属性提升类,不会进、变成手里多出的次数或钱的,归资源类
- 1.5 命名出处节记明该偏泛性并指回 1.3 的判据句
(1.4 是三分类总判据,1.3 是资源类专属判据,层次不同不重复)

二、回复归属定案:留在资源类,不拆第四类
理由是它与金币同为**即时兑付**、都给的是可花掉的余量,判据完全同源。
拆出去之后第四类只剩两项,且与资源类的判据重合——分类的价值在于判据
能一刀切得开,拆一个判据同源的类只会让读者多查一张表。

三、附带修掉两处结构问题
- **1.5 段末与「### 2. 渠道轴」标题粘连**(缺换行,导致第 2 节标题被
  吞进 1.5 段落里,目录层级失真)
- entities.yaml open_questions 编号跳号(缺②、含两条已解决项③⑦),
  重排为五项:类内异质性登记 / 门票四参数无事实源 / 档二不可达延后复裁 /
  charge 仅 3 件数据缺陷 / 断点存档键换名待裁
- entities.yaml naming_note 笔误:「v2.0 曾名「奇物」」→ 修正为
  「v2.0 改名为「奖励」,v2.4 定名为「奇物」」

同步:06-待办清单(条目标题、交叉表行、待拍板项由三项减为两项、现状
描述)、02-系统清单(文档树行 + v1.8)、两个 schema 概念指路注释。
全文「资源与机会类」零残留(仅 02-系统清单 v1.5 版本历史行保留原名,
按规范版本历史不改写)。

数据层数值与表结构零变更;未 merge 回 master(本会话零测试)。
2026-10-05 05:46:54 +08:00

134 lines
8.6 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VERTICAL SLICE - NOT FOR PRODUCTION
# Validation Question: 七核心流派各 ≥3 件入局内随机渠道后,标签+档位激活引擎能否机械判「成型」、
# 专长带能否挂进令牌池稀有/罕见档随机投放(P0——迭代 12 双层 BD 实施批 T1)
# Date: 2026-10-04(双层 BD 实施批 T1——任务书五裁定稿;设计权威 双层BD体系-整合定稿-2026-10-03 v3)
# 概念指路:本表的机制类(专长),与 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 令牌永不入普通档=「挂稀有/罕见档」
# 追认 b 接线口径)/ archetype ∈ ARCHETYPES 七流派标签 / hook ∈ HOOKS 挂点枚举(结算段槽——整合定稿
# §2.1 哈迪斯恩赐槽同构)/ effects Dictionary(hook 消费参数,provisional 投值)。
# 正负双修(整合定稿 B2 判据):effects 允许负向键(cost_* 族)——纯增益件须专项论证(反例 B-3),加载期
# 仅校验键域不禁纯增益(专项论证件以 positive_only 批注登记,人工清单呈报)。
# 档位激活(整合定稿 设计工具 1——以撒套装/小骨铭文):同标签计数 ≥2→档一(流派核心规则)/≥4→档二
# (完全体);散件单体保底=每件效果独立生效,档位只做质变(反例 B-2)——引擎纯函数 RelicsEngine。
# 🔴 层级纪律(任务书红线 2):专长只走局内随机渠道(三选一/商店/格面)——本表行永不入同调位
# (aux_items 表)/局外树(T8 节点表);扫雷触发点铁律:每流派 ≥1 行 hook ∈ MINE_HOOKS(加载校验,
# 违反=红线①触碰面)。
class_name RelicTable
extends Resource
@export var rows: Array = [] # Array[Dictionary] 键 relic_id
## 流派标签词表(七核心——喂雷/淘金不在本批,R5 甲/缓议)
const ARCHETYPES := ["magic", "pierce", "normal", "dig", "flag", "charge", "devour"]
## 稀有度词表(对齐令牌池三档;投放档映射 relic→rare / rarest→rarest)
const RARITIES := ["common", "rare", "rarest"]
## 挂点枚举(结算段槽——首批 23 点位;每 hook 恰一流派域消费,T2-T6 接线)
const HOOKS := [
# 魔法流
"hero_attack_rider", # 普攻命中后追加必中魔法伤(奥术余烬/魔能共鸣)
"clamp_modifier", # 克制点直调(魔网织者/湛蓝誓约/猎手刺剑)
"first_dig_spell", # 每关首次开格必出魔法矢(魔能共鸣第二效果)
# 穿刺流
"kill_overflow", # 击杀溢出弹射(贯穿射击)
"dig_count_segments", # 开格计数转攻击段数(连珠矢)
"roll_discount", # 折扣档改写(猎弱本能前移一档)
# 普攻流
"round_dig_bonus", # 轮内安全开格数转攻击加成(矿工的执拗;踩雷清零=mine_hit 监听同口)
"hit_trade", # 命中交换(矿工重锤——正负双修原生形态)
"armor_roll_rewrite", # 免掷骰恒折扣(专注)
"heavy_debuff", # 命中重甲附加护甲裂解(碎甲震击)
# 开格流
"dig_yield_mult", # 开格产出乘区(贪婪矿灯/矿脉直觉/赌徒的血签——正负双向)
"deep_dig", # 深层资源掘取(深挖钻头——R4 甲非信息税形态:开掘额外 AP 代价)
# 标旗流
"flag_resource", # 标中雷获格面资源(雷区图谱)
"nest_aura", # 控制巢穴数转伤害光环(猎巢人)
"flag_all_hit", # 同轮全中旗伤倍增(完美布防)
"flag_strike", # 轮末旗伤开单(战旗军规——复用 board_typed)
# 蓄力流
"ap_carry", # 轮末 AP 结转蓄力(整备军备——改写 cleared 作废口径)
"charge_shield", # 蓄力层转减伤(铁壁整备)
"charge_spike", # 满层 spike(厚积薄发)
# 吞噬流
"terrain_refund", # 受地形伤掉落资源补偿(地脉采撷——伤害仍发生)
"terrain_dig_double", # 挖开伤害型地形格双产出(荆棘编织者)
"flag_neutralize", # 标中旗中和相邻伤害型地形格(净化工兵——🔴 R4 甲仅限伤害型)
"variant_counter", # 受地形伤积层轮末反打(熔火之躯——触发键不按地形种类特化)
]
## 扫雷结算触发点 hook 集(🔴 红线①承载:每流派 ≥1 行 hook 命中本集——加载校验)
const MINE_HOOKS := ["first_dig_spell", "dig_count_segments", "round_dig_bonus", "dig_yield_mult",
"deep_dig", "flag_resource", "nest_aura", "flag_all_hit", "flag_strike", "ap_carry",
"terrain_refund", "terrain_dig_double", "flag_neutralize", "variant_counter"]
## effects 键白名单(🔴 零裸 flat 同族护栏——机制轴禁无条件属性加项;键出域=加载致命)
## 全部条件触发/机制修正参数;cost_* 族=正负双修负向面
const EFFECT_KEYS := ["value", "value2", "tier_value", "per_stack", "cap", "ap_cost", "chance",
"mult", "cost_mult", "cost_flat", "polarity", "spell_kind", "segment_cap", "discount_shift",
"trade_atk", "trade_hit", "shield_per_layer", "spike_mult", "layers_to_shield",
"neutralize_range", "counter_damage", "resource_kind", "rider_kind", "note"]
func validate() -> Array:
var errs: Array = []
if rows.is_empty():
return errs # 空表合法态(T1 基建先行——T2 起逐流派填行)
var seen := {}
for row in rows:
var rid: String = row.get("relic_id", "")
if rid == "":
errs.append({"category": "domain", "message": "relic_id 空"})
continue
if seen.has(rid):
errs.append({"category": "dup_key", "message": "relic_id 重复: %s" % rid})
continue
seen[rid] = true
if String(row.get("display_name", "")) == "":
errs.append({"category": "domain", "message": "%s display_name 空" % rid})
if not RARITIES.has(String(row.get("rarity", ""))):
errs.append({"category": "enum", "message": "%s rarity 出域 %s" % [rid, str(RARITIES)]})
var arch := String(row.get("archetype", ""))
if not ARCHETYPES.has(arch):
errs.append({"category": "enum", "message": "%s archetype 出域 %s" % [rid, str(ARCHETYPES)]})
var hook := String(row.get("hook", ""))
if not HOOKS.has(hook):
errs.append({"category": "enum", "message": "%s hook 出域(挂点枚举封闭): %s" % [rid, hook]})
for k in row.keys():
if not ["relic_id", "display_name", "rarity", "archetype", "hook", "effects", "note"].has(String(k)):
errs.append({"category": "zero_flat", "message": "%s 行键出白名单: %s" % [rid, String(k)]})
var fx: Dictionary = row.get("effects", {}) as Dictionary
for ek in fx.keys():
if not EFFECT_KEYS.has(String(ek)):
errs.append({"category": "zero_flat", "message": "%s effects 键出白名单: %s(机制轴禁无条件属性加项)" % [rid, String(ek)]})
# 🔴 红线① 扫雷触发点铁律:**有行的流派**各 ≥1 行 hook ∈ MINE_HOOKS(部分填充合法——T2-T6
# 逐流派渐进;七流派全量覆盖完成度由批次一出口断言承载,加载闸不卡渐进填行)
var archs_with_rows := {}
for row in rows:
archs_with_rows[String(row.get("archetype", ""))] = true
for arch in archs_with_rows.keys():
var covered := false
for row in rows:
if String(row.get("archetype", "")) == String(arch) and MINE_HOOKS.has(String(row.get("hook", ""))):
covered = true
break
if not covered:
errs.append({"category": "load_bearing", "message": "流派 %s 无扫雷结算触发点行(🔴 红线①铁律——每流派 ≥1 件挂扫雷端)" % String(arch)})
return errs
func row_by_id(relic_id: String) -> Dictionary:
for row in rows:
if String(row.get("relic_id", "")) == relic_id:
return row
return {}