紫龙上海CTO王琦:我们对游戏工业化的探索
ashkeling报道/2月13日,2022年度中国游戏产业年会在广州召开。本次大会以“奋进十年路,再搏新征程”为主题,并围绕游戏出海、国风游戏、游戏工业化等话题,深入开展了16场分论坛讨论。
当天下午,在以“国际观察——游戏制作工业化升级趋势主题论坛”上,紫龙游戏上海研发中心首席技术官王琦,现场发表题为《ob电竞》的主题演讲。
以下是演讲实录:
王琦:我们其实是一支非常强的团队,从PC时代一直开发到现在,核心成员处于始终在一起合作。这么长时间以来,我们积累下了一些自己关于工业化方面的摸索和实践。
首先,我们团队的理念是缺陷驱动——当发生了一个问题,我们会尝试去理解这个问题如何产生的,然后再去思考如何解决这个问题。那么面向工业化:工业化到底是要解决什么问题呢?
在我们的视角里,首先是工作结果的交付一致性较差。比如做一个角色模型,不同的美术工作人员产出的面数差异、或者是贴图材质差异,都代表了它的一致性比较差。
另一方面,工业化的反面其实是作坊化,这会导致工作过程的一致性较差,从而带来产出效率较低,以及信息传递的缺失、低效和失真。比如策划向美术传递信息的时候,如果产生了一些失真,使得有些信息没有传递到,就会导致最后产出结果一定会产生反复和迭代,这对于成本来说都是浪费。
同时在传统作坊工作方式下,流程通常来说很难保持非常高的一致性。不同工作人员工艺的不一致,一定会导致最终呈现的结果出现差异,并带来质量方面的参差。
基于上述内容,我们其实很难去定义,开发过程中某一个任务是否被完成,以及它被完成的界定准则和参数到底是什么。所以会导致我们无法描述这个任务应该在什么时候完成,以及完成后还会不会迭代。
因此,开发过程的管理信息会变得非常混乱,同时导致开发过程的可控性变得极差,最终结果就是时间、成本失控,交付质量不理想。
而我们视角下的游戏开发工业化有哪些方面构成?第一,是要保证工作过程和结果的正确性和一致性;第二,在这个基础之上需要保证工作过程和结果输出的效率。
为了保证一致性,我们有两个方面:第一是开发过程管理规范,相比传统的软件开发大家应该比较熟悉,毕竟传统开发会非常注重项目管理机制和规则。第二个是针对游戏行业本身,我们会存在具体的工件制作工业流程的规范。在部分规范的情况下,我们是能够靠人力去保证它的一致性。
通常来讲,规范定得越细,检查得越严格的话,工作效率整体会下降。这就需要靠一些开发过程管理的数据化和工具链,以及制作工艺流程环境下的数据化和工具,来使效率得到一个合理的提升。
这里我们分解一下开发过程管理规范。首先,它是以通常意义上的软件项目过程管理为基础。像我们以前做传统软件,也会用到一些项目管理的软件,比如说微软的Project这些东西。
第二,最开始要解决的一个基本问题,是信息流和决策流的管理。整个开发过程的管理,它的人员组织结构应该是会形成一个树状结构,就像军队指挥打仗一样。
如果没有形成一个很好的树状结构,你的信息流不是在树上面通过根节点才能流向叶子节点的话,比如在执行环节,策划会直接和执行层面的程序和美术沟通。这个有可能会导致你的Leader不知道,因此他们对于这些信息是否和原有体系自洽,并没有做出判断。而且在他们不知道的情况下,后续QA流程肯定也被断开的,这都是问题,所以我们需要把信息流和决策流的管理做好。
第三,开发过程管理规范和工业化的关系,前面其实已经提到了。开发规范其实并不依赖工业化存在,在我们没有涉及到工业化概念的时候,就已经在用简单的规范在操作。同时,工业化一定会带来一些流程线的制作成本,针对这些新的流程建设,我们需要对原有的开发规范进行一些适配和调整。
再者,我们即使在有规划地参与情况下,其实随着项目过程的发展,以及同一套工业化流程线在不同项目中的应用,具体的开发规范其实还需要做调整。这里特别需要去避免:一般来说,我们执行开发规范的具体执行人都是PM团队,但PM团队经常有时候会有一些任务导向的倾向。就是说规范里规定了我有abc,上面流程做了那就算没责任了,尽到了自己义务。
但事实上,我们其实需要相互灌输:做这个规范、做某一个条例的目标是什么?它是为了实现什么样的目的?那在具体的某个环境中,如果没有达成相应的目的,我们是不是应该去分析一下,到底是执行环境出了问题还是说规范有问题。
然后第四个,就是开发过程管理需要数据化。数据化其实是工业化的基础,如果我们不能用数据化的方式去描述整个开发过程,就没有办法以数据化的方式去定义每个任务,以及每个任务的分类是什么。
在我们的工具里面其实给每一个任务打了很多标签,它有功能范畴方面的标签,比如是某某系统的、是属于战斗还是属于技能的;还有一个就是它在岗位上的标签,因为我们做某个功能范畴的任务经常会流转很多岗位,而这个任务到底是属于哪个岗位,就需要把整个开发过程元数据化,去定义它。
最后一项,就是我们如何保障上面这些来执行。其实我们会在开发规范上去定义立项的各个阶段,每一个版本要达成的目标是什么、它要验证什么?在达成了某个目标后才能继续往下走。这其实是为了在前期尽量减少成本,解决一些未知问题,后面会更详细地去解释这个问题。
那工业化和流水线之间的关系,在我们的观点里面,工业化的本质就是建设流水线,既然是建设流水线,就会涉及到一个成本问题,一般来讲成本都是很高的。所以预算比较小的项目,那就要需要问问自己值不值得发动它来做事。
既然它成本高,改动它的时候成本也高,那它就一定会有某种局限性,即只适应于为了我们这个目标特别定制的流水线。所以,流水线模式和游戏创新实际上是存在天然矛盾的。可以通过我们项目过程管理规范里对于每个版本的要求,去缓解这样一个矛盾。
这里谈到我们搭建流水线的过程,提到了一个叫做Alpha0阶段。Alpha0阶段其实是一个版本,这个版本之前有两个重要的版本阶段。
第一个版本阶段,是所谓的核心游戏验证阶段。在这个阶段中,我们一般很少有美术来参与,基本上尽量采用白模和既有的美术资源来进行核心游戏性和3C的验证。这个阶段过了以后,我们认为达成了验证目标,就会进入第二个阶段。
第二个阶段,是美术的原型阶段,我们需要确定美术风格,去给美术的每一种工件制定它的标准。基于标准,就会说明这个美术工件的复杂度,标志着它的生产成本。能够衡量游戏中对于这种复杂度资产需要的量是多少,也就是美术内容风格的制定、定标和定量。这几件事是进入Alpha0阶段的前提。
那在Alpha0阶段中要解决的问题,第一是为构成游戏的每个“零件”制定最终要求和规范、以及定量,然后再为每个“零件”制定工序环节和每个环节上的检查规范,并制定是哪个岗位的人来做这个事情。这个问题,后面会再详细解释。
这里拿了几个我们内部工件制作的图解,给大家贡献例子。
在UI系统制作上面,首先我们会画一张流程图,来定义对于制作某一个美术或内容的资产,我们要把它分解为哪些步骤?其实这个步骤已经分解得非常细了。蓝色方框的部分最终会体现在你的工单系统里,会变成某一个人身上的一个Task,会去定到人、定到时间、定到时长。灰色的部分基本上属于一些非任务性的环节,比如某种沟通、或者某种会议。这个图上已经包含了制作流程中很多check的步骤,以及一些迭代、整合、调试的步骤。
另一边和这个流程图配套的,就是我们针对每一个环节的规范,这个规范也是遵从于我们缺陷驱动的开发。当我们发现某个地方出现问题的时候,需要去为它拟定一条新规范,添加到原有的体系当中。当我们不断地去做这种事情,就会使得你的规范越来越完善。比如UI规定了字体应该怎么用,你的按钮控件使用的一些规定是什么。
下一个就是机甲部件制作,要经历一个什么样的流程。我们的规范其实还包含要使用哪些工具,因为我们针对工具有做很多二次开发,因此不能胡乱地遵照你的喜好安排工具安装,必须按照我们自己规定的这些东西。包括工具环境要用什么,机甲的一些比例范围,面数等,都是在这个规范里面。
这是场景相关的制作规范,这个只是描述纯粹的美术方面场景,因为场景应用到游戏当中,还会变成其他的内容,这个规范在后面大家会看到。
这个是场景做完了后,把它应用到游戏当中的策划内部流转。包含关卡策划、文案策划,一些主策划验收,数值策划填充数值等过程的流转,以及他们一条条迭代归纳出来的一些步骤和规则。
然后是开发过程管理的数据化和工具链,我们大概使用的项目管理是Jira或Project。每个工具都有他自己的特长,比如,Jira比较适合每个人只关注自己能看到的任务条目;Project比较适合让整个项目的管理者能够看到任务和任务之间的依赖关系、时间等。
版本管理我们用的是Perforce,也是在做过反复调研后,最终选定的Perforce。它最吸引我们的一个功能是和Swarm的联动,迁入以后可以自动做review环节的联动,等一会我会详细的介绍。
CI环节,我们用Jenkins和一些自研资源检查工具。还有一个就是我们自己开发的消息通知软件,叫DevMsg,这个东西是为了解决什么问题呢?就是我们经常会遇到的在项目中信息丢失。
比如说我开了个分支,要求后面针对某个版本的迁入必须在另外一分支上做,这个时候往往就有美术说“我不知道”、“你没通知我”,他也不看QQ,你也没办法专门找人去盯着他、问他确认。最好的方式就做个软件,把这个Messagebox以模态窗口的方式弹在他脸上,他不点确认这个窗口永远不会消失,彻底消除他们说任何“我不知道”的情况。
这个是Jira和Project的互通。我们整个开发流程的起点,是每个版本的一个Excel。在这个Excel里面去定义了这个版本的Featurelist,然后各个组长会在Featurelist上进行任务拆分。只拆分这个任务节、某个Feature要分解成哪几个任务条目,不安排时间、也不安排人,然后这个Excel会被一个工具导成一个出最初版本的Project的杆状图。
在杆状图上,我们能够非常明显地得知一个任务在时间上的关系。当我们安排了人之后,我发现哪个地方成为长板,需要把它调整一下,负责人就把任务调到其他人身上去,使得每一个资源的阶梯化使用非常清晰明了。从Leader的角度来看,我们整个任务的b型开发流程和故事开发流程会非常的清晰。
做完这一步以后,我们用自己做的Jira拓展工具导入到Jira里上,会形成每个人身上挂的一些工作条目。这些人每天完成工作之后,就把对应的Jira上的工单设置为已完成。我们每天会再做一次同步回Project,杆状图的完成状态也会跟着更新。
与此同时,我们每天会在Jira上做一个自动报表,把所有类型的任务、每一个大的功能分类任务的完成情况和完成比例,以及拖延情况统计出来发给所有的Leader,让公司领导也能很明确的了解。同时我们也会把同步好了的杆状图发出来,能够以一个比较有效率的方式去了解当前项目进度。
这个是Perforce和Swarm的联动。当我们在Perforce上去迁入一个资源或代码的时候,我们有一些强制性的要求。就我们通过二级开发Perforce去规定迁入的时候必须提供哪些信息,其中一个非常重要的信息就是:你针对的Jira工单的工单号是什么?一般来说,开发人员是没有办法直接去迁入的,他只能提交一个review的request,会在Swarm上去丢给你的Leader。
一般来说,这丢给Swarm之后会触发我们一个制定的CI流程,它会根据你的工单的类型,这个就涉及到我们前面那个元素的作用了。我们得知道这个工单是为了什么目的、它到底会涉及哪些资源、我们要做哪些检查,以及根据你迁入的资源在我们工程目录里面的匹配规则,它到底属于哪种资源。去做相应的检查后,我们会把检查结果贴到那个Swarm。
当你的Leader去看的时候,他首先看一下自动检查的结果,有没有一些不合适,或者虽然不太合适但是可以忍受的部分。这个地方和我们代码编译过程会有warning和error的部分一样,但是在某一个比较正式的版本分支上面,这些就已经迁不进去了,然后你的Leader看完以后会决定要打回或者是接受。通过这种方式,我们能够最大程度上的去保证每一个工作环境上的人提交的东西是合法。
这个是DevMsg产品。
这是制作工艺流程中,基本上是美术生产过程的数据化和工具链,我们要谈到它的特殊性和通用性。
特殊性,意味着每一个项目的美术规格都有差异,风格也不一样,有的写实、有的是卡通。游戏类型不同,跨平台的预算分配也不一样。我们可能有的游戏需要在特效上多分配,它允许每一帧所消耗特效的GPU时间会多一点,有的是整个场景的植被渲染要多一点。这个东西都是根据我们中台在Alpha0阶段去做的一些衡量,和项目组做一些沟通后去反复测试,批下来的标准。很多项目也存在自定义的美术资源,特别是一些预制件。在别的游戏中不存在,只在他这里存在,也有自己的一些规范。
有特殊性,它也有通用性。通用性是为了保证,我们不能单独为了一个项目开发一整套工具链和流水线,成本都太高了。在通用性上,我们一般是通过把整个功能和要落地的过程切分很多层次。
首先,我们会存在跨项目的数据规则框架和工具链框架,落实到具体项目中,我们会把数据规则框架进行一些配置,就是数据驱动的规则模板。比如我们每个项目都会去审查某个资产的面数,面数的值由项目组自己来治理。还有工具的组件化部署,你的整个工具链必须是要考虑好组件化,不能直接来个“全家桶”,你得允许项目去选择某些组建来部署。这个地方我们也做了一些像腾讯的同事们做的那些部署框架之类的,有些环境下面是我们把部署好的环境一股脑全迁到收藏库里面,其他工作人员直接盖下来就是最新的,这样的话我们更新的时候也很方便。
后面会举两个例子来说明,美术方面的数据化和工具链。一个是美术资源处理流程,就是美术资源出口资源的导入;还有一个是材质的验证。
这个是美术资产的导入。首先,美术资产生产完了以后,第一件事是要导出。在导出的时候,就会利用我们做的二次开发的一些工具,来检查这个资产。比如一些命名规则、层级结构,顶点数据有没有废数据,在一些变数参数上面有没有符合我们的要求……裸资源导出了以后,第二步就是导入。
在那个裸资源导入引擎的时候,我们在引擎里面做的二次开发会对资源进行二次处理。比如贴图的跨平台压缩设置,针对不同的规格质量要求的包的贴图的设置。比如《ob电竞》项目,他机器人我们导进来的裸资源其实是一套的机甲部件,在满足一定的那个命名规则的前提下,我们会让程序那个自动去做一些预制件的生成。就直接把它组装成最后程序会调用的一些东西。
然后这些资源进入了系统之后,比如我们在场景里面把这些资源放上去了后,我们会做一些profiling的工具来去做初步验证,这些东西组合在一起是否符合要求,这些profiling工具后面我们会再详细介绍一下。
引擎当中的生产过程完成了之后,我们上传的时候就会去做CI检测,以及保证进入source control资源的合法性,这个前面已经做说过了。
这里再谈材质一致性的问题。我们以前会遇到的一个问题是什么呢?比如在一个游戏当中,两个不同的场景可能一个是晴天,一个是阴天,不同的美术、哪怕是同一个美术有时候也会犯这样的错误:他为了达成最后美术画面的呈现效果,有的地方是靠调建筑物的材质和颜色来达成,有的地方是靠调光的达成……就非常的不一致。当你想去做一些全局的后期处理时,这件事情就立马凸显出现。然后你想返过去搞,成本又很高。
所以在处理这种问题的时候,一个前提是要去搞清楚最后画面像素的颜色,在光照着色渲染上面到底分哪几个步骤,每个步骤的贡献到底是什么?以此来针对每个步骤进行计算机制的对齐,以及最终贡献结果的对齐。
比如PBR的渲染,我们首先要确定的是物理早期模型。再就是光照环境的一个确认HDRI天光的拍摄和矫正,物理光照和曝光,然后再是GI烘焙。还有一个GroundTruth是我们自己定义的,他的作用是什么呢?比如你要验证材质模型,必须要有个标准场景,这个标准光照场景我们如何保证正确呢?我们首先把它渲一遍,然后我们再用自己光栅化的渲染方式再把它渲一遍,再比较每一个部分的颜色差异是否在可接受程度内。如果ok,说明我们这个光栅化的东西已经达到了目标要求,当然这个东西只适合做PBR渲染。
然后基于这个标准光照环境,我们可以把其他后续增加的材质放进来。因为策划会去定义,这个材质我们想看这个时候没有那个时候光滑,这个时候会比那个时候也是深一点。那我们在标准光的环境中,就会先放一些标准的资产,如一排石头、一排技术桶之类的。这样的话,你就会把新生产出来的材质放到里面去做比较,看看在他的那个维度上面是否属于一个正确的位置,就能确定你的东西做对了。
这个是在我们另外一个项目的非PBR渲染当中,是同样一个过程,只不过它的风格不一样。我们需要确定风格化的着色器模型,每个角色要用一样。也是要去确定它的光照环境,角色光、虚拟光照和GI烘培。
这个是我们刚才说的,profiling过程中会涉及到的一些检测手段。第一排第一张图是针对渲染过程,我们把每一个渲染层级,或者他在渲染管线上的每一层级的贡献能够单独拿出来去检查,这样的话就是对于TA、美术来说,效率会比较高。
第二行这个是来检测我们MipMap的使用,这个东西很多引擎都已经提供了。最后一个东西比较特殊,是我们自研的一个东西,它是用来解决什么问题呢?制作人有时候看到某个场景,会说这个场景好像不太好,但美术问他具体哪里不好,他其实很难说出来的。非美术人员是很难去回答,他只觉得那个场景屏不够不够丰富。那美术问他,是不是我多加点加点轮胎、或者加点什么小部件,你会感觉更好,有时候其实并不是。
那这个东西的作用是什么呢?你看它上面有几张小图,黑的一个柱状图,那是在统计这张图里面每一个像素的亮度分布。一般来说,亮度分布越集中,你的画面就会越突兀。它的比较高的部分代表亮度高的那个像素,从高区往低区走的过程越平滑,说明你光照的那个分布越平滑,那说明细节越多。当然这个东西不是绝对的,有一些风格化的游戏和摄影过程中,确实会用到非常强的明暗对比,而且明暗过度非常突兀,这是他的风格。
后面那个彩色的方框,是在统计每一个像素在色域上的分布,来让你去检查是否有撞色、补色。在这些支持的情况下,我们明显发现:你如果觉得一个场景的细节度不够、光照很平的时候,第一张图就会呈现出一个部分曲线更陡峭的情况;你觉得有些场景很好,就会发现第一张图它的分布会稍微平滑一点。
最后一个话题是工业化团队建设问题。我们认为再好的装备也需要人去操作,那什么是最重要的,人才是最重要的。
我们是一个持续时间非常长的团队,在推进工业化的过程中,我们其实有一些特殊的优势,就是自上而下的推进。包括我们很多工具链该如何做,我们的对工具链的规划是什么样的、我们要达成什么样目标、每一阶段要做什么?这些事基本上是我自己在做。
再谈到一点就是灰度推进,我们没有办法等所有事情都ready以后再去推进,那个事情永远等不到。我们只能在项目中,让这个项目用得少一点,那个项目用得更广泛一点,但是我们得保证一点:越往后走的项目应用范围越广泛。通过反复的迭代,我们就会得到一个比较好的结果。
再就是谈一下我们中台做的事情。我们中台完成了服务器框架、客户端框架以及渲染管线,还有开发和配置管理工具链的support。当然,服务器框架和客户端框架基本上都是我写的,后面其他人维护的,后来我们中台负责人来搞了渲染管线框架的部分。另外有一个团队专门去负责配置管理工具链的开发。
最后谈到的就是梯队建设的问题。现在游戏开发动辄上亿的预算,是非常复杂的信息管理体系,这些信息管理体系如果需要人去操作的话,需要保证这个团队的延续性,和一个持续的自我迭代。我们有一个操作的方法,即在中台设立一个所谓的教导队。
这个教导队是干什么的呢?他会重度参与公司的某一个项目。在这个项目中去迭代我们的框架代码、渲染代码,包括开发管理工具链的应用。同时,这个教导队的人员来自我们每一年的校招,挑选的天花板比较高,并且被公司挪用足够的人去做密集的培养。这些人未来也是公司成长的关键,他们会逐渐成长为小的力量、大的力量,以及到公司的技术负责人。
这个培养过程会谈到价值观和方法论,我们认为价值观是第一位的,方法论只是术,价值观才是道。我经常会跟大家说,开发过程中“勿以善小而不为,勿以恶小而为之”。
勿以善小而不为,因为开发的过程太庞杂了,有很多细节,你如果觉得某个修改很小懒得做,那就永远不会产生大的进步,必须从一点一滴去做起。而勿以恶小而为之,开发过程当中其实有很多“恶”,是一点点小的不规范。这些东西如果不去做管控,后来的人看到你放低对自己的要求,这个事情就会越来越大,一直滚到一个无法收拾的地步。
还有一个是积累和传承。前面也说过,我们已经长达数十年去做实习生的培养,现在公司很多开发骨干和管理人员,都是当时早先培养出来一些人,这是公司内部本身就存在的需求。我觉得我们公司存在的一个很重要的目标,就是让认同我们价值观的人,能够有一个合适的工作环境。
我们也会和一些大学合作,一开始从大二大三去建立兴趣小组,后来逐步跟学校合作,建立实验室。实验室也会有美术专业和计算机专业的人参加,我们去合作做项目,并且我们还制定了一些课程,包括各种基础的内容、引擎的使用、编程设计方面等等。
这其实就像种一颗树,最好的时候是十年前,其次是现在。只有我们不断去做这个事情,这个行业才会有发展、薪火相传,能够做出更好的产品。
如若转载,请注明出处:http://www.ashkeling.com/2023/02/510102