chore: initial commit
This commit is contained in:
commit
ddd2960fa6
317 files changed
+41717
No files matched your search
@@ -0,0 +1,85 @@
|
||||
# Bug Report
|
||||
|
||||
## Summary
|
||||
**Title**: 结算战斗段首行下发时 StatusSlotRow 按索引误取 tooltip 节点崩溃,结算协程中断 → 结算阶段永久软锁
|
||||
**ID**: BUG-0001
|
||||
**Severity**: S1-Critical(核心循环阻断——结算阶段永久假死,只能杀进程)
|
||||
**Priority**: P1-Immediate
|
||||
**Status**: Closed
|
||||
**Reported**: 2026-09-12
|
||||
**Reporter**: 用户(设计师本人,垂直切片试玩)
|
||||
|
||||
## Classification
|
||||
- **Category**: Crash / 软锁(soft lock,无崩溃弹窗的假死)
|
||||
- **System**: C 区状态效果槽(StatusSlotRow)呈现层 × B1 结算编排(信号链中断面)
|
||||
- **Frequency**: 条件必现(前置 = 状态槽悬停过一次 + 其后任一结算行刷新时英雄侧效果 ≥1;悬停是新增益出现后的自然操作,实际对局高频可触)
|
||||
- **Regression**: Yes——`status_slot_row.gd` 与 C 区数据框为 2026-09-12 五区改造批新增;2026-09-11 build 无此视图
|
||||
|
||||
## Environment
|
||||
- **Build**: 垂直切片 · battle.md 五区改造批(2026-09-12);卡死会话种子 42,19:22:19 开局
|
||||
- **Platform**: PC · Win10 · Godot 4.7.2 (OpenGL Compatibility · RTX 2060 SUPER)
|
||||
- **Scene/Level**: 完整关卡模式(第一关)· 轮末结算(道具窗口跳过后、战斗段首行)
|
||||
- **Game State**: 第 1 场战斗结算中;道具窗口以「跳过」关闭;英雄侧存在本结算新授予的状态效果(槽可见)
|
||||
|
||||
## Reproduction Steps
|
||||
**Preconditions**: 对局中英雄侧至少有 1 个状态效果(如安全格授予的增伤),状态槽在 C 区可见。
|
||||
|
||||
1. 鼠标悬停任一状态效果槽(tooltip 弹出——此步把 `_tip` 挂入 StatusSlotRow 子节点表)
|
||||
2. 正常结束本轮(停手或 AP 耗尽),进入轮末结算
|
||||
3. 结算段任一 step_row 下发(如道具窗口跳过 → 战斗段「主角攻击」行)触发 `_refresh_presentations`
|
||||
4. 游戏无声冻结:棋盘保持去饱和、阶段文案停在「结算中」,所有输入通道无效
|
||||
|
||||
**Expected Result**: 结算七段完整回放,逐行兑现后进入下一轮(或终局 overlay)。
|
||||
**Actual Result**: `status_slot_row.gd:118` 脚本错误沿信号链回卷,`_finish_settlement` 在战斗段(⑤)中途被中止——`_settling` 恒为 `true`、A3 恒为 `PHASE_WAITING`,结算永不恢复。
|
||||
|
||||
## Technical Context
|
||||
- **Likely affected files**:
|
||||
- `prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd:57-63`(`set_effects` 用 `get_child(i)` 按位取槽——`_tip` 入树后索引错位)
|
||||
- `prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd:80-88`(`_sync_slots` 显式保留 `_tip`,与上行索引假设自相矛盾)
|
||||
- `prototypes/dungeon-sweeper-vertical-slice/presentation/views/status_slot_row.gd:114-118`(`_fill_slot` 对 cast 为 null 的 `col` 调 `get_child`)
|
||||
- 中断面:`core/battle_orchestrator.gd:233-263`(`_finish_settlement`——错误回卷致 `_settling` 悬挂)
|
||||
- **Related systems**: `main.gd _on_step_row → _refresh_presentations`(每结算行同步刷新);`level_runner.gd:128` 转发 lambda;`hud_presenter.gd:29`
|
||||
- **Possible root cause**(已由崩溃回溯证实):
|
||||
tooltip 节点 `_tip` 在 `_init` 不入树,仅 `_on_slot_hover` 首次悬停时 `add_child(_tip)`,与动态重建的槽共用同一子节点表。此后 `set_effects` 内 `get_child(i)` 取到的第 0 个"槽"实为 `_tip`(PanelContainer,cast 通过),`_fill_slot` 中 `_tip.get_child(0)` 是 Label → `as VBoxContainer` = null → 118 行 `col.get_child(0)` 报
|
||||
`Cannot call method 'get_child' on a null value`。
|
||||
Godot 4 对信号回调内的运行时错误整条 GDScript 调用栈回卷:按钮 lambda → `submit_window_selection` → `_finish_settlement` → `_combat_segment` 全部中止,B1 无"结算恢复"路径,软锁。
|
||||
|
||||
## Evidence
|
||||
- **Logs**(`user://logs/`,DungeonSweeperVerticalSlice):
|
||||
- `godot.log`(19:22 会话)完整回溯:`_fill_slot (status_slot_row.gd:118)` ← `set_effects` ← `set_status_effects` ← `HudPresenter.refresh` ← `main._on_step_row` ← `level_runner lambda` ← `_emit_row` ← `_combat_segment (battle_orchestrator.gd:474)` ← `_finish_settlement (242)` ← `submit_window_selection (230)` ← `_on_window_skipped` ← skip 按钮 lambda
|
||||
- `playtest_42_20260912T192219.jsonl`:`ux_window_choice{skip:true}` 之后再无任何事件(无 settlement 快照、无 ux_round_exit、无下一轮)——结算协程死亡实锤
|
||||
- **Visual**: 棋盘去饱和锁定、阶段指示「第 N 轮 · 结算中」、明细带展开但停在该结算首行;与 2026-09-11 崩溃 #1 的"输入锁已上 + 呈现层崩溃 = 无声冻结"同族
|
||||
|
||||
## Related Issues
|
||||
- `production/qa/playtests/playtest-2026-09-11-designer.md` 崩溃 #1/#2——同一失败家族(结算期呈现层错误 + 核心中断/输入锁死),当时的防复发三条硬性要求(载荷 schema 成文 / 场景级 headless 测试 / 状态可见性)第三条仍未覆盖本路径
|
||||
- `presentation/views/board_view.gd:476` `_make_cursor_texture` 启动期 `canvas_item is null` 渲染错误(P3,独立缺陷,与本软锁无关)
|
||||
- `status_slot_row.gd:57-63` 潜在次生缺陷:`set_effects` 循环上界是 `effects.size()` 而 `_sync_slots` 只建 `min(size, 4)` 个槽——英雄侧效果 >4 时(off_guard max_stack 16)同函数必崩
|
||||
- 场景探针(ui_probe/ui_click_probe)未覆盖「悬停 → 结算刷新」路径——冒烟再次漏掉呈现层时序态
|
||||
|
||||
## Notes
|
||||
- 修复方向(最小面):槽与 tooltip 分离承载——`_tip` 改挂 StatusSlotRow 之外的独立层,或 `set_effects`/`_sync_slots` 改用槽引用数组(不按子节点位序索引)。两处任选其一,后者改动面更小但必须同步修掉 >4 溢出循环上界
|
||||
- 按代码规范「缺陷修复必须沉淀回归断言」:需在场景级探针补"悬停槽位后触发一次含效果行的结算,断言无脚本错误且 phase 走到下一轮"
|
||||
- 本次卡死用户未点「诊断转储」(现存三份 diag 均来自探针 `{"test":true}` 上下文,core 字段为空)——诊断按钮对真实软锁会话未被使用,不影响本次定位(godot.log 回溯已足够)
|
||||
|
||||
## Fix Record(2026-09-12,Status 仍 Open——正式流转待 /bug-report verify)
|
||||
- **修复**:`status_slot_row.gd` 槽生命周期改由 `_slots: Array[PanelContainer]` 引用数组唯一管理,`set_effects`/`_sync_slots`/`set_cleared_feedback` 全部弃用子节点位序索引;顺带修掉 effects > MAX_SLOTS 时循环越界次生缺陷(超出截断至 4 槽,符合"最多 4 槽可见"规格)
|
||||
- **回归断言**:`smoke/ui_probe.gd` 新增 BUG-0001 回归段(建槽 → 悬停入 tooltip → 重刷断言槽位/填充 → 超上限截断 → 空态清槽)
|
||||
- **阴性对照**:回滚修复版跑探针,精确复现野外崩溃(`status_slot_row.gd:118` 同行同错);恢复修复版后探针通过——断言有效
|
||||
- **验证**:smoke_all 161 检查 0 失败 · ui_probe PASS · ui_click_probe(seed 7)关卡通关/问题=0/选用失效=0/无卡死 · ui_tune_probe PASS ×2
|
||||
- **待办**:人类完整试玩复跑(playtest 报告 Top1 优先级)后走 verify/close
|
||||
|
||||
## Verification Record(2026-09-12)
|
||||
**判定**:VERIFIED FIXED
|
||||
- 复现路径核查:`status_slot_row.gd` 中 `set_effects`/`_sync_slots`/`set_cleared_feedback` 已无子节点位序索引(grep 复核,仅 `_slots` 引用数组访问)——原崩溃代码路径不复存在
|
||||
- 阴性对照:修复前版本在 ui_probe 回归段精确复现野外崩溃(`status_slot_row.gd:118` 同行同错),证明断言与定位有效
|
||||
- 相关测试:smoke_all 161 项检查 0 失败(关闭时复跑)· ui_probe PASS(含 BUG-0001 回归段)· ui_click_probe(seed 7)关卡通关/问题=0/无卡死 · ui_tune_probe PASS
|
||||
- 人工确认:用户试玩确认"没有问题"
|
||||
|
||||
## Closure Record
|
||||
**Closed**: 2026-09-12
|
||||
**Resolution**: Fixed — StatusSlotRow 槽生命周期改由 `_slots` 引用数组唯一管理,弃用子节点位序索引(tooltip 入树不再错位);顺带修复 effects > MAX_SLOTS 循环越界(截断至 4 槽)
|
||||
**Fix commit / PR**: 本地工作区直接修复(项目非 git 仓)
|
||||
**Verified by**: qa-tester
|
||||
**Closed by**: 用户
|
||||
**Regression test**: `prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd`(BUG-0001 回归段)
|
||||
**Status**: Closed
|
||||
@@ -0,0 +1,61 @@
|
||||
# Bug Report
|
||||
|
||||
## Summary
|
||||
**Title**: 浅深度战斗零敌人(d0/d1 遭遇 unit_count=0、round 1 即 victory)——遭遇骰/spawn 路径疑似掷出 0
|
||||
**ID**: BUG-0002
|
||||
**Severity**: S3-Minor(复核降级——原报 Medium;当前构建不可复现,遥测签名另有解释)
|
||||
**Priority**: P3-Backlog(不变式回归已落地,无遗留行动)
|
||||
**Status**: Closed
|
||||
**Reported**: 2026-09-12(playtest-2026-09-12-designer 报告 Bugs 表 #1)
|
||||
**Reporter**: 用户(设计师本人,试玩遥测);本档由 2026-09-13 会话按报告 Action Routing 建档并复核
|
||||
|
||||
## Classification
|
||||
- **Category**: Gameplay(遭遇生成)/ 遥测可观测性
|
||||
- **System**: B1 遭遇骰(C3 Core Rule 8 区间骰)× B2.spawn × settlement_snapshot 观测面
|
||||
- **Frequency**: 原报两次真人局均现(d0 100%、20:13 另含 d1);当前构建复现 0/100 场
|
||||
- **Regression**: No——遭遇骰批(2026-09-12)后无相关代码路径可产出 0
|
||||
|
||||
## Environment
|
||||
- **Build**: 原报 = 垂直切片 · 2026-09-12 五区改造批;复核 = 2026-09-13 当前工作区(status_effects.tres defense_up=-30 批)
|
||||
- **Platform**: PC · Win10 · Godot 4.7.2 · seed 42 固定
|
||||
- **Scene/Level**: 第一关 d0/d1 战斗节点
|
||||
- **Game State**: 战斗第 1 轮结算即 victory,快照 unit_count=0
|
||||
|
||||
## Reproduction Steps
|
||||
**Preconditions**: 原报基于 playtest_42_20260912T201317.jsonl 遥测(快照面)。
|
||||
|
||||
1. seed 42 开局,进入 d0 战斗
|
||||
2. 首轮挖满 8 AP 后结算
|
||||
3. 快照显示 verdict=victory、unit_count=0(原报判为「零敌人空场」)
|
||||
|
||||
**Expected Result**: C3 Rule 8 区间 [unit_count, unit_count_max] 下限 1——不应出现 0 敌战斗。
|
||||
**Actual Result(复核)**: **遥测误读——实为「首轮全灭」而非「空场」**。快照取在衰减段之后的结算末尾,`unit_count` 只计存活敌:英雄首轮爆发(基础攻击 + 伤害A 开格充能 + 爆裂粉尘 instant_aoe 全体)可在 round 1 全歼浅深度低 HP 敌群,快照同样呈现 unit_count=0 + round-1 victory。
|
||||
|
||||
## Technical Context
|
||||
- **Likely affected files**: `core/battle_orchestrator.gd`(begin_battle 遭遇骰 / _emit_settlement_snapshot)、`core/unit_container.gd`(spawn 数量守卫)
|
||||
- **Related systems**: C3 Core Rule 8(区间骰)、playtest_logger(JSONL 快照消费)
|
||||
- **Possible root cause(复核结论)**: 非遭遇骰缺陷。当前实现掷骰 = `roll_lo + estream.randi_range(0, roll_hi - roll_lo)`,数学下限 = `unit_count` ≥ 1;B2.spawn 对 count<1 fail-fast 拒绝(双闸)。**seed 42 当前构建全关回放(damage_probe level 模式)复现同款遥测签名**:d0 spawn=1、d1 spawn=3,全部「round-1 胜利 = 首轮全灭(wipe)」——与 20:41 辅助局 d1 快照(3 只地精各剩 1 HP = 主角攻击斩首只 + 3 颗爆裂粉尘 ×4 AOE)逐点吻合。
|
||||
|
||||
## Evidence
|
||||
- **探针**:`smoke/damage_probe.gd -- level 42`——d0 spawn=1(预测 1 ✓)首轮全灭 · d1 spawn=3(预测 3 ✓)首轮全灭 · 20 种子 × 5 深度 = 100 场 spawn 全域内、0 场空遭遇
|
||||
- **遥测取证**:playtest_42_20260912T204636.jsonl d1 r1——unit_count=2 存活(3 只中 2 只各剩 1 HP)+ hero 承伤 −8,证明同种子 d1 在另一局正常刷出敌群(差异 = 真人挖掘路径不同的奖励抽取,非 RNG 流分歧)
|
||||
- **回归断言**:smoke_all `_smoke_encounter_roll` 增「全深度 × 12 种子 spawn 全域内(60 场,∈[unit_count, unit_count_max] 且 ≥1)——空遭遇不可达」;settlement_snapshot 新增 `spawn_count` 字段 + `_smoke_playtest_logger` 字段/等值断言——unit_count=0 时可判别「首轮全灭」vs「空场」,同类误读不再依赖人肉推断
|
||||
- **修复后验证**:冒烟 148/148 全绿
|
||||
|
||||
## Related Issues
|
||||
- playtest-2026-09-12-designer 报告 Bugs 表 #1 / Top 3 Priorities #1(探针前置)
|
||||
- BUG-0003(Boss 攻击零兑现——同一份遥测的姊妹误读,共用根因探针)
|
||||
- BUG-0001(呈现层软锁——编号顺延基点,无关联)
|
||||
|
||||
## Notes
|
||||
- 「单位数量 0」类观察的判别义务已机制化:任何后续 JSONL 快照携带 `spawn_count`(实例化总数,含死亡残位),`unit_count < spawn_count` = 有击杀,`spawn_count=0` 才是空场。
|
||||
- 原报的怀疑对象(遭遇骰路径)经代码审读 + 100 场扫描证伪;真实可玩性议题「浅深度战斗可被首轮爆发无伤跳过(d0-d3 全部 round-1 通关)」属难度带问题,归 C3 F4/F5 复扫(BUG-0003 关联条目与本会话 Q1 基线数据),不在本缺陷档处置。
|
||||
|
||||
## Closure Record
|
||||
**Closed**: 2026-09-13
|
||||
**Resolution**: Rejected as coded——零敌遭遇在当前实现不可达(数学下限 + fail-fast 双闸 + 100 场扫描零越域);原观察为「首轮全灭」被快照盲区误读。沉淀 = settlement_snapshot.spawn_count 观测面 + 全域 spawn 回归断言(无游戏数值变更)。
|
||||
**Fix commit / PR**: 不适用(非 git 管理;变更 = core/battle_orchestrator.gd 快照字段 + smoke/smoke_all.gd 回归断言 + smoke/damage_probe.gd 探针)
|
||||
**Verified by**: 2026-09-13 会话(damage_probe level 模式 + smoke_all 148/148)
|
||||
**Closed by**: 用户授权任务(playtest-2026-09-12 报告 Top3 执行会话)
|
||||
**Regression test**: `smoke/smoke_all.gd` `_smoke_encounter_roll`(全域扫描)+ `_smoke_playtest_logger`(spawn_count 字段与等值);`smoke/damage_probe.gd -- level`(可复演证据面)
|
||||
**Status**: Closed
|
||||
@@ -0,0 +1,63 @@
|
||||
# Bug Report
|
||||
|
||||
## Summary
|
||||
**Title**: Boss 攻击拍零兑现(ogre_chief pattern 轮转正常但英雄血量纹丝不动——攻击链对该敌未生效)
|
||||
**ID**: BUG-0003
|
||||
**Severity**: S2-Major(复核降级——原报 High;非代码缺陷,零承伤根因为已拆除的减伤墙设计语义)
|
||||
**Priority**: P2-Next Sprint(无代码遗留;难度带复验归 Q1 调参批数据,见 Notes)
|
||||
**Status**: Closed
|
||||
**Reported**: 2026-09-12(playtest-2026-09-12-designer 报告 Bugs 表 #2)
|
||||
**Reporter**: 用户(设计师本人,试玩遥测);本档由 2026-09-13 会话按报告 Action Routing 建档并复核
|
||||
|
||||
## Classification
|
||||
- **Category**: Gameplay(战斗结算)/ 数值设计
|
||||
- **System**: B1 战斗段 F2 乘区(hero_defense 池)× B3 defense_up(stack×max_stack)× B2 行为环
|
||||
- **Frequency**: 原报两局 Boss 战全部攻击拍零兑现;当前构建(defense_up=-30 批)0 复现
|
||||
- **Regression**: No——攻击链代码路径无缺陷;行为由表值组合完全解释
|
||||
|
||||
## Environment
|
||||
- **Build**: 原报 = 垂直切片 · 2026-09-12 五区改造批(status_effects.tres defense_up=-50 旧值);复核 = 2026-09-13 当前工作区(defense_up=-30)
|
||||
- **Platform**: PC · Win10 · Godot 4.7.2 · seed 42 固定
|
||||
- **Scene/Level**: 第一关 Boss 节点(ogre_chief,pattern [attack, attack, charge, heavy],atk 9)
|
||||
- **Game State**: 12 结算轮 hero hp 恒 50/50;快照 buffs[] 恒空
|
||||
|
||||
## Reproduction Steps
|
||||
**Preconditions**: 原报基于 playtest_42_20260912T201317.jsonl(主分析局)+ 20:41 辅助局。
|
||||
|
||||
1. 正常推进至 Boss 节点(此时库存/状态由前序战斗积累)
|
||||
2. Boss 战 6 轮:beat 轮转 attack→attack→charge→heavy→attack→attack 正常推进(advance 在跑)
|
||||
3. 英雄承伤恒 0(含 fresh 池轮)——原报判「攻击链对该敌未生效」
|
||||
|
||||
**Expected Result**: 非 charge 拍应按 atk.total × 池乘区兑现伤害。
|
||||
**Actual Result(复核)**: **攻击链健康——零兑现由 defense_up 叠满墙(设计语义)全额解释**。快照 buffs[] 恒空是观测盲区:快照取在衰减段之后,时效 1 的 defense_up 当轮授予当轮衰减,快照永远看不见——「buffs 空」不构成「无墙」证据。旧数据 defense_up magnitude=-50 × max_stack 2 = 池 -100 = pool_clamp_lo 触底 → F2 乘区 ×0,任何 atk 曲线乘在 ×0 上(原报根因分析「v3 主杠杆是乘在 ×0 上的调参」由此坐实)。
|
||||
|
||||
## Technical Context
|
||||
- **Likely affected files**: `core/battle_orchestrator.gd`(_combat_segment / _clamped_pool / _resolve_damage)、`core/status_container.gd`(stack 授予)、`core/damage_math.gd`(pool_damage)
|
||||
- **Related systems**: settlement.tres(effect_pool_map / pool_clamp)、status_effects.tres(defense_up 行)、reward.tres(defense_up 权重)
|
||||
- **Possible root cause**: 设计语义——「stack 策略 × magnitude × max_stack 触池 clamp 下限 = 100% 免伤」授予段生效、先于战斗段,当轮挖到的减伤当轮全额兑现。非 Boss 特异:普通敌在同一墙轮同样零兑现(20:13 局 12/12 轮零承伤)。
|
||||
|
||||
## Evidence
|
||||
- **探针(fresh 池裸验,当前构建)**:`smoke/damage_probe.gd -- boss 42` Run A(零挖掘停手轮,零授予零墙)——Boss 攻击拍 d_tick = atk.total 全额兑现:attack 9/9 ×2、charge 0(设计)、heavy 18/18,6 轮内击倒英雄(defeat)——**H2(Boss/敌攻击链缺陷)否证**;拍名轮转与真人局逐拍一致
|
||||
- **探针(墙行为,当前数据重证)**:Run B(自动挖掘)——减伤授予可见(池 -30 → d_tick 21→14;池 -60 → 残余 ×0.40),墙轮承伤恒 > 0:**09-13 调参批(-50→-30)后墙最深 -60 > clamp_lo -100,归零不可达**
|
||||
- **遥测取证**:20:13 局 Boss 6 轮 raw 应承伤 9/9/0/18/9/9 = 54 点 vs 实测 0;d2/d3 首轮攻击拍同样零兑现(非 Boss 特异)——与「全轮墙」假说唯一相容
|
||||
- **回归断言**:smoke_all 新增 `_smoke_attack_chain_fresh_pool`——停手轮(零授予→池恒空)断言非蓄力拍 d_tick == atk.total 全额兑现且 > 0;若未来出现 fresh 池零兑现(真攻击链缺陷)在此被抓
|
||||
- **修复后验证**:冒烟 148/148 全绿
|
||||
|
||||
## Related Issues
|
||||
- playtest-2026-09-12-designer 报告 Bugs 表 #2 / 根因分析「问题②难度:v3 调参为何无效」/ Top 3 Priorities #1
|
||||
- BUG-0002(同份遥测的姊妹观察——同一探针分割)
|
||||
- 09-13 减伤墙调参批(status_effects.tres -50→-30 + reward.tres 权重 24→16——本缺陷的设计侧处置,先于本档落地)
|
||||
- Action Routing 原定「/propagate-design-change b3-status-effect.md(候选:clamp 收紧/乘法衰减/重击拍穿防)」——**未执行**:结构冻结域拦截(settlement.tres 池 clamp [-100,+100] 冻结)+ 数值拍板权归 C3,候选改法列入待设计批清单,见 Notes
|
||||
|
||||
## Notes
|
||||
- **待设计批清单(超出本会话授权,列出不执行)**:① 墙语义候选改法(clamp 收紧至 -60/-70 / stack 乘法衰减 / heavy 拍穿防)归 C3 + /propagate-design-change;② B3 GDD "-50" 文字与 status_effects.tres 批注同步(09-13 批已登记随下次 B3 修订批);③ 当前墙残余 -40%/轮仍显著——是否越 F4 带(普通场 ≤20%、Boss 场 ≤50%)由本会话 Q1 复扫数据(production/session-state/active.md 41 条)供 C3 裁决,本会话未做任何数值拍板。
|
||||
- 原报 Action Routing 将本项路由至 /bug-report 与 /propagate-design-change 双通道:bug 通道结论 = 代码无缺陷(本档);设计变更通道 = 候选改法待 C3 拍板(上表)。
|
||||
|
||||
## Closure Record
|
||||
**Closed**: 2026-09-13
|
||||
**Resolution**: Rejected as coded——攻击链无缺陷(fresh 池全额兑现 + 击倒可达);零承伤根因 = defense_up 叠满墙(设计语义,旧数据 -50×2 = clamp 触底 ×0),09-13 调参批已拆除归零能力。沉淀 = fresh 池攻击链回归断言(无游戏数值变更)。
|
||||
**Fix commit / PR**: 不适用(变更 = smoke/smoke_all.gd `_smoke_attack_chain_fresh_pool` + smoke/damage_probe.gd 探针)
|
||||
**Verified by**: 2026-09-13 会话(damage_probe boss 模式 7/7 PASS + smoke_all 148/148)
|
||||
**Closed by**: 用户授权任务(playtest-2026-09-12 报告 Top3 执行会话)
|
||||
**Regression test**: `smoke/smoke_all.gd` `_smoke_attack_chain_fresh_pool`;`smoke/damage_probe.gd -- boss`(Run A fresh 池裸验 / Run B 墙行为实测)
|
||||
**Status**: Closed
|
||||
@@ -0,0 +1,62 @@
|
||||
# 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
|
||||
@@ -0,0 +1,65 @@
|
||||
# Playtest Report — Dungeon Sweeper 战斗阶段垂直切片
|
||||
|
||||
> 判定:**INCOMPLETE**(两次中断的试玩尝试,定性反馈未采集)· Review mode: lean(CD-PLAYTEST skipped — Lean mode)
|
||||
> 技能:/playtest-report(analyze 模式,原始素材 = 本会话用户反馈 + 崩溃日志 + 仪器数据)
|
||||
|
||||
## Session Info
|
||||
- **Date**: 2026-09-10 ~ 2026-09-11(两次中断的试玩尝试)
|
||||
- **Build**: 垂直切片(拍板①–④落地版:atk=6 先手 / 两级奖励 / 库存关内延续 / 窗口单件)
|
||||
- **Duration**: 未完成一场完整战斗(两次均在循环中途中断)
|
||||
- **Tester**: 用户(设计师本人,唯一测试者)
|
||||
- **Platform**: PC · KB+M
|
||||
- **Session Type**: First time ×2(均为中断重试)
|
||||
|
||||
## Test Focus
|
||||
战斗阶段完整循环:开战 → 挖掘/旗/停手 → 七段结算逐行兑现 → 胜负;含 2026-09-11 新机制(主角先手、即时奖励、库存延续)。
|
||||
|
||||
## First Impressions
|
||||
- **未采集**——两次均未撑到可评估的时长。唯一间接信号:用户问"是否有图像"(程序化色块+文字的观感被注意到,属预期内的占位表现)。
|
||||
|
||||
## Gameplay Flow
|
||||
### What worked well
|
||||
- 核心循环链路本身可走通:挖掘、插旗、结算弹出、道具窗口、关卡过渡(第二场试玩已推进到"胜利→库存/HP 带入下一层"节点才崩溃)。
|
||||
- 结算明细逐行输出正常工作(崩溃均发生在呈现层读数,流水内容无恙)。
|
||||
|
||||
### Pain points
|
||||
- **崩溃 #1(High)**:第一轮结算弹道具窗口即假死——窗口数据缺 `round_index` 字段,弹窗构建崩溃但输入锁已上,游戏无声冻结。用户被迫中止。
|
||||
- **崩溃 #2(High)**:胜利/关卡过渡时再次报错——`battle_finished` 信号发出前 `hero` 已被销毁,UI 读 `hp` 崩溃,结算覆盖层未显示。
|
||||
|
||||
### Confusion points
|
||||
- 用户问"是不是设置了断点"——假死无任何提示,玩家无法区分"卡了"与"在等输入"。(呈现层崩溃静默锁输入 = 设计缺陷级体验问题,不只是代码 bug。)
|
||||
|
||||
### Moments of delight
|
||||
- 未采集。
|
||||
|
||||
## Bugs Encountered
|
||||
| # | 描述 | 严重度 | 可复现 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 道具窗口数据缺 `round_index`,弹窗构建崩溃→输入锁死 | High | 是(固定流程必现) | ✅ 当日修复+字段契约断言入冒烟 |
|
||||
| 2 | `battle_finished` 载荷缺 hero 状态(despawn 先于信号),胜利过渡崩溃 | High | 是(打到胜利必现) | ✅ 当日修复(载荷销毁前捕获)+冒烟适配 |
|
||||
|
||||
**共性根因**:呈现层与核心间"信号载荷/时序"契约未成文;GDScript 编译不查这两类错;冒烟从未执行 main.gd。防复发已登记为 D1 GDD 三条硬性要求(载荷 schema 成文 / 场景级 headless 测试 / 状态可见性规则)。
|
||||
|
||||
## Feature-Specific Feedback
|
||||
### 全部新机制(先手攻击/两级奖励/库存延续/单件窗口)
|
||||
- **未采集**——机制是否"可感受、可归因、有趣"没有任何用户输入。
|
||||
|
||||
## Quantitative Data(注意:来自自动玩家,非人类试玩)
|
||||
- 蒙特卡洛 60 场(30 种子 × L1/L2,理性政策):胜轮均值 1.80、每轮承伤均值 2.1–2.7(max_hp=50 的 0–16%)、每场恰清图 1 次、败北 0。
|
||||
- 与设计意图冲突:**多轮结算仪式感 / RAP 取舍 / 囤刀时机未获得发生空间**(B4 失衡预警⑥定量坐实)。
|
||||
|
||||
## Overall Assessment
|
||||
- **Would play again**: 未采集(用户实际行为 = 两次遇崩即报,信任受影响——"写代码没检查依赖吗")
|
||||
- **Difficulty / Pacing**: 未采集(人类视角);仪器视角 = 过易、过快
|
||||
- **本轮试玩判定:INCOMPLETE**——循环完整性与 P2 归因("这个结果是我哪步扫雷带来的")这两个切片核心验证问题均未得到回答
|
||||
|
||||
## Top 3 Priorities
|
||||
1. **修复后完整重跑一次试玩**(当前 build 冒烟 43/43)——采集首轮真正的定性反馈:归因清晰度、结算节奏、新机制手感
|
||||
2. **难度带拍板**(C3 域):以期望表为靶(期望胜轮带/承伤占比),用 monte_carlo.gd 验算 knob 方案
|
||||
3. **headless UI 冒烟**:真实实例化 main 场景跑完整对局——把"呈现层从未被执行"的盲区关死
|
||||
|
||||
## Action Routing(Phase 3)
|
||||
- Bug ×2:已修复;如需正式追踪 → /bug-report 建档
|
||||
- 平衡项(预警⑥)→ /balance-check + C3 期望表
|
||||
- 设计变更:暂无(人类定性反馈为零)
|
||||
- Polish:占位视觉 → 格子样张测试(art-bible 既有任务)
|
||||
@@ -0,0 +1,93 @@
|
||||
# Playtest Report — Dungeon Sweeper 战斗阶段垂直切片(第 2 次)
|
||||
|
||||
> 判定:**COMPLETE**(首次完整通关的真人局,定性反馈两条,均有遥测坐实)· Review mode: solo(CD-PLAYTEST skipped — Solo mode)
|
||||
> 技能:/playtest-report(analyze 模式,原始素材 = 本会话用户口述 + playtest JSONL 遥测 + 代码/数据核对)
|
||||
|
||||
## Session Info
|
||||
- **Date**: 2026-09-12 20:13(主分析局);20:41 辅助局(调参面板加成后)
|
||||
- **Build**: 垂直切片 · 2026-09-12 五区改造批 + BUG-0001 修复前;数据 = v3 调参批(enemy.tres 18:05:atk 7/5/9/6/9、Boss 150)
|
||||
- **Duration**: 完整一关(7 节点:battle×2 → reward → battle×2 → rest → boss,12 个结算轮)
|
||||
- **Tester**: 用户(设计师本人,唯一测试者)
|
||||
- **Platform**: PC · Win10 · Godot 4.7.2 · seed 42(固定种子)
|
||||
- **Session Type**: Returning(第 3 次尝试,首次跑通全程——09-11 两局均被崩溃阻断)
|
||||
|
||||
## Test Focus
|
||||
两条旧问题的复核:① 道具获取(治疗稀缺性 / 伤害:治疗 9:1 体感);② 难度曲线(到 Boss 房前满血)。
|
||||
|
||||
## First Impressions
|
||||
- 未单独采集(用户直接进入两条旧问题反馈)。
|
||||
|
||||
## Gameplay Flow
|
||||
|
||||
### What worked well
|
||||
- **核心循环首次完整走通**:挖掘 → 结算七段 → 道具窗口 → 关卡节点(reward/rest)→ Boss → level_end victory,全程无崩溃。09-11 报告的两个 High 崩溃与 BUG-0001 软锁家族未复现(BUG-0001 修复批 20:23 落地,主分析局在其之前——悬停路径未触发,属幸存而非验证)。
|
||||
- 窗口 usable_now 投影工作正常:满血下治疗包全程禁选(usable_now:false),玩家实际行为 = 连续 skip,机制按设计执行。
|
||||
|
||||
### Pain points
|
||||
- **P1(旧问题②):全关零承伤**——12 个结算快照 hero hp 恒 50/50,Boss 房前满血、Boss 战后仍满血。对照 C3 F4 目标带(普通场承伤 ≤20%、Boss 场 ≤50%):实测 0%,越带。详见「根因分析」。
|
||||
- **P2(旧问题①):治疗包体感过剩**——Boss 战结束时库存 3 件治疗道具 + 已用 1 把小刀;用户体感"9:1 完全反过来"。实现核对结论:**9:1 配比实现正确,体感由三个结构性放大器制造**(见根因分析)。
|
||||
|
||||
### Confusion points
|
||||
- 未采集。
|
||||
|
||||
### Moments of delight
|
||||
- 未采集。
|
||||
|
||||
## Bugs Encountered
|
||||
| # | 描述 | 严重度 | 可复现 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | **浅深度战斗零敌人**:两场真人局中 d0 战斗(20:13 还含 d1)`unit_count=0`、round 1 即 victory——遭遇骰/spawn 路径疑似缺陷(C3 Rule 8 区间 [unit_count, unit_count_max] 最小值 1,不应掷出 0) | Medium | 两次真人局均现(d0 100%) | 待查——建议 /bug-report 建档 |
|
||||
| 2 | **Boss 攻击拍零兑现**:ogre_chief(pattern [attack, attack, charge, heavy])在两局中共 7 个存活结算轮,快照 beat 轮转正常(advance 在跑)但英雄血量纹丝不动——攻击链对该敌未生效(普通敌在 20:41 局 fresh 池轮正常承伤:d1 r1 −34、d3 r1 −9, ambush 乘区算术精确吻合) | High | 两局均现 | 待查——与下条根因共用一个探针 |
|
||||
| 3 | (轻微)`grant_node_active` 直调 stock、不经 `_supply.notify_granted()`——节点奖励完全绕开供给控制器计数,关卡级供给总量失控的结构性漏洞之一 | Low | 结构性 | 待登记 |
|
||||
|
||||
## 根因分析(本次报告核心增量)
|
||||
|
||||
### 问题②难度:v3 调参为何无效
|
||||
- **防御墙机制**:defense_up = stack 策略 × magnitude −50 × max_stack 2,池 clamp [−100, +100](settlement.tres)→ **同轮叠两层 = 100% 免伤**。它在**授予段生效、先于战斗段**——当轮挖到的减伤当轮即全额兑现。
|
||||
- defense_up 权重 24/75 = 安全格池**最高**单行(32%/grant),每轮 7–14 安全格 × ~44% 授予率 ≈ 3–6 次 grant → 单轮叠满两层的概率常在 25–50% 区间;20:13 主分析局 12/12 轮零承伤。
|
||||
- **结论**:v3 批选的主杠杆"atk +50%"是**乘在 ×0 上的调参**——墙不拆,任何 atk 曲线都无效。C3 F4 的 E[减伤] 估算(0.44 × 50% ≈ 22%)严重低估了 stack-to-clamp 的实际行为(实测 ≈100%)。
|
||||
- **未闭合点**:20:41 辅助局 fresh 池轮普通敌正常承伤(−34/−9 精确吻合 ambush 算术),但 Boss 轮 fresh 池仍零承伤——"防御墙"与"Boss 攻击链缺陷"两嫌疑并存,**一次 instrumented headless 探针即可分割**(逐结算行打印 beat/atk.total/pool/d_tick)。
|
||||
|
||||
### 问题①道具获取:9:1 没有反,但体感是真的
|
||||
- **配比核对(三路径全部正确)**:active_inject 池 knife_t1 60 / knife_adv 30 / heal_pack 10 = 9:1(reward.tres 89–93 行注释明示"治疗资源宝贵");grant_node_active 同池同比;B1 分流正确(即时类当场兑付、道具类入库)。
|
||||
- **本局实测**:4 次可选类获取 = 3 治疗包 + 1 小刀(Boss r6 用刀后剩 3 治疗包——与用户口述完全吻合)。按 9:1 单次 10% 治疗率,该组合概率 ≈ 0.4%——但 **seed 42 固定**,这条 RNG 轨迹每次重开都原样重放,"反过来"的体感被逐次确认。
|
||||
- **三个结构性放大器**(配比正确也挡不住):
|
||||
1. **供给量**:09-11 供给控制器批把可选类从格子权重池改为"每战斗首件保证 + 指数递减"——每关 4 战斗 × 首件保证 + 1 奖励节点 + 递减重注 ≈ 4–5 件/关(P(≥1 治疗包) ≈ 40%),且节点奖励绕开控制器(Bug #3)再放大;
|
||||
2. **满血累积**:难度零压力 → heal_pack 永远 usable_now=false → 只进不出堆在库存里,显著度极高;
|
||||
3. **固定种子**:seed 42 让坏抽变成"每次都一样的坏抽"。
|
||||
- **耦合结论**:问题①与问题②**互为放大器**——20:41 辅助局(有承伤)里奖励节点的治疗包在 70/100 时被立即使用。难度修好后治疗包消耗通道自然打开,体感问题预计大半自行消解。
|
||||
|
||||
## Feature-Specific Feedback
|
||||
### 可选类供给控制器(09-11 批)
|
||||
- 机制按设计运转(首件保证/递减/永不绝育均可在遥测中辨认);但"每战斗"首件保证在 4 战斗关卡结构下的总供给量是否偏离"治疗是稀缺奖励"的原始意图,**归 C3 重新拍板**(候选:首件保证升到关卡域、或 inject 池治疗行单独降权)。
|
||||
|
||||
### 难度(v3 调参批后复测)
|
||||
- 承伤 0% vs 目标带 ≤20%/≤50%:**严重越带**;通关率 100% vs F5 基线带 40–60%:越带。与 enemy.tres v3 注释自认的"难度严重不足"一致——**调参后未复测即判定"已处理"是本问题拖延三轮的直接流程原因**。
|
||||
|
||||
## Quantitative Data(遥测实测,playtest_42_20260912T201317.jsonl)
|
||||
- 12 结算轮 / 7 节点 / level_end victory;hero hp 全程 50/50;ambush_layers 恒 0;buffs[] 恒空。
|
||||
- 敌情:d0/d1 空场;d2 bugbear 40hp(2 轮);d3 bugbear 18hp(2 轮);boss ogre 150hp(6 轮,beat 轮转 attack→attack→charge→heavy→attack,兑付伤害 0)。
|
||||
- 输出侧:charge_dmg_a 7–14/轮,boss 逐轮 −21/−16/−53(含 clear_blast 40)/−16/−24/−20——**英雄输出正常,Boss 3–6 轮内可斩**。
|
||||
- 可选类供给:4 获取(3 heal_pack + 1 knife_t1)/ 1 消耗 / 3 库存残留。
|
||||
- 20:41 辅助局(调参面板 max_hp 100 + atk 加成):普通敌承伤正常(−34/−9),Boss 仍零承伤;治疗包在缺血时正常消耗。证明消耗通道与攻击链在普通敌上健康,Boss 路径存疑。
|
||||
|
||||
## Overall Assessment
|
||||
- **Would play again**: 未采集(用户两轮即时反馈 = 高关注信号)
|
||||
- **Difficulty**: 严重不足(0% 承伤,越带)——**非数值问题,机制性免伤墙 + 疑似 Boss 攻击缺陷**
|
||||
- **Pacing**: Boss 战 6 轮偏拖(输出侧正常但无压力回报)
|
||||
- **本轮判定:COMPLETE**——两个旧问题本轮均拿到机理级解释,不再停留在"感觉不对"
|
||||
|
||||
## Top 3 Priorities
|
||||
1. **一次 instrumented 探针分割零承伤根因**:headless 逐结算行打印 beat / atk.total / hero_defense 池值 / d_tick——区分"defense_up 叠满墙"(设计变更)与"Boss/敌攻击链缺陷"(bug 修复)。**这是两问题的共同前置。**
|
||||
2. **拆墙后重调难度带**:多种子 level_monte_carlo 对 C3 F4/F5 期望表复算(承伤 ≤20%/≤50%、通关率 40–60%),禁止单种子判定;v3 的 atk 值此时才第一次真正参与计算。
|
||||
3. **供给量重拍板 + 节点奖励纳入控制器**:C3 裁决"每战斗首件保证"的总量语义(候选:关卡域首件);grant_node_active 补 notify_granted 上报;评估用种子轮换(seed 42 单轨迹不能作为平衡证据)。
|
||||
|
||||
## Action Routing(Phase 3)
|
||||
- **设计变更**(防御墙语义:stack×2→clamp −100 = 免伤;候选改法:clamp 收紧至 −60/−70、乘法衰减、重击拍穿防)→ `/propagate-design-change design/gdd/b3-status-effect.md`(连带 B1 池 clamp 语义 + C3 F4 估算式修正)
|
||||
- **平衡调整**(墙拆除后:atk 曲线/Boss hp/供给量对 F4/F5 期望表复算)→ `/balance-check`
|
||||
- **Bug**(浅深度空遭遇 #1;Boss 攻击零兑现 #2;节点奖励绕过供给计数 #3)→ `/bug-report` 正式建档
|
||||
- **Polish/观测**:治疗包满血堆积的呈现(现有 usable_now 禁选已正确,难度修复后观测残留量)→ 记入失衡预警②仪表(短缺半)
|
||||
|
||||
## 与既往报告的追踪关系
|
||||
- playtest-2026-09-11(INCOMPLETE):Top2"难度带拍板"→ v3 批(09-12 18:05)只调了 atk、**未复测**→ 本轮证实无效 + 根因前置(防御墙)。状态:**未解决,根因收窄**。
|
||||
- 治疗稀缺化(09-11 两级奖励批):配比 6%→inject 池 10%(9:1)**实现正确**;本轮体感失效根因 = 供给量 + 满血累积 + 固定种子,非配比。状态:**配比已解决,体感未解决,路径已明确**。
|
||||
Reference in new issue
Block a user