diff --git a/design/content-archive/道具退役素材库.md b/design/content-archive/道具退役素材库.md index 84ce46f7..f70e3a6e 100644 --- a/design/content-archive/道具退役素材库.md +++ b/design/content-archive/道具退役素材库.md @@ -24,6 +24,24 @@ | probe_dust | 显影尘 | 未投值(effect_kinds 空)——设计方向=信息显影(把玩家暂时看不到的棋盘信息还给玩家) | 退役(2026-10-10 用户裁第一版全弃用) | 2026-10-10 用户裁 | | catacomb_scroll | 地穴全图卷 | 未投值(effect_kinds 空)——名义指向地穴全图揭示 | 退役(2026-10-10 用户裁第一版全弃用) | 2026-10-10 用户裁 | +## 表一附:退役效果词面留底 + +> 所属线=道具/秘宝。下列词面是旧目录时代秘宝数据行的效果类型标识,旧目录退役后不再由任何现行数据行使用;留底供日后重新准入时查证,不构成现行词表。 + +| 词面 | 关联旧件 | 旧效果 | +|---|---|---| +| mine_reveal | 探巢摆钟、爆破工兵包 | 真视 3×3 | +| reward_preview | 探宝罗盘 | 预读 3×3 | +| ap_grant | 工兵令、爆破工兵包 | 一次给 2 或 4 点行动点 | +| mine_hit_halve | 惊巢反制 | 踩雷惩罚减半 | +| reflect_damage | 惊巢反制 | 受击反弹伤害 | +| ap_rounds_front | 工兵晨令 | 开局前几轮每轮 +1 行动点 | +| cell_removal | 爆破工兵包 | 中立移除危险格(棋盘事实不可变契约下已废止) | +| reward_weight_bias | 偏运硬币 | 摇号稀有资源权重偏置 | +| bonus_refresh | 三选一刷新件 | 三选一刷新次数加算 | + +效果引擎侧另有 bias_wallet:原预期为偏运硬币在摇号上影响金币面;现行由 bias_rewards 承载摇号权重偏置、grant_gp 承载 GP 入账,该词面无独立效果。 + ## 表二 专长退役 27 件 只读引用 `game/data/tables/feats.tres` 现行 27 行(feat_id 与 display_name;效果不抄——效果以表为事实源,此处仅留名单)。 diff --git a/design/ux/node-reward.md b/design/ux/node-reward.md index 756e8404..b3752f00 100644 --- a/design/ux/node-reward.md +++ b/design/ux/node-reward.md @@ -13,7 +13,7 @@ - 载体 = 提升三选一覆盖层(与 [level-clear](level-clear.md) 共用组件——零新增交互原语)。 - 头部行:「关卡奖励点 / 从冒险牌库抽三选一(属性值提升与补给;与通关专长三选一同库分流):选择一件带走:」(旁白条目)。 - 三卡点选(✓ 高亮,确认前可改选)→「确认选择」→ 兑付反馈(选中件效果 + 丢弃提示)→「继续」→ 回图选路(零自动推进同款)。 -- **三选一刷新**(X/Y 双源;机制现行事实源=[秘宝](../gdd/systems/跨局循环/秘宝.md)「三选一刷新双源」节,X 源承载件=现行目录「刷新练习」):装配「三选一刷新件」给 X 次(每次碰三选一重给、优先消耗、不结转)+ 营地「刷新升级」给 Y 次(每冒险开局注入冒险周期池、用完即无);刷新钮余量 >0 时现形,点按重抽三候选(奖励抽取既有洗牌流,池规则全保留:不放回/达上限剔牌/掷定前置直显/停点可中断)。自动演示默认不刷(钓鱼归玩家)。 +- **三选一刷新**(X/Y 双源;机制现行事实源=[秘宝](../gdd/systems/跨局循环/秘宝.md)「三选一刷新双源」节,X 源承载件=现行目录「刷新练习」):装配「刷新练习」给 X 次(每次碰三选一重给、优先消耗、不结转)+ 营地「刷新升级」给 Y 次(每冒险开局注入冒险周期池、用完即无);刷新钮余量 >0 时现形,点按重抽三候选(奖励抽取既有洗牌流,池规则全保留:不放回/达上限剔牌/掷定前置直显/停点可中断)。自动演示默认不刷(钓鱼归玩家)。 ## 口径 diff --git a/game/core/action_economy.gd b/game/core/action_economy.gd index 6becbdfc..f2063969 100644 --- a/game/core/action_economy.gd +++ b/game/core/action_economy.gd @@ -221,7 +221,7 @@ func notify_settlement_done(next_round_mode: String) -> bool: # 下轮行动点修正排队:action 型正负行结算期调用,同轮多次授予累加; # 相位无关(授予发生在结算段,此时本类可能处于 ACTIVE/WAITING 任一相位) -# 第 9 API(registry 行动经济×① 接口漂移预授权):ap_grant 道具的 +# 第 9 API(registry 行动经济×① 接口漂移预授权):行动点授予型道具的 # 当轮行动点加量(GDD「加行动点效果给当轮」——区别于 queue_ap_delta 的下轮排队语义)。Active 受理、 # 无上限域、零随机;使用道具本身零扣费(成本在获取时已付——捡道具格不出战斗奖励)。 func grant_ap(amount: int) -> bool: diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index ec52bb49..c69039f7 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -274,15 +274,9 @@ func present_node_curio(candidates: Array) -> void: # 点选兑付(节点域——编排归停点件;呈现层直调面 T5 改 stop()) -# 刷新件余量基数(kind 分发查询——装配集内 effect_kinds 含 bonus_refresh 的行 magnitude 合计; -# 刷新件类加件零 id 分支;停点件 X 重置基数经 start/resume 预算注入) +# 刷新件余量基数(现役目录无行源——X 机制保留恒 0 空转;停点件 X 重置基数经 start/resume 预算注入) func _attune_refresh_x_total() -> int: - var total := 0 - for iid_v in _attunement: - var arow: Dictionary[Variant, Variant] = db.crossrun.treasure_items.row_by_id(String(iid_v)) - if (arow.get("effect_kinds", []) as Array).has("bonus_refresh"): - total += int(arow.get("magnitude", 0)) - return total + return 0 # 同调行投行分派(关卡域库存就位时点——每关一次;首关=种行或旧档行集为源、后续关=快照补行) diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index 38194218..da2ab380 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -156,7 +156,7 @@ func attune_has(item_id: String) -> bool: # 装备件表值读取(charge_n 等——TreasureItemTable 行;未装配不读表。 # 行值经 value_from 在 rebuild 定影,零运行期按件取值) # 装配集参数合计(常时参数面 kind 的装配集 Σmagnitude 读数口; -# kind 分发查询先例=_attune_refresh_x_total bonus_refresh。零装配=0) +# kind 分发查询同形先例见刷新账 X 基数注入面;零装配=0) func attune_param_sum(kind: String) -> int: var total := 0 for iid_v in _facts.attunement: diff --git a/game/core/effect_engine.gd b/game/core/effect_engine.gd index 56b9e75f..91afdee3 100644 --- a/game/core/effect_engine.gd +++ b/game/core/effect_engine.gd @@ -23,11 +23,11 @@ const MINE_EVENTS := ["dig_reveal", "dig_paid", "seal_hit", "mine_hit", "seal_se "refresh_request", "board_refreshed"] ## 效果类型词汇(解释器 switch 闭集——词表实数以 EFFECT_KINDS 常量为准,含共享行拆型: -## grant_gp/bias_wallet、counter_add/counter_spend、reveal_tiles/remove_mines/refresh_pick、 +## counter_add/counter_spend、reveal_tiles/remove_mines/refresh_pick、 ## bias_rewards/preview。需求卡片标题计 23 系笔误,落码按行内容全收——commit 留痕) const EFFECT_KINDS := ["add_ticket_rider", "modify_ticket", "damage_mult", "open_ticket", "attack_bonus", "yield_mult", "spawn_spell", "grant_material", - "grant_ap", "grant_gp", "bias_wallet", "shield", "apply_status", "counter_add", + "grant_ap", "grant_gp", "shield", "apply_status", "counter_add", "counter_spend", "reveal_tiles", "remove_mines", "refresh_pick", "bias_rewards", "preview", # 六型效果(奇物.md 基础件表 27 件声明清单): diff --git a/game/core/refresh_bank.gd b/game/core/refresh_bank.gd index 1259006d..eaa425d3 100644 --- a/game/core/refresh_bank.gd +++ b/game/core/refresh_bank.gd @@ -12,7 +12,7 @@ var _refresh_x := 0 # 刷新件余量(每碰三选一重 var _refresh_y := 0 # Y 冒险周期池(开局参数面注入,用完即无——营地升级行表值) var _paid_refreshes := 0 # 本次停点已付费刷新次数(对齐商店 MC-1——GP 刷新价曲线输入,随停点创建清零=与商店进店清零同构) var _refresh_stock := 0 # 刷新存量账(冒险级——刷新券加仓;**不经 _refresh_x**:X 每停点重置会吞存量=写错账缺陷 F-1) -var _refresh_x_cap := 0 # 刷新件余量基数(装配集 effect_kinds 含 bonus_refresh 的行 magnitude 合计—— +var _refresh_x_cap := 0 # 刷新件余量基数(现役目录无行源,恒 0; # 宿主冒险开始时预算注入;装配集冒险期间锁死〔契约 8〕故预算与逐停点查询等价) diff --git a/game/core/reward_grant.gd b/game/core/reward_grant.gd index 565bc045..4e198ae2 100644 --- a/game/core/reward_grant.gd +++ b/game/core/reward_grant.gd @@ -92,7 +92,7 @@ func reveal_redeem(cell: Vector2i, ri: int) -> void: # use_treasure 四步受理(registry use_orchestration 规范序——序即原子: # ① 相位 gate(Active——行动经济 phase getter)→ ② validate_use(目标校验读排雷玩法只读面,零消耗)→ # ②半 treasure_used 受理闸(counter_spend 订阅——消耗成功才受理)→ ③ 逐 kind 应用(顺序钉死:空间先、 -# ap_grant 后——effect_kinds 列表序非运行时语义)→ ④ consume。 +# 行动点授予后——effect_kinds 列表序非运行时语义)→ ④ consume。 # 拒绝全部发生在 ①②③(④合法输入下无失败路径);使用零 AP 成本(不经 try_spend)。 # 结算明细无道具行(GDD——效果即时可见:overlay 呈现+AP 条刷新;AP 过账本 grant_ap 走 _reject 面)。 func use_treasure(handle: int, target: Vector2i) -> Dictionary: @@ -141,7 +141,7 @@ func _charge_gate(v: Dictionary, target: Vector2i) -> Dictionary: return {} -# ③ 逐 kind 应用(顺序钉死:空间先、ap_grant 后;拒收字典/空字典=受理——④ consume 前零消耗分支) +# ③ 逐 kind 应用(顺序钉死:空间先、行动点授予后;拒收字典/空字典=受理——④ consume 前零消耗分支) func _apply_use_kinds(v: Dictionary, _target: Vector2i) -> Dictionary: var kinds: Array[Variant] = v.kinds if kinds.has("mine_reveal") or kinds.has("reveal_tiles"): @@ -157,10 +157,6 @@ func _apply_use_kinds(v: Dictionary, _target: Vector2i) -> Dictionary: var dig_reject := _safe_dig_open(v) if not dig_reject.is_empty(): return dig_reject - if kinds.has("cell_removal"): - var blast_reject := _cell_removal_open(v) - if not blast_reject.is_empty(): - return blast_reject return {} # 空字典=受理 @@ -180,16 +176,6 @@ func _safe_dig_open(v: Dictionary) -> Dictionary: return {} -# 中立移除兑付(未揭示/无封印/是雷过滤归排雷玩法; -# 邻接数字冻结零重算、清图分母零涉(危险格不入分母);空集拒绝零消耗—— -# consume 之前 return(拒绝面注记扩「③内零消耗分支」),拒绝 reason 可呈现) -func _cell_removal_open(v: Dictionary) -> Dictionary: - var blasted: Array[Variant] = fx_host.minesweeper.remove_mines_in(v.resolved) - if blasted.is_empty(): - return {"ok": false, "reason": "中立移除:3×3 区域内无可移除危险格(须未揭示且未封印)"} - return {} - - # 极性路由兑付(「动作 × 格型」矩阵的执行面:snap = 缓冲期冻结身份快照〔cell_type = 该格装板期 # 摇定的类型身份〕,polarity 由动作决定(开安全格/封印命中 = positive,开危险格/标错封印 = negative), # 兑付行 = 奖励字典(类型, 极性)行。返回 true = percent 行实际生效(flat 行恒 false——兑付结果由行协议承载)。 diff --git a/game/data/schemas/treasure_item_table.gd b/game/data/schemas/treasure_item_table.gd index d4891c9f..81a519e0 100644 --- a/game/data/schemas/treasure_item_table.gd +++ b/game/data/schemas/treasure_item_table.gd @@ -16,15 +16,11 @@ extends Resource const UNLOCK_COUNTER_KEYS := ["adventure_cleared", "boss_kill_count", "vision_used"] const DIMENSIONS := ["info", "risk", "action", "plan", "counter"] -# enum 九 kind 全部条件触发/机制修正类;mine_reveal/ap_grant 语义不变。 -# cell_removal = 中立移除危险格通道;mine_hit_halve 系固定 -# 「减半」语义不消费 magnitude(反弹 N 由 reflect_damage 行 magnitude 承载)。 +# enum kind 全部条件触发/机制修正类;词面只收现役效果类型。 # 主动件 kind 词族(reveal_tiles/preview/grant_ap/remove_mines/ # refresh_pick——效果引擎 ACTIVE_KINDS 同名闭集);被动件不走 effect_kinds 词族 -# (passive 行走 triggers 事件订阅形态);旧词保留共存至迁移完成。 -const EFFECT_KINDS := ["mine_reveal", "reward_preview", "ap_grant", - "mine_hit_halve", "reflect_damage", "ap_rounds_front", "ap_charge_safe", "cell_removal", - "reward_weight_bias", "bonus_refresh", +# (passive 行走 triggers 事件订阅形态)。 +const EFFECT_KINDS := ["ap_charge_safe", "reveal_tiles", "preview", "grant_ap", "remove_mines", "refresh_pick", # 以下八型: # 常时参数面六型(无事件订阅——开局/装板参数注入,注入面按装配集 kind 分发读取): @@ -45,12 +41,11 @@ const TIER_RANK := {"common": 1, "excellent": 2, "rare": 3, "legendary": 4} # 充能重置周期(现役仅 adventure=每冒险;battle=每战重置〔线香〕/level=每关重置〔天眼〕) const CHARGE_RESETS := ["adventure", "battle", "level"] # magnitude 消费面(≥1 校验):grant_ap 与同调 N 值 kind;其余 kind 活行 magnitude 恒 0 -const MAGNITUDE_KINDS := ["ap_grant", "reflect_damage", "ap_rounds_front", - "ap_charge_safe", "reward_weight_bias", "bonus_refresh", "grant_ap", +const MAGNITUDE_KINDS := ["ap_charge_safe", "grant_ap", "light_radius_bonus", "rap_transfer_mult", "dig_range_bonus", "seal_range_free", "refresh_stock_grant", "shop_refresh_bonus"] # 真视类 kind(护栏:活行 target 必须 ∈ {area_3x3, cell}:真视窄域 ≤3×3 契约) -const REVEAL_KINDS := ["mine_reveal", "reveal_tiles"] +const REVEAL_KINDS := ["reveal_tiles"] # 🔴 零裸 flat 结构护栏:行键白名单封闭(键出域=加载致命)——机制轴禁无条件属性加项的表结构承载 const KEY_WHITELIST := ["item_id", "display_name", "dimension_tags", "effect_kinds", "target", "magnitude", "use_phase", "retired", "deferred", "form", "charges_per_adventure", "slot_cost", @@ -149,13 +144,13 @@ func _validate_row_active(row: Dictionary, iid: String, kind_seen: Dictionary) - if kind_seen.has(String(rv)) and not (target == "area_3x3" or target == "cell"): errs.append({"category": "load_bearing", "message": "%s 真视窄域护栏:%s 行 target 必须 area_3x3 或 cell,实得 %s(秘宝 GDD 结构冻结)" % [iid, String(rv), target]}) # 承重护栏②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}) + if target == "board_wide" and kind_seen.has("reveal_tiles"): + errs.append({"category": "load_bearing", "message": "%s board_wide 行 effect_kinds 不得含 reveal_tiles(全图域仅恢复推理原料类——Alpha 重定后落位)" % iid}) errs.append_array(_validate_row_magnitude(row, iid, kind_seen)) return errs -## N 值语义域:magnitude 越域与 MAGNITUDE_KINDS 行消费(≥1);其余活行恒 0(同调批 T1——消费面自 ap_grant 扩至 N 值 kind) +## N 值语义域:magnitude 越域与 MAGNITUDE_KINDS 行消费(≥1);其余活行恒 0(同调批 T1——消费面覆盖 N 值 kind) func _validate_row_magnitude(row: Dictionary, iid: String, kind_seen: Dictionary) -> Array[Variant]: var errs: Array[Variant] = [] var mag: int = int(row.get("magnitude", 0)) @@ -233,10 +228,8 @@ func _validate_row_effect_numbers(row: Dictionary, iid: String, kind_seen: Dicti 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 and not row.has("triggers"): - errs.append({"category": "cross_field", "message": "%s 非 ap_rounds_front 行 effective_rounds 应 0(trigger 行=when value_from 取数源豁免),实得 %d" % [iid, eff_rounds]}) + if eff_rounds != 0 and not row.has("triggers"): + errs.append({"category": "cross_field", "message": "%s 无 triggers 行 effective_rounds 应 0(trigger 行=when value_from 取数源豁免),实得 %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]}) diff --git a/game/tests/unit/core/meta_progression_forge_test.gd b/game/tests/unit/core/meta_progression_forge_test.gd index a0ca9b50..42962161 100644 --- a/game/tests/unit/core/meta_progression_forge_test.gd +++ b/game/tests/unit/core/meta_progression_forge_test.gd @@ -313,7 +313,7 @@ func _meta_settle_and_workshop() -> void: a12.stop().refresh_curio() and a12.stop().refresh_curio() and a12.refresh_bank().refresh_y() == 0 and a12.stop().refresh_curio() == false) a12.refresh_bank().reset_x() - Kit.check("刷新 X 每碰三选一重置(不结转;新目录无 bonus_refresh 行源——X 机制保留恒 0 空转,存量加仓走 _refresh_stock=刷新练习 V8)〔秘宝批换代〕", + Kit.check("刷新 X 每碰三选一重置(不结转;现役目录无行源——X 机制保留恒 0 空转,存量加仓走 _refresh_stock=刷新练习 V8)〔秘宝批换代〕", a12.refresh_bank().free_left() == 0) # ⑬ 主菜单开局传参面(开新/续玩两入口同调三键随开局下传防回归:真实入口曾 # 三键恒空(缺陷①),冒烟夹具直呼 runner 参数面拦不住——此处直呼 main.build_adventure_params diff --git a/game/tests/unit/core/treasure_items_test.gd b/game/tests/unit/core/treasure_items_test.gd index 748e3022..17e3522e 100644 --- a/game/tests/unit/core/treasure_items_test.gd +++ b/game/tests/unit/core/treasure_items_test.gd @@ -28,11 +28,11 @@ class StubDB: func _stub_db() -> StubDB: var t := StubTable.new() t.rows = { - "sapper_order": {"item_id": "sapper_order", "display_name": "工兵令", "dimension_tags": ["action"], + "morning_order": {"item_id": "morning_order", "display_name": "晨操令", "dimension_tags": ["action"], "effect_kinds": ["ap_grant"], "target": "none", "magnitude": 2, "use_phase": "active_dig"}, - "nest_pendulum": {"item_id": "nest_pendulum", "display_name": "探巢摆钟", "dimension_tags": ["risk"], + "incense_stick": {"item_id": "incense_stick", "display_name": "线香", "dimension_tags": ["risk"], "effect_kinds": ["mine_reveal"], "target": "area_3x3", "magnitude": 0, "use_phase": "active_dig"}, - "loot_compass": {"item_id": "loot_compass", "display_name": "探宝罗盘", "dimension_tags": ["plan"], + "sky_eye": {"item_id": "sky_eye", "display_name": "天眼", "dimension_tags": ["plan"], "effect_kinds": ["reward_preview"], "target": "area_3x3", "magnitude": 0, "use_phase": "active_dig"}, } var db := StubDB.new() @@ -56,8 +56,8 @@ func _init() -> void: # 判据出处: design/gdd/systems/跨局循环/秘宝.md:246 (秘宝结构冻结与护栏校验——结构组) # ① 授予归因+受理序+Used 不可逆 var inv = _new_inv() - var r1: Dictionary = inv.add_item("sapper_order", "safe_cell", Vector2i(3, 4), 2) - var r2: Dictionary = inv.add_item("nest_pendulum", "seal_hit", Vector2i(5, 6), 3) + var r1: Dictionary = inv.add_item("morning_order", "safe_cell", Vector2i(3, 4), 2) + var r2: Dictionary = inv.add_item("incense_stick", "seal_hit", Vector2i(5, 6), 3) Kit.check_quiet(int(r1.handle) == 1 and int(r2.handle) == 2, "句柄受理序单调(1→2——零随机)") Kit.check_quiet(String(r1.source_class) == "safe_cell" and r1.origin_cell == Vector2i(3, 4) and int(r1.round_index) == 2, "授予来源可归因(source/cell/round)") @@ -73,7 +73,7 @@ func _init() -> void: "真视边缘窗口=窗口∩板(角 4 格——护栏只缩不扩)") # 预读点击级零信息:中心板内但回调恒 false(全已开)→拒绝零消耗 var inv2 = _new_inv() - var rp: Dictionary = inv2.add_item("loot_compass", "safe_cell", Vector2i(1, 1), 1) + var rp: Dictionary = inv2.add_item("sky_eye", "safe_cell", Vector2i(1, 1), 1) var v_zero: Dictionary = inv2.validate_use(int(rp.handle), Vector2i(5, 5), Vector2i(10, 10), Callable()) Kit.check_quiet(not bool(v_zero.ok) and int(inv2.inventory_count()) == 1, "预读点击级零信息拒绝(不消耗——库存不变)") @@ -97,7 +97,7 @@ func _init() -> void: var replay_b: Array = [] for rep in 2: var inv3 = _new_inv() - var h1: Dictionary = inv3.add_item("sapper_order", "safe_cell", Vector2i(2, 3), 1) + var h1: Dictionary = inv3.add_item("morning_order", "safe_cell", Vector2i(2, 3), 1) inv3.validate_use(int(h1.handle), Vector2i(4, 4), Vector2i(10, 10), Callable()) inv3.apply_overlay("mine_reveal", [Vector2i(4, 4)]) inv3.consume(int(h1.handle)) diff --git a/game/tests/unit/data_config/forge_table_test.gd b/game/tests/unit/data_config/forge_table_test.gd index e77f2c31..6875947f 100644 --- a/game/tests/unit/data_config/forge_table_test.gd +++ b/game/tests/unit/data_config/forge_table_test.gd @@ -215,12 +215,11 @@ func _test_negative_cases() -> void: # ---- V11:效果类型闭集零新增(满级特效本期不开新词)---- # 实数订正(L2 在册):卡片 F11「24 种」系设计文档事实快照, -# 现行 31;本套件零扩签,钉现行数(将来任何加词即转红提示复核)。 -# 32→31:改写族清退批摘 spike(CI run 87 追绿——词表合法收窄的断言随动)。 +# 现行 30;本套件零扩签,钉现行数(将来任何加词即转红提示复核)。 func _test_effect_kinds_closed() -> void: # 判据出处: design/engineering/architecture/architecture.md「模块归属·基础层」effect_engine 行 事件/事实/效果类型/算子四词表封闭(特效闭集组) - Kit.check("效果引擎效果类型闭集 31 种(甲案词表退役 overflow/attack_segments+改写族清退摘 spike)〔锻造工坊批 V11〕", - EffectEngineScript.EFFECT_KINDS.size() == 31) + Kit.check("效果引擎效果类型闭集 30 种〔锻造工坊批 V11〕", + EffectEngineScript.EFFECT_KINDS.size() == 30) Kit.check("效果引擎事件词表在册 21 种(charge_full 位摘名——蓄力层删键批)〔锻造工坊批 V11〕", EffectEngineScript.EVENTS.size() == 21) diff --git a/game/tests/unit/data_config/treasure_target_violation_test.gd b/game/tests/unit/data_config/treasure_target_violation_test.gd index da5ff235..8dd5131c 100644 --- a/game/tests/unit/data_config/treasure_target_violation_test.gd +++ b/game/tests/unit/data_config/treasure_target_violation_test.gd @@ -1,7 +1,7 @@ # 致命类用例(独立进程,期望退出码 1) # treasure_target_violation——真视窄域护栏(秘宝 GDD 结构冻结):真视类行 target # 越域至 board_wide 时,TreasureItemTable.validate 必须报 load_bearing 错、load_tables 整体拒绝。 -# 注入主语 = sky_eye(真视行 reveal_tiles);护栏本体 = mine_reveal/reveal_tiles 两 kind 同守 REVEAL_KINDS。 +# 注入主语 = sky_eye(真视行 reveal_tiles);护栏本体 = REVEAL_KINDS 真视窄域校验。 # 运行:godot --headless --path game --script res://tests/unit/data_config/treasure_target_violation_test.gd # 退出码协议:1 = 校验正确拒绝(预期);2 = 违规表被放行(回归信号)。 # 时序注:纯加载期校验——不触运行期 fatal 通道,断言 load_tables 返回 false + 诊断在案即 quit(1)。 diff --git a/reports/普查-效果通道与事件词零现役-2026-11-06.md b/reports/普查-效果通道与事件词零现役-2026-11-06.md deleted file mode 100644 index 72b524a2..00000000 --- a/reports/普查-效果通道与事件词零现役-2026-11-06.md +++ /dev/null @@ -1,45 +0,0 @@ -# 普查:效果通道与事件词零现役(2026-11-06) - -> **接收方**:待办清单「效果通道与事件词的零现役普查」条——本报告是该条的产出合同。 -> **结论**:需要你处理的事只有 **2 件**(第一节);扫描面内其余全部属预留埋点,**全部保留、零处理项**(第二节只留计数供存档)。词表零改动、内容层零孤儿、零代码改动。 - -## 一、需要你裁断的两件事 - -### 1. 注释叙述订正 5 处——做不做 - -代码注释把三件**未设计入表**的专长(掘进蓄能/深挖钻头/爆破工兵包)写成了在役叙述,后来读代码或写卡的人会被误导(迭代 53 已发生过一次:spike 承接句按注释误判「零新代码」)。订正方式=把注释改成「预留、未设计入表」,不改任何逻辑。 - -| 位置 | 现行叙述 | 事实 | -|---|---|---| -| effect_engine.gd OPS 头注 | mod_zero「掘进蓄能」、gte_ref/lt_ref「深挖钻头配额」 | 两专长零在表 | -| effect_engine.gd EFFECT_KINDS 头注 | spike 独立 kind 在词表 | 实走 modify_ticket 的 mode 通道 | -| reward_grant.gd:130 | 「counter_spend 订阅=掘进蓄能积点账本」 | 掘进蓄能零在表 | -| action_economy.gd:82 | 「深挖钻头付费开掘」 | 深挖钻头零在表 | -| treasure_item_table.gd:20 | 「cell_removal = 爆破工兵包中立移除格」 | 爆破工兵包零在表 | - -### 2. 秘宝表旧词「迁移完成」收尾——做不做、何时做 - -秘宝表 schema 词表里留着 9 个旧目录时代的词面(git 查证:迭代 22 秘宝批把旧目录 12 行全量换代成现役 12 件后,旧词面按 schema 自己注的「旧词保留共存至迁移完成」留下)。按关联效果列名: - -| 旧词承载的效果 | 类型 | -|---|---| -| 雷区揭示/奖励预览/行动点授予(3 个旧词形) | 新旧词共存——现役等价能力已由新词形承载 | -| 踩雷伤害减半/受击反弹伤害/开局前几轮行动点加成/爆破工兵包中立移除格/奖励摇号权重偏置/换图刷新加算区(6 个) | 旧内容已裁、通道位预留 | - -裁断点:这批「迁移完成」收尾要不要做、什么时候做。**词面现在不动**;收尾属于单独一批改动,做的时候再设计。 - -## 二、无需处理项汇总(零裁决点,计数存档) - -扫描面内以下词面全部判定**保留**(预留埋点——引擎架构=词表先行、内容后接,加一件已有效果类型的专长/秘宝只写数据行零代码): - -- **事件词预留 4**:armor_roll(事件岗)/reward_roll/treasure_used/seal_settle——发射点全在役运行,等订阅内容;armor_roll 另有掷点流名岗在役,同词两用。 -- **效果类型词预留 10**:spawn_spell(锻造工坊法杖设计在册待接线);bias_rewards/counter_spend(架构在役机制承载位——偏运合计查询口/受理闸模式);add_ticket_rider/yield_mult/apply_status/bias_wallet/refresh_pick/preview/spike 词面(预留位)。 -- **事实词预留 6**:is_first_dig_of_battle/terrain_kind(载荷特判支撑在)/target_armor_class/seals_count/nest_count/battle_index。 -- **算子词预留 7**:neq/gt/ends_with/has/mod_zero/gte_ref/lt_ref(实现函数全在)。 -- **channel 反弹行族**:open_ticket 反弹域零数据行(预留)。 - -其余全部事件词/效果词/事实词/算子词的数据面订阅行在役(feats/treasure 数据行+天赋树规则合成行),零孤儿。 - -## 三、普查方法(存档) - -四张词表封闭在 effect_engine.gd 常量:事件 21/效果类型 31/事实 18/算子 13;邻接面=秘宝表 schema 旧词层 10 词+channel 域。数据面使用按行结构键(`"on"`/`"kind"`/`"fact"`/`"op"`/`"channel"`)统计自 `game/data/tables/*.tres` 全域+天赋树规则合成行+秘宝表主动件域;注释裸词面不计。skills.tres(敌技)的 when/fact 走独立系统,不入本普查面。 diff --git a/reports/普查-效果通道与事件词零现役-重核-2026-11-08.md b/reports/普查-效果通道与事件词零现役-重核-2026-11-08.md deleted file mode 100644 index 42ef0f75..00000000 --- a/reports/普查-效果通道与事件词零现役-重核-2026-11-08.md +++ /dev/null @@ -1,52 +0,0 @@ -# 普查:效果通道与事件词零现役(重核 2026-11-08) - -> 接收方:待办清单「效果通道与事件词的零现役普查」条。本报告取代 11-06 版结论;旧报告只作历史取证。 -> 本次口径(取自 11-06 会话中你的纠正):不把「零使用的预留埋点」列成待删候选;只核「定义了处理逻辑却没有挂载、没人消费」的通路;词面先给「有依据/无依据」的事实结论;秘宝表旧词按关联的秘宝与效果介绍;报告只分「需你裁断」与「无需处理」两段。 -> 结论坐实前词表一字未动。本次只写报告,未改注释、词面、待办清单与路线图。 - -## 一、需要你裁断的两件事 - -### 1. 秘宝表 9 个旧词面的「迁移完成」收尾——请你裁动哪些 - -收尾这件事本批要做;这里只请你定范围,不代裁。词面现在仍在 `game/data/schemas/treasure_item_table.gd:25-28`,第 24 行仍写着「旧词保留共存至迁移完成」。9 个旧词形在 `game/data/tables/*.tres` 现行数据行里全部零引用;`ap_charge_safe` 有 1 行在役,不在这 9 个里。 - -| 词面 | 关联的旧秘宝 | 旧效果(玩家看得懂的说法) | 现在谁还在用 | -|---|---|---|---| -| mine_reveal | 探巢摆钟、爆破工兵包 | 真视 3×3(揭示一小片格子) | 现行数据行 0;测试假数据行 5 处 | -| reward_preview | 探宝罗盘 | 预读 3×3(提前看一小片奖励) | 现行数据行 0;测试假数据行 2 处 | -| ap_grant | 工兵令、爆破工兵包 | 一次给 2 点或 4 点行动点 | 现行数据行 0;测试假数据行 1 处 | -| mine_hit_halve | 惊巢反制 | 踩到危险格时伤害减半 | 零引用 | -| reflect_damage | 惊巢反制 | 受击时反弹 2 点伤害 | 零引用 | -| ap_rounds_front | 工兵晨令 | 开局前 3 轮每轮多 1 点行动点 | 零引用 | -| cell_removal | 爆破工兵包 | 中立移除危险格(不引爆、不揭示) | 现行数据行 0;测试假数据行 1 处 | -| reward_weight_bias | 偏运硬币 | 稀有资源在摇号里权重 +2 | 零引用 | -| bonus_refresh | 三选一刷新件 | 三选一多一次刷新 | 零引用 | - -**旧版结论里要修正的一句**:11-06 报告说前三个旧词形「现役等价能力已由新词形承载」。本次核对:`reveal_tiles` 有 6 行数据、`grant_ap` 有 5 行,`preview` 现行数据行 0,但 `preview` 属主动件通道、不经事件订阅(`game/core/effect_engine.gd:85-88`)。所以「三个都有现役承载」不成立,第三个只能算通道位在册。 - -**收尾的连带面**:摘除旧词形后,测试里的假数据行要改用现役词形,否则单元测试会红(`game/tests/unit/core/treasure_items_test.gd:34/36/85-90`、`treasure_effects_test.gd:173/259`)。摘除本身对现行游戏行为零影响(现行数据行零引用),且误写旧词会在加载期被判出域,比留着死词面安全。 - -### 2. 效果类型词里一项「零依据」的事实结论——请你裁是否处理 - -9 个零订阅效果词逐个核过,结论如下(词面现在都不动): - -- 有在役落点:`add_ticket_rider`(`game/core/damage_controller.gd:361`)、`yield_mult`(`game/core/settlement/grant_segment.gd:118`)、`apply_status`(`game/core/damage_controller.gd:391`)、`counter_spend`(`game/core/action_economy.gd:115`)、`bias_rewards`(`game/core/battle_fx_host.gd:131`)、`spawn_spell`(`game/core/settlement/grant_segment.gd:138`)。 -- 通道位在册、不经订阅:`refresh_pick`、`preview`(`game/core/effect_engine.gd:85-88` 主动件分发);`spawn_spell` 另有设计在册(`design/gdd/systems/跨局循环/锻造工坊.md:115` 法杖)。 -- `bias_wallet`:本次全库核对零实现消费点、零数据行订阅、零设计文档句;出处只到效果引擎框架落地提交 `7d157b3c` 的「任务书 §3.3 定稿 24 型」(`game/core/effect_engine.gd:26/30` 词表与头注)。 - -按你 11-06 00:16 的口径「有依据的保留、乱写的不能保留」,这一项是本次唯一查不到落点的词面。是否处理、怎么处理归你裁;本报告不提删,也不把它列成待办。 - -## 二、无需处理项(只留计数,不列清单) - -- 事件词 4 个零订阅、事实词 5 个、算子词 7 个:属引擎预留埋点与条件查询面,发射点、实现函数、头注都在役;按你 11-06 00:16 的纠正,不列成候选、不提删。 -- 效果词里 8 个零订阅项:全部有在役落点或设计在册,见第一节第 2 项。 -- **本次未发现「定义了处理逻辑却没实际挂载、也没人消费」的通路。** - -## 三、取证与方法(存档) - -- 四组封闭词表:`game/core/effect_engine.gd:12-18`(事件 21)/`:28-51`(效果 31)/`:58-62`(事实 18)/`:69-70`(算子 13)。 -- 订阅面:`game/data/tables/*.tres` 全域的 `on`/`kind`/`fact`/`op` 行,加 `game/core/effect_engine.gd:145-174` 天赋树规则合成行。 -- 发射面:`game/core/battle_fx_host.gd:71-79`(统一分发入口)、`:128-133`(偏运权重查询)。 -- 旧秘宝目录行:迭代 22 提交 `48b06961` 的父版 `game/data/tables/treasure_items.tres:12-166`;退役去向与效果一句话另见 `design/content-archive/道具退役素材库.md:12-25`。 -- 注释叙述节:现行 `game/` 下「掘进蓄能/深挖钻头/爆破工兵包」零命中(旧报告第一节仍把它们写成现行叙述,合入提交 `7bbde052` 已注明待订正)。 -- 错判修正留痕:`yield_mult`、`spawn_spell` 初判「零消费点」,全库复核(含 `game/core/settlement/` 子目录)后改判为在役落点,未把初判写进结论。 diff --git a/roadmap.md b/roadmap.md index a15996be..4f6c5121 100644 --- a/roadmap.md +++ b/roadmap.md @@ -6,7 +6,7 @@ - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 - **迭代位**:迭代 1–55 已完成。迭代 56 已编待开工(结算期文字列表退役+封印动作改版两卡)。各迭代收口与批后收尾沿革查 git 提交信息与 `reports/`。 -- **下一步**:发令开工 56(≈12.25 日,两卡:结算期文字退役先行+封印改版);待编池:效果通道与事件词零现役普查(唯一遗留待裁=秘宝表 schema 旧词面 9 词收尾)、结算明细文案入表(待文档设计)、棋盘瓦片与立体表现重做(已写卡,待编排)、测试面真输入化批发现四项待裁(待执行);EC8 热重载实装待用户另立条目。 +- **下一步**:发令开工 56(≈12.25 日,两卡:结算期文字退役先行+封印改版);待编池:结算明细文案入表(待文档设计)、棋盘瓦片与立体表现重做(已写卡,待编排)、测试面真输入化批发现四项待裁(待执行);EC8 热重载实装待用户另立条目。 ## 里程碑时间线 diff --git a/tools/balance_verifier.py b/tools/balance_verifier.py index abba7cd4..e5db63a6 100644 --- a/tools/balance_verifier.py +++ b/tools/balance_verifier.py @@ -68,8 +68,7 @@ NODE_TYPE_CN = {"battle": "战斗", "boss": "Boss", "rest": "恢复", "reward": OVERRIDE_ATTRS = ["max_hp", "atk", "armor_class"] # 注入契约三键(词表同 MetaTable.FORGE_ATTRS) ATTR_CN = {"max_hp": "生命上限", "atk": "基础攻击", "armor_class": "护甲等级"} SPEND_CN = {"hp_first": "生命优先", "atk_first": "攻击优先", "armor_first": "护甲优先"} -WORKSHOP_CN = {"probe_dust": "显影尘", "sapper_order": "工兵令", "loot_compass": "探宝罗盘", - "nest_pendulum": "探巢摆钟", "catacomb_scroll": "地穴全图卷", "blast_kit": "爆破工兵包"} +# 工坊解锁报告直显 item_id(旧目录中文名映射已退役)。 # ---- meta.tres 表值(启动时解析——表值锚配置推导化:判定阈值随配置表走,零硬编码) ---- META_TRES = SLICE / "data" / "tables" / "meta.tres" @@ -379,7 +378,7 @@ def analyze_campaign(rows, spend_tag="hp_first"): unlocks = {} for r in runs: for iid in r.get("new_unlocks", []): - unlocks[WORKSHOP_CN.get(iid, iid)] = r["run_no"] + unlocks[iid] = r["run_no"] res["unlocks"] = unlocks # 累计钥石与锻造终态 last = max(runs, key=lambda x: x["run_no"]) diff --git a/tools/coverage_exemptions.js b/tools/coverage_exemptions.js index e656edd4..fb7ad245 100644 --- a/tools/coverage_exemptions.js +++ b/tools/coverage_exemptions.js @@ -43,9 +43,8 @@ window.__QA_COVERAGE__.exemptions = { /* ── 豁免·预留埋点(普查 §2 词表先行内容后接——未来接线内容时撤豁免补验证)── */ "chain_ap_cost", "move_ap_cost", /* action_economy——schema 冻结 0,core 零调用方 */ "hero_hp_pct", "neq", /* skill——TRIGGER_FACTS/算子词预留在册,tres 零行使用 */ - "ap_rounds_front", "effective_rounds", "mine_hit_halve", "reflect_damage", "refresh_pick", - "reward_weight_bias", "slot_cost", "ap_grant", "risk", "cell_removal", - /* treasure——EFFECT_KINDS/MAGNITUDE_KINDS/DIMENSIONS 在册、tres 零行使用 */ + "effective_rounds", "refresh_pick", "slot_cost", "risk", + /* treasure——字段与现役词面在册、tres 零行使用 */ /* ── 豁免·挂起件(全仓零引用,生涯条目承载处置两途)── */ "settlement_review_overlay", /* ── 豁免·假缺口(验证在役、文本关联盲区——按族登记,reason 逐族)── */ diff --git a/体验验证清单.md b/体验验证清单.md index f2ad337e..3ef0b1fa 100644 --- a/体验验证清单.md +++ b/体验验证清单.md @@ -84,7 +84,7 @@ ### ⑩ 奖励重构体验项(余项人工参与) - **逐行结算演出复验**:完全退出游戏后重启(减动效开关在启动时加载),战斗停手看轮末结算是否一行一行滚出(弹道/受击闪白/伤害数字逐行)。机制已落地(排播队列 0.3/0.22s);若重启后仍无演出再报 bug 批。 -- **道具件卡片直显复验**:三选一抽到秘宝件时,卡片应直显「秘宝 / 探巢摆钟 · 真视 3×3」式具体道具(掷定前置已实装,node-reward.md v2.1)——不再是「随机获得一件」盲选。 +- **道具件卡片直显复验**:三选一抽到秘宝件时,卡片应直显「秘宝 / 线香 · 真视 3×3」式具体道具(掷定前置已实装,node-reward.md v2.1)——不再是「随机获得一件」盲选。 - **关卡完成节奏体感**:血回满→20% 部分回血 + 三选一选件后,L2/L3 的紧张度与「这局能走多远」驱动是否成立(读数带内:普通 L1 41.8%/L2 10.2%——体感不满不当场改数,归曲线调参批)。 - **钥石节奏体感**:Boss 逐杀掉落(首杀 3/复杀 2/2/3)后营地积累速度明显变慢——元进度产出重标(均值 1.38/3.01)归元进度设计批,体感反馈是其输入。 diff --git a/待办清单.md b/待办清单.md index bccdc129..0f66d6d4 100644 --- a/待办清单.md +++ b/待办清单.md @@ -367,14 +367,6 @@ ### 文档与结构 -#### 效果通道与事件词的零现役普查(2026-11-05 登记,来源=审计发现) - -**实况**:普查报告 reports/普查-效果通道与事件词零现役-2026-11-06.md——结论=内容层零孤儿、四词表+秘宝表 schema 旧词层全部属预留埋点(词面全保留零清退项;架构原则=词表先行内容后接)。叙述脱节 5 处已按「预留、未设计入表」口径订正(2026-11-06 用户令直改,冒烟 15 项 0 失败三闸全过)。唯一遗留待裁=秘宝表 schema 旧词面 9 个「迁移完成」收尾(做不做、何时做),待用户裁。 - -**改动面**:游戏代码 - -**状态**:待执行 - #### 测试面真输入化分期与存量断言逐条精锚(2026-11-05 登记,来源=批次移交) **实况**:证据=test-conventions §8.3「判据出处行锚」「真实入口判定口径」两条文+§2「UI 驱动断言须走真输入管线」条文(批1补,qa-harness 分支 2cbd2ca9)+「测试函数的判据出处注记」条款与机检 G 道(2026-11-06 批,capability_audit --strict 绿 402 函数)。已承接=探针 emit 站点两批合计(QA 批两探针 51+1 与真输入化批七探针 63 处,8 处在案保留带注记)+判据出处注记全库铺开(402 验证函数挂 `# 判据出处:` 指针)。剩余面=视图层测试方法面(press_candidate/press_continue/press_card/press_confirm/press_refresh_for_probe 等探针消费口,非 emit 站点)。