Files
aetherbound-guild/docs/plans/M80_BATTLE_SIMULATION.md
T

5.0 KiB
Raw Blame History

M80 · 战斗模拟(脚本演示 → 真模拟)

Owner 决定(2026-09-15):选 B 继续——把战斗从"固定 9 拍脚本"变成读取内容规则的真模拟 (320 装备/100 敌人/60 遗物/36 特质/职业基础行动真正起作用),先做最小可玩循环。

Player-visible stopping point

一场战斗由 02_GAMEPLAY_AND_BALANCE.md 的规则决定:100ms tick 与固定优先级、Ready/Tempo 节奏、 reach/目标选择、Guard/护盾、伤害公式(含暴击与标签化随机)、击倒与线列收缩、目标/胜负判定; 玩家能看到的结果由内容决定(敌人规则、装备触发、职业基础行动、特质),而不是固定剧情演出。 表现层(战场/节拍/音效)继续由事件流驱动,视觉方向不变。

Authority

  • docs/02_GAMEPLAY_AND_BALANCE.md:§8 时间/事件/随机、§9 属性、§10 Ready 与自动行动、§11 目标/reach、 §13 治疗与保护、§14 移动/推拉、§15 伤害、§16 状态、§17 装备钩子、§18 死亡与替换、§19 控制/撤退/超时/胜负、§24 固定测试向量。
  • docs/05_CONTENT_CATALOG.md:职业基础行动与资源、特质、装备效果、敌人规则(逐行)。
  • 现有表现层事件契约(battle_live_art 的 kind/actor/target/amount 与 BAT 音效)保持不变。

Ordered steps(每步一个提交 + 一个窄门)

  1. B1(COMPLETE)战斗内核:runtime/domain/battle_simulation.gd —— tick 循环与优先级、 属性→派生(§9 公式)、Ready/Tempo、基础行动、reach/目标、Guard、§15 伤害(含暴击与标签化掷骰)、 击倒/线列收缩、胜负与日志;runtime/tests/battle/battle_core_test.gd(公式抽查 + 同种子逐字节一致 + 不同种子只改对应标签流 + 击倒→收缩→胜负)。
  2. B2(职业 COMPLETE)职业与特质:12 基础职业的行动表已就位——runtime/domain/profession_actions.gd (12 表 × 3 优先级行 = 36 行、12 个本地资源、reach 1/2/line 与 projectile/area/restore 语义,出处为 05_CONTENT_CATALOG.md 的 rules/cadence 与 02_GAMEPLAY_AND_BALANCE.md §5/§10),模拟按优先级行从下往上扫描: ABG_M80_PROFESSION_ACTIONS_OK tables=12 rows=36 resources=12 reach=2-line healing=true deterministic=true。 B2b(下一步)特质:36 特质的触发/效果数据 + 钩子机制(§17);本轮仅有条件行未实现的触发(敌方预警、 设备、链接等)在行扫描中按“未实现=条件不成立”处理,等对应系统在 B3/B4 落地。
  3. B3 装备与敌人:320 装备按触发类别实现(首次受击/换位联动/护卫转移/治疗联动/冷却…); 区域 1 的 12 条敌人规则;Boss 规则最小集。
  4. B4 合同结构与区域语法:12 回合制(round_count)、区域 1 的遭遇语法(reach/保护/推/弹幕屏)、 难度参数只改数值不改隐藏规则(§20)。
  5. B5 接线与门:用模拟事件流驱动现有战场表现/节拍/BAT 音效;全流程驱动换到真模拟; 双档双语探针 + 源绑定 attempt;真机可玩性由 Owner 验收。

Frozen scope

  • 表现层、页面、音频与内容数据不改(只改战斗的"规则来源")。
  • 不新增内容行;不实现设计文档之外的自创机制;数值一律取自文档公式。
  • 登录/联机、付费、语音等内容不在本里程碑。

B1 产出(2026-09-15)

  • runtime/domain/battle_simulation.gd:纯净、无引擎依赖的 tick 模拟(100ms/优先级简化、§9 派生(1/100 向下取整)、 §10 Ready/Tempo 与溢出保留、§11 side→reach→protection→frontmost 与 target_tie、§15 伤害与暴击、 Guard 吸收、§18 Fallen→线列收缩、§19 胜负、标签化掷骰与日志)。
  • runtime/tests/battle/battle_core_test.gd:派生/伤害公式抽查、同种子日志逐字节一致、跨种子 "首个目标一致 + 暴击流不同"、结果/收缩断言 → ABG_M80_BATTLE_CORE_OK derived=formula damage=formula deterministic=true labels=independent outcome=victory ticks=224。

Acceptance checks

  • B1:公式抽查与文档一致;同种子两次运行日志逐字节一致;标签化掷骰只影响自己的流; 0 HP → Fallen → 线列收缩 → 目标判定;无随机伤害方差、无隐藏命中率。
  • B2-B4:每条实现的规则可在 05_CONTENT_CATALOG.md 找到出处,且有对应断言。
  • B5:既有 30 个 marker 不回归;战斗探针(墨迹/尺度/节拍/音频)继续全绿。

Issue register

ID 状态 说明
M80-I01 OPEN 旧 battle_service 的 9 拍脚本是历史演示层;B5 接线后保留其回执/快照边界,替换事件来源
M80-I03 OPEN 职业优先级行的条件中有一批依赖 B3/B4 的系统(敌方预警/设备/链接/资源阈值);当前按“条件不成立”跳过,落地后逐行启用并补断言
M80-I02 OPEN 12 回合 × 16 合同的完整跑量平衡需在 B4 后用模拟批量跑数(经济/时长)复核