周刊(第3期):一个前游戏开发者眼中的游戏后端技术
引言:在我之前的工作里,因为各种原因,断续在游戏行业里有过总共大概四年左右的从业时间,今天想从我的视角聊聊游戏行业后端开发相关的技术,供那些想在这个行业从业,尤其是后端开发从业人员一些参考。
一个前游戏开发者眼中的游戏后端技术
由于我从业的方向都是后端开发,所以这里仅谈论游戏开发后端的技术。
游戏本质是个内容行业,所以游戏开发时相当一部分工作内容,就是不停的更新新的内容出来给玩家消费。这些内容包括但不限于:新的英雄、技能、玩法,等等。
而要支撑这些玩法,相当一部分是策划的配表数据,即:
- 程序员把玩法的框架、逻辑搭建好,留出读玩法数据的接口来。
- 玩法数据由负责该玩法的策划来配表实现。
这其实就是很朴素的“表驱动”的编程方式。
因为这个原因,所以游戏服务器启动时,要加载相当多的数据,主要有:
- 玩家的数据,包括账号、角色、帮派、金钱等数据。
- 玩法相关的策划配表数据。比如一个场景的坐标位置、NPC的坐标位置、任务,等等。
由于需要在启动的时候要加载很多数据,游戏服务器才能完成初始化,所以“编译型”语言在游戏开发里并不适用来编写游戏玩法逻辑,试想下面的开发场景:
- 策划提出了新的玩法需求。
- 开发使用如C++这样的编译型语言编码实现玩法。
- 编译新修改的代码:这里面有包括了编译、修改编译不通过时候的报错,等等。
- 停止服务器,重启服务器来验证玩法的逻辑。
可以看到,姑且不论其他因素,单是每次验证代码修改时需要停服、重启服务器的流程,而重启时又要加载一堆数据才能完成初始化,这个过程就严重影响开发效率。
换言之,“编译型”语言并不适合于用来编码在游戏开发里需要经常变更的玩法逻辑。
于是,一种新的开发架构出现了,见下图。
在图中,将游戏服务器架构分为了两层:
- 引擎层:这部分由C++编码,实现了游戏开发中与具体逻辑关系不大、且不太会变更的部分,如网络数据收发、数据库访问,等等。
- 脚本层:这部分由Python、Lua这样的脚本语言实现,主要就是各种玩法。
采用这样的架构最主要的优点,就是解决前面提到的开发效率问题。由于Python、Lua这样的脚本语言,支持热更新,即“不需要重启进程也能更新最新的代码”,这样开发模式就变成了:
- 策划提出了新的玩法需求。
- 开发使用如Python、Lua这样的脚本型语言编码实现玩法。
- 热更新脚本代码,调试玩法。
可以看到,由于支持“热更新”,省去了停服、重启、加载数据的步骤,一下子开发效率就提升了很多。
多说一句,“热更新”还有一个优点:假如线上出问题时,总不可能停服下来修复,热更新不需要重启就能更新最新代码的特点在这里又发挥了作用。
从这个开发架构里,也可以看到游戏服务器人员的构成:
- 引擎层只有少数人能够去维护,要求稳定、高效。
- 绝大部分人,都在脚本层用脚本语言来写各种玩法逻辑,类似于web开发中的CRUD。
这个架构已经很久没变化了,而且每个公司都有自己一套(甚至几套)维护得较为稳定的服务器引擎,这会有一个问题:
- 技术演进慢。十几年前的架构到现在基本没变。
- 由于演进慢,而且对稳定性的要求高,实际上新人也很难找到机会在引擎层发挥作用,引擎层的代码通常也不会让脚本层工作的人看到,这样就进入不到这一层的开发,而且引擎层绝大部分的问题已经被前人解决了,用现在的话来说,这部分技术“固化”了。
为了证实我的观点,我找来了去年刚出版的《腾讯游戏开发精粹Ⅱ 》这本书,来看看书里关于游戏服务器都有哪些内容。全书一共21章,与游戏服务器相关的只有三章:
部分Ⅴ 服务端架构和技术
第15章 面向游戏的高性能服务网格TbusppMesh 304
15.1 TbusppMesh摘要 304
15.2 TbusppMesh数据通信 305
15.3 TbusppMesh组网策略 309
15.4 TbusppMesh有状态服务 315
15.5 总结 321
第16章 游戏配置系统设计 322
16.1 游戏配置系统概述 322
16.2 游戏配置简介 322
16.3 游戏配置系统 323
16.4 配置设计与发布 324
16.5 配置Web管理系统 328
16.6 总结 330
第17章 游戏敏捷运营体系技术 331
17.1 游戏运营概况 331
17.2 DataMore大数据计算体系建设 335
17.3 基础平台 343
17.4 总结 360
而且,其中一章还是讲的偏运营体系、大数据方面的内容,这部分内容跟“游戏开发”本身相关性不大。造成这样的原因,是因为游戏服务器用脚本写玩法逻辑,这实在没有太多可以说的:)。
在这样一个演进慢、技术固化的领域里,新人大部分时候都挤在了写玩法逻辑的脚本层里。这是游戏行业新人需要考虑的问题:一旦落到脚本层开发,技术积累很慢很少,也会很累、加班很多。这还是由于前面讲述的游戏行业的特点导致的:游戏本质是个内容行业,而“内容”落到开发分工上,主要就是由脚本层的开发来完成。
总结
总结一下我的观点:
- 游戏本质是个内容行业,游戏开发大部分时候都是生产“内容”给玩家消费。
- 由于生产游戏内容的过程繁杂,且启动游戏服务器时需要加载大量数据,编译型语言并不适合来写游戏玩法逻辑。
- 于是产生了编译型语言编写引擎+脚本型语言编写玩法逻辑的架构。
- 而这种架构已经沿用了很多年,游戏服务器后端技术领域,技术演进慢、固化严重。
- 在一个固化严重的技术领域,新人很难找到机会。这个结论不仅适用于游戏行业的开发。
番外
Lua的兴起
Lua是一门发源于巴西的脚本语言,我之前深入研究过Lua 5.1.4版本的代码,写过其分析的文档(Lua source internal),后续被出版为正式出版物《Lua设计与实现》。我在写作本书的时候,研究过一些Lua的发展历史。可以说,Lua在游戏行业开始流行起来就是源自上面的脚本+引擎这样的架构体系,能够提高游戏开发者的开发效率。这部分内容参见The evolution of an extension language: a history of Lua:
It turned out that Bret Mogilefsky was the lead programmer on Grim Fandango, the main adventure game LucasArts released in 1997. In another message he told us that “A TREMENDOUS amount of this game is written in Lua” (his emphasis). This first use of Lua in a game attracted the attention of many game developers around the world to the language. Soon after, Lua started to appear frequently in game newsgroups, such as
rec.games.programmer
andcomp.ai.games
.
人们为什么需要游戏?
游戏一直是个有很大争议的行业:杀戮、利用人性阴暗面、未成年人沉迷导致的各种问题,等等。
我在从业的时候,也会纠结在这些问题里。
再后来,我找到一个解释给自己的理由:由于人们的肉身,受时空范围的限制,所以需要游戏来帮助人们扩展人生体验的范围。
比如,如果没有FootballManager
这款游戏,我如何都体会不到执教、管理一个球队的体验。
《庄子》里有所谓“庄周梦蝶”的故事,其大意是:庄子一天做梦,梦见自己变成了一只蝴蝶。醒来之后他发现自己还是庄子,于是他不知道自己到底是变成庄子的蝴蝶呢,还是梦中变成蝴蝶的庄子。庄子认为人不能确切的区分“真实”和“虚幻”,游戏某种程度上以构建在数字上的“虚幻”,来给了我们不同时空上的“真实”体验。
从这一点看,游戏的内容,和书籍、影视剧,其实没有太多的区别:载体不同,但都让人扩展了体验的范围。
也因为这样,大家都是”内容消费行业“,所以游戏的竞争对手,除了游戏行业以内,还有各种能够消费时间的产品:视频、书籍、电视,等等。
在人口增速放缓之后,换算成能用来消费这些内容的总时间也放缓了,再加上前面提到各种消费时间的产品越来越多,各种游戏也越来越多,所以这个领域是很难的(当然大家都难)。
关于”游戏是内容行业“这个话题,最近看到一篇不错的文章:科技巨头的游戏野心为何经常以失败告终?,有兴趣的可以参考一起看看。
我为什么离开游戏行业?
总结起来有以下的原因:
- 太累:每周都有版本更新(注意是每周),每到版本更新的日子,全组都要一起待到版本发布,经常就搞到了晚上十点后,打车回家只能洗洗睡了。第二天还要早早起来,赶版本更新之后、还未外放前的验证工作,如果有问题要马上线上修复。除此以外,其他时候有严重的线上问题,还要马上更新修复(热更新性质再次救了游戏开发者)。这一算下来,每周五个工作日,至少有两天是在快节奏下工作的。这样的工作节奏,对年纪大的人太不友好了。
- 学不到什么技术:就是我上面说的技术固化、演进慢等因素。天天用脚本写各种玩法,积累不出什么个人技术壁垒来。我一直对”被平台、工作所体制化“的事情保持着警惕,见我之前的周刊:周刊(第2期):从笔记软件谈被体制化 - codedump的网络日志。
推荐
游戏服务器和普通服务器有什么区别?
这是知乎上的一个问题:游戏服务器与普通服务器有什么区别? - 知乎
总结前面分析的游戏行业的特点、开发架构,我做一个简短的回答:
- 游戏要模拟各种虚拟世界的场景,包括但不限于:社交、战斗、玩家可见性(比如买了一个装备,什么样的玩家能看到,涉及到这个属性的广播范围等问题)。简而言之,游戏开发有时候在游戏里就是造世主一般的存在。
- 所以,大部分时候,游戏服务是“有状态的”服务。这点是跟一般的web服务最大的区别:web服务通常一个短链接请求过来,查询一段数据,完事了可能就断开了;而游戏服务器,由于要维持状态,大部分时候都是长连接,一个连接对应一个玩家角色。
科普游戏服务端技术的资料
如果觉得前面的讲解太过粗糙,还想多了解这方面的技术,推荐以下几篇文章:
- 游戏服务端究竟解决了什么问题? - fingerpass - 博客园
- 游戏服务端架构发展史(上) - Skywind Inside
- 游戏服务端架构发展史(中) - Skywind Inside
- 上面两部曲没有下篇了,作者已经鸽了。
skywind
这是我推荐的一位前游戏行业从业者、知乎答主、博客作者、以及开源项目作者。
他主要的领域有:
- 游戏(引擎)开发。
- 网络传输、音视频开发。
这几个方面,他是既有理论技术文章的输出、也有开源项目的,最出名的开源项目当属KCP - A Fast and Reliable ARQ Protocol。(我曾经写过一篇不太好的、个人不甚满意的KCP分析文章,见:KCP 1.4源码分析 - codedump的网络日志)
-
知乎:https://www.zhihu.com/people/skywind3000
-
github:https://github.com/skywind3000
-
博客:http://www.skywind.me/blog/
-
推特:https://twitter.com/skywind3000
由于他之前也是游戏行业的从业者,所以也对游戏领域有自己的见解,见:你为什么会离开游戏行业? - Skywind Inside,也是难得一见的好文。另外,知乎上有很多他有趣的回答。
其他推荐
无穷之路
香港TVB电视台在内地拍摄的一部讲述内地扶贫情况的纪录片。我觉得这类型的片,由内地媒体拍出来,和香港媒体拍出来,感觉还是不一样的,香港媒体的视角更像第三方的视角。在拍摄时,有时候主持人也会切换到自己用自拍杆的视角来拍摄,又多了一些亲切的感觉,不会那么高高在上。
”无穷之路“这个名字也很好:”穷“既代表脱离贫穷,也寓意着内地有很多素材可供香港媒体拍摄记录。
这里面让我印象最深刻的,就是第一集的”悬崖村“,万万没想到就是在最近,还有人居住在这种天险之地。
B站有视频全集无穷之路-纪录片-全集-高清独家在线观看-bilibili-哔哩哔哩,如果能听懂粤语也可以选择听粤语原版。
DeepL
DeepL翻译是由德国一家AI创业公司的推出的翻译服务,主打使用人工智能、深度学习技术来进行翻译服务,支持 简体中文、英语、德语、法语、日语、西班牙语、意大利语、荷兰语及波兰语之间的翻译。
我自己尝试了一下这个翻译工具,将我博客的一篇中文博文翻译成英文,几乎不加修改就能比较顺畅了,读者可以自行对比一下效果:
感觉对于技术类文章的翻译来说,这个工具的表现已经很好了。
Mac、Win桌面版可以免费下载,也有网页版本,但是免费版本有每次翻译的字数限制,文章长了需要自己多倒腾几次。