第一场战斗是怎样诞生的
人和 AI 一起做游戏 · 第 3 篇

本篇依据截至 2026 年 8 月 1 日的开发记录,回顾 2026 年 6—7 月的战斗实现;画面、单位分类与胜负规则对应当时版本。
在第 2 篇里,我们讨论了一个人和 AI 怎样分担做游戏的工作。这一篇进入游戏本身:第一场战斗需要哪些规则,才能从开始运行到结束。
把两组角色放进同一个场景,让它们播放奔跑和攻击动画,并不等于完成了一场战斗。画面可以很热闹,但只要玩家的操作不能持续改变局势,或者系统无法明确给出胜负,它就仍然只是一个演示片段。
《Kibble Street TD》的第一场战斗,真正需要解决的是一个更基础的问题:怎样让一组规则在无需人工修改内部状态的情况下持续推进,并最终得到结果。
最小闭环可以压缩成六个动作:能量恢复、玩家召唤、单位推进、进入距离后攻击、目标承受伤害、一方基地被摧毁。后来的角色动画、战场背景、道具、BUFF、音效和结算奖励都很重要,但它们必须建立在这条闭环已经成立的前提上。

先定义战场,而不是先堆画面
第一版先确定了四个固定锚点:玩家基地、玩家防御塔、敌方防御塔和敌方基地。双方单位从各自一侧进入战场,朝相反方向推进。逻辑上只需要一条横向战线,画面再用少量上下错位避免角色完全重叠。
这种结构刻意保持简单。基地负责承载最终胜负,防御塔负责让推进过程产生阶段性压力,单位则是玩家和敌方不断投入战场的变量。只要四个建筑的位置、阵营和生命状态确定,系统就有了一条可以计算的战线。

到本文记录的开发阶段,战场已经扩展为可拖动的长场景,但底层关系没有改变:玩家从左侧建立攻势,敌方从右侧按关卡时间表出兵,双方先经过防御塔,再接近对方基地。背景有多层,角色也会在视觉上错开,真正决定交战的仍是横向位置和攻击距离。
让一个单位完成完整生命周期
对第一场战斗来说,角色数量不是重点。更重要的是先让一个单位走完完整生命周期:被召唤、进入战场、寻找目标、向前移动、进入攻击距离、造成伤害,最后继续推进或者死亡退出。

每个单位至少需要几项可以计算的状态:属于哪一方、所在位置、生命值、移动速度、攻击力、攻击距离和攻击间隔。系统每次推进时间时,都根据这些状态决定它下一刻该移动还是攻击。
如果范围内没有有效目标,单位向敌方方向移动;如果目标进入范围,单位停止移动并进入攻击;攻击间隔结束后产生伤害;目标失效后再继续寻找。这样一来,画面上的“跑过去打人”就不再是一段预先编好的动画,而是规则运行后的可见结果。
本文记录阶段的《Kibble Street TD》有坦克、近战、远程和攻城四类单位。它们在生命、速度、距离和攻击节奏上承担不同作用,但第一版验证的不是这些数值是否已经完美,而是四种单位能否遵守同一套状态规则。只有公共规则稳定,后续调整角色差异才不会演变成四套互不兼容的实现。
能量把点击变成选择
如果召唤单位没有成本,玩家只需要不断点击速度最快或伤害最高的按钮,战斗很快会退化成操作噪声。能量系统的作用,是让每次点击都带有机会成本。

