Files
gplan-2/game/data/schemas/adventure_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

142 lines
8.9 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: 三关连探冒险(地精洞窟 → 幽暗地域 → 灰矮人矿城)能否以一条命走完,通关兑付的
# 部分回血与提升三选一、Boss 逐杀钥石掉落在冒险摘要里成立(P0)
# Date: 2026-09-21(冒险结构实现批建表;2026-10-01 迭代 10 奖励重构批扩列;2026-10-03 TP0 令牌池换代)
# 数据配置 AdventureTable schema(冒险结构 关卡大奖励行值;单行全局,Rule 4 豁免——HeroTable/SettlementTable 先例)。
# 迭代 10 重构(2026-09-30 用户拍板案丙):大奖励「固定三件套」退役——改三层奖励框架。
# TP0 令牌池换代(2026-10-03 用户全裁 b——node-reward v2.2):三选一池改固定配额令牌池——普通 70/稀有 25/
# 罕见 5=100 张;洗牌不放回抽 3、选中踢池未选回池、池耗即枯竭;种类次数上限退役(池消耗即上限)。
# 档位构成:普通〔小GP 18/小增伤 18/小护甲 17/小生命 17〕+稀有〔大GP/大增伤/大护甲/大生命/恢复 各 5〕
# +罕见〔AP 3〕——罕见档原列「道具件 2」随 aux_item 池种退役(迭代 11 第①批 T7)不投放,配额缺省收窄。
# 恢复件=新入池种类(当即回血)。旧权重/次数上限字段整代退役。
# 全部 knob provisional-pending-曲线调参批(数值所有权归 难度曲线与Boss,上调须重扫通关率带)。
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 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"
const TIER_RARE := "rare"
const TIER_RAREST := "rarest"
## 档位配额结构锚(v2.2 追认 b 定稿——validate() 硬断言;改总量=重裁非调参)。
## 罕见档 5→3:原「道具件 2」席位随 aux_item 池种退役(迭代 11 第①批 T7,落地晚于追认 b)收窄,
## 池总量 100→98——TP0 台账自决+人工清单披露项。
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 feature_candidate_count: int = 3 # [1,6] knob——令牌洗牌不放回抽取张数上界
# —— 令牌配额(kind × tier 计数;未列组合 = 0——heal 只入稀有/ap 只入罕见,v2.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 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 feature_quota(kind: String, tier: String) -> int:
match [kind, tier]:
["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 feature_value(kind: String, tier: String = TIER_COMMON) -> int:
match [kind, tier]:
["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
## 档位判读序(MC 策略 316-f——1 级最稀有:rarest > rare > common;并列同档取最左由调用方稳定序保证)
func tier_rank(tier: String) -> int:
match tier:
TIER_RAREST: return 3
TIER_RARE: return 2
TIER_COMMON: return 1
return 0
## 档位令牌总数(货架/校验读面)
func tier_total(tier: String) -> int:
var total := 0
for kind in FEATURE_KINDS:
total += feature_quota(kind, tier)
return total
## 牌库总量(结构锚——罕见档随道具件退役收窄后 98 张)
func deck_total() -> int:
return tier_total(TIER_COMMON) + tier_total(TIER_RARE) + tier_total(TIER_RAREST)
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 FEATURE_KINDS:
for tier in TIERS:
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 := feature_value(kind, tier)
if v < 0 or v > 999:
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 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