为什么写作这个系列
GDC(Game Developers Conference)是游戏界最富盛名的开发者大会,每年有来自全球各地的顶级游戏开发者分享前沿的游戏设计、技术和运营经验。
GDC上的技术分享,以客户端和渲染类的居多,服务器相关的相对小众。不过仔细找找还是能找到不少关于服务器的高质量内容,其中不乏来自知名游戏的干货分享,如《Sky光·遇》《星战前夜## 标题》。中国的腾讯、网易也带来过不少服务器相关的分享。
本系列将会分享近几年(2020——2023)服务器主题下的演讲,通过阅读本系列,读者可以了解业界最新的服务器技术开发前沿,有助于开阔眼界、活跃思路。
本次分享为大家带来的是GDC 2023上的《在《黑道圣徒》的boss工厂中创建可扩展和吸引人的用户生成内容》(Creating Scalable and Engaging User Generated Content in ‘Saints Row Boss Factory’)。PPT和演讲视频可分别点击链接获取。通过学习本分享可以获得以下收获:
- 如何设计一个可扩展的UGC系统架构,包括内容存储方案。
- 如何对UGC有效监管。
- UGC系统上线遇到的技术问题及处理经验分享。
以下为详细内容分享。
基本介绍
《黑道圣徒》是一个经典的犯罪题材RPG游戏IP,玩家可以扮演黑道与其他人进行畅快淋漓的枪战。这次演讲的内容来自最新发售的《黑道圣徒》重启版。在这个版本中,新增了Boss Factory的功能,玩家可以自定义角色的容貌和道具,并允许在线上与他人分享。
演讲人是一位印度哥们,印度口音不重,发音清晰标准。他自述从产品经理转到开发,拥有10多年的跨行业服务器经验,以及4年多的游戏服务器经验。
Boss Factory功能在游戏正式发售前就已经提供给玩家,最高时一天有多于13万的boss创建量,这给服务器架构带来了一定挑战。
架构
线上服务主要包括:
- IAM Service:用户服务,包括用户验证、管理和封禁。
- UGC Service:用户生成内容服务,包括内容分享、浏览以及点赞、关注等。
- Reporting Service:举报服务,包括举报内容、内容监管。
以上所有的服务都用AWS托管,不同服务之间使用Kafka做消息传递。
存储这块按数据类型分为:
- UGC元数据:存储在MongoDB中,并对MongoDB做主从读写分离。MongoDB的优势在于灵活的非结构性数据,这对于快速的版本迭代(新增元数据字段)是非常有利的。
- UGC文件:包括图片和模型类资源,来自玩家上传的自制角色。这一块使用AWS的S3(Amazon Simple Storage Service)做存储。S3是Amazon提供的对象存储服务,可用于存储各种类型的文件(图片、文本、视频等)。对象存储可以简单地理解为一个加强版的CDN存储,不同点在于:对象存储仅用一个key就能获取到存储的对象(文件),没有传统文件存储中文件夹的概念。而且S3还提供了权限管理、版本管理等普通CDN存储没有的功能。
- 策划数据:包括管理员精选的内容和创作者。此处使用的存储方式Cloud Save应该是指Google Play Services为游戏提供的一种轻量级云存储方案。
笔者认为这个系统更像是互联网服务或者游戏中台,而非游戏服务,原因在于它提供的功能都是无状态的。所以在设计上使用了大量的云原生技术,服务器全部托管在AWS上,方便快速弹性扩展。
内容监管
对于一个UGC系统来说,很可能会出现违禁的内容,因此内容监管十分重要。
内容监管以玩家举报加后台管理相结合的方式进行。玩家可以对疑似违禁的内容进行举报,举报生成的流程单会在管理创建,管理员可以据此做出处理决定(删除内容或封禁用户)。管理员也可以自定义处理规则,例如超过5人举报则内容自动删除。
跨平台实现
Boss Factory同时支持在游戏端和网页端访问,因此有不同的用户验证方式。
在游戏端登录,直接使用第一方的账户系统(Epic、Xbox、PS);在网页端登录,需要使用一个叫OIDC的通用账户系统,并把这个系统的账号与游戏中使用的账号绑定。
上线经验
印度哥们认为最有价值的是关于上线经验的分享。他分享了三点,分别对应预发布、demo发布和正式发布三个阶段。
预发布遇到的问题:数据库中超长字段造成的慢查询。问题在于原始的设计把UGC(图片)放在数据库中存储,因此解决办法有三点:
- 在请求中去除对超长字段的访问。
- 查询请求拆分成两步:先是获取内容列表,再是获取内容预览。
- 将图片类数据改为存储在S3中。
demo发布遇到的问题:用S3存储时缺少数据分片。原本是所有内容全部放在一个bucket下面,这样单个bucket中有多达60万个对象,但是单个数据分片仅能处理最高5K TPS。解决办法是:增加一级按上传时间做的数据分片,将每个bucket的TPS减小到1K。
正式发布遇到的问题:太小或者太多的数据库索引会导致慢查询。按tag过滤是一种常用的查询方式,因此原本的设计为tag添加了索引。但是后面发现,按tag查询会返回大量的数据,例如按游戏平台查询可能会返回占总量1/3的数据,在这种情况下使用索引不仅区分度不够高,而且反而性能上是一个累赘,因此又在tag上去掉了索引。进一步的建议是,基于真实的玩家数据分布情况来使用索引,因为设想和真实情况会有差距。
建议
以下是演讲人基于这个UGC系统的上线经验给开发者的建议:
- 使用真实的用户数据和游戏场景做压力测试,减小不确定性。
- UGC的监管非常重要,需要提前做好监管平台的建设。
- 限制用户输入的名字、描述和tag的自由度,以免给监管带来麻烦。