战斗开始后,能量持续恢复,但存在上限。每类单位消耗不同数量的能量,同时还有自己的召唤冷却。玩家因此需要在“现在派出较便宜的单位”和“等待更高成本单位”之间做决定。
这套设计也给敌方时间表提供了意义。敌方不是等待玩家触发才行动,而是按关卡安排自动出兵。玩家的资源恢复与敌方压力同时推进,战斗才会形成节奏,而不是一方完成动作后另一方才开始响应。
这里同样先做规则,再谈平衡。能量上限、恢复速度、单位成本和冷却都可以继续调整;但“资源恢复—支付成本—进入冷却”这一关系必须先完整运行。后续数值专题中,调整的是这套系统里的参数,而不是重新发明出兵方式。
距离让战斗真正发生在空间里
只有生命值和攻击力,战斗仍然可能只是两张表互相扣数字。距离加入以后,位置开始影响结果:近战必须更接近目标,远程可以在更远处开火,防御塔能够覆盖附近区域,移动速度也会改变单位何时加入交战。
当时的规则会在攻击范围内优先寻找敌方单位,其次是防御塔,最后才是基地。没有目标时,单位继续向前推进。这一顺序保证了战线不会轻易绕过眼前敌人,也让防御塔成为通往基地之前的明确障碍。
目标选择后来经历过多次调整,攻击表现也从即时扣血发展到区分近战命中与飞行物到达。之所以能够持续修改这些细节,是因为“位置—距离—目标—伤害”的主链路从开始就独立存在,没有被绑定在某一张动画或某一个按钮上。
胜负必须由系统明确结束
一场战斗需要终止条件。《Kibble Street TD》当时的核心判断很直接:敌方基地失去战斗状态,玩家获胜;玩家基地失去战斗状态,玩家失败。防御塔被摧毁会改变战线,却不会直接结束战斗;当时的规则也没有用倒计时替代基地胜负。

这个判断看似简单,却决定了很多后续工作应该接在哪里。结算界面、奖励、关卡进度、再次挑战和返回首页,都只能在战斗系统给出唯一结果后启动。否则画面可能已经显示胜利,仍在飞行的攻击却继续结算,或者两个页面同时认为自己拥有控制权。
因此,结束并不只是弹出一张结果面板。系统还要停止接受召唤、清理尚未结算的攻击,并把战场状态交给结算流程。第一场战斗到这里才算真正闭合。
先计算,再把结果交给画面
《Kibble Street TD》的开发顺序,是先建立与画面表现分离的战斗模拟,再接入每帧驱动、战场渲染、按钮和 HUD。配置负责提供关卡、单位、建筑与规则;模拟负责推进状态;状态快照把当前能量、单位、建筑和结果交给表现层;表现层只负责把这些结果画出来。

这条边界避免了一类代价很高的返工:换一套角色动画,不应该改变谁先受到伤害;调整界面布局,也不应该影响能否召唤单位。后续命中时机、目标优先级、BUFF 和战斗道具不断增加,最小闭环仍然可以作为共同底座。
第一场战斗的意义因此不在于“已经像成品”,而在于项目第一次拥有了可持续扩展的中心。只要召唤能够进入战线,战线能够产生伤害,伤害能够导向胜负,后续内容就有了明确的接入位置。
这个环节由谁负责
人负责确定核心体验和验收边界:玩家为什么要做选择,什么条件算胜负,哪些规则必须先做,哪些表现可以延后,以及试玩时的节奏是否成立。
AI 负责把规则整理成可执行状态,检查现有调用链,补全配置、模拟和验证入口,并通过重复运行发现状态冲突。它可以帮助检查固定配置与输入下规则是否稳定推进;涉及随机性时,还需要控制随机种子,但不能替代人判断战斗是否有压力、单位差异是否有意义。
画面、手感和数值都需要人工试玩确认;规则闭环则应尽可能由可重复检查守住。
如果准备做自己的第一场战斗
先写清五件事就足够开始:战场边界和双方起点;玩家可以发出的输入;单位必须保存的状态;移动、攻击和伤害怎样发生;什么条件让系统停止并给出唯一结果。
不要从角色数量、特效规模或完整 UI 开始。先用一个单位、一类建筑和一条终止条件证明闭环,再逐项替换为正式内容。这个版本可以很简陋,但它必须能够从开始独立运行到结束。
