游戏服务器
服务器管的不只是游戏逻辑,还有你的玩家是谁、他们和谁一起玩。
多数人挑游戏服务器,第一句问的是「能不能足够快地跑我的游戏规则」。这个开头就问错了。半年之后吃掉你时间的不是规则,而是账号、好友、公会、聊天、排行榜、推送、收据。要么选一个已经把这些做好的服务器,要么做好自己造的准备。
按社区功能来选,而不是按游戏循环
游戏服务器做的是两件很不一样的事。一件是游戏本身——移动棋子、判定命中、保持世界一致。另一件是围绕游戏的一切,而这第二件事,比新手想的大得多。决定玩家明天还回不回来的,也正是它。
在比较帧率之前,先数一数下面这些里,有几项是你不得不自己造、自己保安全、自己运维的:
<b>账号与登录</b>——设备、邮箱、Apple、Google、Steam,还要把它们绑到同一个玩家身上,换设备也能接着玩。 <b>聊天与论坛</b>——一对一、群聊、房间聊天,断线重连后还在的历史记录,外加举报和拉黑。 <b>公会与好友</b>——入会申请、角色与权限、成员列表、在线状态(现在谁在线)。 <b>排行榜与锦标赛</b>——每日每周重置、同分排序规则,以及把作弊者挡在榜首之外。 <b>推送与内购</b>——告诉玩家体力回满了,以及在发放东西之前先验证收据是不是真的。
Docker——服务器最终是这么跑起来的
不管你选哪个服务器,它总得跑在某个地方——而今天这个「地方」几乎总是容器。Docker 把服务器和它运行所需的一切——运行时、库、配置——打成一个整体。做出来的这一个镜像,在你的笔记本上和在别国租来的机器上,表现完全一样。
对游戏服务器来说,这件事比对多数软件都更要紧,因为游戏后端从来不是一个程序。服务器之外还有数据库,通常还有缓存,它们得互相找到对方、按正确顺序启动。Docker 把这件事从一整页安装说明,变成一个文件加一条命令——这也正是 Nakama 和 SpacetimeDB 的快速上手都用容器来讲的原因。
需要懂的四个词
Compose——一个文件搞定整套
游戏后端是若干必须一起启动的容器。Docker Compose 把它们全部——服务器、数据库、缓存——连同数据卷、网络、谁等谁,一起写进一个 YAML 文件。然后一行 docker compose up 就能把整套跑起来,而复制到真实服务器上的,也是同一个文件。
这就是你今晚就能试 Nakama 的原因。它官方的快速上手就是一个两服务的 compose 文件,跑一条命令,本机上就有了一个带数据库的可用游戏后端。系统里不装任何东西,之后也没什么要卸载的。
新手常踩的三个坑
<b>删掉数据卷,就等于删掉数据库。</b>带上清理数据卷参数的命令,会连玩家数据一起干净利落地抹掉。跑任何清理命令之前,先弄清楚它会动哪些卷——而且在你以惨痛方式弄清楚之前,先备份。 <b>一个主机端口,只能有一个进程。</b>要是已经有东西占着那个端口,第二个容器就干脆起不来。在跑多个站点的机器上,这是最常见的原因;解法是别对外暴露端口,让前面的一个反向代理按域名分流。 <b>起不来,就去读日志。</b>容器失败几乎都会在自己的日志里把原因写出来,而新手几乎都在靠猜。把读日志放在第一步,别放在最后一步。
PES 就是一个 Compose 文件里描述的四个容器——Web 应用、PostgreSQL、负责实时的 Centrifugo,还有 Redis,前面再有一个负责 HTTPS 终止的共用反向代理。发布一次改动,就是把代码传上去、重建一个服务。为了游戏服务器学会 Docker,等于顺带学会了以后你做的任何东西该怎么部署。
SpacetimeDB
SpacetimeDB 走的是一条根本不同的路:数据库本身就是服务器。你不是写一个去和数据库对话的游戏服务器,而是写住在数据库里的函数(reducer),客户端也不调接口,而是订阅查询。没有另外要部署的服务器进程,也没有两套系统之间的同步代码——因为系统只有一套。
所以在做持续存在的世界时,它是真的优雅,结构简单到一个人能把全貌装进脑子里。代价是它还年轻、生态较小,而且思维方式的转变是实打实的功课——它简单,但不是你已经会的那一套。
Nakama 是什么
Nakama 是 Heroic Labs 出的开源游戏后端服务器,用 Go 写成,以单个二进制文件加一个 PostgreSQL 兼容数据库的形式发布。它不是网络同步库,也不是托管平台——它是夹在两者之间的那一层:知道你的玩家是谁、拥有什么、正在和谁一起玩。
开箱即用,它提供这些:
身份与认证 — 设备 ID、邮箱、Apple、Google、Facebook、Steam 或自定义。一个账号绑定多种凭据,跨平台通用。 存储引擎 — 带版本的 JSON 文档,逐对象的归属和访问规则。玩家的存档数据就放在这里。 社交 — 好友、群组与公会、在线状态,以及聊天(一对一、群聊、房间)和消息历史。 竞技 — 可配置重置周期的排行榜与锦标赛,外加按属性做条件查询的匹配器。 经济系统 — 支持原子账本事务的钱包,以及 Apple、Google、Steam 的内购收据校验。 实时 — WebSocket 与 rUDP 套接字,还有一个权威匹配运行时,让你自己写服务端的 tick 循环。 运行时模块 — 用 Go、Lua 或 TypeScript 扩展服务器:注册自己的 RPC,并在任意内置操作的前后挂钩子。
本页把 Nakama 当作若干选项之一来讲。本站自己跑在 SvelteKit、PostgreSQL、Centrifugo 和 Redis 上,并没有用 Nakama。我们在介绍一个工具,而不是在介绍自家技术栈。
它真正的好处
它不擅长什么
决定之前该知道的事。这些都不是什么秘密,而是上面那些设计取舍带来的必然结果。
替代方案
并不存在一个「和 Nakama 一样好」的东西——这个领域是按你想优化什么来分岔的。先想清楚你的难点在哪,再来挑。
气质最接近的——开源、可自托管
| 语言 | 强项 | 相比 Nakama 的弱点 | |
|---|---|---|---|
| Colyseus | TypeScript / Node | 同类里最好的自动状态同步、内置匹配,以及 Unity、Defold、Construct、Haxe、JS 的 SDK。 | 只管实时房间——没有身份、存储、社交、经济、排行榜。元层要你自己造。 |
| SpacetimeDB | Rust / C# 模块 | 一种根本不同的模型:数据库就是服务器。客户端订阅查询,你写的是 reducer 而不是接口。做持续世界类游戏时真的优雅。 | 还年轻、生态较小,而且思维方式的转变是实打实的功课。 |
| Rivet | Rust 内核,JS/TS 脚本 | Apache 2.0,可自托管;游戏服务器、匹配、认证,外加后端脚本——最接近完整替代 Nakama 的一个。 | 社区较小,而且公司转向了通用有状态服务的定位,游戏方向被稀释了。 |
| Agones + Open Match | Kubernetes | 有 Google 背书,是编排专用服务器机群的行业标准。 | 解决的是另一个问题——完全没有元层。它是和 Nakama 搭配用的,不是用来替代它的。 |
托管与商业方案
PlayFab — 微软的产品,功能面在同类里最宽——LiveOps、A/B 测试、分群、分析、经济系统。匹配和专用服务器都有,但只跑在 Azure 上。按用量计费,数据不归你。 AccelByte — 企业级,也是唯一自己做专用服务器编排的竞争者。定价是给拿了投资的工作室看的。 Pragma — 自我定位是面向长线运营游戏的「后端游戏引擎」:深度定制、组队与匹配、服务器分配、背包、成长、战令和商店。商业阵营里,理念上和 Nakama 最像的一个。 Photon (Fusion / Quantum) — 先是网络同步,其次才是后端。Quantum 的确定性回滚在竞技动作游戏里无出其右,但它是带服务的网络同步产品,而不是反过来。 LootLocker · brainCloud · Beamable — 托管、上手快、也更薄。LootLocker 没有匹配也没有服务器;Beamable 只做中继,实时部分转给别人。游戏几乎不需要后端时,用它们挺好。
这个领域的整合比多数领域都快——这块的托管服务出现过没怎么预告就关停或退出的情况。如果你打算做一个要跑好几年的长线服务,这就是选可自托管开源方案的理由。
该怎么选
难点在实时同步,元层很简单 → Colyseus 要做持续存在的共享世界,也愿意重新想架构 → SpacetimeDB 需要身份、社交、经济和排行榜,还想自托管 → Nakama 需要按对局拉起专用服务器机群 → Agones 配 Open Match,或者 Edgegap——旁边再放一个元层后端 宁可买 LiveOps 工具,也不想自己造 → PlayFab 或 Pragma 已经有自己的实时服务器了 → 只把元服务交给 Nakama,是常见也合理的做法
如果你偏好自托管、又不想被某家厂商绑住,诚实的候选就三个:Nakama、Colyseus,或者自己造元层。选 Nakama 的交易是这样的——你接受一个又大又有主见的 Go 二进制,换来省下造好友、聊天、钱包、排行榜的半年时间。该问的问题是:我这游戏的元层,是不是足够贴近 Nakama 的假设,以至于我会是在扩展它,而不是在跟它较劲。