《游戏服务端编程实践》1.2.3 SLG / 策略类游戏架构模式详解

解析 SLG(策略模拟类游戏)的架构模式,包括其在游戏生态中的定位、主要功能与技术要求。

一、SLG 的本质与技术特征

1.1 什么是 SLG

SLG(Simulation Game / Strategy Game),即“策略模拟类游戏”,
是以 资源规划、领地扩张、部队调度、长期运营 为核心玩法的游戏类型。
其典型代表包括:

  • 《文明》系列(单机策略)
  • 《率土之滨》《三国志战略版》(MMO-SLG)
  • 《部落冲突》《海岛奇兵》(休闲策略)
  • 《Evony》《Lords Mobile》(全球化跨服 SLG)

1.2 SLG 的技术定义

SLG 与 MMO 一样具备多人在线特征,但其 核心架构差异 在于:

对比项MMOSLG
玩法核心实时交互、即时战斗异步调度、战略规划
时间尺度秒级(实时)分钟/小时级(异步)
网络模型长连接(实时同步)短连接 + 长轮询 / WebSocket
状态粒度高频状态(移动、技能)低频状态(建筑、行军)
并发类型高频帧事件异步任务
存储重点临时内存状态数据持久化一致性
算法侧重延迟补偿与预测任务调度与离线计算
防作弊重点输入验证状态签名与冷却校验

1.3 SLG 的工程本质

SLG 服务端的本质,是一个 “分布式任务调度系统 + 状态机框架”

每一位玩家的世界(城市、军队、科技)都对应一组持久化状态,
服务端持续驱动这些状态随时间演化(资源增长、建造完成、行军抵达)。

因此,与实时帧同步的 MMO 不同,SLG 的关键挑战在于:

  • 如何在海量异步任务中保持 状态一致性
  • 如何在千万级玩家下实现 低成本持久化与负载分布
  • 如何确保 事件时间驱动(Time-driven) 的正确性。

1.4 SLG 架构核心思想

SLG 的架构可以简化为以下逻辑模型:

graph TD
Client --> Gateway
Gateway --> Logic
Logic --> Scheduler
Scheduler --> DB[(Database)]
Scheduler --> Cache[(Redis)]
Logic --> MapServer
MapServer --> Logic
模块功能说明
Client呈现与指令输入
Gateway长/短连接管理
Logic游戏业务逻辑
Scheduler异步事件调度(行军、建筑)
MapServer世界地图与领地
DB / Cache持久化与快速读取

二、SLG 架构的演进历程

2.1 第一阶段:单服、单线程(早期页游)

早期页游(如《三国志网页版》《傲视天地》)采用单机架构:

  • 所有逻辑运行在单台服务器;
  • 任务调度由数据库定时器完成;
  • HTTP 短连接轮询获取状态。

缺陷:

  • CPU 单点瓶颈;
  • IO 阻塞严重;
  • 定时器执行精度低;
  • 无法水平扩展。

2.2 第二阶段:异步任务驱动 + 多进程架构

随着 Node.js、Go 等高并发语言的普及,SLG 架构进入了事件驱动时代:

  • 使用消息队列(MQ)调度任务;
  • 每个逻辑节点独立处理一类任务;
  • 引入 Redis、Kafka、Crontab。

代表架构:

graph TD
A[Client] --> B[Gateway]
B --> C1[Logic Server]
B --> C2[Map Server]
C1 --> D1[Redis]
C2 --> D2[MySQL]
C1 --> E[Kafka Topic: Events]

优点:

  • 可水平扩展;
  • 异步任务模型提高吞吐;
  • 支持多服与多进程部署。

2.3 第三阶段:分布式 + 世界地图分区

现代 MMO-SLG(如《率土之滨》《三国志战略版》)采用:

  • 世界地图按格子或地块划分;
  • 每个区域由独立逻辑节点维护;
  • 玩家城市与部队分布式存储;
  • 使用消息总线进行区域间通信。

三、SLG 服务端分层结构

3.1 总体架构图

graph TD
Client --> Gateway
Gateway --> Login
Gateway --> Logic
Logic --> Map
Logic --> Scheduler
Logic --> Chat
Logic --> DB[(MySQL)]
Logic --> Cache[(Redis)]
Scheduler --> MQ[(Kafka / RabbitMQ)]

