Files
gplan-2/game/data/schemas/attunement_growth_table.gd
T
DKChan a6a2bf885e 迭代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 令)
2026-10-03 15:41:30 +08:00

82 lines
4.2 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 击杀数」经数据驱动的里程碑谓词表实时求值,
# 试玩后调增长曲线 = 改表不动码(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)