从 0 到 1:一个 SLG 游戏的基础架构、Tick 优化与扩展方向
在写 SLG(策略类)游戏时,真正决定系统能走多远的,从来不是玩法堆得有多满,而是底层结构是否稳定、是否可扩展。
这篇文章记录的是我在实现一套 SLG 服务端基础架构过程中的完整思路:
- 如何从 0 到 1 搭建一个最小可运行的 SLG 骨架
- 在规模出现之前,提前解决 tick 驱动下的性能问题
- 以及这套结构未来可以如何自然扩展
一、设计起点:先保证结构能活下去
在一开始,我并没有急着实现复杂玩法,而是先给整个系统定下了几个不会轻易动摇的前提:
- 所有时间统一使用离散 tick,1 tick = 1 秒
- 地图结构与业务逻辑彻底解耦
- 玩家不是地图实体,队伍才是
- 行军、战斗都不做全量遍历,而是事件驱动
SLG 的复杂度,本质来自于:
大量对象 × 长时间等待 × 少量瞬时活跃
如果一开始就用“每 tick 扫一遍所有数据”的方式实现,后面规模一上来,几乎必然推倒重写。
二、地图层:节点是唯一中心
slg_map
slg_map 是整个地图系统的总入口,负责协调:
- 节点信息
- 行军调度
- 战斗调度
它本身不承载具体业务规则,而是作为调度和聚合中心存在。
graph:动态无权无向图
地图使用的是动态无权无向图。
graph 只负责一件事:
- 管理节点与节点之间是否连通
它不关心:
- 节点归属
- 行军时间
- 战斗规则
相邻节点之间的距离是一个逻辑约定值:
- 固定为 90 tick
这样做的好处是:
- 地图结构足够稳定
- 后续加入地形、科技、BUFF 修正时,不需要修改 graph 本身
node_info:节点业务信息
所有与节点相关的业务数据,都集中在 node_info 中,包括:
- 节点类型(大本营、小城、中城、大城、都城)
- 当前归属
- 是否存在守军
- 节点的战斗状态与战斗队列
在这套设计中,节点是 SLG 一切行为的中心。
三、行军系统:队伍才是地图实体
行军规则
- 玩家本身没有位置信息
- 只有队伍(team)可以行军
- 队伍从己方大本营节点出发
行军是按节点推进的:
- 每跨越一个相邻节点消耗 90 tick
- 到达节点后立即判断节点状态
节点处理规则非常明确:
- 空节点:直接占领
- 己方节点:允许继续行军
- 他方节点:停止行军,进入战斗流程
march_mgr:行军管理器
最直观、也最危险的实现方式是:
- 每个 tick 遍历所有正在行军的队伍
在队伍数量较少时问题不大,但这类实现方式几乎注定无法扩展。
因此,在行军调度上,引入了时间轮机制。
四、第一次优化:行军时间轮
行军的本质,是一个延迟触发事件:
- 队伍会在未来某个 tick 抵达下一个节点
march_mgr 使用时间轮来管理行军:
- 行军阶段注册为时间轮任务
- 时间轮随 tick 推进
- 只有到期的行军任务才会被处理
这样做的结果是:
- 不再遍历所有行军队伍
- tick 推进只处理“现在该发生的事情”
- 调度复杂度从 O(N) 降为 O(K)
这是系统从“能跑”走向“能长期跑”的关键一步。
五、战斗系统:节点驱动,而不是全图扫描
battle_unit 抽象
所有可参与战斗的单位统一抽象为 battle_unit,包括:
- 玩家队伍
- 节点守军 NPC
它们共享统一的战斗接口、状态和冷却规则。
npc:节点守军
npc 继承自 battle_unit,只存在于节点之上:
- 节点被占领时生成
- 被击败后移除
战斗基本规则
战斗以节点为单位调度:
- 一个 tick 内,一个节点最多处理 5 场 1v1 战斗
- 一个队伍在一个 tick 内只能参与一次战斗
当行军队伍进入敌方节点时:
- 行军终止
- 队伍进入节点战斗队列
六、第二次优化:节点战斗时间轮
如果每个 tick 都遍历所有节点检查战斗状态,性能同样不可接受。
因此,battle_mgr 同样采用时间轮思想:
- 只有存在战斗队列的节点才注册战斗任务
- 时间轮触发时才执行战斗
- 每次最多处理 5 场
若战斗尚未结束:
- 再注册下一次 tick 的战斗事件
最终效果是:
- 没有战斗的节点完全不消耗计算资源
- 热点节点才成为性能消耗点
- 战斗调度完全事件化
七、战斗结算与闭环
战斗结算规则保持简单一致:
- 胜利方占领节点
- 节点生成新的守军
- 失败方队伍返回大本营
队伍后续状态重新交由 march_mgr 管理,形成完整闭环。
八、为什么 Tick + 时间轮非常适合 SLG
SLG 中大量行为都具有共同特征:
- 行军等待
- 战斗排队
- 建筑完成
- Buff 到期
它们都是:
- 延迟触发
- 长时间等待
- 少量同时活跃
时间轮的优势正好与之匹配:
- 不扫描
- 不轮询
- 只处理到期事件
九、后续扩展方向
在当前架构基础上,可以非常自然地扩展:
- 地形、科技对行军时间的修正
- 多队伍混战与协同作战
- 联盟协防与援军机制
- 节点战斗优先级与排队策略
- 世界事件、赛季事件的 Tick 注入
这些扩展都不需要推翻结构,只是在节点与时间轮之上叠加规则。
结语
SLG 的难点不在于系统数量,而在于规模增长后的稳定性。
只要做到:
- 地图结构足够纯粹
- 行军与战斗完全事件化
- tick 推进不做全量遍历
这套 SLG 架构,就可以从 0 跑到 1,再从 1 稳定地跑到 N。
--完--
- 原文作者: 留白
- 原文链接: https://zfunnily.github.io/1/01/15/
- 更新时间:2026-08-08 01:40:44
- 本文声明:转载请标记原文作者及链接