迭代11第①批:魔法道具同调实施批 T0-T10 全落(重闸 645/0 + MC off 逐位 PASS)

- 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 令)
This commit is contained in:
DKChan committed 2026-10-03 15:41:30 +08:00
1 parent 02cb92a972
commit a6a2bf885e
37 files changed
+1075 -173

No files matched your search

+5 -15
View File
@@ -10,9 +10,10 @@
class_name AdventureTable
extends Resource
## 三选一提升池件 id 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)
const BONUS_IDS: Array[String] = ["attack", "max_hp", "armor", "gp", "aux_item", "ap"]
## 无次数上限件的 cap 哨兵值(gp/aux_item——牌库恒非空的结构保证)
## 三选一提升池件 id 词表(封闭——断点附随件与牌库剔除态依赖它;扩件走本表+registry 修订)。
## aux_item 池种退役(迭代 11 第①批 T7——同调批出池:魔法道具件改走营地同调装配面,不入三选一牌库)
const BONUS_IDS: Array[String] = ["attack", "max_hp", "armor", "gp", "ap"]
## 无次数上限件的 cap 哨兵值(gp——牌库恒非空的结构保证)
const BONUS_CAP_UNLIMITED := -1
# —— 通关部分回血(固定型,非末关通关兑付)——
@@ -28,14 +29,12 @@ const BONUS_CAP_UNLIMITED := -1
@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 件每场战斗首轮行动点基线增量
@export var bonus_aux_item_count: int = 1 # [1,9] knob——魔法道具件授予件数(受同调位约束)
# —— 三选一权重(加权洗牌不放回,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_aux: int = 1 # [1,99] knob——魔法道具件(受同调位约束)
@export var bonus_weight_ap: int = 1 # [1,99] knob——AP 件(全冒险最紧上限)
# —— 全冒险获取次数上限(达上限件先剔出牌库;gp/aux_item 无上限)——
@@ -44,9 +43,6 @@ const BONUS_CAP_UNLIMITED := -1
@export var bonus_cap_armor: int = 3 # [0,99] knob
@export var bonus_cap_ap: int = 2 # [0,99] knob——全冒险最紧
# —— 同调位过渡读数源(正主 = attunement_growth.tres 谓词表,同调实施批落地后切换)——
@export var transitional_sync_slots: int = 1 # [0,9] knob——道具持有上限
func bonus_value(id: String) -> int:
match id:
@@ -55,7 +51,6 @@ func bonus_value(id: String) -> int:
"armor": return bonus_armor_flat
"gp": return bonus_gp_amount
"ap": return bonus_ap_flat
"aux_item": return bonus_aux_item_count
return 0
@@ -65,12 +60,11 @@ func bonus_weight(id: String) -> int:
"max_hp": return bonus_weight_max_hp
"armor": return bonus_weight_armor
"gp": return bonus_weight_gp
"aux_item": return bonus_weight_aux
"ap": return bonus_weight_ap
return 0
## 次数上限(gp/aux_item 返回 BONUS_CAP_UNLIMITED = 无上限,牌库恒非空的结构保证)
## 次数上限(gp 返回 BONUS_CAP_UNLIMITED = 无上限,牌库恒非空的结构保证)
func bonus_cap(id: String) -> int:
match id:
"attack": return bonus_cap_attack
@@ -95,10 +89,6 @@ func validate() -> Array:
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_aux_item_count < 1 or bonus_aux_item_count > 9:
errs.append({"category": "domain", "message": "bonus_aux_item_count 越域 [1,9]: %d" % bonus_aux_item_count})
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]})
if transitional_sync_slots < 0 or transitional_sync_slots > 9:
errs.append({"category": "domain", "message": "transitional_sync_slots 越域 [0,9]: %d" % transitional_sync_slots})
return errs
@@ -0,0 +1,81 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# Validation Question: 同调位增长是否由「通关次数 + Boss 击杀数」经数据驱动的里程碑谓词表实时求值,
# 试玩后调增长曲线 = 改表不动码(proposal-magic-item-attunement-2026-09-22 §2.1 用户点名要求)
# Date: 2026-10-03(迭代 11 第①批 魔法道具同调实施批 T1——任务书 v1.1 §六 T1;设计权威底稿 proposal §2)
# 数据配置 AttunementGrowthTable schema(魔法道具 回填 owner)。
# 单行全局常量表(slot_cap + milestones 行族——AdventureTable 单行全局先例,Rule 4 豁免)。
# 行 = Dictionary:{id: String 唯一, grant: int, requires: [{key: String, threshold: int}]}——
# requires 为 (计数键, 阈值) 对的 AND 列表,全部满足即授予 grant 槽;
# 同调位读数唯一口径 = Σ已达成 grant clamp slot_cap(slots())。
# 承重契约(任务书 §三 7 + 底稿 §2.1):
# 计数键封闭枚举(COUNTER_KEYS——预留可插拔位 COUNTER_KEYS_RESERVED 本期不实现、加行即扩展不破坏
# schema);阈值 [1,999];Σgrant ≤ slot_cap(超出部分永不可达,禁);数值全 provisional 归
# 难度曲线与Boss——本表只锁形态,试玩调平衡的全部动作落在表上(改阈值/换计数键/slot_cap 加行)。
# OR/复合需求出现时升级谓词形态走任务书修订(底稿 §2.1 同款约束)。
class_name AttunementGrowthTable
extends Resource
@export var slot_cap: int = 3
@export var milestones: Array = [] # Array[Dictionary] 键 id/grant/requires
# 计数键封闭枚举(底稿 §2.1——save_file 逐域记账的键词表;T2 落 boss_kill_count 记账)
const COUNTER_KEYS := ["clear_count", "boss_kill_count"]
# 预留可插拔位(本期不实现,schema 枚举不收——底稿 §2.1 明列四件)
const COUNTER_KEYS_RESERVED := ["boss_firstkill_count", "adventure_count", "no_damage_clear_count", "run_depth_best"]
func validate() -> Array:
var errs: Array = []
if slot_cap < 0 or slot_cap > 9:
errs.append({"category": "domain", "message": "slot_cap 越域 [0,9]: %d" % slot_cap})
var seen := {}
var grant_sum := 0
for row in milestones:
var mid: String = String(row.get("id", ""))
if mid == "":
errs.append({"category": "domain", "message": "milestone id 空"})
continue
if seen.has(mid):
errs.append({"category": "dup_key", "message": "milestone id 重复: %s" % mid})
continue
seen[mid] = true
var grant: int = int(row.get("grant", 0))
if grant < 1 or grant > maxi(1, slot_cap):
errs.append({"category": "domain", "message": "%s grant 越域 [1,slot_cap=%d]: %d" % [mid, slot_cap, grant]})
grant_sum += maxi(0, grant)
var reqs: Array = row.get("requires", [])
if reqs.is_empty():
errs.append({"category": "domain", "message": "%s requires 空(无条件授予非法——里程碑必有谓词)" % mid})
var key_seen := {}
for req in reqs:
var key: String = String(req.get("key", ""))
if not COUNTER_KEYS.has(key):
errs.append({"category": "enum", "message": "%s 计数键出域 %s: %s" % [mid, str(COUNTER_KEYS), key]})
if key_seen.has(key):
errs.append({"category": "dup_key", "message": "%s 计数键重复: %s" % [mid, key]})
key_seen[key] = true
var th: int = int(req.get("threshold", 0))
if th < 1 or th > 999:
errs.append({"category": "domain", "message": "%s 阈值越域 [1,999]: %d" % [mid, th]})
if grant_sum > slot_cap:
errs.append({"category": "cross_field", "message": "Σgrant(%d) > slot_cap(%d)——超出部分永不可达,schema 禁" % [grant_sum, slot_cap]})
return errs
# 实时求值:Σ已达成 grant(谓词 = requires 全键达标;counters = {计数键: int},缺键按 0 计)
func granted_slots(counters: Dictionary) -> int:
var total := 0
for row in milestones:
var ok := true
for req in row.get("requires", []):
if int(counters.get(String(req.get("key", "")), 0)) < int(req.get("threshold", 0)):
ok = false
break
if ok:
total += maxi(0, int(row.get("grant", 0)))
return total
# 同调位读数唯一口径:Σ达成 grant clamp slot_cap(求值服务/装配覆盖层/运行期上限共读此口径)
func slots(counters: Dictionary) -> int:
return mini(granted_slots(counters), slot_cap)
@@ -0,0 +1 @@
uid://tfgsbs87xakg
+96 -6
View File
@@ -18,15 +18,39 @@
# 真视窄域——effect_kinds 含 mine_reveal 的活行 target 必须 area_3x3(真视一次最多 3×3,禁全图看雷);
# board_wide 仅恢复推理原料类——target=board_wide 的活行 effect_kinds 不得含 mine_reveal(现行无此类活行,
# 显影载体待 Alpha 重定后落位)。
# 同调实施批扩列(迭代 11 第①批 T1,2026-10-03——任务书 v1.1;设计权威 proposal-magic-item-attunement-2026-09-22):
# form ∈ {"", "passive", "active_charged"}(空 = 切片期过渡形态行——掉落/停点渠道现行承载,T7 退役;
# passive = 装配整局生效;active_charged = 每冒险充能、挖掘期发起);
# charges_per_adventure(active_charged ≥1 / passive 恒 0);slot_cost(同调行恒 1——底稿裁决 5,schema 强制);
# unlock_requires 谓词行 [{key ∈ AttunementGrowthTable.COUNTER_KEYS, threshold ∈ [1,999]}](空 = 已解锁——
# 首批全解锁合法态,底稿 §2.2 用户裁;正式解锁渠道归 元进度 道具工坊柜台);
# effective_rounds(前 N 轮限时件轮数——P4 甲表值化;仅 ap_rounds_front 行消费);
# charge_n(充能进度阈值 N——仅 ap_charge_safe 行消费)。
# 🔴 零裸 flat 结构护栏(任务书 §三 1——机制轴禁无条件属性加项):行键白名单封闭(KEY_WHITELIST 外键 =
# 加载致命)+ effect_kinds 封闭枚举只收条件触发/机制修正类 kind——任何「无条件属性加项」类效果不得以
# 新 kind 或新键入表(返工红线)。
class_name AuxItemTable
extends Resource
@export var rows: Array = [] # Array[Dictionary] 键 item_id
const DIMENSIONS := ["info", "risk", "action", "plan", "counter"]
const EFFECT_KINDS := ["mine_reveal", "reward_preview", "ap_grant"]
# 同调批扩 enum(迭代 11 第①批 T1)——新增九 kind 全部条件触发/机制修正类;mine_reveal/ap_grant 语义不变。
# cell_removal = 爆破工兵包中立移除格(T7 原位换装时启用——T6 影响评估前置);mine_hit_halve 系固定
# 「减半」语义不消费 magnitude(反弹 N 由 reflect_damage 行 magnitude 承载)。
const EFFECT_KINDS := ["mine_reveal", "reward_preview", "ap_grant", "venom_rider", "flag_burst",
"mine_hit_halve", "reflect_damage", "ap_rounds_front", "ap_charge_safe", "cell_removal",
"reward_weight_bias", "bonus_refresh"]
const TARGETS := ["none", "area_3x3", "board_wide"]
const USE_PHASES := ["active_dig"]
const FORMS := ["", "passive", "active_charged"]
# magnitude 消费面(≥1 校验):ap_grant 与同调 N 值 kind;其余 kind 活行 magnitude 恒 0
const MAGNITUDE_KINDS := ["ap_grant", "venom_rider", "flag_burst", "reflect_damage", "ap_rounds_front",
"ap_charge_safe", "reward_weight_bias", "bonus_refresh"]
# 🔴 零裸 flat 结构护栏:行键白名单封闭(键出域=加载致命)——机制轴禁无条件属性加项的表结构承载
const KEY_WHITELIST := ["item_id", "display_name", "dimension_tags", "effect_kinds", "target",
"magnitude", "use_phase", "retired", "deferred", "form", "charges_per_adventure", "slot_cost",
"unlock_requires", "effective_rounds", "charge_n"]
func validate() -> Array:
@@ -62,6 +86,13 @@ func validate() -> Array:
var phase: String = String(row.get("use_phase", "active_dig"))
if not USE_PHASES.has(phase):
errs.append({"category": "enum", "message": "%s use_phase 出域 %s: %s" % [iid, str(USE_PHASES), phase]})
# 🔴 零裸 flat 结构护栏:键白名单封闭(同调批 T1——机制轴禁无条件属性加项)
for k in row.keys():
if not KEY_WHITELIST.has(String(k)):
errs.append({"category": "zero_flat", "message": "%s 行键出白名单: %s(KEY_WHITELIST 外键禁入)" % [iid, String(k)]})
var form: String = String(row.get("form", ""))
if not FORMS.has(form):
errs.append({"category": "enum", "message": "%s form 出域 %s: %s" % [iid, str(FORMS), form]})
if retired or deferred:
# 退役/失义行:免 effect_kinds 非空与承重护栏校验(登记面保留,不入投放与 F2)
continue
@@ -82,17 +113,76 @@ func validate() -> Array:
# 承重护栏②board_wide 仅恢复推理类:全图域行禁替推理效果
if target == "board_wide" and kind_seen.has("mine_reveal"):
errs.append({"category": "load_bearing", "message": "%s board_wide 行 effect_kinds 不得含 mine_reveal(全图域仅恢复推理原料类——Alpha 重定后落位)" % iid})
# magnitude:仅 ap_grant 行消费(≥1);非 ap_grant 活行恒 0
# magnitude:MAGNITUDE_KINDS 行消费(≥1);其余活行恒 0(同调批 T1——消费面自 ap_grant 扩至 N 值 kind)
var mag: int = int(row.get("magnitude", 0))
if mag < 0 or mag > 999:
errs.append({"category": "domain", "message": "%s magnitude 越域 [0,999]: %d" % [iid, mag]})
if kind_seen.has("ap_grant") and mag < 1:
errs.append({"category": "cross_field", "message": "%s ap_grant 行 magnitude 应 ≥1,实得 %d" % [iid, mag]})
if not kind_seen.has("ap_grant") and mag != 0:
errs.append({"category": "cross_field", "message": "%s 非 ap_grant 活行 magnitude 应 0,实得 %d" % [iid, mag]})
var mag_consuming := false
for k in kind_seen.keys():
if MAGNITUDE_KINDS.has(String(k)):
mag_consuming = true
if mag_consuming and mag < 1:
errs.append({"category": "cross_field", "message": "%s N 值 kind 行 magnitude 应 ≥1,实得 %d" % [iid, mag]})
if not mag_consuming and mag != 0:
errs.append({"category": "cross_field", "message": "%s 非 N 值 kind 活行 magnitude 应 0,实得 %d" % [iid, mag]})
# ---- 同调行约束(form 非空——装配面;过渡行 form="" 不校验)----
if form != "":
if int(row.get("slot_cost", 1)) != 1:
errs.append({"category": "load_bearing", "message": "%s 同调占位统一 1 槽(slot_cost 恒 1——底稿裁决 5,schema 强制)" % iid})
var charges: int = int(row.get("charges_per_adventure", 0))
if form == "passive" and charges != 0:
errs.append({"category": "cross_field", "message": "%s passive 行 charges_per_adventure 应 0,实得 %d" % [iid, charges]})
if form == "active_charged" and charges < 1:
errs.append({"category": "cross_field", "message": "%s active_charged 行 charges_per_adventure 应 ≥1,实得 %d" % [iid, charges]})
var eff_rounds: int = int(row.get("effective_rounds", 0))
if eff_rounds < 0 or eff_rounds > 999:
errs.append({"category": "domain", "message": "%s effective_rounds 越域 [0,999]: %d" % [iid, eff_rounds]})
if kind_seen.has("ap_rounds_front") and eff_rounds < 1:
errs.append({"category": "cross_field", "message": "%s ap_rounds_front 行 effective_rounds 应 ≥1(P4 甲表值化),实得 %d" % [iid, eff_rounds]})
if not kind_seen.has("ap_rounds_front") and eff_rounds != 0:
errs.append({"category": "cross_field", "message": "%s 非 ap_rounds_front 行 effective_rounds 应 0,实得 %d" % [iid, eff_rounds]})
var charge_n: int = int(row.get("charge_n", 0))
if charge_n < 0 or charge_n > 999:
errs.append({"category": "domain", "message": "%s charge_n 越域 [0,999]: %d" % [iid, charge_n]})
if kind_seen.has("ap_charge_safe") and charge_n < 1:
errs.append({"category": "cross_field", "message": "%s ap_charge_safe 行 charge_n 应 ≥1(每次充能需 N 安全格),实得 %d" % [iid, charge_n]})
if not kind_seen.has("ap_charge_safe") and charge_n != 0:
errs.append({"category": "cross_field", "message": "%s 非 ap_charge_safe 行 charge_n 应 0,实得 %d" % [iid, charge_n]})
# unlock_requires 谓词行:空 = 已解锁(首批全解锁合法态,底稿 §2.2);非空键 ∈ 计数键封闭枚举
var ureqs: Array = row.get("unlock_requires", [])
var ukeys := {}
for req in ureqs:
var ukey: String = String(req.get("key", ""))
if not AttunementGrowthTable.COUNTER_KEYS.has(ukey):
errs.append({"category": "enum", "message": "%s unlock_requires 计数键出域 %s: %s" % [iid, str(AttunementGrowthTable.COUNTER_KEYS), ukey]})
if ukeys.has(ukey):
errs.append({"category": "dup_key", "message": "%s unlock_requires 计数键重复: %s" % [iid, ukey]})
ukeys[ukey] = true
var uth: int = int(req.get("threshold", 0))
if uth < 1 or uth > 999:
errs.append({"category": "domain", "message": "%s unlock_requires 阈值越域 [1,999]: %d" % [iid, uth]})
return errs
# 同调行词表(form 非空)——装配覆盖层/效果接线/同调位上限的唯一取数口径(迭代 11 第①批 T1)
func attunement_rows() -> Array:
var out: Array = []
for row in rows:
if String(row.get("form", "")) != "" and not bool(row.get("retired", false)) and not bool(row.get("deferred", false)):
out.append(row)
return out
# 过渡行词表(form 空 = 切片期过渡形态活行)——掉落投放/停点池/过渡覆盖面的取数口径;
# 同调行永不入过渡渠道。T7 退役面切换后本口径随渠道消亡。
func transitional_rows() -> Array:
var out: Array = []
for row in rows:
if String(row.get("form", "")) == "" and not bool(row.get("retired", false)) and not bool(row.get("deferred", false)):
out.append(row)
return out
# 活行词表(非 retired 非 deferred)——投放校验/奖励节点池/F2 覆盖面的唯一取数口径
func active_rows() -> Array:
var out: Array = []
+23 -2
View File
@@ -12,6 +12,8 @@
# 达标 clear_threshold——2026-09-20 排期裁决;局内效果整体归 Alpha 魔法道具重设计批,本表只有解锁状态面)。
# conversion = 区间平移换算率行(attr 与 forge 词表一致恰三;per_level_shift_pct ∈ [0,100]——
# registry 键 meta_progression_conversion_table;护甲行强条目:验收读数必须按解锁后参数重测)。
# attune_refresh_upgrade = Y 刷新升级行族(迭代 11 第①批 T4——P1 甲:每冒险开局给 Y 次、冒险周期池、
# 用完即无;level 连续从 1,等级 L → refresh_charges=Y 表值,钥石直购 keystone_cost;数值全 provisional)。
# 行值全部 provisional 归 元进度设计批配读数(用户拍板骨架先行,先例 = GP+商店房批)。
class_name MetaTable
extends Resource
@@ -20,6 +22,7 @@ extends Resource
@export var boss_keystone: Array[Dictionary] = [] # Array[Dictionary] 键 level_index
@export var workshop_items: Array[Dictionary] = [] # Array[Dictionary] 键 item_id
@export var conversion: Array[Dictionary] = [] # Array[Dictionary] 键 attr
@export var attune_refresh_upgrade: Array[Dictionary] = [] # Array[Dictionary] 键 level——Y 刷新升级行族(迭代 11 第①批 T4)
const FORGE_ATTRS := ["max_hp", "atk", "armor_class"]
const WORKSHOP_ITEM_IDS := ["probe_dust", "sapper_order", "loot_compass", "nest_pendulum", "catacomb_scroll", "blast_kit"]
@@ -31,8 +34,8 @@ const WORKSHOP_CHANNELS := ["total_clears"]
func validate() -> Array:
var errs: Array[Dictionary] = []
# 行族空护栏(四族皆为 ConfigDB 消费面——缺族即致命)
for family in ["forge_products", "boss_keystone", "workshop_items", "conversion"]:
# 行族空护栏(五族皆为 ConfigDB 消费面——缺族即致命)
for family in ["forge_products", "boss_keystone", "workshop_items", "conversion", "attune_refresh_upgrade"]:
if get(family).is_empty():
errs.append({"category": "empty_table", "message": "MetaTable 行族为空: %s" % family})
# forge_products:attr 词表封闭 + 唯一 + 覆盖恰三(注入契约三字段必齐)+ flat/价格域 + 公比域 [100,400]
@@ -115,4 +118,22 @@ func validate() -> Array:
for conv_key in FORGE_ATTRS:
if not seen_conv.has(conv_key):
errs.append({"category": "coverage", "message": "conversion 缺属性行: %s(三行与 forge 词表一致)" % conv_key})
# attune_refresh_upgrade:level 唯一 + 连续从 1 + charges/cost 域(迭代 11 第①批 T4)
var seen_al := {}
for row in attune_refresh_upgrade:
var al: int = int(row.get("level", -1))
if seen_al.has(al):
errs.append({"category": "dup_key", "message": "attune_refresh_upgrade level 重复: %d" % al})
seen_al[al] = true
var ach: int = int(row.get("refresh_charges", -1))
if ach < 1 or ach > 9:
errs.append({"category": "domain", "message": "attune_refresh_upgrade L%d refresh_charges 越域 [1,9]: %d" % [al, ach]})
var acost: int = int(row.get("keystone_cost", -1))
if acost < 1 or acost > 999:
errs.append({"category": "domain", "message": "attune_refresh_upgrade L%d keystone_cost 越域 [1,999]: %d" % [al, acost]})
for i in attune_refresh_upgrade.size():
var al_at: int = int(attune_refresh_upgrade[i].get("level", 0))
if al_at != i + 1:
errs.append({"category": "structural", "message": "attune_refresh_upgrade level 不连续(须从 1 连续递增): 位 %d = %d" % [i + 1, al_at]})
break
return errs
+6 -6
View File
@@ -10,24 +10,24 @@ bonus_max_hp_flat = 5
bonus_armor_flat = 1
bonus_gp_amount = 20
bonus_ap_flat = 1
bonus_aux_item_count = 1
bonus_weight_attack = 3
bonus_weight_max_hp = 3
bonus_weight_armor = 3
bonus_weight_gp = 3
bonus_weight_aux = 1
bonus_weight_ap = 1
bonus_cap_attack = 3
bonus_cap_max_hp = 3
bonus_cap_armor = 3
bonus_cap_ap = 2
transitional_sync_slots = 1
; 迭代 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/道具无次数上限。
; 同调位过渡键 transitional_sync_slots=1(道具持有上限;正主 = attunement_growth.tres 谓词表,同调实施批切换)。
; 权重:属性/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 欠账③清偿)。
; 末关通关不发三选一与回血(奖励只朝下一战生效)。
; 退役字段:level_clear_hp_bonus(血回满+上限提升件)、keystone_per_level(钥石改 Boss/精英击杀掉落,行值归 meta.tres boss_keystone)。
; 退役字段: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% 系难度上压方向,带重扫随批呈报)。
+34
View File
@@ -0,0 +1,34 @@
[gd_resource type="Resource" script_class="AttunementGrowthTable" load_steps=2 format=3]
[ext_resource type="Script" path="res://data/schemas/attunement_growth_table.gd" id="1"]
; 迭代 11 第①批 同调实施批 T1(2026-10-03)——同调位里程碑谓词表。
; 数值全 provisional 归 难度曲线与Boss(任务书 §三 7);行形态 = 底稿 §2.1 示意形态。
[resource]
script = ExtResource("1")
slot_cap = 3
milestones = [{
"id": "m1",
"grant": 1,
"requires": [{
"key": "clear_count",
"threshold": 1
}]
}, {
"id": "m2",
"grant": 1,
"requires": [{
"key": "boss_kill_count",
"threshold": 3
}]
}, {
"id": "m3",
"grant": 1,
"requires": [{
"key": "clear_count",
"threshold": 3
}, {
"key": "boss_kill_count",
"threshold": 6
}]
}]
+83 -3
View File
@@ -4,6 +4,8 @@
[resource]
script = ExtResource("1")
; 迭代 11 第①批 T1(2026-10-03):追加七件同调行(form 非空——永不入过渡渠道);值全 provisional 归 难度曲线与Boss。
; nest_pendulum/blast_kit 维持过渡行,T7 渠道退役时原位换装 form=active_charged;sapper_order/显影尘/地穴全图卷/罗盘 T7 逐件销账。
rows = [{
"item_id": "probe_dust",
"display_name": "显影尘",
@@ -20,7 +22,8 @@ rows = [{
"effect_kinds": ["ap_grant"],
"target": "none",
"magnitude": 2,
"use_phase": "active_dig"
"use_phase": "active_dig",
"retired": true
}, {
"item_id": "loot_compass",
"display_name": "探宝罗盘",
@@ -37,7 +40,10 @@ rows = [{
"effect_kinds": ["mine_reveal"],
"target": "area_3x3",
"magnitude": 0,
"use_phase": "active_dig"
"use_phase": "active_dig",
"form": "active_charged",
"slot_cost": 1,
"charges_per_adventure": 2
}, {
"item_id": "catacomb_scroll",
"display_name": "地穴全图卷",
@@ -54,5 +60,79 @@ rows = [{
"effect_kinds": ["ap_grant", "mine_reveal"],
"target": "area_3x3",
"magnitude": 4,
"use_phase": "active_dig"
"use_phase": "active_dig",
"deferred": true
}, {
"item_id": "venom_edge",
"display_name": "淬毒刃纹",
"dimension_tags": ["counter"],
"effect_kinds": ["venom_rider"],
"target": "none",
"magnitude": 2,
"use_phase": "active_dig",
"form": "passive",
"slot_cost": 1
}, {
"item_id": "flag_burst",
"display_name": "标中殉爆",
"dimension_tags": ["action"],
"effect_kinds": ["flag_burst"],
"target": "none",
"magnitude": 2,
"use_phase": "active_dig",
"form": "passive",
"slot_cost": 1
}, {
"item_id": "nest_counter",
"display_name": "惊巢反制",
"dimension_tags": ["risk"],
"effect_kinds": ["mine_hit_halve", "reflect_damage"],
"target": "none",
"magnitude": 2,
"use_phase": "active_dig",
"form": "passive",
"slot_cost": 1
}, {
"item_id": "dawn_order",
"display_name": "工兵晨令",
"dimension_tags": ["action"],
"effect_kinds": ["ap_rounds_front"],
"target": "none",
"magnitude": 1,
"use_phase": "active_dig",
"form": "passive",
"slot_cost": 1,
"effective_rounds": 3
}, {
"item_id": "dig_charge",
"display_name": "掘进蓄能",
"dimension_tags": ["action"],
"effect_kinds": ["ap_charge_safe"],
"target": "none",
"magnitude": 1,
"use_phase": "active_dig",
"form": "active_charged",
"slot_cost": 1,
"charges_per_adventure": 2,
"charge_n": 3
}, {
"item_id": "luck_coin",
"display_name": "偏运硬币",
"dimension_tags": ["risk"],
"effect_kinds": ["reward_weight_bias"],
"target": "none",
"magnitude": 2,
"use_phase": "active_dig",
"form": "passive",
"slot_cost": 1
}, {
"item_id": "pick_refresh",
"display_name": "三选一刷新件",
"dimension_tags": ["info"],
"effect_kinds": ["bonus_refresh"],
"target": "none",
"magnitude": 1,
"use_phase": "active_dig",
"form": "passive",
"slot_cost": 1
}]
+13
View File
@@ -77,6 +77,15 @@ conversion = [{
"attr": "armor_class",
"per_level_shift_pct": 1
}]
attune_refresh_upgrade = [{
"level": 1,
"refresh_charges": 1,
"keystone_cost": 30
}, {
"level": 2,
"refresh_charges": 2,
"keystone_cost": 60
}]
; 元进度实现批(2026-09-21,设计权威 design/gdd/systems/冒险循环/元进度.md 定稿 v1.2):
; 数值全 provisional 归元进度设计批配读数(骨架先行——元进度实现批 2026-09-21,先例 = GP+商店房批)。
@@ -107,3 +116,7 @@ conversion = [{
; 钥石渠道自本批起 =
; Boss/精英击杀逐杀掉落(大奖励 keystone_per_level 渠道退役;精英掉 1 预留行随怪物批实装落)。
; 产出结构变化 → 元进度标定义务重开(06-待办清单 2026-10-01 登记条)。provisional 归曲线调参批。
;
; 迭代 11 第①批 同调实施批 T4(2026-10-03):attune_refresh_upgrade 行族 = Y 刷新升级行(任务书 P1 甲——
; 每冒险开局给 Y 次、冒险周期池、用完即无;等级 L → Y=L 次刷新,钥石直购)。数值全 provisional 归
; 难度曲线与Boss(任务书 §三 7)。