老司机乱谈游戏开发
老司机乱谈游戏开发——谨以此文追忆那些逝水年华
前言:我们生活在一个幸福的时代
那个时代是2004年,公司刚从赛格工业园搬到飞亚达。当时的研发模式还比较原始,我自己开发后台,偶尔兼职前台,还要做运维,负责数据备份、扩容,配置防火墙和路由策略等等。有时开发的过程中出现问题,就要去机房。当时server.oa.com 上有很多信息不准确的,比如找不到的IP,错误的机架号,都是需要自己多去几次机房整理准确的服务器列表。进机房门推一个小推车,推上键盘鼠标,机器的ip等信息贴在机架前面,找到机器后,开指示灯,机箱后面就会亮起来,然后到绕到机架后面去把键盘鼠标接上开始操作,再次核对真实ip(标签贴错也是有的),然后才能真正的开始操作。幸运的事情是这个时代已经过去了,现在公司级的网管和BG级的网管已经非常完善,在组件层也提供了云服务,业务层也有专业的运维,开发人员已经可以专心负责研发了。
一 、一个游戏如何成功
大部分开发人员都沉浸在游戏中,废寝忘食欲罢不能
一个好的游戏是从一个好的玩法开始,这是自己的核心竞争力,必须做到极致。这里引入一个心流的概念。匈牙利裔美国心理学家米哈里·齐克森米哈里(Mihaly Csikszentmihalyi)对心流体验的定义为:“行动者进入一种共同经验模式。在该经验中,使用者好像被吸引进去,意识集中在一个非常狭窄的范围内,以至于与活动不相关的知觉和想法都被过滤并忽略掉,并且丧失自我意识,只对活动的具体目标和明确的回馈有反应,透过对环境的操控产生控制感”。
我曾经参加过一个游戏的开发,团队大部分开发人员都沉浸其中,虽然没怎么推广,还是取得了一定的成绩,是工作室收入最高的页游之一。当然这个不是游戏成功的充分条件。游戏的设计是一个极其复杂的过程。
学习与创新的平衡
游戏设计与开发是一门复杂的过程,涉及美学、心理学、文学、图形学、计算机科学等等。一个成功的游戏并没有那么简单,如果只想模仿一款游戏,十有八九模仿不好,因为你只看到了冰山一角。就像有人想抄袭微信或者支付宝一样,事实上整个体系远超你的想象。当然我们必须学习其他游戏,站在巨人的肩膀上。并且在学习的基础上改进创新。合适的创新是先驱,过度的创新是先烈。这是一个平衡之道,很难讲清。 但有一点是可以确定的,必须反复打磨自己的核心玩法,形成核心竞争力,做到极致。
无论是什么学问,成长的曲线基本都是一样的,
1、模仿,这是一个很好的开始2、脱离模仿,形成自己的主见
3、学然后知不足,知道自己的缺点才能更快的进步
4、融汇贯通,可以自立门派了
5、以简御繁 ,“天下之理原于约者,未尝不散于繁。散于繁者,未尝不原于约”,当你的知识逐渐完成就会像俄罗斯方块一样消除,变成最简单的东西。 比如欧拉公式,麦克斯韦方程组,简单的公式后面蕴藏了多少东西?
6、大彻大悟,您已经看见了上帝。
所有人都是策划、团队目标的高度一致
团队成员必须达成一致的目标对游戏的整体有一个全面的了解。有自己的见解,并不断体验自己的游戏。如果大家都不愿体验自己的游戏,或者说体验游戏也仅仅当做任务完成,那这个游戏基本不太可能成功。
民主与专制
团队在遇到意见分歧的时候,表面看起来一般民主比较安全,但是大家忘记了一个事实:大部分人都是愚蠢的,聪明的只是少数人。所以只有少数人才能成功。团队的负责人要在关键的时候进行拍板,而不是处处都需要民主。如果团队负责人只是负责组织投票,那人人都可以做负责人了。
二、如何做一名合格的游戏开发人员
保持一颗学习的心,不断的学习
重要的不是你学会了什么,而是不断的磨练你学习的能力,当机会来的时候可以快速学习,快速转变。例如手游来临的时候快速的转换技术能力,VR来临的时候快速的转换技术能力。没有快速学习快速适应的能力,必将被快速的淘汰。
相由心生 境随心转
在电梯里经常会遇到满口抱怨的程序员。人在这种状态下是无法提高工作效率的,而且会给团队带来负能量,更不用谈用心创造快乐了。梭罗说“大多数人都生活在平静的绝望中”,生活不止只有当下还要有诗和远方。天天怀着上坟的心来上班,如何给别人创造快乐。接受你终究平凡的事实,也不能放弃对梦想的追求。人生就是对梦想的追求,如果你的人生没有梦想或者梦想都已经实现,你就跟游戏里的顶级账号一样,全无意义了。当你有里一颗怀着梦想的心,你才能为其他人创造快乐。而不是你的技术水平有多高才能创造出一个成功的游戏,事实上做一款游戏在技术上失败的可能性不大。如果只对技术感兴趣对游戏没有兴趣,请立即更换BG。
请记住:用心创造快乐
时刻用不同的眼光看问题,用发展的眼光看问题。
当你站在在一个不同的角度,你看到的景色将不同,以下图片我拍摄于香港。因为心不同,角度不同,所以照片不同。
读书或学习的时候不要仅仅理解作者的看法,想想自己的看法。并且参照当时的历史背景深入理解。学习是为了忘却,不要遗留下来顽固的观念束缚了自己前进的道路。每一个理论都必须放到理论提出当时的历史背景情况下才是正确的。
2004年IEG还只有飞亚达大厦8楼西面的一半的位置(如果没有记错)。我因为要去重构一个服务器去请教曾总。曾总给了我QQGame 最初的网络相关代码,清晰简单,对网络IO和逻辑处理进行了分离,并且说不要在服务器里使用STL相关的东西,动态的内存分配效率低,并且影响服务器的稳定,等等。听君一席话胜读十年书,马上按照大神的思想重构了服务器,逻辑清晰,性能高,稳定运行。10多年过去了,游戏后台开发基本逻辑变化的不大,但是服务器的硬件能力数量级的提高。项目里早已大量使用STL,极大的提高了开发效率,性能早已不是问题。所以要用发展的眼光看问题。宁花机器一分不花程序员一秒,这也是Unix哲学之一。
由于硬件的飞速发展,技术早已不在是游戏研发的瓶颈了
请体会《死亡诗社》里的一段台词
Just when you think you know something,
you have to look at it in another way.
Even though it may seem silly
or wrong, you must try!
Now, when you read, don't just consider
what the author thinks...
consider what you think.
Boys, you must strive to find
your own voice.
Because the longer you wait to begin,
the less likely you are to find it at all.
三、如何提高游戏开发的效率
团队培养闭环
如何比别人更多的享受生活?效率是关键,我在高三的时候读遍了金古梁的小说,哪里来的时间呢?因为我上课从来不听课,老师一节课可以讲3道题,我自己学习呢?可以做6道以上吧。而且可以参考不同作者的思路。后来因为做的快,书店能买到的各种奇葩教材我都看过,上课呢就睡觉,因为放学了看小说要到深夜。讽刺的是高考的时候我还是校第一名。深林里有两条路,有的人选择了宽阔的大路,有的人选择了人迹罕见的小路,人生的差别由此不同。
请注意,走小路的后果也可能是死的很惨
对于一个研发团队也是一样,如果使团队的效率提高,就会进入正反馈的循环,团队的效率会不断的提高。有充足的时间进行学习,进而团队的效率进一步提升。如果团队的效率不高,被需求和bug缠身,完全没有时间来进行自我提高。团队的研发效率不但不会提高还会降低,因为团队的气氛不好,甚至人员流动频繁。这样的团队永远处于初级阶段。磨刀不误砍柴功,这依然是真理。
开发越多,效率越低
我们以后台开发来举例,假设我们有一个开发人员,质量大概是0.9。如果有10个开发人员每个人的质量都是0.9组合起来的质量大概只有0.35了。质量低意味着bug率高,互相推诿,进度缓慢。而且期间的沟通成本也是十分的大。我们假定一个开发一周产出为10。如果有2个开发产出大概为18。如果有10个开发产出可能只有40。如果增加开发还是新手,对团队产出的影响还是负值。那种所谓的团队合作一加一大于二的事情只是流传多年的谎言而已。对于游戏开发来过程来说,合理的控制团队规模非常重要。
开发一个游戏需要多少技术人员
以前开发过一款游戏,从零开始。我以前主要做大容量服务器相关的设计与开发,这是第一款游戏的开发。一个前台和一个后台情况下1年内基本完成游戏的开发,上线前才追加了其他开发人员。一前一后的模式,开发效率相当的高,不会出现多个和尚没水吃的情况。后期前台吃紧的情况下,大家就帮忙一起做前台。一个普通系统可能一天就能完成开发。因为团队很小,策划也都是技术人员,任何文档都省略了,所有的策划文档是上线前照着游戏补充的,因为没有文档就没法测试。事实上这个游戏也不算失败,也是工作室当时收入最高的页游。但因为团队初期除了一个美术都是技术人员,没有专业的策划人员。这个游戏的整个架构设计(策划方面)以及数值体系还是存在问题,影响了用户数据。对于手游来说由于各种原因,开发人员会多一些,RPG游戏技术人员更是会几何倍数增长。如何发挥团队的最大效率就是我们需要考虑的首要问题了。
人员的热备份
对于一个项目所有模块必须有2个或以上的人非常熟悉。这样团队才能持续稳定的运行,而不至于由于某种原因缺了一名成员而导致进度的落后甚至运营事故。这样做我们也会获得一些额外的好处。例如一个人熟悉多个模块,系统的边界减少,debug的效率极大的提高。
跟时间赛跑
尽一切可能消灭拖延症,比如我现在的写文章的状态,笔记本故意不带适配器。你看电池还有40分钟了。你是不是会写的更加快了,跟时间赛跑? 而不会去浏览网站什么的。以前在团队小的时候,我自己使用番茄工作法,效率也是相当的高。
附《番茄工作法》
番茄工作法是简单易行的时间管理方法,是由弗朗西斯科·西里洛于1992年创立的一种相对于GTD更微观的时间管理方法。使用番茄工作法,选择一个待完成的任务,将番茄时间设为25分钟,专注工作,中途不允许做任何与该任务无关的事,直到番茄时钟响起,然后在纸上画一个X短暂休息一下(5分钟就行),每4个番茄时段多休息一会儿。番茄工作法极大地提高了工作的效率,还会有意想不到的成就感。
四、游戏架构设计
管中窥豹
架构上的分层
在上图中,我们大致讲一个游戏分为:
1、接入层,这一层TGW已经做的很完善,不需要我们做什么。2、逻辑层,我们的主要工作集中在这里,包括Zone一级的服务器以及全局的服务器。
3、中转层,这一层不管用什么技术实现,都是通用的,不需要我们做什么。主要是建立服务器群集内部的通讯机制,包括Zone之间的通讯,以及到各种proxy的通讯,这里4、通过各种 proxy对系统外的各种系统进行解耦,以保证游戏在不同国家以及各种账号体系下的一致性。
5、数据层,这一层Tcaplus已经非常强大,也不需要我们做什么。无论是分区分服的游戏还是全区全服的游戏,我们不在db层进行分表,只作为逻辑上的划分。所以我们可以做到动态合服。
这里我们引入全局数据存储,逻辑层虚拟分区的概念。
我们可以获得如下好处
1、不停机动态和服。无需深夜加班合服到清晨,想合就合。2、单进程内的动态负载均衡,单服50人?单服10000人?我们在逻辑层进行虚拟分区,极大的方便了运营成本的预算。有些游戏在开发初期往往无法给出单服在线的准确预估,在设计的时候做到一切尽在掌握。
以气御剑
我们的目标:尽一切可能,降低模块之间的耦合性。
一个游戏的内部模块分层的例子
软件设计有两种方式:一种是设计的极为简洁,没有看得到的缺陷;另一种方式是设计的极为复杂,有缺陷也看不出来。现实中大部分团队可能是第二种,所以加班改bug是避免不了的了。
事实上游戏属于一种复杂软件,唯一能降低debug成本的方式就是将bug限定到一个个清晰简明的模块中。对于良好的模块设计,我们会获得诸多好处,例如:隐藏细节,提供抽象;软件分为若干层次,逐层、逐模块实现,方便并行开发;方便代码复用,按照项目的相似性,越相似,可服用的越多。
那么如何才算是模块划分的合理了呢,至少满足下面两个特点:
1、功能的唯一性,对于一个模块,产生每一个输入,只会产生一个结果而不会产生其他副作用。当然对于游戏开发来说这条很难满足,我们至少保证某一个系统的底层接口的功能是唯一的。例如一个底层的包裹操作接口,不应该操作包裹以为的任何数据。2、真理的单点性(Single Point of Truth),任何一个接口在系统内应该有唯一、明确的实现。绝对不能出现条条大路通罗马的现象。实现同样的功能,可以调用A接口也可以调用B接口甚至直接调用了底层接口。常常当你修正了一个bug后,线上的游戏依然无规律的出现同样的bug。因为条条道路通罗马啊,一个地方用的A接口,另一个地方用的是B接口,其实A和B接口基本是差不多的,粘贴的时候bug也粘贴了一份。事实上大部分bug都粘贴了两份以上。这一点为加班改bug奠定了坚实而稳定的基础,自己埋下的孽缘需要自己买单,甚至是团队买单。
当然事物总有缺陷,我们很难做到单向的依赖。这时候我们需要使用回调或者多态之类的技术来完成解耦。
重剑无锋,大巧不工
我们先看上线游戏的核心代码
其实一个游戏服务器就是实现这么几个接口而已。
1、init 初始化2、fini 反初始化
3、tick 计时器处理
4、proc 事件处理
5、reload 从新加载配置
重要的是在项目中把代码的逻辑结构整理的更加合适,便于大家的阅读以及bug的修改,仅此而已。
千里之行始于足下
异步IO
1、网络通信和业务逻辑分离(剥离网络IO)2、业务逻辑和存储分离 (剥离磁盘IO)
3、业务逻辑和日志分离 (剥离磁盘IO)
4、复杂业务和主业务分离 (运算量分离)
保证主业务不会受到任何阻塞,保证单用户不会掌控你的系统资源。
平衡之道
数据层设计
1、热点数据全缓存2、对多个写入操作进行合并处理
3、对写入操作设置优先级
4、全局DB写入频率控制,防止DB崩溃
5、数据版本控制机制,停机回写机制
数据内部的分层
2、其他数据在服务器启动的时候进行重新计算,避免数据不一致。
总结
架构是一种生态,而不是设计出来的。架构是在项目的开发过程中不断进化形成的适合于项目组的一套隐形的规范。教外别传,不立文字。
这种良好生态环境会带来哪些好处?
1、系统干干净净,开发满意
· 项目代码易于理解,bug率低,易于维护。
· 团队成员有充分的时间学习,团队成长迅速。
· 团队成员稳定,离职率低。
2、自动化运维,运营人员满意
3、可靠性高,玩家满意
4、研发效率高,老板满意
最后用大刘的话送给大家
这个世界上,已经有人在宇宙漫步,星空是他们最后的坟墓。 相比之下,你那点考试升职亲子关系家庭问题就像屎壳郎找不到合适的粪球一样卑微。
Jaco 于2016年春节