对战平台 · P6

让不同人的 AI, 在同一张地图上分出高下

公平只能由裁判保证,不能靠 Bot 自觉。Bot 永远碰不到共享内存:它只能拿到裁判按视野过滤过的观察,只能提交动作,每条动作先校验归属。

设计中 · 地基实验进行中 现在就按公平模式写
三种形态

按「公平能不能保证」排

本项目观察能力的来源,正是「客户端持有全部玩家的状态」—— 这对你自己的机器同样成立。所以公平只能来自一个大家都信任的裁判。先做 A,同一套协议直接升级到 B;C 只当娱乐。

A

本机擂台

一台机器一局游戏,Bot 各占一个槽,裁判进程替它们下令

裁判控制一切:视野、归属、节拍
适合:开发调试、本地联赛
B

托管天梯

A 搬到服务器;玩家上传 Bot,服务器在沙箱里跑

同 A,再加代码隔离
适合:公开比赛、排名
C

各自联机

每人在自己机器上跑游戏 + Bot,局域网对战

不能保证:注入的客户端能读全图
适合:朋友之间的友谊赛
裁判

一个进程,替两边下令

Bot A任何语言
Bot B任何语言
WebSocket · JSON
裁判(可信)
  1. 编排 选图、开局,按槽写种族和难度
  2. 节拍 每 T 游戏毫秒一拍(默认 200);锁步模式下发观察时暂停游戏
  3. 观察 快照 → 按每个槽的视野过滤 → JSON
  4. 动作 校验「单位属于这个槽」→ 预算(每拍条数、APM)→ 快车道批量下达
  5. 记录 每拍观察摘要 + 每条动作:可回放、可复盘、可做训练数据
  6. 判定 某槽没有建筑 → 出局;超时 → 按剩余战力 / 资源判
快车道 · player 车道 ×2
一局游戏 · 两个槽
协议草案 v0

观察进,动作出

任何能收发 JSON 的程序都能上场 —— 包括直接让大模型逐拍输出动作。用 SDK 写的 Python Bot 不需要改代码。

观察 只含我方单位 + 我方视野内的敌方单位;野怪、金矿按视野或开局公开
动作上限 每拍最多 32 条,超出的截掉(防刷命令拖慢裁判)
同一单位 同一拍只认最后一条
时间预算 拍长 × 0.9,超时这一拍空过;慢的一方自己吃亏,不拖别人
锁步 需要严格公平时,发观察时暂停游戏、收齐(或超时)再继续 —— 机器快慢不影响结果
交换出生点 同一对 Bot 双方各打一次,消除地图不对称
天梯 Elo / TrueSkill;每对至少 20 局再下结论(2 局能看出的最小胜率差约 60 个百分点)
{"t": "obs", "tick": 57, "gameMs": 11400, "me": 1,
 "res": {"gold": 320, "lumber": 150, "food": [18, 30]},
 "units": [
   {"id": 101, "type": "hfoo", "owner": 1,
    "x": -4500, "y": 2200, "hp": 380, "hpMax": 420}],
 "visibleEnemies": [
   {"id": 733, "type": "ogru", "owner": 2,
    "x": -3900, "y": 2500, "hp": 700}],
 "deadlineMs": 180}
每拍一份,只含这个槽的单位和它视野里的敌人。id 是裁判分配的稳定编号,整局不变。
地基实验

按顺序来,前一条不过不做后一条

#实验判据已知
1 一局里开 2 个槽,都不带内置 AI 两边单位都不动 槽位的 AI 标记和难度字段已知
2 替本机以外的槽下令 敌方槽的农民真的去采矿 最关键的一条:不过就只能退到「每个 Bot 一个客户端、走真联机」
3 按任意玩家号查视野 同一点对两个槽给出不同结果 引擎的可见性检查接受任意玩家号
4 程序化判胜负 一方建筑全灭时 1 秒内知道 事件总线有更直接的入口
5 锁步暂停 / 继续 暂停中收齐动作、恢复后生效 暂停已验证

顺带的一次检验:参考大脑现在大量依赖全图信息(比如电脑对手的进攻目标)。上擂台需要它换成门面接口、只用视野内的单位 —— 离开全图信息,它还剩多强?