3.2 各层职责

层级功能
客户端发起建造、行军、科技升级等操作
网关层连接管理、认证、限流、路由
逻辑层游戏规则、资源消耗、战斗计算
地图层世界状态、地块归属、联盟占领
调度层定时任务管理(建造/行军)
存储层玩家、城市、建筑、联盟数据
消息层异步事件、日志、排行榜、统计

3.3 Go 语言结构体示例

type City struct {
    ID        int64
    OwnerID   int64
    Level     int
    Resources Resource
    Buildings []Building
    Troops    []Troop
}

type Resource struct {
    Wood int
    Stone int
    Food int
    Iron int
}

四、异步任务与调度系统

SLG 中最核心的机制是“异步调度”。

4.1 典型任务类型

类型示例持续时间
建造任务升级建筑分钟级
科技任务升级科技树小时级
行军任务攻城、驻防、采集分钟~小时级
资源产出每秒增长持续任务
联盟事件宣战、占领、建造奇观多阶段

4.2 调度核心思想

  1. 所有任务具备开始时间与结束时间;
  2. 服务器定时触发回调;
  3. 调度精度通常为秒级;
  4. 分布式任务避免重复执行。

4.3 Go 实现:异步任务调度器

type Task struct {
    ID        int64
    Type      string
    StartAt   time.Time
    EndAt     time.Time
    Payload   []byte
}

type Scheduler struct {
    Tasks map[int64]*Task
}

func (s *Scheduler) Tick(now time.Time) {
    for _, t := range s.Tasks {
        if now.After(t.EndAt) {
            go s.execute(t)
        }
    }
}

func (s *Scheduler) execute(t *Task) {
    switch t.Type {
    case "BUILD":
        handleBuildComplete(t.Payload)
    case "MARCH":
        handleMarchArrive(t.Payload)
    }
}

此模型可进一步结合 Redis ZSet(按时间排序)实现跨节点任务分发。

4.4 分布式调度机制

使用 Redis SortedSet:

  • key:task_schedule
  • score:timestamp
  • value:任务 JSON

调度器节点定期扫描最早的任务执行。

tasks, _ := redis.ZRangeByScore("task_schedule", 0, now)

4.5 分布式锁与幂等控制

  • 使用 Redis SETNX 防止重复执行;
  • 使用 任务状态机 控制状态流转。
状态说明
PENDING等待执行
RUNNING执行中
SUCCESS完成
FAILED错误(可重试)

五、地图系统(Map System)

5.1 地图分区

SLG 世界由若干 区块(Tile) 构成。每个区块记录:

  • 坐标;
  • 所属势力;
  • 地形;
  • 资源类型。
type Tile struct {
    X, Y    int
    OwnerID int64
    Terrain string
    ResourceType string
}

5.2 区块分布与负载均衡

采用 “空间分区 + Hash 一致性” 分配地图负载:

模式说明
规则划分按固定坐标范围分配服务器
动态迁移根据在线人数调整
Hash 分区坐标 hash 决定分区节点

5.3 地图同步与推送策略

SLG 通常采用 区域广播 + 客户端可视范围同步

sequenceDiagram
Client->>Server: 请求地图(x,y,范围)
Server-->>Client: 返回可见区块
Server-->>Client: 当周边变化时推送更新

5.4 世界状态一致性

  • 使用 Redis 缓存热点区域;
  • 异步写回数据库;
  • 跨区通信使用 Kafka 事件流。

六、战斗系统(Battle System)

6.1 异步战斗模型

SLG 的战斗往往是 离线模拟

  1. 玩家发起攻击;
  2. 服务端计算双方部队属性;
  3. 执行一轮战斗模拟;
  4. 异步生成战报;
  5. 推送结果。

6.2 战斗流程

sequenceDiagram
Client->>Server: Attack(TargetID)
Server->>Server: ValidateResource()
Server->>BattleSim: ComputeResult()
BattleSim-->>Server: Report(Result)
Server-->>Client: NotifyBattleEnd()

6.3 战斗模拟实现(简化版)

func SimulateBattle(attacker, defender Troop) BattleReport {
    atkPower := attacker.Soldiers * attacker.Attack
    defPower := defender.Soldiers * defender.Defense
    result := BattleReport{}
    if atkPower > defPower {
        result.Winner = attacker.ID
    } else {
        result.Winner = defender.ID
    }
    return result
}

