TP0令牌池落地(迭代12条件卡——node-reward v2.2追认b实施批):三选一池改固定配额令牌池70/25/3=98张(罕见档道具件2席随aux池种退役收窄=台账自决披露项;schema validate结构锚硬断言)+抽签Fisher-Yates同kind去重+选中踢池未选回池+池耗即枯竭+种类次数上限退役+恢复件+6新入池rare档+数值对全落;MC策略316-f落地(autoplay 1级最稀有/2级最左_pick_token单点);货架=令牌级抽签价格tier-blind维持批②裁定+消费在架令牌本体;断点扩键bonus_deck余库逐枚还原(旧断点缺键=满库重建防御单版本周期);跨表校验⑥改令牌配额检查;文档四正主=node-reward v2.4+冒险结构v0.14+registry+06落地状态;normal档重锚runsum_m4iter12_tp0_n20_20261003(seed0=90000配对读数同带0/5/0零结构位移+316-f构成佐证)——闸=冒烟670/0三闸+run_all 15套+探针五绿click存量红零新增+doc三闸零新增+熵增PASS

This commit is contained in:
DKChan committed 2026-10-04 00:17:39 +08:00
1 parent cc34531048
commit fd6a8325f0
14 files changed
+525 -303

No files matched your search

+103 -65
View File
@@ -1,94 +1,132 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# Validation Question: 三关连探冒险(地精洞窟 → 幽暗地域 → 灰矮人矿城)能否以一条命走完,通关兑付的
# 部分回血与提升三选一、Boss 逐杀钥石掉落在冒险摘要里成立(P0)
# Date: 2026-09-21(冒险结构实现批建表;2026-10-01 迭代 10 奖励重构批扩列——registry adventure_table 条目同批改写)
# Date: 2026-09-21(冒险结构实现批建表;2026-10-01 迭代 10 奖励重构批扩列;2026-10-03 TP0 令牌池换代)
# 数据配置 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,不在本表)。
# 迭代 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
## 三选一提升池件 id 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。
## aux_item 池种退役(迭代 11 第①批 T7——同调批出池:魔法道具件改走营地同调装配面,不入三选一牌库)
const BONUS_IDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap"]
## 无次数上限件的 cap 哨兵值(gp——牌库恒非空的结构保证)
const BONUS_CAP_UNLIMITED := -1
## 三选一提升池 kind 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。
## aux_item 池种退役(迭代 11 第①批 T7——同调批出池);heal 恢复件新入池(v2.2 令牌池追认 b)。
const BONUS_IDS: 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 魔法数结构化:自 adventure_runner 抽签字面量 3 收口进表;
# 默认 3 = 现行行为零改动——加权洗牌不放回掷 N 的 N,改值须重扫三选一体验与牌库剔除节奏)——
@export var bonus_candidate_count: int = 3 # [1,6] knob——候选数上界受 BONUS_IDS 词表封闭约束
# —— 三选一候选数(2026-10-02 修复批 T2 魔法数结构化)——
@export var bonus_candidate_count: int = 3 # [1,6] knob——令牌洗牌不放回抽取张数上界
# —— 三选一件值(兑付面)——
@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 袋定额入钱包
# —— 令牌配额(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 席位随池种退役收窄)
# —— 令牌件值(小/大数值对——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 件每场战斗首轮行动点基线增量
# —— 三选一权重(加权洗牌不放回,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
## 令牌配额读数(未列 kind×tier 组合 = 0——heal 无普通档/ap 无普通稀有档按 v2.2 构成)
func bonus_token_count(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
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
## 令牌件值(kind × tier;v2.2 数值对——小/大两档)
func bonus_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
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
## 档位判读序(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 BONUS_IDS:
total += bonus_token_count(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 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]})
for kind in BONUS_IDS:
for tier in TIERS:
var c := bonus_token_count(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)
if v < 0 or v > 999:
errs.append({"category": "domain", "message": "bonus_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})
return errs
+30 -19
View File
@@ -5,29 +5,40 @@
[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
bonus_weight_attack = 3
bonus_weight_max_hp = 3
bonus_weight_armor = 3
bonus_weight_gp = 3
bonus_weight_ap = 1
bonus_cap_attack = 3
bonus_cap_max_hp = 3
bonus_cap_armor = 3
bonus_cap_ap = 2
; 迭代 10 奖励重构批(2026-10-01 扩列——registry adventure_table 条目同批改写):
; 大奖励 = 非末关通关恰一次:部分回血(clear_heal_pct,封顶上限不回满、满血回 0 合法)
; + 提升三选一(池六种加权洗牌不放回 E-S weight-key 掷 3,玩家点选兑付恰一件;消费 reward_pick 封闭流)。
; 权重:属性/GP 各 3、AP 1;次数上限:属性件各 3、AP 件 2(达上限件先剔牌库)——gp 无次数上限。
; 迭代 11 第①批 同调实施批 T7(2026-10-03):aux_item 池种退役出三选一牌库(bonus_weight_aux/
; bonus_aux_item_count 两字段随批退役);transitional_sync_slots 过渡键退役(正主 = attunement_growth.tres
; 谓词表求值,Attunement.slots——迭代 10 欠账③清偿)。
; TP0 令牌池换代(2026-10-03,node-reward v2.2 追认 b 落地):三选一池 = 固定配额令牌池——
; 普通 70/稀有 25/罕见 3 = 98 张(罕见档原列「道具件 2」随 aux_item 池种退役收窄——台账自决披露项);
; 洗牌不放回抽 3、选中踢池未选回池、池耗即枯竭;
; 种类次数上限退役(池消耗即上限;货架库存同账本=牌库剩余令牌数)。
; 档位构成:普通〔小GP 18/小增伤 18/小护甲 17/小生命 17〕+ 稀有〔大GP/大增伤/大护甲/大生命/恢复 各 5〕
; + 罕见〔AP 3〕——罕见档原列「道具件 2」随 aux_item 池种退役(迭代 11 第①批 T7)不投放。
; 数值对:小GP 20/大GP 50、小增伤 +1/大 +2、小护甲 +1/大 +2、小生命 +5/大 +10、恢复 +6(当即回血)、AP +1。
; 恢复件 = 新入池种类(rare 档)。
; 退役字段:bonus_weight_*(E-S 权重族)/ bonus_cap_*(种类次数上限族)/ BONUS_CAP_UNLIMITED 哨兵——
; 洗牌改令牌 Fisher-Yates(不放回抽 3,消费 reward_pick 封闭流)。
; 迭代 11 第②批 商店共享池注记:货架 = 令牌级抽签(同 kind 去重每 kind 至多一卡、价格公式 tier-blind
; ceil(基价×b^(关序−1)×A^visit) 维持批②裁定、购买消费在架令牌本体)。
; 末关通关不发三选一与回血(奖励只朝下一战生效)。
; 退役字段:level_clear_hp_bonus(血回满+上限提升件)、keystone_per_level(钥石改 Boss/精英击杀掉落,行值归 meta.tres boss_keystone)、
; transitional_sync_slots / bonus_weight_aux / bonus_aux_item_count(本批 T7 退役三件)。
; 全部 provisional-pending-曲线调参批(值锚与上调约束归 难度曲线与Boss;回血 20% 系难度上压方向,带重扫随批呈报)。
; 全部 provisional-pending-曲线调参批(值锚与上调约束归 难度曲线与Boss;档位配额总量 70/25/5 系追认 b
; 结构锚——schema validate 硬断言,改总量须重裁)。