# Bug Report ## Summary **Title**: grant_node_active 直调 stock、不经 _supply.notify_granted()——节点奖励完全绕开供给控制器计数 **ID**: BUG-0004 **Severity**: S4-Trivial(原报 Low;纯计数口径漏洞,零战斗数值影响) **Priority**: P3-Backlog(本会话已修复并沉淀回归) **Status**: Closed **Reported**: 2026-09-12(playtest-2026-09-12-designer 报告 Bugs 表 #3) **Reporter**: 用户(设计师本人,试玩报告);本档由 2026-09-13 会话按报告 Action Routing 建档并修复 ## Classification - **Category**: Gameplay(奖励经济计数口径) - **System**: B4 奖励经济 × RewardSupplyController(可选类供给状态机)× C1 奖励节点 - **Frequency**: Always(每个 reward 节点必现——结构性) - **Regression**: Yes——2026-09-11 供给控制器批引入 notify_granted 入账点时,关卡扩展批的 grant_node_active(更早)未同步接入 ## Environment - **Build**: 复核 = 2026-09-13 当前工作区(漏洞在位 → 本会话修复) - **Platform**: PC · Win10 · Godot 4.7.2 - **Scene/Level**: 第一关 reward 节点(战×2 → 道具 → …) - **Game State**: 节点奖励 roll 一件可选类直接入库 ## Reproduction Steps **Preconditions**: 任意到达 reward 节点的关卡流程。 1. `level_runner._enter_next_node` 处理 reward 节点 → `b4.grant_node_active(Vector2i(-1,-1), 0)` 2. grant_node_active 内部 roll 一件 damage_item/heal_pack 后直调 `stock(...)` 入库 3. `_supply.granted_count()` 不变——供给控制器对这次发放零感知 **Expected Result**: 「发放即获取」口径全通道一致——节点奖励与格子授予(`grant()`)同一入账点。 **Actual Result(修复前)**: 节点奖励绕过计数——供给控制器战斗域计数(首件保证/指数递减的入账基础)与 `supply_granted_count()` 观测面均漏记节点奖励,关卡级供给总量核算失真(原报:「结构性漏洞之一」)。 ## Technical Context - **Likely affected files**: `core/reward_economy.gd`(grant_node_active) - **Related systems**: `core/reward_supply_controller.gd`(notify_granted 唯一入账点)、`core/level_runner.gd`(调用方) - **Possible root cause**: grant_node_active 早于供给控制器批存在(2026-09-11 关卡扩展批),供给控制器批改造 grant() 入账时未覆盖此调用点——事实约定「发放即入账」未成文导致漏改(code-conventions 1.5 同款)。 ## Evidence - **代码审读(实锤)**:`core/reward_economy.gd` grant_node_active 直调 stock,无 notify_granted;对照 grant() 对 damage_item/heal_pack 发放必调 `_supply.notify_granted()` - **修复**:grant_node_active 在 stock 受理成功(`inst is Dictionary`)后补调 `_supply.notify_granted()`——与 grant() 同一入账语义;失败路径(清库后拒绝)不入账 - **影响面评估**:供给计数器为战斗域(notify_battle_start 清零),节点奖励发生在战斗间——修复**零战斗数值影响**(下一战斗开战即清零,注入概率路径不变);收益 = 计数口径统一 + `supply_granted_count()`/遥测供给核算完整 - **回归断言**:smoke_all `_smoke_supply` 增⑦——`grant_node_active` 受理后 `supply_granted_count() == 1`(发放即入账;修复前该计数为 0,断言可抓原缺陷) - **修复后验证**:冒烟 148/148 全绿 ## Related Issues - playtest-2026-09-12-designer 报告 Bugs 表 #3 / Top 3 Priorities #3(供给量重拍板 + 节点奖励纳入控制器) - 报告根因分析「三个结构性放大器」第 1 条(节点奖励绕开控制器再放大供给量) - **Top 3 Priorities #3 的另一半(供给量语义重拍板)不在本缺陷档**:「每战斗首件保证 → 关卡域首件保证」候选归 C3 裁决(列待拍板清单,本会话未动) ## Notes - 报告 Top 3 #3 原文要求「grant_node_active 补 notify_granted 上报」——本档即该义务的执行与沉淀。 - 关卡域供给总量的观测:修复后 `supply_granted_count()` + 库存查询可完整重建「每关可选类获取账目」(格子授予 + 节点奖励 + 注入三通道),供 C3 供给量重拍板时直接消费。 ## Closure Record **Closed**: 2026-09-13 **Resolution**: Fixed——grant_node_active 补 `_supply.notify_granted()`(stock 受理成功后入账,与 grant() 同一口径);零战斗数值影响(计数器战斗域清零语义不变)。 **Fix commit / PR**: 不适用(非 git 管理;变更 = core/reward_economy.gd 1 处 + smoke/smoke_all.gd `_smoke_supply` ⑦ 回归断言) **Verified by**: 2026-09-13 会话(smoke_all 148/148,含新回归断言) **Closed by**: 用户授权任务(playtest-2026-09-12 报告 Top3 执行会话) **Regression test**: `smoke/smoke_all.gd` `_smoke_supply` ⑦「节点奖励计入供给控制器(发放即入账)」 **Status**: Closed