6.4 战报系统

战报(BattleReport)为异步消息,可存入 Kafka / Redis Stream。
客户端登录时按分页加载。

七、联盟与社交系统

7.1 联盟结构

type Alliance struct {
    ID        int64
    Name      string
    LeaderID  int64
    Members   []int64
    Territories []Tile
}

联盟功能涉及复杂的权限控制与世界交互。

7.2 频道式聊天系统

采用 Redis Pub/Sub

  • 每个联盟一个频道;
  • 全服广播使用 Topic;
  • 历史记录通过 Kafka 落地。

7.3 联盟任务与奇观系统

联盟任务是跨玩家合作的典型场景:

  • 阶段性进度;
  • 服务器全局状态共享;
  • 事件广播。

八、通信与同步机制

8.1 协议层选择

类型用途传输方式
登录 / 数据同步HTTP / gRPCRequest/Response
地图事件推送WebSocket异步推送
战斗/行军消息队列异步任务
聊天Pub/Sub实时广播

8.2 WebSocket 推送(Go)

func (c *Conn) PushUpdate(event string, data interface{}) {
    msg, _ := json.Marshal(map[string]interface{}{
        "event": event,
        "data":  data,
    })
    c.ws.WriteMessage(websocket.TextMessage, msg)
}

8.3 协议压缩与安全

  • 使用 Snappy / Zlib 压缩;
  • 加密层:AES + HMAC;
  • 防止篡改:签名验证(timestamp + token)。

九、分布式与可扩展性设计

9.1 模块划分

模块水平扩展方式
网关层负载均衡(Nginx / Envoy)
逻辑层按用户 ID Hash 分区
地图层按坐标分区
调度层分布式定时任务
数据层分库分表(MySQL Sharding)

9.2 数据分片示例

玩家ID % 16 = 数据库分区号

9.3 状态一致性策略

  • 强一致(Critical):支付、资源;
  • 最终一致(Non-critical):排行榜、统计;
  • 使用事务消息(Outbox Pattern)确保幂等性。

9.4 弹性伸缩(K8s)

通过 Horizontal Pod Autoscaler 动态伸缩:

  • CPU 负载 > 70% → 扩容;
  • Idle → 缩容;
  • Redis Cluster 自动分片。

十、性能与安全

10.1 性能优化方向

层级优化点
网络层WebSocket 连接池
调度层分布式任务桶
数据层异步写入队列
缓存层热点键分布
消息层批量消费 / 异步提交

10.2 防作弊与防刷机制

  • 行军冷却校验;
  • 签名验证;
  • 防时间篡改;
  • 建筑队列上限;
  • 服务端权威验证。

十一、典型案例分析

11.1 《率土之滨》

  • 世界 1024x1024 区块;
  • 服务器分区 + 区域联盟;
  • Redis 缓存热区;
  • 定时任务驱动;
  • 战斗异步模拟;
  • Kafka 日志追踪。

11.2 《三国志战略版》

  • 世界服分层(登录 / 区服 / 世界);
  • GeoHash 空间划分;
  • 行军与战斗通过任务队列;
  • Redis 用作任务时间轮;
  • 战报异步生成;
  • 联盟领地强一致更新。

11.3 《Clash of Clans》

  • 部落系统采用一致性 Hash;
  • 数据完全持久化;
  • 战斗离线模拟;
  • 全球化分布式部署。

十二、未来趋势:AI + Cloud + Simulation

方向描述
AI 代理玩家(AI Agent)模拟玩家行为、自动决策
云原生 SLGMapServer 动态分配
可验证游戏(Verifiable Game)区块链状态签名验证
分布式仿真引擎状态更新通过物理时钟驱动
跨世界交互多服联盟、全球匹配

十三、总结:SLG 的架构哲学

SLG 是一类 以时间为核心变量 的分布式系统。
它不像 MMO 那样追求实时性,而是在“持久性与正确性”之间平衡。

MMO 解决“现在的世界”;
SLG 解决“未来的世界”。

它的工程本质是:

  • 一个全局时间驱动的状态机;
  • 一个分布式任务系统;
  • 一个数据一致性的长期仿真系统。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页