Merge branch 'master' into criterion-rename-20261107

This commit is contained in:
DKChan committed 2026-11-07 07:39:25 +08:00
commit 7c3de01017
4 files changed
+190 -20

No files matched your search

@@ -0,0 +1,183 @@
# 需求卡片:结算期文字列表退役与日志零文案批
> 状态:待用户裁决(写完呈用户,开工令归 /iter 或用户另行发令)
> 验收档:中(依据 test-conventions §8.3:后果玩家可见但不损持久状态,本批不动存档写读、RNG 流、结算公式与数值表结构;用户批卡 U0 时可改判)
> 来源:`待办清单.md`「结算期逐行文字列表退役与日志零文案」条(2026-11-07 登记,来源=会话提及)
> **唯一事实源**=2026-11-07 用户裁定(会话设计讨论闭合、待裁点清零)+ `design/gdd/08-Alpha版本标准.md` v1.29(「逐行结算排播」行已删)+ `待办清单.md` 该条实况。三处 GDD 条款改写属实现批禁写面,列在第 6 节由文档批落文。
## 1 目标与完成定义
撤掉战斗屏结算期一行行滚动的文字列表;保留伤害飘字、攻击特效与站桩动画;日志侧零中文文案、只存结构化字段,并保证数值分析判读结论与改前逐位一致。
完成定义:①结算期 B 区不产任何逐行文字;②FX 排播链与两类 toast 仍在;③新日志 `step` 行零中文字段、原有全字段与全部 payload 仍在;④`tools/analyze_playtest.py` 对同一份历史锚与一份新日志的判读结论与改前一致;⑤每个需求点有从真实入口进入的正向验收断言并跑绿,读数写进该步提交信息。
## 2 设计事实源
- 用户裁定(2026-11-07 会话,待裁点清零、用户点头):撤掉结算期逐行滚动文字列表;保留伤害飘字与攻击特效;日志零文案只存字段;战斗画面优化另立待办。
- `design/gdd/08-Alpha版本标准.md` v1.29:「五、表现」表已删「逐行结算排播」行,「战斗演出链(弹道/受击/血条/灰化)在役」行保留。
- `待办清单.md` 该条实况与状态(写卡时推进为「文档设计已闭合+已写卡」)。
- 设计闭合凭据说明:req-card 第〇步要求的闭合凭据=用户裁定已落 `08-Alpha版本标准.md` v1.29;`battle.md`/`战斗结算.md`/`战斗表现.md` 三处条款改写不是设计待裁点,是按裁定的文档同步义务,按「实现批禁写 `design/`」纪律列进第 6 节与反哺点清单,由文档批落文。
## 3 现状事实(代码级考证)
| 事实 | 位置 |
|---|---|
| 结算行协议:`_emit_row()` 发 `step_row`,公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight+extra 全平铺 | `game/core/battle_orchestrator.gd:710-735` |
| 玩家侧逐行文字渲染(7 处读 display_name、BBCode 行模板、上轮摘要、聚合计数) | `game/presentation/views/battle_log_view.gd:87-103`、`:146-264` |
| 排播泵:文字入带是 `log_view.append_row/append_bb/finish_settlement_round`;FX 链是 `stage.on_step_row_fx`/`_play_cross_zone_fx`/`_play_settlement_mark`/`refresh_request`/`pump_ended` | `game/presentation/row_pacer.gd:83-101`、`:106-152` |
| 动画定位走 target/target_id,不读行文案 | `game/presentation/views/battle_stage_view.gd:327-344` |
| 两类 toast 仍读 display_name/display:清图奖励、Boss 半血解锁技名 | `game/presentation/main.gd:417-425`;`row_pacer.gd:97-100`;规格 `design/gdd/systems/战斗循环/敌人系统.md:207` |
| 日志逐行全字段落盘;中文字段两处=`text`(:138)与平铺进去的 `display_name`(:140-142) | `game/presentation/playtest_logger.gd:130-143` |
| 开新/续玩均开日志会话并挂接战斗 | `game/presentation/main.gd:247-253`、`:295-302`;`game/presentation/main_adventure_flow.gd:62` |
| 分析工具依赖 `text` 做四类判读:effect_id 反查、群伤奖励判定(两处)、未生效原因分类 | `tools/analyze_playtest.py:83-88`、`:189`、`:434`、`:471-478` |
| 群伤行已有结构化 `target: "all_enemies"`;未生效行散有 `batch_key`/`forfeit`/`deferred`,无统一「原因」字段 | `game/core/damage_controller.gd:515-516`、`:623-624`;`game/core/reward_grant.gd:269-271`、`:362-369`;`game/core/settlement/combat_segment.gd:123-124`;`game/core/settlement/grant_segment.gd:103`、`:321` |
| 玩家可见文案的现役测试/探针面 | `game/tests/README.md:135`;`game/tests/unit/presentation/theme_projection_test.gd:385`;`player_copy_sweep_test.gd:86-108`;`pacing_queue_test.gd:165`;`game/probe/ui_probe.gd:133-135`;`game/probe/ui_click_probe.gd:423`、`:473`、`:616`、`:798-844` |
## 4 设计契约(🔴 触碰=L3 停机呈报)
1. 🔴 保留伤害飘字、攻击特效、站桩闪白/弹道/灰化;`row_pacer.gd:89-101` 的 FX 调用链与 `pump_ended`/`refresh_request` 零删改。文字列表退役不等于取消结算演出。
2. 🔴 核心层 `step_row` 公共字段集不变:`display_name` 保留(清图奖励 toast、Boss 解锁技名 toast、历史日志兼容都读它);本批只改日志消费端与补 `reason` 这类结构化 extra,不动 `_emit_row()` 签名与载荷键集。
3. 🔴 日志逐行全字段落盘义务不变(kind/type/source/cell/round/value/highlight+全部 payload);只去掉 `text` 与 `display_name` 两份中文文案。
4. 🔴 数值与随机零改动;玩法数值只经 ConfigDB 单点,随机只经 RngService;Core 零 UI。
5. 🔴 实现批禁写 `design/` 整个目录、根规则文件与 `game/tests/README.md`(能力清单归写卡段维护);文档义务只进 `reports/` 反哺点清单。
6. 🔴 按 2026-10-24/2026-10-28 用户裁:禁变异类测试与撤销类取证,禁删断言/放宽阈值换绿;验收主力=从真实入口进入的正向断言,同种子复放对拍只作兜底。
## 5 范围边界
- 做:撤 B 区逐行文字(含上轮摘要、轮首分隔行、聚合计数行的文字呈现);日志零中文文案;补未生效原因的结构化字段;分析工具改读结构化字段;相关测试/探针改写成退役后的正向断言;能力行换代。
- 不做:战斗画面优化(另立待办,等用户发令)、美术资产、`design/` 三处条款改写(文档批)、日志采集面扩充(除 `reason` 外零新增)、`step_row` 行协议重构、`08-Alpha版本标准.md`(已落地 v1.29)。
- 不收件去向:动画密度与素材范围 →「战斗画面优化」待办;三处设计条款 → 反哺点清单;历史锚里的旧 `text` 字段 → 不改历史数据,分析工具保留旧日志兼容分支。
## 6 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| `design/ux/battle.md:157`/`:230`/`:304` | 结算期明细带逐行滚动;「结算逐行兑现不可整体跳过、只给减动效」 | 实现批禁写 `design/`;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后由文档批落文 |
| `design/gdd/systems/战斗循环/战斗结算.md:73`/`:87` | 明细流水是结算明细屏的数据源;「显示名等玩家可见文案是数据面字段、代码读表拼行」 | 同上 |
| `design/gdd/systems/战斗循环/战斗表现.md:53`/`:99`/`:149` | 结算逐行兑现是信息载体;因果可读验收「能说出这一行来自哪步操作」 | 同上 |
| `design/gdd/08-Alpha版本标准.md` v1.29 | 「逐行结算排播」行已删(合并 `f7d7761e`) | 已落地,本批零动作 |
| `game/tests/README.md:135` | 能力行「结算明细带逐行呈现与排播节奏」 | 实现批禁写;归写卡段维护,换代项写在 T3,本卡登记 |
| `体验验证清单.md:86`/`:206`/`:220`/`:314`/`:315`/`:326`/`:442`/`:519` | 逐行结算、明细带来源/行序/文案可读性、减半标签等目检项 | 实现批禁写根规则文件;列进反哺点清单,由文档批落文;真人目检登记不阻塞 |
## 7 文件结构图
| 路径 | 职责 | 行为/非行为 | 对照表行 | 复用/新增 |
|---|---|---|---|---|
| `game/presentation/views/battle_log_view.gd` | B 区文字列表渲染面退役(保留视图壳供挖掘期摘要位或整体退役,二选一定在 T1) | 行为改动 | R1 | 复用既有件,不新增 |
| `game/presentation/row_pacer.gd` | 移除文字入带调用,保留 FX 排播链 | 行为改动 | R1/R2 | 复用既有件 |
| `game/presentation/main.gd` | 组合根 `log_view` 接线与 `clear()` 调用面同步 | 行为改动 | R1 | 复用既有件 |
| `game/presentation/playtest_logger.gd` | 日志 `step` 行去掉两份中文文案 | 行为改动 | R3 | 复用既有件 |
| `game/core/damage_controller.gd`/`reward_grant.gd`/`settlement/combat_segment.gd`/`settlement/grant_segment.gd` | `reward_ineffective` 行补 `reason` 枚举 extra | 行为改动 | R5 | 复用既有 `_emit_row` 出口 |
| `tools/analyze_playtest.py` | 四处 `text` 判读改读结构化字段,保留历史锚兼容分支 | 行为改动 | R4 | 复用既有解析入口 |
| `game/tests/unit/presentation/*`/`game/probe/*` | 旧断言改写成退役后正向断言 | 行为改动 | R1/R2/R3 | 复用既有套件 |
| `game/tests/README.md` | 能力行换代 | 非行为改动 | — | 复用既有表行 |
| `reports/需求卡片-…`/实现报告/代拍板追认单/反哺点清单/验收审计 | 过程件 | 非行为改动 | — | 复用既有模板 |
## 8 落位与可复用性预检
- **复用面**:本批零新增视图、服务、工具脚本。`grep` 现成实现结果=文字渲染唯一在 `battle_log_view.gd`,排播唯一在 `row_pacer.gd`,日志落盘唯一在 `playtest_logger.gd:130-143`,分析判读唯一在 `tools/analyze_playtest.py`;同名同义标识符无第二处。新增文件只有 `reports/` 过程件与新增测试函数(落在既有套件内)。
- **唯一面**:`step` 行字段定义只在 `battle_orchestrator.gd:723-735`;`reason` 枚举取值只在第 9 节 T2 定义一次,四个发射点只引用不各自定义;日志行字段组装只在 `playtest_logger.gd:136-143`;分析工具的「旧日志兼容分支」只在 `effect_id_of()` 一处。
- **分层与交互面**:core 发 `step_row` → 呈现层 `row_pacer`/`playtest_logger` 并列订阅(删文字只动呈现层那条);`row_pacer` → `stage.on_step_row_fx`/`settlement_fx`/`board_zone` 的调用链不变;core 零 UI、数值经 ConfigDB、随机经 RngService 三条红线不因补 `reason` 而绕。
## 9 任务卡
估时合计 3.5–4.75 个工作日(软盒 5 日);T2 若 `reason` 枚举落点超 4 处,按「先 damage_controller+reward_grant 两处、再 combat/grant 两处」切成 T2a/T2b,不扩 T 卡验收面。
### T0 开工核对与改前基线(0.25 日)
取用:本卡第 3 节全部 file:line。产出:`sim-data/` 下改前判读基线读数一份(不入库)、T1..T4 共用的 `REASON_ENUM` 取值表。
- [ ] 逐条复核第 3 节 file:line 与现役代码一致,不一致处回呈写卡段,不改卡硬做。
- [ ] 跑 `python tools/analyze_playtest.py` 对现行历史锚出一份判读基线,落 `sim-data/` 并在实现报告登记路径。
- [ ] 跑 `python tools/run_all_gates.sh --docs` 确认写卡段文档域闸绿,回执记入实现报告。
### T1 撤玩家侧逐行文字(1–1.5 日)
取用:T0 复核结果、`battle_log_view.gd`/`row_pacer.gd`/`main.gd` 现役签名。产出:`row_pacer.log_view` 句柄与文字入带调用清零、FX 调用链原样。
- [ ] 在 `row_pacer.gd:83-101` 移除 `log_view.append_row(row)`、`log_view.append_bb(...)`、`log_view.finish_settlement_round()` 三处调用,保留 `:89-101` 其余 FX 调用与 `refresh_request.call()`。
- [ ] 在 `row_pacer.gd` 移除 `log_view: BattleLogView` 句柄声明与组合根注入面,保留 `stage`/`board_zone`/`settlement_fx`/`board_view` 四个句柄。
- [ ] 在 `main.gd` 移除 `_start_adventure`/`_resume_from_menu` 的 `ui.battle.log_view.clear()` 与 `wire_battle` 相关文字接线,`_on_step_row` 的清图奖励 toast 保留。
- [ ] 定 `battle_log_view.gd` 去留并落实现:视图壳整体退役或只保留挖掘期摘要位,二选一以「B 区结算期零文字节点」为准,改动写进实现报告。
- [ ] 从真实入口(停手→结算)跑 `battle_log_zero_text_test.gd:_smoke_settle_zero_rows`,断言结算期 B 区 `RichTextLabel` 行文本为空且无逐行追加,读数写进本步提交信息。
### T2 日志零文案与结构化字段补齐(1–1.5 日)
取用:`step_row` 行协议(公共字段+extra 全平铺)、`REASON_ENUM`。产出:新日志 `step` 行零中文字段、`reward_ineffective` 行带 `reason`。
- [ ] 在 `playtest_logger.gd:136-143` 从 `line` 去掉 `"text"`,并在 `:140-142` 平铺循环里跳过 `display_name`,其余字段与 payload 一行不减。
- [ ] 定义 `REASON_ENUM` 四个取值:`full_layers`/`full_hp`/`no_enemy_alive`/`hero_down`,只在本卡定义一次。
- [ ] 在 `damage_controller.gd:623-624`/`reward_grant.gd:269-271`、`:362-369`/`combat_segment.gd:123-124`/`grant_segment.gd:103`、`:321` 的 `reward_ineffective` 行 extra 各补一个 `reason` 键,取值按现文案对号入座。
- [ ] 从真实入口(开新局→真实结算→落盘 JSONL 读回)跑 `playtest_logger_step_fields_test.gd:_assert_no_text_and_full_payload`,断言 `step` 行无 `text`/`display_name`、且 `type`/`source`/`cell`/`round`/`value`/`highlight` 与全部 payload 键集与改前逐位一致。
### T3 分析工具、测试与探针正面化(0.75–1 日)
取用:T0 判读基线、T2 的 `REASON_ENUM`。产出:分析判读结论与改前一致、旧断言全部改写而非删除。
- [ ] 在 `tools/analyze_playtest.py:83-88` 的 `effect_id_of()` 保留旧日志 `text` 兼容分支,新日志分支改读 `effect_id`。
- [ ] 在 `:189`/`:434` 把 `"全体敌人" in r.get("text","")` 改读 `r.get("target") == "all_enemies"`。
- [ ] 在 `:471-478` 把未生效原因分类由 `text` 子串改读 `s.get("reason")`,四类取值与 `REASON_ENUM` 一一对应。
- [ ] 把 `theme_projection_test.gd:_smoke_battle_log_view`/`player_copy_sweep_test.gd:_sweep_source_names`/`ui_probe.gd:133-135`/`ui_click_probe.gd:423`、`:473`、`:616`、`:798-844` 的旧文字断言改写为退役后的正向断言(例:结算期零行文本、来源标签从数据表读而非从行文本读),逐条登记进测试削弱申报表。
- [ ] 同步 `game/tests/README.md:135` 能力行为退役后口径。
- [ ] 对同一份历史锚与一份新日志各跑一次 `tools/analyze_playtest.py`,判读结论与 T0 基线逐位一致,读数写进本步提交信息。
### T4 批末验收与产出物落位(0.5 日)
取用:T1..T3 各步读数、第 10 节对照表。产出:`reports/` 四份过程件。
- [ ] 按本批改动域跑重闸选档全绿,回执记入实现报告。
- [ ] 跑独立验收审计(入口 `reports/iter<N>-验收审计-<日期>.md`,由未参与实现的会话或子代理执行),未过不合并。
- [ ] 在轻闸全绿后、合并前写齐 `reports/` 三份:实现报告(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单、反哺点清单(第 6 节每条都有落点)。
- [ ] 用户目检项只登记不阻塞,登记完成即本卡义务了结。
## 10 验证闸(改动—验收对照表)
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|
| R1 结算期零逐行文字(design/ux/battle.md:157) | `battle_log_view.gd:87-103`/`row_pacer.gd:83-101`/`main.gd:417-425` | `battle_log_zero_text_test.gd:_smoke_settle_zero_rows`(新增,落在表现层单元套件) | 单元+探针 | 真实停手→轮末结算→读 B 区场景树与 `RichTextLabel` 行文本 | `step_row` 消费后 `RichTextLabel.append_text` 调用计数=0、parsed_text 空;不绑终屏态 | 新增:结算期零逐行文字与 FX 排播链保持 |
| R2 FX 与 toast 链不断(design/ux/battle.md:297) | `row_pacer.gd:89-101` 保留 | `pacing_queue_test.gd:_assert_fx_chain`(既有套件扩断言)+`standee_fx_sweep_test.gd:_init` | 单元+集成 | `step_row`→`row_pacer`→`stage.on_step_row_fx`/`settlement_fx` | `on_step_row_fx`/`play_damage_number`/`play_projectile` 调用计数与改前逐位一致 | 新增:结算期零逐行文字与 FX 排播链保持 |
| R3 日志零文案、字段不缺(design/gdd/systems/战斗循环/战斗结算.md:73) | `playtest_logger.gd:136-143` | `playtest_logger_step_fields_test.gd:_assert_no_text_and_full_payload`(新增) | 单元+集成 | `start_session`→真实结算→落盘 JSONL 读回 | 落盘 `step` 行键集:`type`/`source`/`cell`/`round`/`value`/`highlight`+全部 payload 与改前一致,且无 `text`/`display_name` | 新增:日志 step 行零文案与结构化判读等价 |
| R4 分析判读等价(design/engineering/test-conventions.md:133) | `tools/analyze_playtest.py:83-88`/`:189`/`:434`/`:471-478` | `analyze_parity_check.py`(新增,落在 `tools/`) | 工具/集成 | 同一份 `sim-data/` 历史锚+一份新日志各跑一次判读 | `eff_counts`/`reward_dmg`/未生效分类计数字典与 T0 基线逐位一致 | 新增:日志 step 行零文案与结构化判读等价 |
| R5 未生效原因结构化(design/gdd/systems/战斗循环/战斗结算.md:80) | 四处 `reward_ineffective` 发射点 extra 补 `reason` | `reward_ineffective_reason_test.gd:_assert_four_reasons`(新增,落在结算域单元套件) | 单元 | 真实结算产生满层/满血/无存活敌人/主角已倒下四类未生效行→`step_row` 载荷 | `step_row` 载荷 `reason` 键取值四类逐一命中,不绑终态结算结果 | 新增:日志 step 行零文案与结构化判读等价 |
**测试削弱申报**:随文字列表退役需改写的旧断言=`theme_projection_test.gd:_smoke_battle_log_view`、`player_copy_sweep_test.gd:_sweep_source_names`、`ui_probe.gd:133-135`、`ui_click_probe.gd:423`/`:473`/`:616`/`:798-844`、`pacing_queue_test.gd:165` 的文字呈现部分。一律改写为退役后的正向断言,**不删除、不放宽阈值、不缩小扫描面**;实现期出现未申报的删除断言由独立验收审计判红。
**独立验收审计**:`reports/iter<N>-验收审计-<日期>.md`,由未参与实现的会话或子代理执行,未过不得合并。
## 11 异常分级
- L1 自救:单件直跑出红,只重跑该红件最小单元(一次重试)。
- L2 记录继续:连续三次同红灯,记录进实现报告并继续本卡其余步骤。
- L3 停机写报告等用户:触碰第 4 节任一 🔴、分析判读结论与改前不一致且定位不到字段来源、独立验收审计未过。
## 12 代拍板白名单
1. 新增测试函数命名与落点(须落在第 7 节列出的既有套件/工具目录)。
2. `battle_log_view.gd` 视图壳整体退役 vs 只留挖掘期摘要位,以「结算期 B 区零文字节点」为判据自判,结论写进实现报告。
3. `reason` 四个枚举键在四个发射点的写法(照现役 `_emit_row` extra 模式,不新增helper)。
超出以上三项一律呈报。
## 13 待裁点
零待裁点。用户裁定已覆盖方向、保留面、日志口径与 08 清单行处置;开工门=U0(用户发令 /iter)。卡片写完呈用户裁决后才可开工。
## 14 复核记录
复核发现按四类去向逐条登记(自判/补写/待裁/退回上游);本节即复核凭据,不另设报告文件(2026-11-06 用户裁)。
| 发现 | 去向 | 处置结果 |
|---|---|---|
| 视图壳整体退役 vs 只留挖掘期摘要位 | 自判 | 以「结算期 B 区零文字节点」为判据自判,写进第 12 节白名单第 2 项 |
| 新增测试函数命名与落点 | 自判 | 写进第 12 节白名单第 1 项,落在第 7 节列出的既有套件 |
| `reason` 枚举键在四个发射点的写法 | 自判 | 写进第 12 节白名单第 3 项,照现役 `_emit_row` extra 模式 |
| 上一轮核查漏项:`tools/analyze_playtest.py` 四处读 `text` | 补写 | 补进 T2/T3/R4,并保留旧日志 `text` 兼容分支 |
| 未生效原因缺统一结构化字段 | 补写 | 补进 T2/R5,定义 `REASON_ENUM` 四个取值 |
| 验收对照表列名与 2026-10-24/10-28 两裁冲突 | 补写 | 第六列改「判据绑定面」,内容全改正向断言与改前改后对照 |
| req-card 第〇步「标题带设计面=标记」与现行 §12.1 模板冲突 | 补写 | 按现行规约,闭合凭据以用户裁定+`08-Alpha版本标准.md` v1.29 为准,第 2 节写明 |
零待裁点、零退回上游。
**自审六查**:①规格覆盖——第 1 节五条完成定义逐条指到 T1..T4 与 R1..R5,无悬空;②步骤扫描——每步一个动作+一个可核查结果,无「TBD/酌情/适当优化」;③类型一致性——`REASON_ENUM` 四个取值在 T2 定义、T3 与 R5 逐字引用;④审查焦点+改动覆盖——最可能坑到玩家的失败模式=FX 链被误删(R2 兜)、分析判读静默失真(R4 兜)、日志丢 payload(R3 兜),文件结构图每个行为改动都有对照表行;⑤篇幅比例——本卡以签名、取值、断言名为主,未抄函数体;⑥落位与复用——第 8 节三问逐条答完,零新增视图/服务/工具,与第 7 节「复用既有」标注一致。
**上一轮核查漏项补正详情**:此前报「日志零缺漏」时未查到 `tools/analyze_playtest.py:83-88`/`:189`/`:434`/`:471-478` 对 `text` 的四处判读依赖;本卡已列为 R4 并补 `reason` 字段(R5),不属新增需求,属用户令「缺什么补什么」的同批处理。