文档 核心概念

十五条规矩

每一条都是在真实对局里踩出来的。写 Bot 时对照一遍,能省掉大部分排查时间。

把这一页和 api.json 一起交给大模型,它写出来的 Bot 会少走很多弯路。

读状态

1. 读不到是 None,不是 0

resources()、time_of_day()、production()、cooldown() 都可能返回 None(载入中、单位没有细节、建筑没在生产……)。先判断再用:

res = g.resources()
if res is None:
    return

2. 用句柄认单位,别用地址

地址会被新单位复用:旧地址可能指到一个新出生的单位上。要跨拍记住某个单位,存 u.handle,用 g.unit(handle) 找回来。

3. 事件流是全局的

production.done、unit.died 里有对手的、野怪的。按 ev.owner(或建筑句柄)过滤:

if ev.kind == "production.done" and ev.owner == g.me():
    ...

4. 进了金矿的工人不在快照里

工人进金矿那一下会从快照里消失(unit.removed,不是死了)。要统计每座矿几个人,自己记账,别按快照剪账 —— 否则会往满矿里多派人。

下命令

5. 回执「接下」≠ 做成

树林里的建造点引擎也当场接下,工人走到才失败;技能可能被打断。效果看快照和事件:盖房子用 build_near(它跟踪地基是否出现),放技能看 g.cooldown() 有没有进冷却。

6. 看不见的目标不能打

对迷雾里的敌人下目标命令会被拒,原因码 1001。想追迷雾里的敌人,对它最后出现的位置 attack_move。

7. 只给闲着的单位下令

每拍给同一个单位重下同一条命令会打断它:兵在原地抽搐,农民的采集周期归零。判断「闲不闲」用 g.order_of(u)(含你这一拍刚下的),别用快照里的 u.order(快照还没追上)。

8. Shift 只有「插在当前后面」

引擎没有「追加到末尾」:连着用 queue='after' 发 B、C,会得到 A、C、B。按顺序走一串点用 g.path(units, 点列表),一个工人连造几座用 g.build_queue(worker, 计划) —— 它们会倒序插入,替你处理好。

9. 一拍的命令一批发

几十条命令逐条发,要等几十次游戏线程;包进 with g.batch(): 只等一次。

经济与生产

10. 一矿最多 5 个工人

再多不涨收入。工人目标跟着矿数走:每座矿 5 个采金,再加几个伐木。

11. 训练队列只排 1 个

排满 7 格会把钱锁在队列里(实测大厅排了 4 个农民、300 金锁住,开局慢一大截)。g.queue(b) 空了再排下一个。

12. 人口卡住看生产表

g.production(b).blocked = 有排队但没开始,多半是人口不够。它比「人口快满了再盖」早一步:打仗掉了一片兵、补兵时队列一卡就知道。

13. 英雄唯一,大厅队列没空时不能升本

  • 英雄死了只能 g.revive(祭坛),再训练会被拒(221);复活也要人口(英雄占 5)。
  • 大厅队列里还有东西时不能升级大厅(原因码 185,「建筑正忙」)。

时间与空间

14. 2 倍速下别按墙钟等

想等 3 游戏秒,就看 g.clock() 涨了 3,不是 sleep(1.5)。倍速下引擎时钟比墙钟走得快。

15. 岛图、树林图别用直线距离

选野点、选分矿用 g.path_distance(a, b)(地面 A*,绕树林、悬崖、建筑),走不到返回 None。直线最近的那个点,可能在海对面。

还有一条:按公平模式写

--fair 下只看得见视野里的单位、物品、生产和事件,擂台就是这个规则。现在就按公平模式写,将来上 对战平台 不用改。详见 公平模式。