- T1 表与schema:attunement_growth.tres 谓词表(m1/m2/m3+Σgrant≤slot_cap 校验+slots() 求值口径)+道具表扩列(form/charges/slot_cost/unlock_requires/effective_rounds/charge_n+effect_kinds 九kind+KEY_WHITELIST 零裸flat护栏)+七同调行 - T2 save v4(boss_kill_count 收束入账+attunement_equipped+attune_refresh_level+断点 attunement_charges+迁移链 v3→v4) - T3 Attunement 求值服务(纯函数零 await 零 RNG) - T4 营地装配覆盖层(工坊扩容程序占位+Y 升级行 attune_refresh_upgrade 行族) - T5 被动六件接线+装配注入链+刷新 X/Y 双源(BonusPickOverlay 刷新钮,autoplay 默认不刷) - T6 掘进蓄能全链+摆钟能力面(骑库存面差额注入+断点充能键);炸格 P5 甲影响评估破面大→用户裁拆后批,blast_kit deferred 留位 - T7 退役面五件(BONUS_IDS 除名 aux_item+transitional_sync_slots 过渡键退役=迭代10欠账③清偿+授予路/四容量闸拆除+nest_pendulum 换装 active_charged) - T8 冒烟六新断言(645/0)+MC attune 开关+贪心画像分层 off/on 各 N=60 双策略(on 画像功率显著带平移归调参批;off 新锚=对拍正主留盘主区 sim-data,81000 降批入口基准) - T9 连带修订九件(魔法道具定位重写/元进度v1.6/地图战斗资源v0.16/行动经济v0.7/05不做v1.3/关卡节点地图v1.4/node-reward v2.2/registry 三处/06 收口+炸格拆后批新条) - T10 重闸全绿:冒烟 645/0+熵增 PASS+doc 三闸零新增+MC off 复跑同种子逐位一致 PASS;出口人闸后移迭代 12(用户 2026-10-03 令)
95 lines
5.2 KiB
GDScript
95 lines
5.2 KiB
GDScript
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||
# Validation Question: 三关连探冒险(地精洞窟 → 幽暗地域 → 灰矮人矿城)能否以一条命走完,通关兑付的
|
||
# 部分回血与提升三选一、Boss 逐杀钥石掉落在冒险摘要里成立(P0)
|
||
# Date: 2026-09-21(冒险结构实现批建表;2026-10-01 迭代 10 奖励重构批扩列——registry adventure_table 条目同批改写)
|
||
# 数据配置 AdventureTable schema(冒险结构 关卡大奖励行值;单行全局,Rule 4 豁免——HeroTable/SettlementTable 先例)。
|
||
# 迭代 10 重构(2026-09-30 用户拍板案丙):大奖励「固定三件套」退役——level_clear_hp_bonus(血回满+上限提升件)
|
||
# 与 keystone_per_level(钥石每关入账)两字段退役;改三层奖励框架 = 部分回血(clear_heal_pct)+ 提升三选一
|
||
# (池六种:件值/权重/次数上限三组列)+ Boss/精英击杀钥石掉落(行值归 meta.tres boss_keystone,不在本表)。
|
||
# 全部 knob provisional-pending-曲线调参批(数值所有权归 难度曲线与Boss,上调须重扫通关率带)。
|
||
class_name AdventureTable
|
||
extends Resource
|
||
|
||
## 三选一提升池件 id 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。
|
||
## aux_item 池种退役(迭代 11 第①批 T7——同调批出池:魔法道具件改走营地同调装配面,不入三选一牌库)
|
||
const BONUS_IDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap"]
|
||
## 无次数上限件的 cap 哨兵值(gp——牌库恒非空的结构保证)
|
||
const BONUS_CAP_UNLIMITED := -1
|
||
|
||
# —— 通关部分回血(固定型,非末关通关兑付)——
|
||
@export var clear_heal_pct: int = 20 # [0,100] knob——回复生效上限的百分比,封顶上限不回满
|
||
|
||
# —— 三选一候选数(2026-10-02 修复批 T2 魔法数结构化:自 adventure_runner 抽签字面量 3 收口进表;
|
||
# 默认 3 = 现行行为零改动——加权洗牌不放回掷 N 的 N,改值须重扫三选一体验与牌库剔除节奏)——
|
||
@export var bonus_candidate_count: int = 3 # [1,6] knob——候选数上界受 BONUS_IDS 词表封闭约束
|
||
|
||
# —— 三选一件值(兑付面)——
|
||
@export var bonus_attack_flat: int = 1 # [0,999] knob——攻击轴累加(覆盖值通道)
|
||
@export var bonus_max_hp_flat: int = 5 # [0,999] knob——生命上限轴累加(不连带当前生命)
|
||
@export var bonus_armor_flat: int = 1 # [0,999] knob——护甲轴累加
|
||
@export var bonus_gp_amount: int = 20 # [0,999] knob——GP 袋定额入钱包
|
||
@export var bonus_ap_flat: int = 1 # [0,10] knob——AP 件每场战斗首轮行动点基线增量
|
||
|
||
# —— 三选一权重(加权洗牌不放回,E-S weight-key)——
|
||
@export var bonus_weight_attack: int = 3 # [1,99] knob
|
||
@export var bonus_weight_max_hp: int = 3 # [1,99] knob
|
||
@export var bonus_weight_armor: int = 3 # [1,99] knob
|
||
@export var bonus_weight_gp: int = 3 # [1,99] knob
|
||
@export var bonus_weight_ap: int = 1 # [1,99] knob——AP 件(全冒险最紧上限)
|
||
|
||
# —— 全冒险获取次数上限(达上限件先剔出牌库;gp/aux_item 无上限)——
|
||
@export var bonus_cap_attack: int = 3 # [0,99] knob
|
||
@export var bonus_cap_max_hp: int = 3 # [0,99] knob
|
||
@export var bonus_cap_armor: int = 3 # [0,99] knob
|
||
@export var bonus_cap_ap: int = 2 # [0,99] knob——全冒险最紧
|
||
|
||
|
||
func bonus_value(id: String) -> int:
|
||
match id:
|
||
"attack": return bonus_attack_flat
|
||
"max_hp": return bonus_max_hp_flat
|
||
"armor": return bonus_armor_flat
|
||
"gp": return bonus_gp_amount
|
||
"ap": return bonus_ap_flat
|
||
return 0
|
||
|
||
|
||
func bonus_weight(id: String) -> int:
|
||
match id:
|
||
"attack": return bonus_weight_attack
|
||
"max_hp": return bonus_weight_max_hp
|
||
"armor": return bonus_weight_armor
|
||
"gp": return bonus_weight_gp
|
||
"ap": return bonus_weight_ap
|
||
return 0
|
||
|
||
|
||
## 次数上限(gp 返回 BONUS_CAP_UNLIMITED = 无上限,牌库恒非空的结构保证)
|
||
func bonus_cap(id: String) -> int:
|
||
match id:
|
||
"attack": return bonus_cap_attack
|
||
"max_hp": return bonus_cap_max_hp
|
||
"armor": return bonus_cap_armor
|
||
"ap": return bonus_cap_ap
|
||
return BONUS_CAP_UNLIMITED
|
||
|
||
|
||
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 id in BONUS_IDS:
|
||
var v := bonus_value(id)
|
||
if v < 0 or v > 999:
|
||
errs.append({"category": "domain", "message": "bonus_value(%s) 越域 [0,999]: %d" % [id, v]})
|
||
var w := bonus_weight(id)
|
||
if w < 1 or w > 99:
|
||
errs.append({"category": "domain", "message": "bonus_weight(%s) 越域 [1,99]: %d" % [id, w]})
|
||
for id in ["attack", "max_hp", "armor", "ap"]:
|
||
var c := bonus_cap(id)
|
||
if c < 0 or c > 99:
|
||
errs.append({"category": "domain", "message": "bonus_cap(%s) 越域 [0,99]: %d" % [id, c]})
|
||
if bonus_candidate_count < 1 or bonus_candidate_count > BONUS_IDS.size():
|
||
errs.append({"category": "domain", "message": "bonus_candidate_count 越域 [1,%d]: %d" % [BONUS_IDS.size(), bonus_candidate_count]})
|
||
return errs
|