我是从12年开始进入页游行业,接触到的第一个游戏项目就是淘米网的《摩尔庄园》,公司那个时候也刚在美纽交所上市,被Benson,魏震和Rock腾讯三巨头的感染下,做着喜欢的游戏... (后来在工作中我经常会遇到过不少00后的同事碰到我说,jack,我就是玩着你们之前做的 摩尔庄园和赛尔号长大的,巴拉巴拉...惭愧,是我老了还是你们长得太快了。。。)后来去其他团队转手游,但无论怎么转,做了这么多年的服务器开发,服务器开发的主要代码仍然是C++,除了历史原因之外,性能问题是大头。
基本上游戏的整个开发从立项到上限,服务器都在考虑如何降低内存占用,防止内存耗尽;服务器在考虑提高稳定性和单服支持的最大人数。用脚本语言有一个很BUG的问题,调试难不可控。很少有策划会注意性能问题,最终很容易导致各种卡。这个也难怪他们,他们的重点在游戏逻辑上,不是那么关注技术方面。不过我知道C#,Java,Lua之类的垃圾回收机制在回收内存时很容易导致卡。
海外开发者的服务器端开发
我曾经有过和海外开发者打交道的机会,曾经接触过 铁皮工作室, Games Workshop,MadFinger Games等知名工作室的开发者,他们很聪明的避开了C++这种笨重的语言,铁皮的《王国》系列产品(应该是3之前)的都是flash开发,Games WorkShop的《战锤40K》等作品的服务器是js(应该是他们的很多游戏项目都是在GameSparks平台上开发的,毕竟GameSparks上提供了丰富的SDK,可以让开发者只关注自己的业务逻辑,不用关心网络底层库,数据库,多线程,缓存),我接触过MadFinger Games的Unkilled产品的开发,他们使用主要是java,使用的是谷歌的GAE平台,做成服务直接发布。(如果读者感兴趣的,可以在后台或者文章末尾留言,我们可以交流下你感兴趣的海外开发者的一些技术,他们的框架平台选型编辑)
国内游戏大厂为何仍然使用C++
其实用C++用的多是国内端游界的常态。在国内的页游手游小团队Hold不住。
分析原因可能是有以下几个方面吧。
1.从历史原因来说,早期国内游戏研发大公司基本都是用C++写的游戏引擎。可能原因是因为当时可能并没有专业的服务器端程序员,很多程序员都是客户端服务器端两手一起抓。而写客户端基本上就是C++的天下了。所以用同一种语言比较顺手,也不需要重新招聘,就直接用C++来写服务器了。其次可能是当时Java确实也不成熟,在业内没有一个有说服力的案例。.net就更加了。端游行业又是一个很看重成功案例的行业,前一个项目用C++效果不错,可能后一个就继续了。而且当时那一帮人出来创业的话,一定也会用自己熟悉的方案,所以C++就一直流传下来了。
2.从技术原因来看,C++确实是一个写服务器的好语言。
- 上限高
- 掌握核心技术
- 生态和其他
上限高,也就是性能极致。大公司一般不会采用上限低的技术,3A产品都是各种极致的集成,比如WOW这种规模的产品。什么开发成本,开发难度等,对于他们都不是大问题,反而因为上限低导致关键功能实现不了,这个才是硬伤。能堆人解决的都不是事,就怕堆人也解决不了,比如硬件限制。想想之前那些连STL,虚函数都不让你用的这种场景发生在多少大公司中你就明白了。
掌握核心技术。大公司不可能让自己的核心技术被别人控制。想想华为为什么研发鸿蒙系统。所以大公司造轮子都是常态。即便UE开放源代码,大公司都会继续研发自己的引擎,没有任何选择,钱都不是问题。核心技术基本都是基础设施,C++是大头。
所以基于这3点,大公司是不可能用其他技术作为核心工具的,C#,Java和Go败在性能,Rust败在生态。
很多时候,游戏服务器的瓶颈通常不是在cpu,也不是在io,而是在内存。游戏不同于网站服务器,游戏在线玩家数据都会放在内存,数据库只是作为一个数据持久化的存在。所以限制游戏服务器同时在线人数的关键是内存的利用率。而对内存的利用上,还没有一门语言能达到c/c++相同的级别。所以对于一些同时在线不多,交互少的游戏,用什么语言无所谓,但是单服同时在线人数过1000,强交互的游戏基本都选择c++。
举几个例子让我的论述更有说服力一些(注意我一直说的是大型项目):
- Naughty Dog使用Object LISP开发几个大作后迫于SONY对于生态的问题换回了传统方式(C、C++)
2. 育碧有个职务叫general-programmer,基本上都会同时跟进前端和后端还有其他方面。(是的我就是这个职务开始的)
3. 大部分3A手游都是C++做的,比如现在的UE4发移动端,同一个引擎大部分技术就共享了。Android没有ndk之前,哪里有3A游戏在android上。慢慢的移动平台开发越来越像pc开发了,共享就更有优势了。
4. 微软都放弃XNA框架了回归native开发了,推纯C#大型游戏开发目前还是扶不起来啊。(具体原因忘知情人士透露)
5. 连Unity都用IL2CPP生成native了,一个是性能,另一个是移植mono后端成本太高了(当然还有其他比如授权的原因)。说明对于大引擎来说,脱离上游维护自己的工具链(还仅仅是个运行时)成本还是非常大的。
6. 选java或者go做服务器的,都是想利用它们做web后端的生态。大公司有自己的C++生态所以大公司用C++好处多,小公司可能就不一样了,只能抱web大腿。
C++写服务器的弊端
如果你写过node.js,python,或者php你偶尔会心疼下常年写C++的自己,不,是自己掉的头发。
- 用C++写逻辑简直是反人类,实现同样一个功能代码量多N倍(你和node.js的技术比一下,他能用四五行代码能写出一大堆业务逻辑的实现)。
- C++逻辑出了bug就是能core掉你一组服务器的bug。项目团队大了+再牛逼的人也会有脑抽的时候,线上服务器随时都有core掉的风险。
- 早期端游没多少的时候,是卖方市场,你的游戏挂了我玩家就没其他游戏可玩了。后来端游是买方市场,你的游戏挂了我只要付出成本没多少我一个不爽就换另一款跟你品质差不多的游戏去了。所以热更新已经成为大厂端游标配。纯C++服务端怎么热更新?所以你会听说到大批老的纯C++写服务端的页游、端游热更新的唯一办法是快速重启(事实如此,不用听说,听说是经不起推敲的)。
为什么还有团队在招C++
先看下传统C++端游团队的心路历程:
团队扩张,要招点业务逻辑狗。C++逻辑程序太特么难招了,低薪程序员成天core,高薪程序员不愿意做业务逻辑狗。
怎么办?改改改。
担心性能?那我IO线程不改了,还用C++;AOI不改了,还用C++。
逻辑线程主循环虽然跑的还是C++,但是python/lua各种侵占的逻辑模块越来越多,一开始可能只是小范围尝试,后来发现:咦?性能影响不是特别大嘛,慢慢的C++那块代码已经没人敢动也没人想动了。再不济,招个大厂出身的、用过bigworld的来做“架构师”,借鉴点大厂泄露出来的ppt讲座什么的,也来搞一组可以热扩展的gate,db前面也挂一组可以热扩展的proxy,再配合一下分线,性能问题还算问题吗?
这就是目前国内大部分老的端游团队,所以他们招人的时候为什么喜欢问C++呢?因为他们以前搞C++的对C++熟,C++当面试题逼格高,C++当面试题对老C++程序员简单,面试前一晚翻一本《Inside C++ Object Model》能问翻80%,再随便看看C++新特性,能再问翻15%,剩下的5%是什么?也只剩搞编译器的了吧?咦说好的业务逻辑狗呢?
你可以用什么语言写游戏服务器呢
好吧,那究竟该用什么语言写游戏服务端呢?
用你喜欢的语言就行。
大概分下类:
第一类。C++叉某种脚本(C++ &lua较多)。
优点:一般是大厂职位,技术积累雄厚。
缺点:底层部分碰不得。即使有代码你也不敢改,很多都是线上跑过几年的,即使发现有bug你敢改吗?
第二类。各种模型的服务端开发框架。比如直接Erlang,比如云风的skynet,比如网易的pinus或者pomelo。
优点:大部分搞游戏服务端的程序员思维是比较传统的,只认逻辑线程+IO线程的死理,他们虽然没用过actor,但就是觉得MMO拆成actor不靠谱。但是程序员的初心应该就是学习新知识,所以你到这种团队可以远离没初心的程序员接触有初心的程序员。
缺点:基本上是限定工作城市在广州,杭州,西安了(可能还有其他城市)。
第三类。游戏服务器开发平台,比如photon,playfab,gamesparks,GAE等。
优点:开发者不需要关注网络底层库,缓存,负载,只需要关注自身的游戏逻辑即可,大多数平台可以根据服务器压力横向扩展,这些平台能提供一些玩家数据存储,排行榜,多人匹配,多人对战,GM,热更新配置和部分业务逻辑,而且语言开发基本上都是js,java,甚至有些直接只需要在后台配置即可,从dev环境切换到prod环境也很方便。
缺点:部分服务的收费比较高,而且免费试用期限较短,对于大型项目使用前期费用不少。