十五条规矩
每一条都是在真实对局里踩出来的。写 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 下只看得见视野里的单位、物品、生产和事件,擂台就是这个规则。现在就按公平模式写,将来上 对战平台 不用改。详见 公平模式。