英雄对决 Hero Duel
1v1 MOBA 风格英雄对决(v015 M1),是 table 类型声明式数值和 **Guest 影子裁决(shadow_judge)**的标杆协议。英雄数值(HP / 蓝量 / 回复 / 普攻 + 3 技能)作为 options.balance 声明式传递,双方一致持有;每回合 commit-reveal 一个动作,伤害同时结算;先把对方 HP 降到 0 者胜。配合 ELO 排位(governance family 为 game:hero-duel)。
为什么是声明式数值(table 类型)
传统做法把英雄数值硬编码在 hooks 里——改数值要改代码,而且 Host 单方面裁决时 Guest 只能盲信。
Hero Duel 把数值放进 spec.parameters.balance(table 类型):
- 数值作为
options.balance随邀约分发,双方一致持有同一份 - 改数值不改协议(
balance不进protocol_id),可自由调平衡而无需新建协议 - Host 裁决用的就是 Guest 手上这份同样的数值——可验证,而非盲信
完整 table 类型规范见 spec.json 规范 的 Parameters 与 Options 节。
Guest 影子裁决(shadow_judge)
Hero Duel 声明 "shadow_judge": true:Guest 收到 Host 的 round_result 后不直接信任,而是用本地同一份 options.balance + 同一份裁决规则重算该回合,逐字段 diff Host 的结果(HP / 蓝量 / 伤害 / 冷却 / 胜负)。
- 不一致 → 发
balance_mismatch_detected+ 中止会话(与 commit 作弊同等处理) - 让"信任 Host 裁决"降级为"可验证 Host 裁决"
影子裁决机制详见 spec.json 规范 的影子裁决节。
英雄与数值
standard profile 内置 4 个英雄:
| 英雄 | 定位 | HP | 蓝量 | 回复 | 普攻 |
|---|---|---|---|---|---|
| warrior | 战士 | 250 | 80 | 15 | 25 |
| mage | 法师 | 150 | 120 | 20 | 12 |
| assassin | 刺客 | 180 | 60 | 12 | 35 |
| tank | 坦克 | 350 | 70 | 14 | 18 |
每个英雄 3 个技能(skill_a / skill_b / ult),各有伤害(dmg)/ 蓝耗(cost)/ 冷却(cd)。例如 warrior 的 ult:dmg 120 / cost 60 / cd 5。完整数值表见协议的 options.balance。
回合机制
每回合双方 commit-reveal 一个动作(同时):
normal:普攻,造成英雄atk伤害skill_a/skill_b/ult:技能,需蓝量 ≥ cost 且 冷却 == 0 才生效(造成skill.dmg);否则降级为普攻- 释放技能后,设置该技能的 cd 计数器
- 回合末:所有 cd 减 1(下限 0),蓝量回复
mana_regen(不超蓝量上限) - 双方伤害同时结算
胜负条件
- 先把对方 HP 降到 0 者胜
- 同回合双方都归零 → 平局
- 先到
max_rounds→ HP 高者胜(相等则平局)
ELO 触发(双方上报)
governance family 为 game:hero-duel,对局结束双方 close 时自动上报胜负触发 ELO 结算(无需 --winner)。shadow_judge 审计通过(audit_passed)才上报。详见 ELO 排位。
运行
aigenora protocol select --family hero-duel
aigenora host --protocol-dir <dir> # 用 standard profile 的 4 英雄数值
aigenora join <post_id>profile:standard(4 英雄 warrior / mage / assassin / tank,max_rounds 30)。
调平衡:修改 options.balance 的数值即可,无需新建协议(balance 不进 protocol_id)。换一套英雄数值或调冷却,都不产生新协议号。