« April 2008 | Main | June 2008 »

May 31, 2008

3d 引擎中对场景数据的接口设计

目前是我第一次设计 3d engine ,虽然主要贡献 3d 方面代码的同事不是第一次做了。我们做了两年多,大方向上是我在把握设计。但是毕竟是没有什么经验,也就老在修改。

这个周末再审以前做的东西,觉得接口上还需要调整一下。比如精灵的控制接口、摄象机的控制接口、场景描述的接口等等。以一个游戏开发人员的角度来看,我需要接口是什么样子的?

我希望是最方便的描述虚拟世界中各样东西的相互关系,引擎当隐藏住不必要的细节,比如 3d 方面的数学知识,专业化的术语,复杂的坐标转换等等。今天写下这些,不是定论,而是做些思考的记录。

我想知道,对于 3d 引擎的使用人员,如何描述虚拟场景,暴露出怎样的接口是比较合适的。

对于我们的游戏,和大多数游戏,角色在场景中的坐标是二维而不是三维的。就好象描述你在地球上的位置,大体上经纬度就够了,只有在需要更在很复杂的场景中(比如一栋高楼中),再加上一个离地面的高度。

这里,我们取的都是离地面的高度,而不是相对地心的。所以你站在南极比站在赤道上离地面更近,或是站在拉萨的街道上比站在上海的商场里离地心更远,都是不需要考虑的事情。

高度这个维度,远不需要经纬度的精度高。在一些需要得到高度信息的位置,比如我们在高层建筑里,只需要说自己在第几层。而在小河边,则只需要了解在桥上还是桥下。因为大多数情况下, 人必须脚踏实地。

最终,我需要 3d engine 加载完场景数据后,使用它时,只需要设置经纬度,就可以把一个物件放置在那里了。默认情况下,物体总是紧贴地面的。如果需要让物体悬浮在空中,我们只需要外加一个高度属性,这个属性的值描述了物体相当当前经纬坐标上的地表的高度值。

当同一个经纬坐标上,有多层地表怎么办?解决方法是分层表示。地面可分成多个层面。举个例子,有一条河,两岸之间架了一座桥。这样一个场景当被分成三个层面。

两岸及河床是第一层,水面是第二层,桥面是第三层。

当河水干涸的时候,水面一层消失,退化成两层。(通常在建模的时,岸边和河床就是一体的,水是额外做上去的)

人从岸边上桥,就从一个层跨越到了更高的层,这个跨越线,可以额外标注出来。

同样,从岸边下水,也是一个跨层的过程,同时触发游泳的事件。从水面下潜,也有类似的过程。

根据逻辑需要,引擎还应该提供层与层之间的高度换算。比如桥面的高度相当于从水面计算的高度值。

那么空中的物体如何计算?方法是,提供一个零层,这个层面一定是在欧式几何空间中保持水平的。(当然如果想做一个球面的游戏,这个层面也可以是球形的)浮在空中的物体可以依据这个来换算坐标。

我们还需要引擎提供同一层面上每个经纬坐标点上的法向量值,或是两个不同点之间相对零层面的高度差(这个值可以通过上面的方法换算得到)。这个用途之一是为了处理四足动物的摆放。

不是每个层面的任意坐标点上都有有效的法向量的,比如一座桥,桥面以外的空间在它那个层面上都是无效的。如果命令物体移动到无效的位置上,我们可以知道该物体会发生坠落,掉到下个层面上。或是简单的阻止这样干。所以这个信息还可以用于描述阻挡物。


大多数情况下,我们并不需要精确的描述物体的坐标。正如我们在现实生活中,除非手持 GPS 设备,否则很少用经纬度来汇报自己的方位。我们只需要知道什么在什么的附近就够了。所以确定位置通常是编辑器做的事情,而游戏逻辑只用知道物体在哪个地点。

坐标值通常只用在描述和计算物体运动的过程里面。存在于比较低阶层次的接口上。

尽量脱离坐标值本身,我们也不必太在意坐标是二维量,还是一个三维量;物体在空间中的状态,是用一个向量表示、还是一个矩阵,或是四元数等等。我们也就隐藏了引擎是 3d 还是 2d 或是所谓 2.5D 这些细节了。

最后的目标就是,用图象引擎提供的接口来描述物体和物体之间的关系,而不是单个物体在空间中的绝对位置。应该抽象出哪些接口供开发者使用,还需要再斟酌一下。

May 25, 2008

会抽到自己的那张吗?

周末和一个朋友聊天,说是要去阿里巴巴报道了。听说阿里巴巴的入职培训中有个有趣的游戏。所有学员都要在一张纸条上写下自己的一个短期愿望,投进纸箱中。然后大家各抽一张。抽到别人的愿望后,要想办法帮那个人实现愿望,且不能告诉对方是你抽到了他的愿望。

我突然想,如果抽到自己的愿望怎么办?:D

抽到自己的写的那张的概率是 1/n (n 为人数),这个概率和你先抽后抽无关。当人数很多时,概率自然是很小的,但是整个集体中,至少有一个人抽到自己那张的概率看起来却不小。到底是多少呢?我饶有兴趣的算了一下。

简化一下题目,其实就是把 1-n 个自然数,排成一个数列里,至少有一个数字 i 刚好排到第 i 个位置的概率。

n 个数字的全排列有 n! 种,我们只需要计算出,没有一个数字排在它所在次序位置的排列数。

先定义一个函数 f(n) ,表示把 n-1 个数字排到 n 个位置上,每个数字都不在自己位置上的排列数。

可知 f(2)=1 (把 1 排在两个位置上 , X 1) f(3)=3 (把 1 2 排在三个位置上, X 1 2 ,2 1 X ,2 X 1) ...

再定义一个函数 g(n) ,表示把 n 个数字,排到 n 个位置上,每个数字都不在自己位置的排列数。

可知 g(n+1) = n * f(n) ,这么理解, g(3)=g(1+2) 也就是排 3 个数字时,先把 2 或 3 排到第一个位置。剩下的两个数字中,1 一定不会在自己位置了。另一个数字排到 2 个空位不在自己位置的排列数就是 f(2)

又可以推导出: f(n+1) = g (n) + n * f(n)

这样理解: f(n+1) 可以分成两种情况,一种是空出那个多余的位置,剩下 n 个数字都不在自己位置的排列数即 g(n) ;另一种情况是,从 n 个数字里挑出一个放在多余的位置上,剩下 n-1 个数字去排 n 个空位,这种情况总数为 n 倍的 f(n) 。

两式联立得到 g(n+1) = n * ( g(n-1) + g (n) )

这样,我们就得到了一个递推式。由于已知 g(3) = 2 * f(2) = 2 ;g(4) = 3 * f(3) = 9 ,所以写个程序很容易求出后续数值。

然后来算概率,n 个数时,概率 h(n) = g(n)/n! 。

我用程序计算了前 100 项,发现从第 8 项开始,概率就几乎不变了,稳定在 0.3679 左右。这引起了我的好奇心,然后重新用笔来推导上面的公式。

h(n+1) * (n+1)! = n * ( h(n-1) * (n-1)! + h(n) * n! )

可以得到

和 ( h(n+1) - h (n) ) *(n+1) = h(n-1) - h (n)

我们可以看到, h(n) 这个数列,相邻两项的差是 1/2! , -1/3! , +1/4! ....

因为我们已知,h(2) = g(2) / 2! = 1/2 , h(3) = g(3) / 3! = 1/3

可以得到 h(n) = 1 -1 + 1/2! - 1/3! + 1/4! - 1/5! .... 1/n!

这看起来是什么?哈,正好是 1/e 的麦克劳林展开式 :D 所以 h(n) 当 n 增大时,它会收敛到 1/e = 0.367879 。且收敛速度极快 :D


结论:当 n 较大(n>5) 时,没有一个人抽到自己那张纸条的概率是 1/e = 36.8% 左右。还句话说,至少有一个人抽到自己写的那个愿望的可能性有 63.2% 左右,这种事情还是很容易发生的,无论人多还是人少。这个概率随 n 变化的量很小。

哈,怎么又绕到欧拉数 e上面去了,数学还真是神奇啊。

May 23, 2008

关于 openGL 的 4444 贴图

我们在实现游戏界面时,用了一张 RGBA 4444 的贴图做 buffer 。最近同事测试效率时总不满意,发现上载 4444 贴图时,openGL 表现出来的性能实在是太差。(显卡为 ATI X300 ,最新版驱动)

几个人一开始怀疑是显卡或驱动程序的缺陷,进而想换总做法,不用软件渲染界面的方案。改把界面元素全部放到显存里。前几年,我为天下二设计界面的模块时,也有同事有此疑惑,编写代码做过比较。记得当时的结论是:仅仅从性能角度上考虑,把界面所用资源全部放到显存里,并不能提高太多速度(反而可能性能更低)。当时用的 Direct3D 做底层,似乎没有今天遇到的问题。

后来又经过测试,如果这张贴图换成 RGBA 8888 时,速度可以提高几倍。我们揣测可能是因为现代显卡对不常用的 16bit RGBA4444 贴图模式放弃了(软件或硬件)支持的缘故。原本希望采用 16bit 贴图节省一半的显存传输带宽,没想到适得其反。

一度,我们考虑了更换界面的美术制作标准,换为 RGBA8888 的格式。甚至讨论设计了一种采用 DXT 压缩算法压缩的图片内存数据格式。

不过我有点不死心,多试了几次。后来发现,居然把 GL_UNSIGNED_SHORT_4_4_4_4 换成 GL_UNSIGNED_SHORT_4_4_4_4_REV 速度就明显提高了 :D 比 8888 的模式要快许多。

想来是 ATI 的 openGL 驱动没有写好。上载贴图时,一旦和硬件支持的色彩模式不符,用了一种极其低效的方式做像素格式转换。

btw, 测试了另几块不同的显卡,有的显卡(比如一些较新的 N 卡上,GL_UNSIGNED_SHORT_4_4_4_4_REV`GL_UNSIGNED_SHORT_4_4_4_4 几乎没有区别。

May 22, 2008

防止中间人攻击

去年,几个游戏组的同事给我描述了他们发现的针对游戏的中间人攻击(MITM attack)。有人做了一个代理服务,种植木马到用户机器上,使用户机器对游戏服务器的 tcp 连接都重定向到代理服务上。(这个步骤其实不一定在用户机器上做,网关和路由器上都理论上存在被做手脚的可能,这是用户自身无法保证的。

代理服务可以一直监听用户到服务器的通讯,直到认为认证过程结束,不再转发用户的数据,改由自己操作用户的帐号。这样就可以达到转移用户虚拟财产的目的。

今天,和几个同事讨论了这个问题和解决方案。

之前,游戏部门的同事已经做出很多改进,增强了通讯协议的安全。但仔细分析后,我发现还是有些漏洞,想总结一下,找到个更安全的方案。

先列出一个简化版的协议,后面再讨论其中的问题:

  1. client 产生一个随机数,用 client 和 server 共知的秘密(在这里是用户密码和将军令产生的 OTP 一次性密码),加密个随机数,发还给 server 。为了保证 server 能认可这个结果,还需要附加一个校验值 checksum 共同编码。

  2. server 解出一个随机数,校验完毕后,以此为通讯密钥,建立一个加密信道,和 client 保持通讯。

在这里,由于中间人不知道 client 和 server 公有的秘密,而这个秘密又没有在通讯中传递,所以它只能充当转发人的角色,而不能监听和伪造双方中的任一方。


这里存在的问题:

网易的将军令产品(以及市面上的类似产品)能产生的 OTP 长度有限,是 6 位 10 进制数字,大约是 20bit 左右。如果把安全寄托在 OTP 上,强度太低。

因为协议中的握手过程,大家需要相互认可,这个认可标准是不受保护的。唯一可以利用的是事先约定的秘密。中间人完全可以截获握手过程的一切通讯,然后离线暴力尝试,以这个握手成功的标准去找出 OTP。当 OTP 的强度只有 20bit 时,在很短的时间就可以试出来。而 OTP 的有效期可以长达一分钟,是很难理论上杜绝这种暴力攻击的。

我的建议:

第一,可以使用 RSA 这样的算法,把共有的秘密转移到 RSA 的 key pair 中。这样就有了 128bit 甚至更高的强度。RSA 的 public key 可以有更多的方案发放到 client 中,所以理论上可行。问题仅在于 RSA 等不对称加密算法运算量太大,仅靠软件实现时,有可能服务器承担不起。

第二,我们降低 checksum 的长度,不超过 8bit 。这样,不只合法的 OTP 会满足这个 checksum ,还会有大量的 fake OTP 也满足 checksum 。中间人在穷举的时候会拿到大量 fake OTP 。按 OTP 一共 20bit 计算,大约有 2^12 约四千种可能。由于 OTP 有一分钟的生命期,只需要限制在这一分钟内允许尝试的次数(比如说 4 次),那么,单次握手,被试出的可能性就只有千分之一了。在此基础上需要进一步限制同一 ip 对任意帐号的尝试频率。可以提高安全性。


有道 的周枫在我们讨论的时候找到了一份 ppt ,其中 16 到 19 页讨论了类似的问题( Page 16: How to set up a strong, shared key, given only a short OTP ),可供参考。

May 20, 2008

那些日子(终)

由于《仙履奇缘》这个名字已经被人使用过,公司决定给新产品换个更响亮一点的名称。内部征集了很多意见,大家决定使用《梦幻西游》。

《梦幻西游》这个项目比《大话西游二》更为稳健,策划有相当长的时间做调整。我依稀记得早期徐波在论坛上和玩家们的争执。哪些门派应该增强一些,哪些应该削弱一点。被逼急了,他也放过话,“谁说各个门派需要做成平衡的了?”。

游戏的各种玩法也是一样。徐波自己的角色慢慢练了上去,建立了服务器上第一个帮派。还不想让人知道帮主就是他,怕被人怀疑是作弊练出来的。我想设计人员能有机会耐心的把自己的游戏玩上一年,以一个普通玩家的身份去玩,各种细节自然就照顾的到了。大部分策划不是不想这么干,而是没有机会。有多少项目有如此长的测试期,在稳定的环境下,拥有这样多的玩家一同游戏呢。

梦幻的美术部分也算是精益求精了。虽然有同行对他评价不算太高,但我觉得大家是尽了很多心力的。

到后来,丁磊请了一个从中国美院退休的老教授来给美术人员上课,为美术质量把关。第一堂课我也去旁听了,讲的一些概论性质的东西。我以前没学过专业的美术,听起来自然是收益非浅。后来经常看见晚上会议室有在上课,原画稿也被更严格的审核。

程序方面更不用多说,前面已经讲的很多了。我和郭老搭档的非常愉快,基本上他不会提什么非常要求,因为他在提需求时已经仔细考虑过了。然后,我把需求都一一实现。大家也时常探讨一下接口的设计,不为眼前的问题做草率的决定。后期,为大话二写界面逻辑的许扬调过来做梦幻的界面逻辑。这次 C++ 到 python 的接口比大话二时设计的对 lua 的接口要漂亮一些,工作进行很顺利。

郭老自己也玩梦幻,做起来更来劲一些。后来,帮派地图,玩家家中的家具摆设这些玩法实现都花了很多心思去做。在梦幻运营之后,我们还更换过一次通讯加密的方案。研究了很久,只是觉得新方案更 Cool 一点,然后两个人很努力的干了几个月。

起初有一个外挂花了很长时间研究(我们在 client 中下了些套子,一些不正常操作会被记录下来备案),最终发布了出来正式版本,打算准备收费。就在第二天,我们就更新了几乎全部的相关代码(其实之前已经做了很久了,时间上完全是巧合),狠狠的挫伤了为梦幻做外挂的人的信心。


03 年底,梦幻公测之前,我就脱离梦幻的一线开发了。这一年,随着网易股价的疯长,在福布斯中国富豪榜上,丁磊被排在了首位。他信心高涨,一心想把公司发展壮大。

年底,我们还是按往年的那样,从网上和广州本地的学校里选了几份简历,打算做个简单的招聘活动。突然 dingdang 被老丁的邮件批评了一顿。他说,郭斌打算新成立一个研发 P2P 产品的部门,都填了二十人以上的人员预算,你们若大一个游戏部怎么才要这么几个人?不行,得多招人。人才最宝贵,不能让别的公司抢了去。

dingdang 急匆匆的制定新的招聘计划,我隐隐有些担忧。这种担忧 dingdang 也有,人员扩张太快,会不会消化不良?但是在一片大好形势下,老板的殷切希望中,我们开始了新的招聘之旅。全国各大城市间做宣讲会,收集简历,做笔试面试。

记得那几天,每天都有成箱的简历运到公司,几乎所有程序员晚上都在看简历。我们八九个人围在会议室中,每个人分到半箱,一份份的读。把简历分为好中差三类。最好的一堆要求比较严格,按一个高标准,只要一个人认可就可以归去那类;差的一类底线非常的低,也是一个人认可就可以扔掉。中间类别的堆的最高。全部梳理完毕,接下来再如法重新轮换一圈,换人翻阅,从中选出较好的出来。

此时,ruiheng 已经被大家公推升认技术部总监,而因 micro 已经正式离开公司,dingdang 从原来的技术部总监升为游戏部总监。我和 ruiheng 两人一组开始奔波于全国各地做巡回招聘,同时还有别的组别分头去各地,有时我们也汇合在某一个大学较多的大城市。有丁老板的指示,游戏部的技术人员几乎全员出动了。相比前一年 02 年的招聘工作,完全不是一个阵势。

头一次没有什么经验,也没想过委托专业的招聘公司协办。记得 03 年底我和 ruiheng 第一站去浙江大学最为狼狈。事先完全没有和校方联系,就是网上的 bbs 上发了个消息。直到我们进了校园才跑过去找毕分办的老师借教室,名片还正巧用完,ruiheng 拿着身份证去登记的 (._.!) 。然后我一个个的给学生打电话,通知他们来笔试加面试。笔试题都是在飞机上现出的。广州很热,杭州很冷。我就穿了件衬衣,在小雨中的校园里冻了个半死。好在之前简历挑的很细,来面试的同学许多成了日后的同事。不过这次得罪了浙大的老师,等我们回到广州后,怪罪我们不跟他们事先联系就去招聘学生。为了陪罪,一个月后,大家又组织人马去浙大做了次规模盛大的宣讲会。

接下来有些经验和准备了,事前都让公司和学校打好招呼,然后再过去先搞个宣讲活动。那些天那个累啊,每到一个学校先讲上一个多小时。然后发下头天编好的题目,开始笔试。晚上回酒店开始批改卷子,找到答卷中的亮点,并比对收来的简历研究。

因为丁的要求是多招人,我们的要求放的较低,这就更不好挑人(否则直接找出出类拔萃的就够了)。往往选出一大堆,第二天开始面试。面试从早上排到夜晚,基本上是没时间吃中饭的。为了保证质量,每场面试都是一对一做 40 分钟左右。全部面试结束后,还要出下一份笔试题(一份题目一直用下去显然是不合适的)。 所以晚上只能睡上五六个小时。

有些学生过来做完面试,一兴奋就拉上他的同学。通常这样的拉过来的人都不错,而我们又有多多益善的指示在先,加班加点是常有的事。记得那年在重庆站,就因为面试排的太多,我一个人改签机票多留了一天。

这样高负荷工作,也找出不少优秀的人才。甚至一些是从别的公司口中抢出来的。现在大话三的 client 主程祥子,当时在成都读书。本来他已经拿了金山的 offer ,被同学介绍到我们面试现场看看。然后就让我“连蒙带骗”硬是说到网易来了。当时他说,他对破解很有兴趣,我就给他介绍 ida pro ,说怎么做效率比较高,如何分析别人游戏资源中的图片格式。还讨论他刚做的一些东西的细节,告诉他我的办公室电脑里还有自己写的很多好玩的程序。聊到兴奋处,祥子就决定把金山毒霸组给他的 offer 拒掉。我没有问他那份 offer 的薪水数值,只承诺了一个不高的数字。他说,不比那份高。

那一年,我们能许诺的待遇不高(以后几年也是如此),只能靠跟学生聊聊技术。让优秀的人觉得来我们这里工作会很有趣。曾经有几个学生,他们刚考完人工智能的考试,就来参加我们的面试。我就和他们聊刚刚考过的试题,说出我的解法,列举这些知识以后能怎样运用。让大家觉得,学到的东西是有用的,以后的工作中,还会有更多人一起来探讨这些。我始终觉得,这是吸纳人才最有效的方法。

等招聘活动结束,我想自己也闲着没事,就搭了一个 maillist ,给每个签了 offer 的学生发 email 联系。一是想促进交流,避免再被别的公司挖走,二是想进一步了解每个人的实际水平,为日后进入公司组织工作做计划。

当时做这件事很来劲,给大家出了题目布置下去做,列出书目供大家读。为每个人批改作业,写邮件交流。我觉得为团队培养新鲜血液,是促进整体发展的重中之重。

03 04 05 做了三年的招聘工作,感触很深。也面试了太多人。现在想想,在公司里和许多程序员关系很好,也来源于此呢。到 04 年许多新同事到公司报道,头几个月都是一到周末就领着大家到处玩耍吃喝,一个月吃饭买单的开销都是五六千,挺快活。

ruiheng 提议在在公司里多组织技术交流和专题课程,我想我准备的最多。前后做了五六个,有些课程还做了两次。

HR 的工作真是非常重要,也需要有心去做好的人去做。看到后来 google 进入中国,李开复亲自组织 HR 工作,我是由衷的理解。


《梦幻西游》在招聘的间隙公测,那是 2003 年 12 月中的事情。之前的内测反应相当的好,公测后在线人数也是节节上升。不少游戏制作圈子的老朋友都跟我说,梦幻西游挺好玩的。而以往,这些人都是单机游戏的玩家,对网络游戏不屑一顾。我想我们这次成功了。

丁显然也是充满信心。有上次顶住玩家漫骂,把大话西游二从三毛提价到四毛的成功收费经验;这次他想把价格定在五毛一小时。在正式收费前,大家都没太多意见。毕竟没什么好说的,大话二有前车之鉴。反对的话也是找骂。

但是在 2004 年 1 月正式收费那天,游戏的同时在线人数瞬间从 10 万以上跌到了 3 万以下。丁丁和徐波都坐不住了。我能理解他们的心情,测试期间的繁华到收费后的冷清,落差太大。

他们想降价。那天晚上我在公司,跟他们争论了很久。我是不主张立刻降价的,虽然一开始不赞成把价格定的过高。但既然定下来了,也不是坏事,我们不应该在第一天就否定掉这个决定。如果图一时之块把价格又降下来,可能日后会损失一大笔长期的收入。dingdang 也是急促不安,他给步步高的阿段打了电话,征询意见。最后犹豫了一天,终于拍板说降。

这是个没有答案的争论,至今我还坚持我当时的观点。而没过几天,梦幻就宣布调低了收费标准

以我今天的观点,当时更应该做的是延长免费公测期,并同时开放点卡交易系统(收费后,点卡交易系统并没有立刻移植到梦幻中)。让游戏内的经济尽快达到一个平衡,然后再依原计划标准收费。在时间收费是唯一收费模式的游戏中,辅以点卡交易系统后,玩家群体的消费能力是由群体的支付能力决定的,而不是个体。如今的许多道具收费游戏,平均每个玩家的消费水平都要略高于梦幻。但梦幻却只有一个手段扩大收入——增加玩家群,而很难提高个体的平均消费水平。

当然这是一家之言了,也说不定因为坚持五毛一小时的收费标准,梦幻就从此一蹶不振,谁又能说的清呢。

无论怎样,《梦幻西游》一路凯歌走到了今天,成为了中国第一大 MMORPG 。你说它颓势尽显也好,无聊之极也罢。它的最高同时在线人数还是在前不久又创下了新记录:200 万人。不能否认,这是款成功的产品。

我为自己在那些日子,为之贡献了代码,贡献了想法,贡献了力量而骄傲。


尾声:

故事远没有结束,但我想应该停笔了。

泡泡游戏的故事、大唐的故事、飞飞的故事、大话三的故事、天下二的故事…… 千百人经历过,正在经历。我想如果有缘,会有人接下去讲述。

网易互动娱乐 从 04 年开始极速壮大,不再是一个小小的团队。方方面面,我们多了更多的观察角度。每个人的眼睛里都看到了不同的东西。如果你也身在其中,也许你会喜欢上这些人,也许你突生反感,也许你因为和这样一些人一起工作而兴奋,也许你有许多无奈。

但每个人都应该想着:只要自己努力,明天会更好,不是吗?


附一张 04 年和同事一起负重爬山,登顶扎营前的留影 :D 那天一起爬山的同事好几个已不在网易了。但大家仍是朋友。


谢绝转载

那些日子(目录)

May 19, 2008

那些日子(二十)

2003 年 3 月,网易最大的一家风险投资商,新闻集团,套现。短时间内,公司的股价从 15 块以上跌到了 11 块。我想公司那个时候是有许多人感到不安的,毕竟咬在嘴的肉一下子少了一块,多少有些不舒服。接下来的股票执行窗口(按美国法律,公司员工买卖自己公司的股票,必须在限定的时间段内进行,这个时间段被简称为交易窗口),许多人抛掉了自己手上的股票。但游戏部门的人对将来都充满信心。

这段时间,公司又为员工颁发了奖励性质的期权。我拿的比前一年少,dingdang 也是。而游戏部的人多了许多,每个人都有。我还记得那天,CEO Ted 亲自颁发的文件。他头发花白,看起来比实际年纪大许多。人很和善。读到我的名字,当我上去领文件时,特地与我握了下手。当时说了些什么不太记得了,但是他给我传递的那种感觉,影响非常深刻。这是我第一次见他,也是最后一次。

Ted 人缘很好,是慢慢感觉到的。第二年跟 Michael Tong 去美国出差时,有机会拜访了几位跟网易有些渊源的朋友。见面后,大家一定会很关切的询问 Ted 的身体情况。聊起来都会说,Ted 真是个不错的人啊。

05 年底收到丁发给我的 Ted 手术失败的消息时,我正从岩道上下来休整,一下子感慨万千。多好的一个人走了,活着的人更应该保重身体。上海一个同事曾给我转述了他听来的故事,据说是北京办公室的同事讲的。Ted 走的那一晚,他在北京空着的那间办公室的天花板上的消防水龙头突发故障,喷出的水洒了一屋。周一大家得到了噩耗,纷纷说那是 Ted 放心不下,又回来看看了。


五月间,非典袭来。最早是深圳的同学给我发短信,说是他们那的醋被抢购一空,让我赶紧备一点。接下来几天,广州满大街的酸味。我是从头到尾没觉得多大个事儿,每天照样去健身房锻炼,到公司上班。我能理解人们的恐慌,但不知为啥,无论别人怎么渲染,我就是觉得没啥。倒是健身房和公司里的消毒水味道有点不好受。最严重那几天,公司的同事都在家办公了。我家里没有计算机,所以依旧泡在公司里。

这个事件对运营的游戏的影响说不太清,有好有坏吧。大话正处于加速上升期,而在此同时短信方面的业务量在萎缩。游戏部门相对独立,大部分时间,部门以外的人甚至别的部门的高管都不清楚游戏的情况。不然,到 03 年年底的时候,也不会有无线部的头儿违反规定,私自抛售公司股票,最终被美国证监会抓个正着了。

我在 03 年年中的时候,卖过一点点公司的股票,换到一些美圆。很好奇的炒了几个月外汇。读了许多技术分析的书,颇有些心得。大约玩了半年,起起落落,最终赚了百分之二三十,相比同期许多赔了的人,已经是很好的成绩了。但终究觉得无论是外汇还是股票,都只能当玩具玩玩。

炒这些东西,从中找到些许规律,并尽量做出准确的趋势估计,固然可以满足自己的成就感。但那实在是太浪费时间和精力了。人不能把美好的青春浪费在这么点成就感上。

不过一直以来,我还是乐于帮同事做分析,许多人也信任我的判断。只是每每说到自己公司的股票,我只有一句话,要相信自己的公司,自己做的事业。因为自己公司的股价,是股市上唯一能靠自己把握的东西了。

今天,ntes 几经沉浮,再次升到 24~25 美圆(曾经一拆四,相当于以前的 100 美圆左右)。我很庆幸我坚持的理念,把自己大半的积蓄都投资在上面(19 美金,大家都纷纷套现时还继续跟进过,当然是在窗口交易的),它给了我莫大的回报。


03 年的下半年,我们确认要购买一个成熟的引擎制作 3d 项目(不久被定名为天下二)。dingdang 最终选择了 bigworld ,价格不菲。再此之前,我们也和很多游戏公司谈过。曾考虑过无冬之夜的引擎,甚至还联系过暴雪,希望他们把魔兽三的引擎授权给我们开发,结果当然是被拒绝。

bigworld 几乎是最后唯一的选择。dingdang 看中的是他们宣称的网络模块的优秀性能。这是一种动态负载均衡的技术。

bigworld 和别的网络游戏不同,它并不是把地图切分成一个个独立部分分担到独立的进程中去管理。这样比较来讲,bigworld 是以人群而不是以地图区域来分担负载的。举个例子,如果有一大堆人拥挤在一起,那么他们就由一台服务器为它们服务。当这个人群群体向一个方向移动时,那么为他们服务的服务器也会跟着在虚拟场景中移动。只到有人从里面分流出来,在资源允许的情况下,分流出来的人会进入一个新的服务器。

听起来很神奇,bigworld 理论上可以支撑无限大(其实还是有限的,只是比常规做法大几个数量级)的游戏世界。世界间的每个区域都是无缝连接的。因为服务器本就不是按区域划分的,那就谈不到缝了。

我们拿到了部分代码,服务器真正核心的那部分(负载均衡)他们不愿意卖给我们,只是提供了二进制文件。dingdang 读过入手的一些程序,据说代码质量很高。反复衡量后,决定购买这套引擎。我说,其实没有什么东西是绝对神秘的,让我试试,可能可以还原被隐去的代码。

如果允许我接触已经购买的代码,需要签下一份保密协议。这样,我就签了,和许多正式转入 3d 组的程序员一起签的。kyo 也在那时脱离了大话二的开发,进入这个小组。

bigworld 的服务器是用 C++ 编写的,跑在 linux 上。当时只支持 red hat ,而我们公司用较多的是 freebsd 。部分源码缺失,使得移植很困难。我拿到 C++ 的头文件和那些 .o 文件后,发现做个简单的逆向工程,甚至可以把大部分缺失的代码还原出来。隐藏的源码的那部分其实和开放源码的部分耦合度很高,设计上根本不应该拆分开。它们中间有着千丝万缕的联系。部分内部数据结构虽然表面看不到,但是到后来我基本都推测出来了。

由于 bigworld 大量用了多重继承,早期分析还是挺麻烦的。读这些汇编,让我对 C++ 编译器生成出来的复杂的数据结构有了几分认识。几个月后,对于各种形式的 C++ 程序最终编译出来的汇编形式,以及对象的内存布局,我几乎都能立刻在脑海里做出条件反射般的印象了。对着这些汇编码,新写下的 C++ 程序重新编译后,可以做到和无源码的 .o 文件,逐字节一致。

这个工作其实只做了一半,后来公司花了极大价钱买下了全部的代码。只是那个时候我已退出天下组,没有权限去看那些东西了。

从 bigworld 的源代码中我倒没学到什么新鲜东西。那段时间只是把逆向工程当成一件有挑战的趣事在做。做的过于细节,反而无法高屋建瓴的来看 bigworld 的整体设计。额外的收益就是实践了一把 C++ 的对象模型,我想当时的公司里不会有比我对 C++ 语言 更熟悉的人了。


年底,由 dingdang 带队,kyo 我还有老王三个程序,月猫和陈由金两个美术,六个人出发去悉尼接受 bigworld 开发公司给我们做的短期培训,学习 bigworld 的用法。

此行让我感触比较深的是老外程序员的敬业。他们工作很正规,一天八小时都在那写程序,如果没有特别的事情,不会像我们那样在办公室里穿来串去。下了班就准时回家,上班就工作。可以说,一个工作日就是一个,不象我们公司,程序员们相对懒散,除了短期的兴奋期,每天集中精力能写程序的时间远不到八小时。想来这也不是网易一家如此,我见过的许多国内公司都有此问题。所以在澳洲看到的情景给我不小触动。

另外他们的电脑,大多数人都装的 linux ,运行 windows 的机器上没有任何盗版软件。一个个把画笔和记事本用的相当娴熟,因为只有这些是不用额外掏钱买的。

回到 bigworld 的话题上,我学到并欣赏的一点是:他们嵌入的 python ,使用起来非常方便。client 和 server 之间完全屏蔽了网络这个东西。server 的各个进程之间也感觉不到跨进程通讯的存在。这应该算是一个设计非常良好的引擎了。给予了我后来几年独立开发的东西许多灵感。只是隐藏了太多细节,也出现了很多局限性。从我的感觉上,引擎是为特定游戏类型去设计的(或许他们最早想做一个 MMOFPS?),离我们心目中 MMORPG 的需求有一些距离。

后来的发展也的确是这样。可以说,03 年到今天(08 年),网易和 bigworld 公司是一种相互依存的关系。我们用他们的引擎,提出各种意见,找到设计问题和 bug ,反馈给他们修改,一步步的把 bigworld 打造成更适合现代 MMORPG 的游戏引擎。kyo 后来担任天下二的技术主管,坚定着不自己开发服务器的分支版本,一切问题交给澳洲处理的方针。虽然开发过程往往有点憋火,但也保持了最终版本的唯一。最近几天在看《人月神话》,里面提到设计概念一致的重要性,这就是一个佐证。

如果让我主观的评价一下网易购买 bigworld 的意义,我想说,我们其实是花钱雇佣了一支海外军团,帮我们干活呢。


在澳洲,别人公司的办公室里,我跟 dingdang 吵过一架。可能让老外看去有点莫名其妙了。

我说,花了这么多钱,购买这么贵一个游戏引擎,我们就应该在游戏设计上有所突破。既然 bigworld 的技术优势就在于更大的世界,更多的人互动。我们为何不为之实现一个不一样的游戏出来,突出这些特点。而不仅仅是重复已有的网游游戏模式,只是把我们已经做到的 2d 游戏 3d 化。如果不做这些,让我们自己开发一个 3d engine 就够用了,不过半年的时间,我有信心搞定。

大概就是这样的观点吧,具体也记不清了。不知为什么,我们的分歧越来越大。最后,我坐在桌子上一言不发。过了好久,dingdang 心情也平静了些,主动过来向我道歉,为他的态度道歉。这是我们第一次,也是最后一次争吵。其实我能理解他,一如既往。

回广州的一年后,类似的问题我和叶航也争过一次。慢慢我就明白,永远不要对别人的项目指手画脚,当局者未必迷,旁观者未必清。有什么事情自己有想法的话,最好的办法是自己去做。


在我们一队人去澳洲上飞机的那一天,还有一个有趣的小插曲。当天公司的中层人员都被安排去参加一个管理培训。虽然我手下没有一个兵,可也被安排去了。

估计是丁磊故意的,dingdang 我 还有张金等五个人被分到一个组。培训课上做了一个小游戏颇有意思,培训结束后,我们还热烈讨论。真的是可以看出每个人的性格来了。有兴趣的同学可以找人做上一次。

游戏是这样的,五个人被发了五张纸。游戏开始后,大家阅读手上的纸,并努力完成游戏。这个游戏需要五个人合作,但不许语言交流。信息沟通只能靠传字条。便签纸是可以无限取用的,但是每个小组只指定了一个人可以向任何一个人传字条,而其他人只允许向他传。

我们这一组,这个关键人是张金。游戏一开始她就收到了大量的字条,忙个不停。

我拿到的纸上什么字都没有,只画了五个奇怪的符号。我觉得其他人也应该是如此,我们借助张金传递着信息,想弄清楚别人手上都画了些什么。大家都在猜测这个游戏到底想让我们做什么。很快我们就达成了一项约定,在字条上写上 to XXX, from XXX ,让张金负责转发。比如我想问 dingdang 点什么,就写上 to dingdang from 云风。

一开始我在字条上写了好多,写了我看到的图案,还有我的猜测。写了很多字,比如,假设游戏需要我们找出所有的图案,我们应该怎么办;假设游戏需要我们找出一个特别的图案应该怎么办,假设游戏需要找到某个人手上一个特别的图案应该怎么办……

而旁边 kyo 的组没多久就完成了游戏,相继还有许多组。我们这里还一筹莫展。

我是颇为着急,写了个字条给张金,让她把所有手上的条子全部给我。因为我看她在那里一边分析着手上的情报,一边帮其他人传递,实在忙不过来了。dingdang 也在那边沉思,不断的找张金要新的条子。我想这么下去也不是办法,索性一个人来做算了。

当我对比了所有人的字条,艰难的从杂乱无章的各种信息中判断游戏的真实意图时,我发现每个人的图案都有一些共同点。如果这是有一道智力题,那么就应该是找出大家公有的部分了。但是老师不理会我的结果,直到 dingdang 最后也做出了判定,才结束了游戏。


游戏的谜底原来是这样的,dingdang 那张纸上除了五个图案外,还有详细的文字解说。明明白白的写着,找到五个人手中共有的一个符号。

老师向我们解释,其实这个游戏中每个角色都是有象征意义的。拿到 dingdang 那张纸的象征着老板,他知道目标;负责中转的人,张金那个角色,相当于管理人员,她负责跟员工沟通;剩下的三个人,就是公司的员工,他们负责实现目标。

在游戏中,dingdang 始终没有想到,别人其实都不知道游戏要干什么,他以为大家手上均有文字说明。认为只要通过张金,最后总能有一个人完成游戏。而我当时所想,就是大家和我一样,都只看到一堆莫名其妙的图案,我们的目的是猜测游戏目的。

kyo 那个组之所以完成的快,和 kyo 的第一张字条分不开。kyo 明确的写道,我不知道我要做什么,我的纸上只画了这些……。并且他不厌其烦的把这段话 copy 了 4 份,转发给每个人。当“老板”得到这个消息后,再向“管理人员”要求把所有信息转到他那里,很顺利的就找出了答案。

真是可笑,我们这一组,做如此要求的人却是什么都不知道的我。

这个游戏教会了我,让一个团队有一个明确的目标是多么的重要。由于信息不对等,每个人看到的东西都不一样,想的也不一样。我们在团队合作时,沟通胜过一切。说出你之所想你所知,了解他人之所想所知,道理很简单,做起来很难。


谢绝转载

那些日子(目录)

May 18, 2008

那些日子(十九)

不计算周边工具,我一共为《梦幻西游》贡献了引擎部分(包括图象、声音、网络和 UI 以及对象管理)三万多行 C++ 代码。这是今天用工具统计出来的数字。这些全部是在大话西游二完成后,从零开始写的,几经增删留到今天的部分。

对于梦幻的 client ,郭老的代码贡献量更大。除了保留修整少量我从大话二遗留下来的底层部分外,他写了个 python 的接口部分,和所有的游戏逻辑部分的 C++ 支持。再次设计,我们做的比以前好。代码很精简,而完成的功能要多的多。依稀记得总共 C++ 代码不会超过五万行吧(手头没有数据可供统计)。而对应的大话二的 client 代码量则是图象及声音的引擎部分二万七千行,逻辑和网络及 UI 部分三万一千行。

我想,合理的构架下,代码的体积应该是更为精巧,而不要过于膨胀。代码写的短小,是自然而然的结果,其成因是避免了重复。代码行数多少,则不是刻意去追求的。对于网游 client (也包括 server ),都不应是超过 10 万行 C++ 的规模。从程序角度上说,网络游戏是个小项目,不是吗?如果有人硬把一个小项目做成了大项目,不出问题才怪。

郭老是个很勤奋的人,非常主动的完善程序。当时他改进了地图文件的格式,重写了地图数据生成工具。对于已完成可以正常工作的东西不满足,自己去改进。这样的程序员对项目非常难得。

这种在这种追求完美的心态下的产物,几乎不可能从工程管理角度上去保证有人做。这也是我后来作为项目管理人员也一定要自己参于写代码的原因之一。对于一个项目,如果我们只从完成功能角度去验收,充其量只能达到合格,远谈不上优秀。何况是一些很难度量的质量、细节方面,做到怎样的程度可达到多少收益,这中间的关系没有人说的清楚。

想把游戏项目塞进一个流水线中,拧上闹钟,到时间了来收割。绝对是一个笑话,只存在于投资人的梦想中。

梦幻里的很多画面细节,并非专职策划人员写进文档、提出需求,然后交给程序员实现出来的。那些日子,郭老玩了许多网游,他自己就是个《魔力宝贝》的玩家。看到别人游戏中有趣的亮点,就想办法实现。同时也想一些有趣的东西加进去。我也乐于配合。

到梦幻发行时,许多老朋友表示游戏挺好玩,有些单机游戏的感觉。这中间,大家对细节的把握甚关重要。既然是互动游戏,我们就应该和提交电子表单区分开,游戏玩的是过程,而不是结果。


我想梦幻这个项目,大家都很努力,并不因项目没有指定确切的结束日期而松懈。记得那个夏天的一个周末,有 QC 部门的同事报告了一个 bug ,会引起 client 崩溃。但是 bug 如何发生的,毫无规律可寻。只是玩了几个甚至十几个小时后,程序异常退出而已,没有任何方法可以重现错误。发生的概率也非常之低,几天才碰到一次。出错之后,查看调用栈,发生问题处的代码逻辑一切正常,引起问题的是一个对象里的数值不太正确。而这类对象在内存中有上千个同类,每次出错点都不太相同。

有过程序调试经验的同学当知道,这种 bug 是极其难追查的。你无法通过出错现场判断 bug 成因,无法设置断点来侦察早期的内存异常状态。通常只能靠阅读代码来分析那些部分写的有问题。当出错现场周围的代码正确时,程序员面临的可能是通读所有相关代码。

如果没有一切 bug 都是可以追查出成因的信念,我想对于这种出现概率相当低又束手无策的问题,对于很多急迫的项目都会暂时搁置。而郭老和我都认为,不查到原因,就一定不能把程序做下去。bug 就像心里的疙瘩,解不开,干什么事都不舒服。

记得那几天,我们从周四找到周六,一直没有进展。周日上午,我在健身房推杠铃,突然手机响了,郭老兴奋的说采集到一个录象,在启动 client 开始半小时后就程序崩溃了。前面谈过录象文件对 bug 追踪的帮助。之前面对这个问题时,录象都是长达几个小时的。我们为重现一次现场就等上几十分钟,那样效率实在太低。当采集到这个只有半小时的录象时,意义非常重大。立刻打车回来公司,我们两人就在空空的办公室中,调试这个问题。

事后的发现让我们解开了心结。真正导致问题发生的时刻比引起内存错乱的程序崩溃点提前了几分钟。是由于 python 和 C++ 的接口处,一次增减引用的次序写反了。这使得在某一瞬间,python 引用了一个刚好被释放的 C++ 对象。通常,引用随即被解开。但在一种巧合下,中间一块内存的指针有可能被传递到别处重新引用起来。这种错误的引用关系保持了很久,在后继的一系列临时对象销毁过程中暴露出来。

这是我职业生涯中,最难调试的一个 bug ,印象极为深刻。以后再少有对已知 bug 三天内还解决不了的了。


除了忙梦幻的事情,还有大话方面的一些工作。

03 年 2 月的时候,我跟 dingdang 聊天,说能不能在大话二中试着加一些卡片类小游戏。可能我受 console game 的影响比较深,许多 console game 都在主体游戏之外,还做一些分支游戏(比如最终幻想 X 中的水球)。这些分支游戏并非零碎的硬凑到里面的小游戏,而是也有它们的线路。

我的建议是在大话中增加一种卡片收集对战类的游戏。但是大话二的策划组不太愿意整体的来考虑这件事情。他们担心工作量太大,并且不能预知对游戏整体系统的影响,这种心情是可以体谅的。后来我拉着叶航一起来做大话牌,考虑到重新设计规则需要投入太多精力,便直接搬来了最终幻想八中的卡片游戏规则。这个对于程序很好实现,而我的想法是想在大话中试验多条游戏线路,具体这第二线路的玩法就不太在意了。

事实证明,独立于游戏主体规则之外的第二游戏玩法是不能成功的,玩家不买帐。这也算是一次宝贵的经验吧。事后想,若是把奖励和主体规则挂钩会好一些。这件事让我明白了,网游和从前单机游戏不同,玩家有很深的成果导向,对游戏性本身的注重远不如单机游戏那么多。

倒是为这个大话牌制作的美术资源没有浪费,这也是我们立项开始做前就想好的退路。我们为之设计了变身卡的玩法,可以充分利用外包美术制作的卡片图案。整个大话牌的制作,全程都有叶航的参与,他编写了所有的文档。不知道这件事对日后设计天下二的元魂珠变成有多大影响。

这段故事中间有个小插曲。在做卡片调落和集换规则时,我想尝试做一些新的东西,不以调落概率来控制卡片的稀有度,而做一个中心服务来统一发放卡片。kyo 对这种做法非常的反对。他认为,一切程序都是不可靠的,我们应该绝对避免中心式的数据服务,因为一旦中心式的服务出现问题,所有游戏系统中的玩家都会受到影响。按照这个思路,在服务器中出现唯一(或有限)资源就是应该回避的设计。他希望系统能保证:每个玩家的私有数据,都不跟其他人发生交互。(这种交互应该从广义上理解,比如有样虚拟道具在服务器中需要严格存在 10 件,那么你能不能拥有这件道具,以及获得这件道具的概率,就跟还有哪些人已经拥有了发生了关系,这也是一种交互)。也就是说,服务器程序应该对任何一个玩家的服务都是独立的。

而我站在了他的对立面,按我的想法,网络游戏的发展趋势应该是交互。这可以提供游戏更多的游戏性。稳定性第一、游戏性第二固然正确,但是死守着稳定性,而不尝试在游戏性方面做一些技术突破是不行的。这个问题和 kyo 争论了很久,最终的结果是我自己实现了代码,并在数据可靠性方面做了额外的保护(为此专门写了一个双份交互备份的简易数据库防止系统以外掉电引起的数据残缺,以此用来保证卡片发放的正确)。

让程序员做自己不认可的工作是很难做好的,很多情况下,自己来实现是无奈之举。这也是为什么许多不懂程序的策划难以把游戏做好的原因。因为最终的实现还是在程序员手上,同样的工作,做的好和差,质量相差巨大。有些设计,看起来很美好,但是很可能因为实现质量不够,好事也变成了坏事。作为游戏策划,当然希望做实现的程序员可以懂点游戏,这样写程序的时候更容易达到预期的目标;但程序员太懂游戏了,不免有自己的想法,我们又很难让他们心甘情愿的去按自己的思路做。

另一个是做大话兵器谱,同样是一次失败的尝试。也是想试着在玩家间建立联系,而不是按从前通常的做法:采取简单的积分制。由于策划们的担心,这个系统没有和游戏中的实际利益挂钩,是一个完全独立的系统。刚开始我觉得无所谓,只是先看看这个排名积分系统是否能正常工作。后来才发现,脱离整个游戏的任何独立系统,都是不受玩家欢迎的。

于之可以做比较的是几年之后的 wow 中的荣誉系统,同样是设计一套规则,用来计算玩家间的胜负关系。我们可以设想一下,如果荣誉系统不给玩家荣誉整备这样的奖励,这个系统还有多大的存在意义。

最终,我意识到,其实游戏的策划设计跟程序一样,一个项目永远只能有一个主导人。无论游戏项目如何分工合作,在任一方面,都只需也只能有一个人把握。从此我不再干预公司其它游戏的开发。


03 年,我的生活远比今天丰富多彩。

在我和叶航的倡议下,公司组织员工进修日语。dingdang 专门找了个外语学院的学生来办公室给我们上课,一周两晚。我们的政策是只要考试一次过关,公司免去学费,并额外颁发 1000 元奖金;如果补考不及格,则要交纳双倍学费。平时不准无故旷课。

仿佛又回到了学校。甚至比读大学时更卖力,大学里,我可从来没有哪门课有那样高的出勤率。考试前还连夜复习。到后来真是苦不堪言呐 :D 。第一期结业后,就没再继续。不过收获也挺大,至少打日文游戏时,不至于两眼一抹黑只会认里面几个汉字了。

到了夏天时,我莫名其妙的爱上了自行车运动。怂恿 dingdang 一起去装了两部车。他没我玩的那么起劲。经过半年的锻炼,我的身体状态非常不错,腿部肌肉也挺有力。每个周末都出门骑行,平均时速 30 公里以上,每次都是 100 公里左右。把珠三角逛了个遍。每次都是一个人中午出去,然后到天黑了才回来。

沿途乡村里的人都挺热情,还好奇的问这是为啥。我知道自己看起来就是自找折腾。啥事不干,背着地图,挂上指南针,骑个车几十公里出去,立刻折返。速度还挺快,不作停留,不为欣赏风景。在出城前的那一段,还要忍受一路的汽车尾气。

路上觉得孤独的时候,就放声的唱歌,不着调儿的老歌,感觉很好。每次爬坡的时候都特别累,但我发现,每当爬上坡顶,接下来就是非常惬意的下坡。老天绝对不亏待你,有上就一定有下,有下那么一定接着一段上。

八月,我和 dingdang 约定骑车去一趟珠海,他刚参加工作时干过一次,认识路。我们周六早上九点出发,我来负责背行李,走省道过去。那次是我骑行生涯中最有挑战的一次。太阳很大,晒的人很不舒服。广州到珠海的路很不好走,许多地方满是碎石子。一路好多拱桥,上上下下累的半死。后半程路上刮起了风,一路都是顶风前进的,只能勉强维持 15 公里的时速。路上被铁钉扎破了胎,掉了两次链子,走错一次路,多跑了十几公里。中间有个大下坡时,拿着水壶喝水,一仰头,帽子被吹掉了。下意识的单手去捏刹车,不小心摔了一跤。中午弄的胃口全无,在路边的小餐馆里,就只觉得那两条生黄瓜特别好吃。

到珠海已经是晚上八点。帮我们预先定了酒店房间的赵青一个劲的打电话问怎么还没有到。珠海海滨的情侣路,骑在上面才觉得怎么如此漫长。到达酒店时已是晚上九点,马表上显示超过 150 公里了。

夜里吃完饭去金山的办公室见了雷军,随便聊了几句就回去睡觉了。

第二天我们骑到码头,乘船到了深圳蛇口。从深圳回来的路程也是 150 公里左右,但是路面非常的好。虽然头一天消耗的不少体力,但是轻松了许多。深刻感受到珠江两岸的经济发展差异。

这次魔鬼之旅,我身上晒脱了一层皮,半个月以后长出新的来,痒痒的。可能是因为脱水和劳累的缘故,体重一周内掉下去 15 斤,到 04 年都没完全补回来。后来就没再做长途骑行了,也打消了从广州骑车回武汉的念头。

路上我跟 dingdang 聊了许多,聊我们的项目,我们的公司,我们公司里的人。也谈这个行业,说说听来的一些八卦。诸如盛大是怎么起来的,为什么当年中华网撤资后,陈天桥还有钱去买传奇之类。

这次以后,dingdang 少有时间出去了。接下来几年,我经常组织同事在周末出去活动。但每次叫他,他都很忙。起初我不太理解,认为工作和生活可以分开,周末出去放松一下不会有什么影响;后来跟 dingdang 的妻子在网上聊天,可以感觉到一些他的心理状况,慢慢的理解了。

如今,我自己带了一个团队,更加感同身受。当承担了太多人的责任时,更多的是心累。脑子里自然无法分心做完全属于自己的事情。


附一张 03 年底在家用 pda 自拍的照片,怀念我那两年的骑行时光。


谢绝转载

那些日子(目录)

May 17, 2008

那些日子(十八)

大话二收费以后,因为我脱离了这个项目的开发组,也就没什么记忆了。不过也时常关心一下,记得十月刚回公司时,在游戏里的聊天频道中,经常有玩家哭述自己被骗。他们用游戏币和人交换点卡,却总有单方面失信的事情发生。

我们曾想过在玩家条款中加入禁止游戏虚拟物品和虚拟货币与现实货币交易的条款,正如暴雪今天在 wow 中做的那样。有一种直觉告诉我们,游戏牵扯进金钱交易,游戏本身会受到冲击,不是什么好事。

直觉不总是正确的。固然,我们可以利用程序规则限制虚拟物品的转移,但那也会极大的破坏游戏性。有如美国当年的禁酒令最终执行不下去一样,禁止不了的事情,不如提供更大的便利去疏通。开发团队决定给系统增加一个公正的点卡交易系统。

这个系统,在 02 年 10 月底一台服务器上试运行 。不久就在全部服务器推广开。我很赞同这个系统,但技术上没出什么力。讨论过程中,我只强调了一点,一定要在交易过程中征税,这个意见被顺利采纳了。

点卡交易系统一开始并不起眼,没人会想到它能起到多大价值。只是几个程序员看见玩家的需求,临时拍脑袋加上的。设计实现时也完全没考虑它会促进游戏的收益。开始时,有玩家传言,某些玩家寄售的点卡是由系统变出钱来凭空买下的。这种事情从未发生过,如果真的这么做了,其实也很容易被玩家发觉。其实,经过仔细考虑,我们也觉得没有必要这样去做。

玩家在这个系统的辅助下,游戏内的经济系统达到一个更为稳定的平衡状态。实际上促进了游戏的发展。金融工具可以促进经济的发展,点卡交易系统,就是一种在现实社会中不可能存在的金融工具,但对于网络游戏中的虚拟社会,则是非常有益的补充。

ps, 几年之后,我重新研究了这个问题。写过一篇 blog

慢慢的我也明白了,网络游戏和从前单机游戏之不同。网络游戏更为注重人和人之间的交流,更多的是在模拟一个社会。而社会的稳定和平衡是一个动态的过程,并非一开始设计好规则,就可以保证的。人的行为没有固定的模式,尤其是对比现实社会少的多的人群,规律更不确定。没有游戏规则是普适的。对规则的不断修改,增删,调整,就是一个动态调节的过程。后来我们的许多产品,包括许多同行发行的产品,没能经历这样一段调整期,也是最终没能成功的因素之一。


由于没有项目开发的压力,我的注意力主要放在了学习研究各种有趣的东西上。因为对 C++ 的热爱,那些日子大部分的精力都是围绕这方面。比如 boost ,阅读它的源码是主要的工作之一。

一开始看的是 boost.thread ,因为之前的多线程程序的复杂度印象太深刻了。我相信 C++ 可以带来一些方法来回避其复杂度。设计良好的线程库非常值得参考。当时和泡泡组黄晓东的后继者李鑫也有讨论,他们在项目中尝试用过 boost.thread 。我询问过他的意见,他说他们发现这个东西还不太稳定,有一些 bug 。现在无法确定当时泡泡那个版本遇到的问题是否真的有 boost.thread 的问题。但是,C++ 模板库不好调试,已经深深的影响了实际的开发。

从我们那个 C++ 邮件列表 02 年 10 月的信笺存档中,可以找到当时大家关心的许多话题。当时我还去看了 boost.python ,它是 boost 中不多见的几个需要编译才能使用的部件之一。为什么不是 boost.ruby 而是 boost.python ,引起了我的好奇心。看起来 C++ 社区对 python 真的是特别有爱啊。这引起我对 python 语言的关注。

boost.python 挺有趣,不仅仅是它做到的事情,也包括它怎样做到这些。比如它给指针分类,让 python 可以正确的处理 C++ 的对象生命期,用以避免 dangling pointer 。

boost.python 相当活跃,就在我把玩它的那几天,就经过一次翻天覆地的变动,把接口全改了。

那几天,孟岩曾在北京采访过 C++ 之父 Stroustrup 。回来在 C++ 邮件列表里投了一帖。其中也提到 python :

“他(Stroustrup)说 Python 很有趣,不过说 Python 是 C++ 的最佳搭档言过其实,因为 C++ 一直都是很多种语言的最佳排挡。关键不在于那种语言多么的出色,而在于你应该选择最合适的工具解决问题。而 C++ 很少被用来构造整个系统,通常只构造系统中的关键部分,这时候,他当然鼓励把其他语言与 C++ 共同使用,而且实际上,一直以来都是这样。”

另外值得一提的是 Stroustrup 的其他一些观点,例如对于 boost 和 loki ,他毫不犹豫地赞同我们这个圈子当时许多人的观点,“某些库中有过分运用模板机制的倾向”。并强调,“ C++ 是一种多范式语言,最好的风格是综合运用各种范式,保持平衡,求得对某个特定问题的最佳解决方案。过分运用泛型程序设计技术,与过分运用面向对象技术一样,都是他不赞成的。”

还有关于指针的问题,“他(Stroustrup)通常把实际对象也放到容器里,然后再用一个容纳指针的容器 进行关键操作。他认为只要你仔细考虑,大多数资源都是有一个唯一的 owner 的。接着,他主动谈到智能指针,最有趣的东西就在这里了,他说,有很多人开发了类似 shared ptr 这样的东西,使事情看上去很漂亮。但是他不太喜欢智能指针。这个东西实际上是一种半吊子 GC ,它比手工管理自动化,又不如 GC自动化,高不成低不就。你同样不知道对象是什么时候被析构的,那为什么不直接用GC呢?在他看来,普通指针仍然有很大用处,不应该试图绕开它。”


当时,我们也关注一些诸如敏捷编程的时髦话题。孟岩曾经(02 年 10 月 24 日)转过一封 Bob 大叔 Robert Martin 给他的信,里面有一段话无关敏捷编程,但我觉得挺有趣,

It has been quite awhile since I have done any serious C++ work. Most of my work now is in Java, and is transitioning to C#. I'm not thrilled with either of these languages. They are OK, but not great. The languages that most pique my interest at the moment are Python and Ruby. I think the future likes in that direction.

是时候好好看看 python 了,不知不觉的公司里许多程序员中都开始出现学习 python 的势头。我第一次认真的审视这些动态语言,而不仅仅把它们当作一种嵌入式脚本使用。


叶航是在 02 年 10 月来公司报道的。以前我更熟悉他的网名:高铃响。我们在 sina 游戏制作论坛泡了好些年,是多年未见过面的网友。只听说他在深圳万智源做最初幻想,然后就被 dingdang 叫到了网易来。也有人叫他老高,不过我更多还是只呼其名了。

那天,我在天河跟 sina 论坛的坛友龙云峰喝酒。听说叶航过来了,打了个电话把他叫过去,大家版聚一下。就在一个很小的酒吧,为他接风。他是个好青年,时不时的接一下女朋友的电话。我们聊一些论坛上的旧事。叶航和我同届,真是奇怪的很,我认识的许多做游戏的同行,居然都是 2000 年大学毕业的,

叶航入职后进了大话组,不知道忙着什么。离他正式转入天下组做策划,随后升为主策划还有半年时间。不过我想 dingdang 早就想好了让他负责天下的吧。


大话一的玩家流失的很快,到了 03 年时,据说有的服务器上最少的时候只有两三个人,其中还有一个是在线的 GM 。不得不佩服这样忠实的玩家,即使把一个网络游戏玩成单机版,也要坚持下去。

徐波在那里摆弄大话一的新版本“仙履奇缘”,成天在论坛里跟玩家吵吵闹闹。同时, 大部分的大话一玩家被分流到这个使用大话二的新 client 以及从大话二服务器分支出来开发的服务器系统。这个服务器免费,聚集着上千个前大话一的玩家。我想那是一块实验田,可以不断的尝试加一些新的东西,对规则不断的修正,补充一些细节。我想,我们到现在为止,再没有一个项目可以这样。有稳定的程序,稳定且有一定数量的用户,没有项目时间的安排,只是不断的修改游戏设计,让它更好玩。

丁丁去而复返,dingdang 安排他做徐波的上司,在这个分不清是旧瓶装新酒还是新瓶装旧酒的项目里做主策划。作为外人,我对项目策划方面的进展了解不多,无法判断到底是丁丁的贡献更大,还是徐波的。但是我能肯定,不能否定他们任何一人为这个游戏,日后被称为《梦幻西游》的游戏,初期所做的一切。


03 年初,lua 第 5 版即将发布的消息从 lua 的邮件列表中传出。我饶有兴趣的查看了新特性列表,被深深吸引的是新加入的 coroutine 。直觉告诉我,这是一种用来描述游戏逻辑不错的工具。

coroutine 其实就是协作式多线程。在 windows 3.1 的年代就被用于多任务系统的开发。现在的 windows 也支持一个叫作 fiber 的特性。我想,其实用 C 语言也可以轻易模拟出这样的东西来。

之前,大话二的 client 一直在用类似状态机的方式控制屏幕上的角色。虽然 kyo dingdang 都觉得这样就够了,因为已经比大话一做的好。但是我始终不太满意。我想找到更自然的方法去描述画面行为。只有这样,程序员才好放手去描述更多的细节,游戏才能表现的更生动。

我花了许多时间来写一个 C 的 coroutine 库。事后发现完全可以用标准 C 语言(借助 longjmp) 来实现,但是当时还是采用了汇编。这样我能更精确的控制内存的布局(尤其是堆栈方面的处理),因为按我的想法,为每个控制序列附加一个线程控制,可能会达到千个这样的数量级。不仔细推敲是不行的。

郭老对这个东西很感兴趣,我给他演示了一些简单的例子,他觉得用起来很方便。

大约在 03 年的春天,郭老对我说,我这里风魂已经用 C++ 再次重写过了。我们这半年又弄出了许多好玩的东西,例如那个 coroutine 。不如大家用新的代码重新写一个游戏 client 吧。这次我用 coroutine 实现了新的网络底层接口,声音模块,还有对象的管理。一切都感觉比上次做大话二时舒服多了。

还有 python ,大家那时都认定它比 lua 更好用。

掌握了新的技术,总是能激发程序员们的斗志。就这样,我们再次开始从头开始写西游的客户端程序。目标是让《梦幻西游》可以用上新的技术。哦,那个时候还不叫《梦幻西游》,但不久就会换上这个留在无数玩家心里的名字了。

《梦幻西游》就这样兵分几路,独立的开发着。策划用着大话二的程序系统测试着玩法,并由服务器程序跟进。美术按照留下来的规范制作着新的资源,当然,我们的工具慢慢的也齐备了。我为之制作了可视化的编辑器,郭老做了一个魔法效果的编辑器。因为我们讨论的结果是,既然有时间,应该进一步的压缩 client 需要的美术资源,以后当以程序控制的动画为主。还有诸如更换武器,局部换色等等方案,都在有条不紊的制定出来。

而 Client 程序方面,由郭老和我一起制作。我还是写底层,除了重写了所有的 engine 代码外。还新增加了不少特性。比如图象动态缩放,这 RLE 压缩图片的实时缩放写起来相当麻烦,虽然最后我把它实现了,但因为换装拼接时,出现一些接缝问题效果不太满意,最终放弃未用。这会是名副其实的并肩作战,大家在发现潜在的问题时都可以当天解决。新的 client 质量得以提升就是理所当然的事了。

梦幻西游这个项目,悄然开始,顺利展开,正在于这种相互独立的开发。这个优势,在大话西游二的研发期间已经显露出来,但到梦幻西游,发挥的淋漓尽致。


大话二的收入不错,慢慢的大家的口袋里都富裕了起来。我不知道公司具体给开发组的提成是多少。从往日的一封邮件来模糊的揣测,应该不到 8% 。但是,这个游戏的收入总量是巨大的,而我们也没有投入太多的研发经费。连宣传都是少之又少。最终,大家拿到手的奖金自然是非常丰厚。这给了所有人一个非常宽松的开发环境。

没有多久,我们每个人都领到了一件纪念 T 恤,上面印了,十万人在线的大话西游。


如果要说点别的,在 02 年底,我突然爱上了 ps2 上的游戏。从最终幻想 X 开始。公司里有两台 ps2 ,就放在办公区的一角。每天下班后,大家都去玩一玩。一天,我看见麻雀在那玩最终幻想,这是个老游戏,但英文版出来不久。我帮他做翻译,一边看着他玩。然后自己就开始手痒了。由于不好霸占着公共的游戏机资源。周末立刻去买了一台回家。

之后一发不可收拾。我想我购买了几乎所有发行过的 ps2 游戏,数以千计。和许多游戏收藏爱好者不同,有一年的时间,我都是很认真的玩每个不那么垃圾的游戏。很多很多游戏都从头打到尾了。

那几年的业余生活很简单,健身,打游戏。当然后来还有更多的一些活动,比如骑车、攀岩、看卡通,这么看的话,不算宅男,嘿嘿。


谢绝转载

那些日子(目录)

May 16, 2008

那些日子(十七)

2002 年 9 月底,再次回到广州,仿佛一个新的开始。我想我要长住下来了。这次打算住在办公室附近,越近越好。

头几天,我住在安宁住的小屋子里。原来小蓝租下的,现在他已经离开公司。屋子很小,晚上我就睡在地板上。安宁给我看他写的一些小玩意,一个汇编写的软件 3d 渲染器,挺有意思。还有一个使用 d3d 做的简单引擎。公司的 3d 项目已经做了大半年了,一直没有定下一个技术方案,可能还想多一些技术尝试吧。

我也去公司转转,没有正式复职,只是跟朋友们打个招呼,我回来了。顺便向周围一个个小区问值勤的保安打探情况,看看有没有房子出租。这比找中介要划算一些。工业园还不太繁华,房源很多。没多久就找到一家,步行到公司才几百步(以前数过的确切的数字,后来又忘了),中间会路过一个中国银行,挺方便的。

只是屋里格局设计的不好,也没有家具。空空的有张木板床,床板裂开,躺上去有点硌。我也够能将就的,就在这张床上睡了几百个夜晚。我妈常说那间房临着马路,有点吵,担心我睡不好。我倒不觉得,心灵上的平静才是最重要的。接下来几年过的很舒服。因为没有书架,还像上学时那样,把书齐齐的码在床内侧,取起来容易。

偌大的客厅就那么空着,直到我妈说要过来住几天,才去超市买了台电视。我决定过一种有规律的生活,把自己的时间规划的好好的,一块块的用。所以已经不想在家拉网线,摆计算机了。宁愿过一种不插电的生活,家中只是睡觉看书而已。这个习惯一直保留到现在,我没有买过笔记本,住所没有计算机,没有网线,要写程序一律去办公室。慢慢的身体也养成一种习惯,做什么必须在特定场所才有灵感。如果离开办公室的那张椅子,高一些,低一些,硬一点,软一点,都会让写程序的兴致全无。

国庆去了趟深圳,见了许多沉浮于此的大学同学,看着大家都在为生活奔波忙碌,感慨万千。


长假过后,正式到公司报道。

公司冷清了许多,一问才知道,不少美术都休假了。是啊,他们非常辛苦,长期都是一周六天工作,晚上还有固定的加班时间。当然,每周多出的加班时间,都是累积到假期里的。所以那几年,美术都是把假积攒到一起,然后休上足月出去旅游。(现在好象已经不这样了,周六再很少见有部门要加班的)

刘琪说,大家商量着想把大话西游的美术重新做一次,以前的不太满意。这次新的想做的 Q 一点。我不太在意。反正到时候换换图片就够了。大话西游因石器时代的风靡而立项,或多或少受到它的后续版本魔力宝贝的刺激而向后发展吧。

郭伟已经在公司上班,坐在我的旁边。他在读大话西游的代码,我给他讲解引擎。他的任务暂时是给大话西游做一个较大分辨率的版本,因为这部分涉及地图预读策略的问题,所以我仔细的讲述了那块糟糕的代码。郭老倒不含糊,没用多久就让引擎支持了各种更高的分辨率。可惜这个改进并不受玩家欢迎。玩家更喜欢已有的 640 宽的小窗口,因为这样更流畅,还可以同时开几个 client 一起玩。同样,过大的分辨率,除了提高用户机器的需求外,也加大了服务器的负载(对每个玩家广播的信息量增加);整体来说,对我们和玩家都是极不划算的,这样的一个版本放出后不久,最终还是被取消掉了。

游戏部门开始筹备自己的市场部,想把游戏市场工作从公司的大市场部中独立出来。这个决策应该是对的,丁磊也有一种对老的公司部门精兵简政的想法。黄华逐步从策划转为产品经理,管的更多是市场方面的事儿。随着精灵的逐步没落,设在上海的精灵团队(主要是市场方面)被集体南迁广州。这次大迁徙,公司上海部门离开了许多人,很多人不愿意离开长三角。剩下的一批搬到广州住下来以后,也慢慢散去。当第二年工业园里多出一家网游企业:光通,许多人(我记得的有老刀)去了那儿。光通就开在我租的屋子前面,我总觉得他们的大门朝向不对,若拿伪科学来讲,就是风水有问题。呵呵,一家之言。

当大话西游二成了网易游戏唯一一个赢利产品时,黄华做到了市场部门总监。萝卜则从大话二的主策划变为项目负责人。说起这游戏市场部来,张金姐后来不无遗憾的跟我说,当时大家都是从零开始,原本她很想,也有能力和实力去带市场部这个新团队的,那样她可能会发展的更好。可惜正好生小孩去了,错过了时机。如今张金的娃娃该上小学了吧,很聪明,被他的妈妈成天的夸。这些年,看见张金每天很晚回家,没有那么多时间照顾自己的孩子。让我觉得公司一步步发展起来,真的是有无数人投入了太多心血,做出了极大的牺牲。

大话西游二收费后进展很顺利。但和一切一切的网络游戏第二版一样,同样遭到了第一版玩家的猛烈抨击。念旧,还真是人之常情呢。逝去的东西东西永远是最美的,无论它还在的时候给你带来多少烦恼。大家不再记得那些 bug 那些设计失误,只记得它的好。

徐波就是其中一个,他做大话一的 GM 有很长一段时间,自己也玩。记得有一次他对我说,其实大话一游戏做的还是满好的,如果 bug 少一点,可以做的很精彩。

今天我在旧信箱里翻出徐波 02 年 5 月中给我写了一封信,里面附了他对大话二的诸多意见。有两份很长的文档。当时我正忙于程序,没有回复和他讨论。不过这份文档,应该看起来算是狠狠的批判了当初大话二的设计。当他转给大话二的策划组看后。在讨论会上,自然招致一片反对声。徐波不是个容易与人相处的人,我没有参加那次策划讨论,但我能想象出当时的情景。一大组人被一个毫无经验的“外行”否定,从心理学上分析,就能知道那种集体而生的排斥心。策划组全体都觉得他在那信口开河,争吵中,脾气最好的萝卜居然都气的拍桌子。最终只得让 dingdang 来调停。

如此看来,徐波没能融入大话二的策划团队就是自然的事。dingdang 只好让他做点别的。游戏的 client 已经稳定,那么就可以尝试把原来的大话一搬到新的 client 上来运行(和大话二公用一份 C++ 代码,但重新编写逻辑脚本)。陈舟(舟字用了个同音字,原字生僻不好输入)负责移植服务器;徐波以一个大话一老玩家及资深 GM 的身份介入这个项目的策划。这个版本被内部命名为“仙履奇缘”。看过大话西游电影的同学当明白这个词的寓意。


我的生活变的很有规律。暂时不想做什么新项目,只想学点东西,做一些积累。重新上班第一天,我就开始筹备一个技术讨论的邮件列表。因为当时对 C++ 颇有兴趣,就叫作 C++ 邮件列表了。

这个邮件列表到今天还在活动中,用的开源软件和专门架设的服务器。但是最早的时候,我是在本机制作了一个收发邮件的脚本来完成订阅、转发等服务的。就是利用一个普通的 email 信箱,让大家把邮件发到里面,然后我收下来,用脚本分发处理,再转发给每个人。

我整理了通讯录中所有的程序员,邀请他们加入我这个邮件列表。一部分是公司同事,一部分是网友。包括了新认识的孟岩等人。大家聊的挺开心,我觉得挺有趣,也想把这个做下去。今天翻出最早的几封信,02 年 10 月里发的,谈到买的新书:The Art of Computer Programming 第 2 卷 的中文译本。想起那段时间,还在拼命的做书上的习题呢。

后来这个邮件列表随着人员的增加,出了许多问题。经常被 smtp 服务器误认为在群发 spam 。我用的 email 是 163.com 自己的。原以为问题很容易解决。也就是为了这个问题,开始和公司邮件组的同事进行交流。我总觉得,处理这个问题弄个白名单就 ok 了,对于长期群发邮件,但没有被任何人投诉的帐号,应该很容易纳入白名单。但接下来听了邮件组的同事倒的许多苦水。嗯、其实一些表面上容易做的事情,即使技术上也没有障碍,实际操作时还是有各式各样的困难的啊。

虽然一再被封帐号,甚至冻结 ip ,这个半人工的 maillist 还是开了一年多。只到 03 年 11 月底,我群发了最后一封邮件宣布它关闭。大家觉得可惜,不久以后,我从公司申请到服务器资源,又重新开起来。


另一件事情,我开始健身。一直坚持了近三年。这段经历让我明白了一个道理。别人能做的事情,自己也是能做到的。无论目标看起来多么遥不可及。关键还是看是否有决心坚持下去。而一件事情能坚持,往往看的并不是兴趣爱好,或是利益诱惑,更多的只是习惯。养成习惯才是最重要的。

我从小身体就非常瘦弱。到小学毕业时,一个引体向上都拉不起来。上学期间,我觉得自己天生在体育方面就比别人差。进高中前,还担心体育不达标会影响入学。到读大学期间,曾经被寝室的同学怂恿着去健身,但只去了几天,听了教练讲一些要领后就没怎么再去。毕业后,一米八多的个头,体重只有 130 。夏天脱了上衣就是一身排骨。

心一旦安定下来,我想试试能不能有所改变。

公司不远处(员村)有一间健身房,先去打探了一下,感觉设施很齐备。如果按次去,就比较贵,一次要十多块。而且容易荒废。比较了一下,办那种早卡比较划算,一个月才 100 多点,唯一的限制是在中午 12 点前进场。一咬牙,决定彻底一点,改掉晚睡晚起的习惯。每天七点起床,吃个早餐休息一下,就走过去(大约半小时路程)锻炼。

旁边是个电影院,只要是周末,训练完了还进去看场电影。电影业很萧条,好几次放映厅空空的就我一人。感觉是个人包场,非常的惬意。碰到滥片,窝在情侣座里小睡一会。那几年,真是贡献了不少银子给我们国家的电影事业呢。

健身房的器械区早上基本没人,教练也很无聊。几句话我们就聊上了。他乐得交个朋友,便帮我指定计划,一点点的开始练习。我想我就是那么下了个决定就开始了。一直坚持下去。一开始是隔天去一次(因为没有习惯大量肌肉练习的人,一开始必须保证每次之后 48 小时的休息),然后逐步增加频率,直到一周五次。

很辛苦,也很单调。每天一个半小时的训练,各个大肌肉群分开练习。全是各种器械的反复机械练习。一组组的做,直到压榨出肌肉中的每一点能量。还有每天 100 个的仰卧起坐(从平板到斜板再到几十千克的负重)。最初的那段时间,整天腰酸背痛,四肢无力。记得有天躺在床上,用手硬是撑不起身体坐起来,我知道那是肱三头肌脱力的现象。

唯一的乐趣,就是每天测量自己的各处肌肉的围度,以及称体重,看那些数字在小数点后的变化。神奇的是,晚上的睡眠也是相当的好。白天虽然没力气,但很有精神。每天都能吃上十多个白水煮鸡蛋。身体也就一天一天明显的膨胀起来。

一年之后,体重就从最初的 130 上升到了 156 。卧推从刚开始的不到 30 公斤,增加到接近 100 公斤,深蹲也达到了 140 以上。看着杠铃两端厚厚的哑铃片,心里特有成就感。

而引体向上慢慢的也可以做到 18 个(这个受体重增加影响,进展很慢),这都是以前不敢去想的事情。

一直以为,身体主要是父母给的,后天能改变的很少。当看见别人身材魁梧,总是很羡慕。小时候没注意锻炼,觉得大学毕业后就成年了,能改善的可能性不大。没想到,一切都不晚,只要去努力,依旧可以改变自己的。

只是这两年,项目实在太忙,主要是劳心。我中断了健身的习惯。感觉身体状态降了很多。体重也掉了下来。不过还是比大学时好一些。我想能够在这几年玩命去做新的项目,这身体基础跟前几年的坚持锻炼是分不开的。真所谓养兵千日,用兵一时啊 :D 。等现在手头的事情做完,一定要恢复这些好习惯。


谢绝转载

那些日子(目录)

May 15, 2008

那些日子(十六)

《大话西游二》是在 2002 年 8 月 15 日正式收费 的。而就在之前几天, 02 年 8 月 7 日,网易宣布股票发行以来,第一次实现赢利。这次赢利,净利润仅 3.8 万人民币,我在网上看到这条消息时,感觉太搞笑了。根据财报,一个季度的运营费用有 2719万,结果恰恰就赚了不到 4 万。这个数字若不是精心做出来的,而仅仅是一个巧合的话,我觉得那实在是太幸运了。

事后,我给后进来公司的新同事讲这个段子时开玩笑说:当时我的第一反应是,前段时间公司暂停了我们大家的办公文具申报,连以前每月发到个人桌上的卷纸也没有了。感情公司这历史上的第一次赢利,是大家坚持三个月,集体节约下那些铅笔、记事本和卷纸给省出来的。每个网易员工都是功不可没呀。

不过不管怎么说,从五月里开始,一切都朝着好的方向在发展。

但我并未在广州亲身经历这几个特殊的时刻。


2004 年以前,公司的劳动合同等管理并不严格。合同放在我的抽屉里,一放就是两三年,中间有人问过一次。我拖着没签,就再也没有人过问了。我想公司为了早日实现赢利,在运营成本上扣得很细。能不招人的岗位就不招人。尤其是行政财务等部门,长年都只有那么几个人在办公。有点什么事情都不敢轻易打搅那几个 mm 。早年,我的一些报销单能压上半年才处理完到帐。弄到后来,除了出差的飞机票和酒店住宿这些大额的做一下报销单外,小额日常的报销都是不想去做的。

研发部门中,直接开发人员之外的后勤管理人也出乎寻常的少。上百人的游戏部,就一个前台 Candy 忙内忙外,剩下的全是研发人员。后来调了张金姐过来,仍旧不堪重负。最后几乎所有的文职人员,都需要做一些内勤的工作,像做韩语翻译的金香兰,我们的法务顾问等等。

游戏部门人还远不如今天这样多的那时,办公室坐不满。泡泡组便搬到工业园一起办公。黄晓东(不久后离开,后去微软为移动做飞信)当时任泡泡的项目经理,我们也时常聊天。泡泡组的加入,也加大了许多后勤工作上的压力。

我想若不是靠大家的自律,这么大的团队无法自我组织起来,完成这样一个项目。

七月,眼见着大话二顺利收费已成定局,技术问题基本上全部克服了。dingdang 在考虑的是收费后要不要删档的问题;丁磊考虑的是收费维持一小时三毛的标准、还是提高到四毛一小时。很多人反对涨价,但丁自有他在精灵上五毛一小时的成功案例,固执的坚持要涨一毛钱。事实证明他的对的,除了那时候残留下来的极少数大话一玩家在网上闹闹外,大部分用户接受了这个价格。另一方面是因为几个月后增加的一个不起眼的小设计,点卡交易系统的成功。这段故事放在下回讲述。

我的工作,即那些代码的日常维护,同事全部可以轻松接下来。留在公司已经不是特别必要的事情了。这样说,我的初衷是完整的做成一件事,到这里、目的就已达到。至于成功的果实,由哪些人怎样去分享,已是微不足道。

一个周末,我去电脑城买了块移动硬盘。用它备份了一些代码,几篇业余写的策划稿,收集的一些资料,把家里的计算机送还给公司。这块硬盘质量不好,不久就坏掉了,那些文件从此消失,心痛了好久。

七月月中,我跟 dingdang 说,我想休假。好好想想再该去做什么。没有提辞职,其实我也拿不准是否真的想辞掉这份工作。只是说,把薪水停掉吧,可能我想多休息一段时间,领着薪水我心不安。dingdang 说,无论两个月还是三个月,随便休吧,完了再回来。

走的那个周末,下着瓢泼大雨。雨水一上午就积到了脚踝。我没太多行李,主要是书。可随身几大箱,也很难步行出院子。租的那个房子在一条很深的小巷子里,终于有个好心的出租车司机愿意进去接我出来。那个巷子真的是很窄,车进去都无地方掉头,倒着开出去的。

房东和邻居都有点舍不得我走,因为我的作息时间,我本不是个容易很邻里打交道的人。但母亲偶尔过来住,和街坊相处的很好。她很乐于助人。那栋楼的楼上原有个独居的老太太,儿女都定居在美国。有一次心脏病发作,母亲送她去的医院。房东一对老人,在我离开广州后还偶有联系,等我日后再次回到广州,母亲时常去看望。老人家一直唠叨,后来几任房客都不太合意,最后只好把房子低价贱卖了事。


就这样突然的决定离开广州,显得有些冲动了。其实当时我已经在武汉供房,为父母买一套新房子,让他们过的好一些,恐怕是所有儿女的心愿。

02 年初的房价还不高,只是人们看到的都是相对价格,而非绝对数字。从福利分房的年代过来,当时单位里的房子把产权卖给职工,不过几百块一平米。而福利房周边的商品房价已经是高达一千多了,不是很好卖。一开始我看上一处两百多平的复式,单价要 1200 。计算了一下,可以承担的起。不久又觉得小区设计的不太好,而旁边打算新开的楼盘感觉更好(还只是楼花,地基还没打,只有模型),但是单价要两千多了。这在那一片已是天价。父亲有些犹豫,因为按我的计划,贷款五年买下,每个月需要还贷 5600 。实在是贵了点。单靠父母微薄的工资,无论如何供不起的。而他们辛苦一辈子,有了钱都接济亲友,又没有丝毫积蓄。

我当时坚信,只有最好最有价值的东西,才有足够的升值空间。而且既然要买房给父母,就一定要最好的。在我的坚持下,买下了这套房子。同时也背上了六位数的债务。

有时候,我也怀疑自己是不是乐观的过了头。虽然明知道身上有几十万的负债,银行里的存款也都拿出去付了价格不菲的首期,但对于即将失去固定收入还是满不在乎。似乎自己从来没有思前想后的去考虑以后可能会面临的诸多困难。

不过,为了打消父母的担心,我还是在八月去了北京。毕竟在家混日子是赚不来钱的。


北京有家新开的网络游戏公司叫作侠客行。他们头儿董晓阳是我在网上认识的朋友。据说他在美国读书时,曾经和方舟子一帮人等开发过名为侠客行的 mud 。这次回国创业,就是想把这款 mud 图形化。

他在用“风魂”写 client ,想让我帮他做点东西。

当时我在心里认为,已经可以给网易公司一个交代了。大话这个项目圆满完成,对的起我过去拿的一年半的工资。我还没有跟网易在附有禁止竞争协议的劳动合同上签过字;已经中断了薪水,处于停薪休假中;而且这次也只是做一些底层技术工作,帮人解决问题而已。对于我来说,写程序和做游戏是分开的两件事。所以,我爽快的答应了。就算是兼职吧。

董晓阳给我开了一个比网易更高的薪资,希望我能全心加盟。我拒绝了,因为我不想再次重复做过的事情。侠客行的游戏看过,当时还很一般,我觉不出会比大话更好。某些方面做的跟大话一一样简陋。看的出来,很多模块是借用一些开源的东西东拼西凑出来的。

如果真的是我来接手的话,等于又重新做一遍大话二,这可受不了。人生不过数十年,重复自己有何乐趣。

他们的一大问题是缺少完好的 GUI 系统,有如大话一曾缺少的一样。我在北京干了不到一个月,挺自由的在他们的办公室出入,解决这个问题。这方面,已经积累了太多经验,去北京前在武汉家中,我已把 glow 全部完成,所做的只是一些整合工作。

最后董晓发了我一个月的兼职工资,大信封装的现金,厚厚的有一万。带回家中交给父母,让他们放心,儿子这辈子无论干什么,都是饿不着的。


在北京过的那个夏天,更多的还是拜访旧友。同时也结识了些新朋友。

一天,胖肖给我打电话。说黄晓东离开网易后一直在北京,大家可以出来聚一下。另外还可以叫上在联想工作的 孟岩 。我听到这个名字很耳熟,只花了几秒钟就想了起来。当时网上流传着一个帖子,关于配置 STL port 在 Windows 下编译并整合到 VC 中使用。此贴就是此人大作。我当时对 C++ 和 STL 兴趣浓厚,颇想结交一下玩 C++ 的同道。而且听说他正在和候捷合译 《C++标准程序库》,很是期待这本重要的译作。

我们四个人在一家川菜馆碰面吃的火锅,听说孟岩也是武汉人,相互感慨了一番。大家都非常健谈,边吃边聊,意犹未尽。并没有在晚饭后散去,而是转战一家茶馆继续。

程序员碰面,总是有聊不完的话题,很多不做此行的人很难理解。一开始大家还只是聊一些程序技术问题。C++ 语言方面,胖肖和晓东不是很有兴趣,就我和孟岩讨论甚欢。随便拿出个奇技淫巧来,都可以说上半天。而后,大家上升话题谈一些高屋建瓴的软件设计方面的学问,由于各自都有许多工程经验,自然故事连篇。记得,还聊了一段优化,最后胖肖总结,最大的优化手段,无非是一种广义的 cache ,即想办法避免重复的操作和运算。还有一些在实际工程中并不多见,即是数学上的算法改进。话题就这样扯到现代数学和物理的进展。当时我很着迷于超弦理论,看了不少科普书,当即吹了半天的牛。说着说着,不知怎么又扯到历史上去,难得孟岩也读爱读史书,我们从秦始皇一直聊到李秀成。

直到深夜,孟岩的 mm 不停的发来短信,他才不舍的离开。我和胖肖干脆跟着晓东去他住的地方彻夜长谈。

补充修正:后来翻出来一封老邮件,是胖肖约我出去吃饭的。时间是 2002 年 5 月 9 日,约在 12 日吃饭。所以上面这段故事记叙时间有误,应更早一些。7,8 月份的时候我再去北京,又去找过一次黄晓东。那天半夜,我被关在住所外面,进不了门。手机没电,幸亏有随身携带电话卡的习惯。身上摸出张黄晓东的名片。满大街找电话亭,把他从床上拉起来接我去他那过夜 :D 。


回到武汉后,我去了一趟庐山,风景很美,玩的挺开心。这也是我第一次自己跑出去游山玩水。大学时,假期都去写程序或做兼职去了,同时也没钱远游。工作后,一直很忙,即使出去玩,也是一大忙同事赶去景点转上两天。而这次,却有很多时间,慢悠悠的过。前面的事情做完了,后面还不确定做什么,觉得挺放松。那种感觉叫——自由。

接下来,在武汉家里待着。母亲早已退休,除了白天照顾我吃饭外,就是出门忙乎她的一些事情,照顾几位老人:她工作时的师傅;父亲还在上班,成天在单位里忙碌。我便去图书批发市场淘些折价书回来看,倒是特别清净。时常想想是不是应该继续一年前的想法做个有历史感的游戏。可越发研究历史,想的越多,越觉得自己的学识太浅薄。我想,即使转行不写程序,不做游戏了,这个世界上还是有很多有趣的事情可以去琢磨的。

网易的股价在我休假的日子里,随着大量的利好消息,玩命一样的向上疯长,不多久就六七块了。能和这成长速度媲美的是大话西游二的在线人数。我想,这次又被丁磊说对了,我们超过盛大,不过是时间问题。

在家里安定了一段时间之后,终于想明白。虽然不确定以后想再做什么,但自己想做的事情,自身的学识和能力还差的很远。提高自己,不一定要一个人独居在家中。有个好的环境,和人交流的环境,只会更好。网易是个好公司,现在也在迅猛发展。而自己是个有用的人,无论在哪里都有能力为别人做些事情。一旦有个好的平台,只会做的更多。

同事在网上问,休息够了没?赶快回来上班吧。在那金秋十月,我又回到了广州。


谢绝转载

那些日子(目录)

May 14, 2008

那些日子(十五)

大话西游 2.0 在 02 年五一封闭内测的时候,已经更名为大话二。因为丁觉得,反正是重新做的,就应该以新名字重新来推广。

由于先前的刘铁等几个策划离开,月心被调离大话组,转到 3d 项目中(这也一定程度的导致了这个 3d 项目最终被命名为天下二)。Micro 在他回加拿大前的一个月,开始重新为游戏策划招兵买马。

萝卜从大话西游的界面设计师改行做游戏策划,黄华被提升为大话西游的主策划。而丁丁(日后的《梦幻西游》产品经理)就是这个时候入职网易的。这是 2002 年四月间的事情。

按我讲述这个故事的前后习惯,所有提到的人均用我平时在公司对他们的称呼。那么就用丁丁代这么个人了(有人也把丁磊称作丁丁,不过不是我的习惯)。公司里也有人称他为老妖,那是他的一个网名吧。

丁丁总是带着一副彩色的眼镜,年龄看起来比实际上的小许多。在当时的游戏开发团队里,只有 dingdang 比他年长一点。他从学校里出来的早,所以工作经历比其他人要多许多。据说早年卖过花,早早的起来去花市里,把花架在自行车上运出去卖,收入还不错;后来手工焊过线路板,做数控机床的驱动电源,赚了不少钱 …… 也算是久经江湖了吧。

那一年末他又离开网易,但不久以后再次回来,一直做到现在,已经是游戏部门的领导了。

这段时间有前同事跟我在泡泡上聊,说怀念过去的工作经历,想再回来网易,但是又担心回去后受到不公正的评价,影响日后的发展。其实中途离开过公司,之后又回来的的例子很多很多。在这个故事里提到的人中就有 ruiheng 和丁丁。我现在也管理一个团队了,从内心中感到,其实用人往往还是希望更熟悉点,所谓知己知彼,百战不怠。大多数领导团队的人,还是希望那些自己离开的同事可以回来继续共事的。何况周而复返,更能说明经过了深思熟虑。

丁丁来的那一晚,Micro 叫我一起去吃饭,说要给新朋友接风。饭局不太隆重,我们就在工业园中的明记大排档吃的。天气开始有点热了,老板说屋子里有空调,大家就坐进去。我跟丁丁之前没有见过面,但是一聊起来发现还有点缘分。他是《古龙群侠传》的数值策划,那么就是郭伟的老同事了。我们立刻就有了共同话题。


大话二的 client 放出后,作为引擎开发者,我已经没太多事情。我给自己找了些事情做,那就是想方设法减少外挂和加速器对游戏的危害。

外挂问题,是一个长期的处理过程,前后持续投入了一两年。但都是断断续续的在做。灵感来了,添点东西,从来不是我的主要工作。相关的一些方面,前面已经谈起过,不再累赘技术细节。下面简单提一下加速器的监测。

所谓加速器,就是让 client 以高出常规频率向 server 发送一些指令包。早期的 MMORPG 服务器都是单纯的包驱动,即,根据 client 发送过来的指令,在检查了逻辑合法性后,做出相应的处理以及反馈。大多数网络服务都是这么做的,比如 web server 用的 http 协议就是这样。用户从浏览器发起一个请求,服务器就做出一个回应。普通的网络服务仅仅在防止恶意攻击时,才限制一下同一处来的并发请求数。但 MMORPG 则不够,因为时间信息也是影响游戏规则的一部分,我们需要保证时间间隔信息的合法,以此维护游戏公平。另一方面,也要阻止非法用户吃掉过多的 server 带宽和 cpu 资源。

今天看起来很简单的道理,当时我并不是一开始就意识到的(虽然着手处理加速器的工作更早就开始做了)。最早是 tarcy 给我讲的一件事,让我意识到这个问题的严重性。

tarcy 在九城测试《奇迹》时就开始为这个游戏写外挂了。我一开始很奇怪,不是说《奇迹》的战斗逻辑都放在服务器计算的吗?那么就不再会出现《精灵》那种修改 client 就能做到无敌天下的问题。使用外挂又有什么特别的好处呢?tarcy 说他们写的外挂很好用,可以让火球提高最高八倍的攻击力。一开始我不相信,他一解释就明白了。原来只是提高的发火球的频率而已。(btw ,tarcy 的奇迹外挂后来据说达到六位数的注册用户,还发展了海外代理,赚了个钵满盆盈 :D 如果单单是个人想赚点钱,这比为网游写程序要来的容易多了)

后来 wow 是用技能冷却 ( CD : Cool Down) 时间来回避这个问题的,这也是欧美系网游一贯传承下来的方法。今天被很多游戏学了去,但那个时候却不普遍。

最开始,我去解决加速器引起的问题,只是想阻止玩家用不合法的手段在虚拟场景中移动的比正常速度快,也就是避免玩家以非法的频率发送移动指令。玩家做到这一点,甚至不需要修改 client 程序。他只需要用一个小软件修改操作系统的时钟逻辑频率即可,这样的软件比比皆是,被称为变速齿轮。

我们的服务器程序设计的并不好,mudOS 的底层也没有精确控制时间的设计。在做这件事情时,和通讯加密一样,我尽量避免要求服务器做大的修改。

方法是很简单的,就是在通讯底层加上时间戳。也就是在时间流逝后,发送一个时间信息包,通知 socket 上的对方自己本地的时刻。理论上,socket 两端的时间流逝速度应该是一致的。假设一开始通讯时,client 和 server 的时刻校对一致,由于网络通讯需要消耗一段时间,所以,server 收到的 client 发送的时间戳时,时间戳表示的时刻都应该比本地时间慢一些。一旦快于本地时间,就可认为 client 在作弊。

这个方法很多游戏开发团队都想到了。

头一年(01 年)国庆的时候,我曾经去上海拜访过新浪游戏论坛上的一群网友。小箭2000 带着 freemind ,analyst ,softboy 等一帮人在上海为金智塔做《星河贝贝》。那是个下午,小箭的电话始终没有人接。analyst 说他就是这习惯,睡觉不关手机,也不接电话,等醒了会打回来。freemind 请我吃螃蟹,他说来到上海后,就开始喜欢吃这个东西了。还专门买了个蒸螃蟹的锅,周末从菜市场提上一串回家,放点冰糖一蒸,那可是人间美味。

吃完饭去他们办公室打星际。之后我们没交流太多技术问题,唯一印象深刻的一个就是谈这个加速器检测的方案。

这个方案从理论上看起来没错,但实际应用中,经常会发生误判。原因有二,一是准确对时非常困难 ,尤其在对时过程中 client 系统和通讯网络不稳定,会极大的影响后面的判定;第二是,PC 机的各钟主板,甚至运行的操作系统,都会导致时钟精度的不一致

所以在用时,这个方案还是有许多细节需要改进的。大话西游二的测试期间,不完善的检测手段,冤枉过不少可怜的玩家。kyo 的保守作风在这个问题上发挥了作用,原本我认为理论上完全可以判定出是否使用了加速器,但 kyo 一再坚持,即使检测到,也需要累积多次再做处理,这样大大减少了误判对玩家造成的影响。


2002 年的夏天,我基本脱离了《大话西游二》的开发。因为我总是自己找事情做,所以公司就没有指派给我任何任务。这期间读了几本书,影响了我好几年。

第一本书是著名的 C++ D&E :《C++语言的设计和演化》,我读了两遍,读的很快,但很透彻。这本书让我又一次重新认识了 C++ 。

第二本则是侯捷写的《STL 源码剖析》,我并没有读完。而是在实体书出版前, kyo 介绍我读了侯捷放出了前四章电子版。因为这本书,我把 STL 的源代码几乎浏览了一遍。发现 template 这个东西居然如此奇妙,从此陷入在把玩 template 的智力游戏中,一晃就是三年多。

02 年被我自己称为 C++ 年,C++ 的有关经典著作不断的被翻译,程序员杂志也在推波助澜。各大开发论坛的 C++ 版块都异常火爆。我在 csdn 注册了一个帐号,没发多少帖子,仅有的一些全在 C++ 版里了。我想我读了那几年翻译出版的所有的关于 C++ 的书,也为自己重新发现 C++ 这样一把无所不能的开发利刃而沾沾自喜。

ps. 通过 google 翻出当年的一个论战贴,讨论多重继承和组合模式的。我想很多同学在学习 C++ 时都有这类经历 :) 。

那些日子,不断的把自己学到的领悟到的新东西教给同事,我想,许多人都受到了感染。对于许多年轻的程序员,都会为找到一样可以证明自己比别人更聪明的玩具而兴奋不已。

在最为狂热时,我把 C++ 的字样印上了个人名片。和今天相比,当时的心境真是判若两人。

那段时间,我开始重新写 gui 的模块,想用“更 C++” 的方式来表达设计。编译期运算、(用 template)函数式编程、泛型抽象,无所不用之极。那套东西被我称之为 glow ( game library of windsoul) ,这名字还真是热情洋溢啊 :D 。

之后,便翻新重写“风魂”。不过鉴于 glow 开发时发现的一些问题,如编译速度过于迟缓、调试不便等,这个新版的“风魂”就不那么 C++ 了。也正庆幸这一点,这个版本可以一直用下去并被人持续维护,成为了后来《梦幻西游》以及其它几个网易产品的底层代码,甚至还用在了《天下二》的 GUI 模块中。

直到 2006 年,我开始对 C++ 开发项目进行反思。等到 2007 年写下 C 的回归 这篇颇有争议的 blog 时,我很能理解那些反对声音,如同理解当年的自己。


看到大话西游二顺利的发展,每天都能看到在线人数有新的突破,不多久就超过三万人在线了。我心里长舒了一口气,总算搞定了。

庞鑫离开后不久的一天,dingdang 把几个开发人员叫到了会议室。分别发给大家了一份文件。说是网易的期权。

所谓期权,就是一种在一段时间内,以一定价格买入指定股票的权利。这个价格往往就是制作期权文件那天的公开价位。虽然不是现金,但期权自有它的价值,这个在金融方面早有定论,不过当时我是没有太多概念。

简单的理解,就是当持有一支股票的期权,若它日后涨了,你可以以当初的价格买入。如果你在行使期权的当天再在公开市场上将股票卖出,其中的差价就是立刻能入手的获利了。而如果股价跌了,你可以放弃期权,也没有什么损失。在美国这样成熟的金融市场上,期权这种金融工具本身,甚至都可以被炒来炒去。

上市公司常常以颁发期权这种方式奖励员工,并鼓励员工努力工作,一同把公司发展的更好。一旦公司股价上涨,大家能有很大的收益。

直到 2004 年,网易每年都为所有正式员工颁发期权。无论是前台接待,还是仅入职几天的程序员,人人皆有。那一天,我手上的文件上写着 70 美分一股的价格,五年的有效期。等到 2006 年底即将过期时,我将这些期权全部行使,变成股票存放时,股价已经翻了一百多倍。

dingdang 向我解释说,本来我入职时间不长,可以拿到的数字比文件上的要少一些。但是由于一些同事的离开,大家商量后给我多一点。我所做的只需要签一个字了。

记得当时我很犹豫,迟迟不肯落笔。因为我觉得自己的事情都做完了,心里盘算着离开。


ps. 闲扯几句关于网易期权的事情吧。虽然公司里不让讨论大家各自期权多少和分配方案,但具体的情况,多少我还是有所耳闻的。当初那几年,我绝口不跟人谈这个,一是理解公司在这方面保密的苦心,二也是的确不太关心,否则也不至于每笔期权都到最后快过期的关头才着急行使,弄成每年都要做一次的大事。甚至感觉有些麻烦。

如今,公司已经不是人人发期权了,股价也涨到很高,我想再难有几十上百倍的收益。那些高收益的期权文件今天已经几乎都过了有效期限。有人在涨到 20 倍、30 倍时迫不及待的兑现,有人像我这样留到了最后,最终收益和当初期权数量反而关系不大。从金融角度看,当时的期权多少的差别其价值的绝对差距就不高。今天来谈这些,已经不太所谓了。

其实游戏部门的期权一开始总体不算多。这点我曾和其他部门一个头(已经离开网易)聊天时,他帮我打抱不平过。他说游戏部门为公司做出了很大的贡献,但在为自己部门谋福利这点上,dingdang 争取的太少。由于游戏部门人多,机构大,一平摊就没多少了。往往部门人一多,普遍级别就不高(官少),分期权的时候,级别又占了很大权重。他劝我去申请提一个级别,省得比别的部门干活少的多的人拿的还少。

利益分配真是个难题啊,共患难容易,共富贵难。

后来几年,让 dingdang 殚精竭虑的问题之一,就有如何奖励这个越来越大的团队中的每个成员。这绝不是一个写个程序,套个公式,就能完成的任务。它需要更多的智慧。


谢绝转载

那些日子(目录)

无言

这几天估计所有中国人都在关注一个共同话题。大家都自发的想做点什么。这两天谈论的太多,反而不想写啥了。

转个公司的内部公告:

心系四川灾区 员工募捐倡议

各位亲爱的兄弟姐妹:

看着四川地震灾难的图片,您一定已经默默地流过了泪,我们感受到了你的爱心,更加感受到了灾区人民的无助,是苍天无眼,但身为中国人,我们是一家人。现在就伸出您的双手,拉上身边的伙伴,虽然我们不能亲自去安慰他们,但我们一样可以支持他们。

已经三天了,全国上下在不断的献出爱心,现在就尽上我们的绵薄之力,去支持他们活下去,去支持他们重建家园。"家"是美好的,但他们失去了,就在一瞬间……让网易的全体员工,积极行动起来吧,让我们的爱去温暖他们受伤的心灵!

昨日公司已率先向灾区捐款500万人民币,并将视灾情考虑追加捐款。

同时,网易四地:北京、上海、广州、杭州今天中午12点起将开通"心系四川灾民--员工捐款箱",接受员工现场捐款,捐款时间截止2008年5月23日(下周五)18点。

此次募捐,因人力原因暂不接受物品捐物。所筹得四地捐款将与公司的捐赠集中统筹使用,灾区重建时公司将委派专人赴灾区,根据实际需要合理使用善款。

现在开始,请擦干心中的眼泪,勇敢些,让我们陪着他们一起努力!

天亮了,我们相信,有我们的爱心,明天会更好!

四地捐款地点如下:

(以下略)

另推荐:科学松鼠会之地震专辑

May 13, 2008

那些日子(十四)

让网易在网络游戏上看到希望的是《精灵》。这是个从韩国代理来的游戏。当时我们也有可能去谈 MU ,即《奇迹》。为什么定了精灵而不是奇迹呢?我听到的不确切的说法是,奇迹要价太高。

现在看起来,今天几家大的网游运营公司真的是特点明显啊。代理奇迹的九城,几个产品都敢花大价钱下注,先是奇迹,而后是魔兽世界。我想它的成功也绝非偶然了。

至于当时我看到的 RO ,其实也是个相当不错的产品。要价也不低,不过更重要的是 RO 制作完成的时间稍微晚一些,而精灵已经声称可以运营了。公司等不及,也是一方面原因吧。

在我的感觉里,从 01 年末开始,网易在各方面都是非常节省的。或许和丁磊的性格有关。也是这份节省,让公司在几家在 nasdaq 上市的中国网络公司中第一个起死回生。

《精灵》的市场部门放在了上海,办公室就设在人民广场边的高楼大厦中。西藏南路,楼下有家馆子叫作上海人家,味道不错。去上海出差时同事总是带我去吃。现在上海公司已经不在哪了,可能是因为人员增加,房租太贵吧。大猫猫就在《精灵》开始运营时,回了上海。

精灵的的技术支持部门以及机房设在广东。如果我没记错的话,机房租在佛山(ruiheng 提醒我说是在东莞,哈,还是记错了),这也是因为机位便宜的缘故了。小强从学校毕业没多久,便被指派到这个项目里做远程系统维护。

据说,当时公司为了节省开支,全部按普通家用 PC 的标准采购了一大堆的兼容机做服务器。4000 块一台的标准,甚至配的是 IDE 硬盘。可害苦了值守机房的同事(经 ruiheng 提醒,是 charles ,我没打过交道,没印象),时刻都有硬盘坏掉。守在机房,几天不能回家。后来精灵停止运营,这些机器淘汰下来,全部搬回办公室给大家办公用机更新换代。我做梦幻那会儿的机器就是精灵服务器呢,换下来的机器则交给策划写文档。策划再将淘汰的机器送去客服组监控游戏中的聊天频道,或是扔到 QC 部门做低端测试机。

任在服役的一台服务器,被我借了块空间存放个人主页了,一直到今天还在工作着。

精灵的收费标准是破天荒的五毛一小时。那个年代,大家都还摸不清玩家的心理底线和承受能力。居然这个价位游戏也依然火暴,真的是个奇迹。要知道当时玩的人最多的传奇要便宜很多,而且精灵相比传奇还缺少一个重要功能:PK 。

精灵大约是在 6,7 月开始收费的,没过多久就收回了成本。记看起来,小强也拿了不少奖金,刚毕业就能这样,自然是很高兴的。

从我的角度事后去看精灵,它更大的作用是推广开了网易一卡通,让网易的点卡顺利进入了各个渠道,为日后大话西游二的顺利收费铺平了道路。

那段时间,丁磊显得踌躇满志。一天晚上他到游戏开发组的办公室转悠,走到我的位置前要看看大话新的 client 。之后我们谈起游戏产品。他说,“我们的目标是做国内第一,盛大算不得什么。”我心里只嘀咕,现在我们离盛大还差一大截呢,就算在国内网游市场,前三都还排不上。精灵看起来是不错,但是比起传奇的用户来,远远不及。这大话,老实说,我愿意花心血投入做新版本,仅仅感觉前一版有自己参于但没做好,羞于见人。真正做出来,能不能抢占到最大的市场,还是个未知数呢?石器时代仍有人气,后续产品魔力宝贝已经上市。甚至国产的幻灵游侠也比我们之前做的好。


可惜,精灵的火暴没持续了几个月。毁掉这个游戏的居然不是游戏的设计,不是游戏的稳定性,而是外挂。

听到第一起相关报告时,我的脑子里只怀疑了几秒钟。居然有玩家用 FPE (当年很流行的一种单机游戏修改软件,可以锁定内存中的数值)就可以修改这个网络游戏。有玩家用 FPE 锁住血,就可以在游戏中获得不死之身。我立刻理解了这个游戏代理费为何如此便宜,还真是一分钱一分货啊。(虽然日后奇迹 MU 也饱受外挂之苦,可也没这么离谱的)

在网络游戏发展的初期,我想任何一家开发公司都是缺乏经验,需要一段时间积累的。早期开发出来的产品多半有些问题。据我个人猜测,精灵是从一个半成品的单机游戏中改动过来的。大部分设计都是单机模式。而做成网络版的好处是,可以省略单机游戏必须的一些要素,比如丰富的剧情,过场动画,等等。这个游戏只是在单机游戏的基础上增加了一点网络通讯功能,让玩家之间可以相互看见对方在干什么。所以也能想到,为何它们游戏中没有设定 PK (韩国官方的说法是,他们国家里网络游戏会被分级,PK 的设定会导致某个年龄以下的玩家不准来玩)。听说精灵后期的版本开放了 PK ,这我就不得而知了。

开发难度小,自然费用也就下来了。

还有几件事情可以看出精灵的程序之不成熟。

我们曾经向韩国公司反馈过 client 不能在 windows 98 下运行,他们说,他们没有考虑过支持 windows 98 ,因为在 2002 年,韩国人几乎全部升级到 windows 2000 了。我们很无奈,当时 windows 98 在国内的网吧还是主流操作系统。从我一个程序员的角度来看这个问题,兼容 windows 98 系统并不是什么困难的事情。可以在 windows 2000 下跑的游戏,如果在 98 下会出错,多半是一些 bug 导致的,而非用了什么专有 api 。(例外也是有的,有些因为 win98 早期版的一些 bug ,用户又不愿意更新系统。此类问题我在调试大话的兼容性时遇到过,解决起来也很快)

起初精灵的 Client 在没有声卡的机器上会挂掉。我用 ida pro 分析了一下,发现他们没检查声卡设备的初始化结果。Ali (精灵当时的产品经理)说,他找几个朋友搞一下就好了。我明白他的意思,他做游侠网,一定认识许多做破解汉化的朋友。对着二进制的程序做点这种小改动那是小菜一碟。其实甚至用不着他去欠朋友人情,我自己来弄也就是一天的事情。只是既然我们跟韩国公司是合作关系,他们有源代码,做起来也是快的很。可这件事,还是 ali 去找朋友搞定的。或许是沟通上的麻烦?

我们在精灵运营之前,派人去了趟韩国做技术上的交接。dingdang 带着 ruiheng 和 kyo 去的。大约是 2002 年 5 月的事。当时世界杯正准备召开,kyo 回来时还送了个一个世界杯的钥匙扣。本来我也要去的,因为筹备大话 2.0 的 beta 测试很忙,一直没能请假回家办护照。所以在韩国看见了什么,就都是 ruiheng 和 kyo 给我转述的了。

我们去只是去商量汉化以及登陆收费接口对接的事情。但 ruiheng 说了一些无关这些的见闻。对方是个小公司(接收了网易的版权费后才逐步扩大),几乎所有的程序都是一个人(CTO?)在做,当一个人急着赶产品时,版本控制这么关键的东西也被忽略掉了。所以精灵的代码管理很成问题。这也是我们几次三番要求他们改东西,对方都显得那么痛苦的缘故。

到 2002 年 9 月时,韩国方面按我们的要求做中秋活动,不小心弄出点 bug 。我们报告后,对方怎么也改不好。韩方的理由就是,正在做国庆活动呢,老代码已经找不回来了 :( 。代码管理之混乱,可见一斑。经过我们的强烈要求,他们才上了 vss 。

btw, 精灵的服务器也是架在 windows 上的,不是很稳定。

kyo 在韩国时跟我爆料,说韩国的网络条件很好呀,他们公司每台机器都有一个外部的固定 ip 。可他们的网络安全防范意识简直是太差了,在这些直接暴露给外网的机器上,居然开着文件共享。公司里也没有装防火墙。

那几天,大话西游新版上线,效果非常好。在主要开发人员都不在办公室的情况下,也基本没出什么问题。我们在之前测试的实在是太长时间了。我便买了台 GBA ,上班时坐在那里打黄金太阳和高级战争。一周就把两个游戏都翻版了。


精灵的外挂问题从软件设计角度看就是无法解决的。当然,如果精灵不那么设计(把绝大多数的运算放在客户端本地计算),它可能也做不到流畅的游戏感觉。

公司想了很多办法也无能为力,至少我是绝望的。韩国方面派了几个韩国人常驻我们公司,除了跟外国人交流一下让我觉得挺新鲜外,我觉得在外挂这件事上,他们起不到什么作用。倒是韩国朋友给我的印象还不错,相处很融洽。他们笑广东人吃不了辣的,我就带他们去吃正宗的川菜;我带他们去陈家祠转,介绍木门上的三国演义的雕刻。说起三国,他们也是知道的。大家英语都很一般,有时候说不清楚,写写汉字居然也有些效果。听说韩国人上学时要学千字文,还是识得许多汉字的。

最后他们留下来的一个计算机研究生,编程水平一般。就是很好强。有一次需要写一个统计精灵的数据库中数据的程序,他实现出来效率非常低。ruiheng 说不能这么慢的(跑一遍要几个小时),他硬是重写了一遍(减少到几分钟),声称不能更快了。我们都没再好意思去驳他的面子。

到 10 月的时候,精灵的产品组下了个无法判断对错的决定:把用程序检测出来数据异常帐号全部删去,号称删除了 10 万玩家帐号。一时间,骂声一片。现在想来,一定有误删的,无论相信自己的程序判断的多精确,都有可能有一些例外没有考虑到。这个错误,后来我在抓大话的加速外挂时也犯过。当和用户打交道时,毕竟不能太强势了。

至此之后,精灵开始走下坡路。丁磊曾经从雷军那里借了个人来,和金山联合开发反外挂软件。其实就是一个软件加壳监控系统。检测用户有没有非法修改内存。我对这种旁门坐道的玩意不以为然,实际上也的确没有什么效果了。

那段时间和 tarcy 喝酒时也聊过这个段子,tarcy 做这行的,对此非常不屑,举了很多手段来绕开这些监视系统。从这条路去堵住外挂,绝对是条死胡同。

再过了两年,我带了三个应届毕业生,想利用精灵的图片资源,重新实现一个《精灵》。(主要目的是想让新人练练手,重现精灵的辉煌倒没怎么想过)。之后,因为公司加大了天下二的投入,把这几个人全部编入天下组。重制《精灵》的项目也就取消,就这样不了了之。


从 2001 年底开始,随着短信收入的增加,丁磊在网易的地位就逐渐稳固了。董事会没有了那么多的反对声音。虽然游戏在 2002 年的开发尚未赢利,但老丁看准了这条道。dingdang 接手游戏部后,人员开始扩张。

程序方面,先有庞鑫和安宁的加入,打算开始制作 3d 项目。原本跟庞鑫一起过来的还有徐创,但因为一些原因,没多久就离开了。徐创跟丁磊起言语冲突的那个晚上我也在场,记忆尤新。不过扫兴的事情不想重提,谁是谁非也很难公断。倒最后剩庞鑫和安宁留下。

接下来几个月,庞鑫因为感情的问题,每个月都回一次北京。他笑称,赚的钱都贡献给中国民航了。他的前女友最终跟别人结婚我是知道的,甚至我还借了他几千块凑钱买结婚大礼。庞鑫在广州干的并不快乐,他走的也很突然。谁也没告诉,毫无征兆的连着两个月没来上班。安宁说他回了趟北京后就没再来广州。甚至在广州公司附近租的房子都没有退租,屋子里留下了新买的电器。

之后,我和庞鑫失去了联系。听说他回去后自己在做手机游戏,弄了个英文网站,把游戏卖给外国人。据说这种收游戏注册费的形式,做的还挺不错,口袋挺滋润的。

安宁留了下来安心做项目。3d 项目一直没定下来做什么,技术方案也不确定。早先想用 Torque 3d ,这个引擎一度在国内很有名气,因为它只售 100 美元。我甚至看到 3d 组的人搭了一个像模像样的一个场景出来,还倒入了许多西游中的人物模型,看起来就可以做个大话的 3d 版了。其间,曾为大话西游一写过几行代码的黄东海回来看过大家一次,对公司 3d 项目如火如荼的展开感叹不已。

可毕竟 Torque 这个东西是个七拼八凑起来的玩具,真应了我反复说的那句话:便宜没好货。(免费开源的不列入其中 :) )

这里就不仔细评论 Torque 引擎的好坏了,我没亲身用过,都是道听途说。想采购引擎的朋友别来问我。ps. 我说的也是 02 年的故事,至于 Torque 今天发展成什么样子,一无所知。

接下来,曾在鹰翔工作的小蓝也来了网易。不知道 dingdang 怎么和他搭上的线,反正不是我介绍认识的。dingdang 告诉我小蓝会过来时,我还楞了一下。那天我给小蓝接风,和 dingdang 一起陪他在 36 楼楼下的蓝与白快餐店喝粥。在广州的第一年,我最喜欢这家快餐店。就在我家对面,方便实惠,味道还不错。我恨不得把这家店写入游戏的感谢名单中。

小蓝在网易也没干多久,他的离开我没去问。我想他分到 3d 项目里,可能有些漫无目标的感觉。这个项目做了太久,实际上比我们当初能想象的都久。直到今天,也就是那个被称为“天下二”的游戏项目,尚未完成。

这真是个矛盾。一个成熟的游戏,包括它的各个部件,需要大量的时间来做。而参与项目的人,往往经受不了长时间的煎熬。开发人员很容易疲惫。而快速赶出来的东西,又很难做好,总是有太多的细节缺失。

或许抄袭是条捷径,但不甘心抄袭呢?都说当局者迷,旁观者清,可又有几个当局者真的是笨蛋?

每个成功都有其偶然性,也有其必然性。不可忽略两者其一。我们需要一些坚持,守着有一定概率发生的事情真的发生。


谢绝转载

那些日子(目录)

May 12, 2008

那些日子(十三)

这几天,许多同事 popo 上跟我聊天,谈及这段时间写的这个系列。老同事一刀(从大话一开始到现在一直在写游戏服务器),那是感慨万千,还帮我纠正了一处人名的错误;同样的有许多人,督促我修正一些小地方,我都一一改过了。有人聊起来,夸我记的好清楚,如同昨天才发生的一样。

真是不敢当,我的记性其实不好。记不清的人和事远比记下来的多,尤其容易忘记别人的名字,很惭愧啊。我只是写下那些能记住,可以理清前后因果脉络的故事;更多的人和事情,由于记忆残缺,分不清时间,不知道该放到故事的哪个角落。

我记得麻雀当年陪我选手机;记得美术部的一群长发帅哥集体去剃光头;记得给乌鸦夫妻参谋买房子;甚至记得牙牙来报道的那一天情景……

记得一刀他们在公司地板上过夜;记得 Mario 半夜里陪着 mm 在办公室里看流星花园;记得我们大家常去的大排档;记得凌晨两点干完活,一起打车去石牌东吃烤蚝,萝卜还一个劲的说没有他们家乡的好……

我只是记下自己的历程,但我不只是为自己写。我也为大家写,尽可能帮一起共事过的大家留下过去快乐的点点滴滴。美好的记忆不是什么可耻的事情 :) ,可耻的只是永远停留在回忆里的人,我想我们都不是这样的人。如果再有同行的朋友读过来,尽可以在留言中留下你的故事,或是提醒我一些被我遗漏的重大事件。

对于新加入网易的同事,据说有许多人是这个系列的读者,如果我写的能让迷茫的人看到一条模糊的路,那没有什么比这更能让我高兴的了。让我觉得在繁忙的工作之后,从每个晚上划出三个小时写这些很有价值。

网易之所以是一个好公司,正是因为不断的有同样信念的人聚集在一起。那些尚且不足的地方,需要大家一同努力。

以下是今天的正文:


说起国内自主研发的第一款商业上成功运营的 MMORPG,不应该算给《大话西游2》。

2000 年底,另一款网游悄然上线,并在 2001 年初成功收费,同时在线人数一度攀升到好几万,远超过当时失败的《大话西游》,它就是天晴数码的《幻灵游侠》。

我下载了一份《幻灵游侠》的 client ,发现居然是用 C++ Builder 做的,不由自主的想起了姚晓光。他 QQ 上的名字是 npc6 ,这个网名可能更多人熟悉一些。

2000 年在北京鹰翔的时候,我经常给林广利推荐一些写程序的网友过去工作,林广利不懂程序,也时常让我帮忙和一些来应聘的程序员谈,算是面试了。姚晓光和他的哥们陈晨就是那个时候进入的鹰翔。

加上在大学最后一年辍学的小蓝,和我的一个老朋友彭乐,他们一起做《碧雪情天》。一个单机游戏,后来也制作了同名的网络版。

姚晓光喜欢用 RAD 的工具做开发,所以尤喜 BCB 。我那时维护了一个风魂的 BCB 版,但之后由于 BCB 的一些 bug 把我弄的痛苦不堪,就放弃维护了。姚晓光就是给我 report 那些 BCB 版风魂 bug 的人。

他和陈晨不久后离开鹰翔,我没有打听去了哪里。直到《幻灵游侠》上线,好奇的网上一问,他还真的在天晴。

《幻灵游侠》运营的情况我不甚了解,但是半年后我和姚重逢在林广利的办公室里聊天时。我意识到这款游戏还是很成功的。姚晓光说他后来一个月能拿到三万的月奖金,让我心里暗暗惊叹。倒不是羡慕,只是觉得,网络游戏还真的能赚钱哪。

《大话西游一》的最后那几个月,公司给大家发了一次奖金,算是犒劳辛苦了快一年的兄弟们。我领到奖金时,古越和果子都走了,micro 还在,但没多少事做。那一次,似乎有几千块(或是一万?)的奖金。我总觉得我能拿这么多,是因为做 client 的人只剩下我一个。

两者一对比,足可见成功的项目与失败的项目之差别了。

不久以后,姚晓光和彭乐去了盛大制作《神迹》,小蓝来到了网易加入 3d 组(即以后的天下二),此是后话。


当《幻灵游侠》如火如荼之时,我们还在紧张制作这《大话西游 2.0》。当时国内市场上还有几款更为火暴的游戏,其中首推《传奇》。几乎占据了大半壁江山。《石器时代》的后续产品《魔力宝贝》也崭露头角。我几乎觉得形势已定,根本没想过产品日后要在商业上超过这些,但我单纯的想把大话2.0 做好。内心里,我把大话一的失败看成自己的一种耻辱。

前一次说了不少大话2 项目的好话,现在可以谈谈一些不足了。

其实大话2 的制作时间很短,主要是在程序上重来。美术则增加了不少素材,让游戏更加完备,这些工作并行进行,跟程序不起冲突。策划方面随着月心的离开,交到了黄华的手上,对我大话2 策划方面的制作流程几乎没有关心过,只记得黄华担任了最早的主策划一职,别的就没有印象了。

今天的眼光来看,大话二的 client 程序也存在许多的问题。尤其是在我经手的一些地方,如果能再一次重新设计,会做的更好一些,这个想法促成了后来与郭伟合作为《梦幻西游》重写 client 。

client 对网络包的解析模块做的很生硬,这部分是由詹东设计的,被 kyo 抱怨了很久。因为他把解析数据流的底层接口放到了脚本层。甚至需要程序员去数字节数,一旦数错,逻辑就会出错。这种过于底层的接口暴露,放到今天来看是绝对不合格的。

服务器逻辑和客户端逻辑都需要维护一些对象和 id 的对应关系表。我们起初的一个疏忽,希望可以利用 某种逻辑一致性,省略了中间的 id 转换过程,结果导致了后期无穷尽的麻烦。客户端的对象系统中,还包括许多界面元素和一些与服务器逻辑无关的对象,为了回避和服务器对象的 id 冲突,我们使用了许多极其丑陋的方法。

不过,也有一些灵机一动的有趣想法。有一天,有个美术(刘祺?)找到我,说能不能在聊天中插入一些包子符号?我想他们老是混 mop ,受了那些 874 、253 的影响。这倒是一个新鲜玩意,我已不记得当时 msn 可不可以发表情符号聊天了,至少 qq 还没有加上,我们的 popo 也不可以。当时我立刻联想到的就是猫扑论坛里那些可爱的包子(不过我是不喜欢 mop 的那种感觉,从来没泡过)。我想了下说,让我试试吧。

在 UI 控件里增添动画图片的支持花了我一个多月的时间。没有人告诉我该怎么做,应该做成怎样。我只是凭直觉写着。我想可以更丰富一些,让玩家可以方便的改变颜色,插入表情,甚至做出一些特别的效果(文字闪烁等)。按程序员习惯,通用的转义符号是 / 。但这个被服务器程序员用来扩展 GM 指令去了。我觉得其它很多符号对程序员来说有特别含义,最终选择了 # ,这个符合我觉得顺眼。

关于插入图片,原本跟策划聊天时,有人想用传统的 :) :( 这些。我表示反对,一则实现稍微麻烦,二则美术提供了几十个符号,以后维护这些转义符太烦琐。所以我自作主张的改成了简单的 # 加数字的形式。

这里另一个小插曲足以见得我们当时的仓促:第一批表情图片只有 64 个。据写服务器 ten 的经验,在以前的 mud 中,一旦用户拥有自己发送彩色文字的权利,总有玩家恶意去模拟系统公告来行骗。所以最好的方案是使用图片来标识频道。顺理成章的 65 号到 73 号表情就被频道图片占用了。

为了不让玩家可以输入这些频道图片,kyo 用了个简单有效但野蛮的办法,在显示聊天信息时,严格过滤掉 #65 到 #73 ,这也就是为什么网易游戏中一段游戏表情符号号码断层的原因。很傻,不是么?其实完全没有必要把玩家输入的表情符号与系统内部使用的图片混杂在一起。在 UI 上实现图文混排模块时,设计的稍微好一点,就可以回避这个问题。

这段代码写的太仓促了,也由于当时偏执的追求效率,一大堆词法分析和文字排版的代码拥挤在一起,留下不少隐患。后来大话2 client 许多 bug 都出在这里。是个深刻教训。无论是写程序还是设计,在经验不足的时候,还是要三思而后行。很久很久没有人愿意重写我那堆烂程序也是意料之中的事。实际工程中,几个人做的小项目,就不要指望自己犯下的错误会有后人来擦。我自己每次去改别人的 bug 时都郁闷的想吐血,自己不愿意做的事情,想必他人也不想去碰的。可见二进制复用还是满重要的,呵呵。接口清晰,出了问题换人重写即可。

莫小瞧这一点点东西,自己做过了才知道烦。后来许多人抄袭网易的产品,抄袭聊天这一块,却总也做不好。技术门槛虽然不高,也还是有那么一丁点。等到网易泡泡的项目需要加入图文混排的聊天框时,他们组专门拨了一个程序员专职写这样一个模块,弄了好久。


大话一到了后期,client 的问题显得不那么严重了。除了古越在后期维护修正了不少 bug 这个因素外;似乎玩家也习惯了 client 出错,反正我们的 client 重启飞快,几乎没有 loading 的时间。但还有一个让人哭笑不得的原因 —— 外挂横行。

大话一的通讯管道是明文的,随便用一个截包工具拦下网络包,做一个简单的黑盒分析就能看的一清二楚。有玩家用 MFC 写了个简单的程序就可以模拟我们的游戏通讯。因为不需要显示图象,又不用处理一些复杂逻辑,所以可以做的很稳定,甚至允许同时开几个帐号同时游戏。

在和 dingdang 聊这事时,他无奈的说,现在风巢(大话的一个高等级区域)里几乎已经没有活人了。机器人玩家对游戏的危害性,从 mud 时代开始,大家就深有体会。我想,这个问题一定要想办法解决。

当时最火暴的游戏之一《金庸群侠传》也深受外挂困扰,一度外挂可以做到官方 client 做不到的事情,比如可以远距离和 npc 对话。我想那是因为服务器未做限制的缘故。这些距离校验以往都是在 client 做的,而非法 client 可以轻易直达目的。当时业内传闻,为《金庸群侠传》写外挂的人都有百万级的收入了,真是令人乍舌。

dingdang 认为外挂问题很难解决,毕竟 client 在玩家手上,理论上无法阻止玩家分析通讯协议,并制作模拟程序。而 server 不可能分辨出究竟网络包是由怎样的程序发出。我们能做的只是把关键运算全部由服务器校验而已,让玩家做不出违反规则的事情。

我说,至少我们把通讯管道加密吧,别让人家那么容易的分析出来。要分析也得让他们分析我们的 client 程序本身(即做白盒分析),而不能仅仅靠截取网络包就够了(只做黑盒分析)。dingdang 表示通讯加密可能会加大服务器的负担,目前的硬件不一定承担的起。况且开发日程比较紧,新增加一个模块需要额外的测试,我们承担不起降低服务器稳定性的风险。离大话新版内测上线的日子不到一周了,从项目管理者的角度看,dingdang 是对的。我了解他,dingdang 和 kyo 都是在技术上很保守的人,这其实是一大优点,我们用一个褒义词来形容,那就是稳重。这份稳重保证了大话二程序的稳定,以及它的持久发展。但也可能让我们失去了一些东西,历史不能假设,谁又说的清呢?

我是一个技术上很激进的人,至少比现在的我激进多了。当时我认定,做通讯加密是至关重要的,而且得不惜一切代价在大话的新 client 对外发布的第一版之前完成。一旦流失了一个可以工作在明文环境下的 client ,都可能造成损失。加密和解密,外挂和反外挂,永远不会出现最强的矛和盾。这门技术总是游历于正统软件技术之外,属于旁门左道。我们争取的并不是一个完美的解决方案,只是延长时间而已。在过去的年代,加密技术延长的是软件被破解的时间,现在反外挂也只是拖延一个可用的外挂被制作出来而已。流出一个不设防的程序,无疑会大大减少外挂制作者的精力消耗了。

应用密码学》这本书,在北京时就开始读了,一直觉得很有趣。到这个时候我已经读过两遍。我想,设计一个即简单,运行速度快,又少占内存的加密算法并不难。问题只在于留给我去实现的时间不多,还要保留一些时间说服 dingdang 整合进服务器里去。

大话西游 2.0 ClosedBeta 是在 2002 年 5 月 1 日对外开放的。我在一个古老的留言本上记录下了这一时刻。

看到当时自己的留言:


今天熬夜上传大话西游2.0 ClosedBeta 版中.... 明天就有人可以玩到我们这个新游戏了. 自己感觉马马乎乎. 还过得去. 总算搞完了啊.

(90) 云风 | 主页 | (2002-04-30 05:49:40)


仿佛回到了那一天。

我的加解密模块是两天前完成的,同时给 dingdang 讲解分析了 cpu 消耗,以及额外的内存占用情况。接口也设计的很简单。我想他很容易就被说服了,在最后两天全力把这些加入服务器。

上面这条留言是 4 月 30 日早上凌晨提交的,记得我那一夜我没有睡。同上一次大话西游一发布前夜一样,更多的是在打杂。检查各种数据是否完备。为了让压缩包更小一些。这次甚至又修改了动画的格式。

一个是在动画中插入控制信息,让动画的停顿可以直接用控制信息描述出来,而不用浪费资源去重复储存相同的帧。

另一点是将大面积的魔法光效做抽线处理,这样数据量就只有原来的二分之一。在渲染时,再把这些抽掉的线条用程序实时填补上。

做这些不仅是为了玩家的硬盘空间,减少下载的 client 的体积,更重要的还是想节省内存。以及提高运行时资料的加载速度。

这些工作也是在最后那几天做的。本以为大话二已足够顺利不需要赶在发行前熬夜了,没想到事都临头还是逃不过。不过已经比之前好的多了。至少我们是在 5 月 1 日的前一晚熬夜,而不是当晚。

其实一般来说,我很少通宵通宵不睡觉,那段时间许多同事都比我辛苦,我从没有在公司打过地铺。晚上不睡觉时,比谁都精神。只是有时候情绪不太好,大家也知道缺少睡眠容易发怒,所以在我提高自己的音量时,都很能容忍。我还记得那晚,交代给黄华一些临时写的一些工具,让他按我指定的次序转换图象资源文件,而他不小心做错,不得不忍受我在旁边大声嚷嚷,呵呵,还真是情绪失控呀 :) 。事后想想,我的责任更大一些。如果写那些工具时,多加一些检查,就不会有人无谓的犯错了。不过这个事情影响还是挺大,最后大话二的资源里有好些地方出了纰漏,至少到一年之后才完全找清楚修改干净。

等到五月一日前的那个晚上,dingdang 终于把服务器那边的通讯加密全部搞定。我终于松了一口气,居然准时完成了任务。

那晚,tarcy 老兄打电话让我出去喝酒,我一口答应,心情非常愉快。


ps. 关于外挂的问题,前几年我写过一个帖子。应该还能 google 到。今天我对这些没什么兴趣,倒是有不少同事再接再厉的做了许多。所以这里就不详细描述了。


谢绝转载

那些日子(目录)

May 11, 2008

那些日子(十二)

dingdang 上任不久,我们开车去珠三角转了一圈。拜访深圳,珠海的许多公司。有点新公司成立、四处拜山头的意思。

丁磊和雷军私交不错,据说还经常私设赌局,赌各自产品能做到多少人在线。嗯,有些遥远的故事,记忆模糊,还是不加详述。我们一行人自然也去了金山。当时他们在做《天王本生》,买的 LithTech 的 3d engine 。赵青是开发团队的 leader 。我和赵青颇有些交情。

事情源于 1998 年,一帮梦想在互联网上联合开发 RPG 的小子,成天泡在 irc 频道里 YY (也不完全是,我们还真做了不少东西)。其中,我是唯一的一名程序兼职小组网站制作。我们给开发小组定了个名字“风魂”。后来小组解散,为了纪念这段历史,我把这个名字延用在了后来那个引擎上。

今天为写这篇,还专门翻出了当年我们的策划 Gary 做的故事背景社定。更完整的版本在 irc 的聊天记录中,早已遗失。这个 Gary 半年后加盟珠海金山,担任《剑侠情缘2》的主策划。

99 年的暑假,我去珠海拜访 Gary ,他介绍了剑侠情缘2 的程序王炜、赵青,以及著名游戏音乐人罗晓音与我认识。还记得那天黄昏,我们几个人晚饭后步行来到海边,坐在草地上遥望对面的澳门。大家交流技术经验,畅谈着国产游戏的希望。王炜是个仙剑迷,把仙剑翻来覆去的研究了个透彻,还为此制作了专题个人网站;赵青则回忆着红警如何吸引着他进入游戏这一行。

2001 年金山的食堂里,很多朋友围坐在一起。Gary 和王炜已经离开,赵青平时话不多,但在老朋友面前依然健谈。还有许多新面孔。

网易和金山的这种友好关系一直延续了下去,之后,金山的同行也曾经率领大部队来广州回访交流经验。我们的程序员也曾有过合作(精灵的反外挂程序是由金山一名程序员常驻广州完成的)。再之后,赵青领着一队人,过来网易组建了新的方舟工作室,似乎也没太损坏公司之间的友谊。我们还保持着互访的传统,几年后,我个人就几次拜访过已迁往成都的罗晓音。

再往后,网游市场产品竞争激烈,对于一些影响到玩家群的公众事件的内幕,虽也有些耳闻。但那些就是市场营销方面的事情了,无损程序员之间的友谊,不提也罢。

在深圳,有很多游戏开发公司,如正在制作《百花物语》的联志软件,还有完成了《最初幻想》的万智源。在万智源所在的公寓前,一个大胖子迎接的我们,居然是陈重,那个曾在金字塔有过一面之缘的小子。我们寒碜了几句,感叹圈子之小。

可能是因为网易做网游项目时间长了,居然自然而然的泛起这种念头:怎么还有这么多家游戏公司在做单机游戏呀。虽然我自己不喜欢玩网游,也喜欢单机游戏能继续红火。可看到这么多公司依旧为单机游戏投入资金和人力,不免奇怪。我对自己这种思想的转变也颇有感慨,看来,网游取代单机游戏的市场已不可逆转了。

最后去的是在深圳的 gameone 。这是一家港资公司,老板施仁毅。虽然 gameone 的员工对老板颇有些牢骚,但我个人还是挺喜欢这个人。认识他也满长时间的,据说他早年跟黄易是同事,有些交情。我读大学时喜欢看黄易的小说,他信势旦旦的说去把《大唐双龙传》要过来给我做 RPG 的剧本 :D ,后来又颇为无奈的告诉我,就晚了两天,游戏改编权被智冠抢走了。之后,他谈成了古龙小说的游戏改编权,我本想做这个《古龙群侠传》的程序,应该是考虑到当时我一个在校学生,全职做主程不太靠谱,最终是交给金字塔去做的。

99 年第一次见风老总(施仁毅在 icq 上的网名)的时候,他请我吃饭,口若悬河的讲述他在《万王之王》中的势力。并一再强调网络游戏的美好前景。想必后来的《古龙群侠传 online》也是蓄谋已久的了。

那天在深圳的 gameone 办公室,风老总不在,不过我见到了另一个老朋友郭伟。

郭伟,我们都管他叫郭老。其实郭老并不老,也就比我高两届。最早也是业余做游戏的,大家通过 email 做过一些交流。早年网上流传过他们业余小组做的一个游戏 demo ,名字我不太记得了。是一个斜 45 度视角的 2d 动作游戏。曾经他找过金字塔投资继续开发,我在大众软件封底还见过这款游戏的小广告。

见到郭老的时候,他给我演示了《古龙群侠传》,原来一直是他在做这款游戏的程序。效果很好,颇有暗黑破坏神的味道。我们很兴奋的讨论了一下关于光影效果的优化等。之后,dingdang 私下跟他谈了很久,看起来早有接触,我想 dingdang 是想挖这个人。

一年之后,郭老坐到了我的旁边。一起工作了三年。我们配合非常默契,他就是《梦幻西游》客户端的主程。06 年的时候,《梦幻西游》的主策划徐波带着一拨人离开,接受了金山的投资。我听到这个消息后,立刻给 dingdang 打了电话,第一句就是问,“郭老走了没有?”,dingdang 说没有,然后我长舒一口气。我知道从 05 年初开始,郭老做的并不太开心,他话语很少,可能就数我们工作上聊的多。他有许多想法,但是无从施展。更多时候只能跟我聊聊。给我看看他写的一些东西,包括他用 python 做的游戏服务器。或许那时我最能理解他写的那些程序。我跟 dingdang 说,不如让郭老跟我一起干,可是那时他已经结婚,不会离开广州。

最终他还是离开了网易。我问 dingdang ,知道郭老去哪了吗?是不是去徐波那里了。dingdang 说,应该没有吧,他走的时候说不去的。公司里很多人很关心徐波他们离开后做的新产品,担心对梦幻西游造成竞争。我对很多同事说过,只要郭老不帮徐波写程序,我对他们新产品能否顺利完成表示怀疑。

郭伟后来还是跟徐波一起干了,现在他们的《梦想世界》的运营情况我不甚了解,这些已经是这两年的事情,另一段故事。


该回到我们的故事主线了。时间已经迈入了 2002 年,对网易至关重要的一年。

网易找到了一根救命稻草,那就是短信业务。我想,公司的发展主线是一脉相承的,而不是外界评论中,丁磊无意中拣到了宝。按我的理解,我想丁一开始就不太相信单纯靠在网站上打广告就能维持一个大公司的全部开支并赚到钱。做公司只做概念,光烧钱而无进帐,是不可能长远发展的。这个道理如此浅显,想必每个人都明白。

国内的网上支付体系那个时候很不健全,大多数网民还没有在网上消费的习惯。如何从直接用户那里收到钱,是经营者们日夜考虑的事情。网络游戏是第一步,原本希望借此推广网易一卡通,以此进一步的促进网民在网站上的消费。没想到游戏业务一开始很不顺利,大话西游过了头几天的 5000 人同时在线的高峰期后,停留在 3000 人的水平,半死不活了。

手机短信无疑是一种小额代收费的好途径。我想丁是瞅准了这一点,才全力进军短信业务的。并成立了无线事业部。

对于短信的赢利,丁显得很兴奋。有一次朋友一起喝酒时,丁拿着我的手机给他的朋友演示怎么订阅网易的天气预报,喜悦之情溢于言表。

以前在北京做手机平台开发时的一个合伙人去了中移动。那段时间他来广州找我聊天。我抱怨过我们的大话西游原来可以通过手机做小额冲值,没做多久就被取消了。他给我解释说,其实移动相当不愿意充当帮人收费这个角色。移动希望在无线网络上有更多的内容,让用户去消费;而仅仅只做代收费,没有什么利润,且要承担许多资金风险。这种傻事是不会干的。

我想这个道理,丁磊更明白。所以网易应该没有把这项业务发展壮大的远期计划。毕竟是为人做嫁衣,就算做好了能赚到钱,也被移动分去了一半;做坏了,风险是自己的。只是,钱来的很快,我想是超预期的,公司还是加大了无线事业部的投入,一直做下去,直到现在。

2002 一开年,NTES 在 nasdaq 上复牌。那天晚上,丁兴奋的请我去喝酒。等到美国股市开盘,迫不及待的用手机查了下,高兴的宣布,我们公司的股价又回到了 1 美圆以上。“看吧,我们又活过来了。第一天就比 sina sohu 的价格都高呢”。


我时常跟 dingdang 讨论游戏,比如研究游戏里玩家盘店的情况。我觉得系统做的不好,完全表达不出虚拟的经济系统。dingdang 说玩法是继承于西游记的 mud ,其实那里面玩家盘店挺有趣的。不过 mud 毕竟同时在线玩家少,跟现在的网游决然不同。

由于制作 client 的缘故,我也试玩了正在重制的大话西游,始终找不到 RPG 的感觉。无论是战斗还是日常闲逛。向 dingdang 抱怨这些,我说,反正我现在闲着,如果日后做第二版,让我试试重新做游戏设计吧。dingdang 挺高兴的答应了。然后我开始写策划案。

大话西游虽然玩的人不多,但是还是配备了相当数量的客服人员。丁磊希望可以在服务方面做好,弥补开发上的失误。首批招聘来的客服都是游戏玩家,他们以三班倒的方式在游戏里 7*24 小时的值班,并真心喜欢这个我眼中问题多多的游戏。

因为我在筹备写游戏的策划案,很可能还是以大话西游这个品牌推出,所以我跟这些忠实的游戏玩家交流。其中有一个人让我很感兴趣,他时常以徐宥箴为笔名在玩家论坛跟玩家辩论发帖,公司里大家直呼他的真名徐波或是更亲切一点叫他老徐。因为我在公司比较习惯叫他徐波,下面就这么称呼吧。

显然徐波玩过很多游戏,我也是。我们一起怀念 sfc 上的机器人大战,四狂神传说,浪漫沙加,风水回廊记等等许多。我那时对和我一样对单机游戏玩的多而杂的人挺感兴趣,因为可以交流的东西比较多。比较而言,网易当时的程序员喜欢玩游戏的人比例要少许多,许多人玩的话也是固定几款。还有一些人,谈起来都是 mud 长 mud 短,可我偏偏就不玩 mud 。

几天后,我找到 dingdang 说,徐波这个人对游戏挺有想法,不如不要让徐波做 GM 了,让他跟我一起做新游戏的策划吧。dingdang 说他也对这个人挺有好感,就按我的意思办吧。

按我的要求,徐波先写了一份简单的战斗系统设定稿让我看看。这两天,我从一个旧的 U 盘上翻出这两份旧文档。一份 txt 档的草稿的创建时间是 2002 年 1 月 8 日,另一份 word 档正式一点,2002 年 1 月 9 日。

还有一份我自己当年写的策划案草稿,最后一次修订时间,2002 年 1 月 15 日。


dingdang 让我主持一次策划会议,把我跟他聊过的一些想法讲给大家听。并且听一下策划的意见。1 月中旬的那次会议,到了许多策划,我们在大会议室里讨论。我没有做 ppt ,只用了块白板。前天夏的策划,也是大话西游的主策月心,依旧抱着他最喜爱的紫砂茶壶在下面静静的听,时不时泯一口茶。我对他的记忆不多,更多的是他离开公司后留下的几本策划案的打印稿。封面上敲着他的标志戳——“机密”,呵呵。

还有黄华(大话2 开始的主策,以及日后游戏市场部的负责人),狂狮(后来天下二的策划之一),等等。徐波也在场。

会上谈了许多我对网络游戏的看法,主要是关于经济系统的。我觉得网络游戏既然是一个虚拟社会,必然存在经济系统。这个应该是我们设计的重点。然后说了一些我的观点,比如应该想办法紧缩虚拟货币的供应等等。许多东西放到今天是再普通不过的话题了,当时我想也有许多同事想到这些。这些应该是在制作网游一段日子后,制作人自然而然的想法。

我提了许多关于控制虚拟经济系统的具体观点,现在已经记不清了。记得好多人提出了反对意见,到今天几乎都没留下印象,但徐波的发言我是记的清的。因为只有他指出了我的一处逻辑错误。虽然无关整体框架,可印象深刻。因为徐波的敏锐,让我觉得这是个聪明人,而且也在考虑我正在考虑的这些问题。


做策划的那段小插曲没过多久就结束了。每天依旧有很多程序问题围绕在我的身边。最终我放弃了自己来写策划案的想法(或许根本就没有开始过?)。做一个自己设计的网游,一搁就是好几年。

之后,我便全力投入到大话西游 2.0 的 client 开发中。随着开发工作顺利的开展,游戏部也逐渐补充进新的血液,有美术,有策划,也有程序。头一年,我在 36 楼参加了一次应届毕业生招聘的活动,那一次我们是分组进行的。我负责的组里有两个人,让我最后在他们的简历上化了圈。一个是曾强,一个是许扬。

当这两人毕业正式入职时,进入了游戏部。小强被分派到《精灵》的筹备工作中去,打理那些服务器,再之后转入天下二。许扬则划归大话组,配合 kyo 做界面方面的开发。

大话西游二项目的早期就是这样,因为很顺利,异乎寻常的顺利,所以也显得平淡。

多年之后,个人总结大话西游二的成功,从我参于部分的角度,归纳为这么几点:

  1. 有完整的美术资源。这些从第一版遗留下来,不需改动就可以使用。这避免了美术方面的工作拖累程序的开发进度。

  2. 程序底层稳定,关键模块都已经完成,并通过了前一版的公众检验。少数底层的 bug ,经过大量的用户被动测试,都找了出来。我们在编写上层代码的时候非常放心。几乎不会出现 bug 出现位置难以判定的情况。

  3. 事先有技术上的合理规划,有了充分的准备才开始动手。并且期望值不高,有明确的目标:复制原有的功能。

  4. 有更强的技术力量支持。

  5. 漫长的测试期,并没有在制作基本完成后匆匆上市。

待到下次继续谈梦幻西游,我会说,它的成功是大话西游二的翻版,以上诸点都成立,且做的更加好。


谢绝转载

那些日子(目录)

May 10, 2008

那些日子(十一)

《大话西游》一边运营着,大家改着 bug ;另一边,2.0 版开始筹备了。

还记得深秋的那个夜里,已经很晚了。丁磊一通电话问我睡了没有,没睡的话去淘金路上一间小茶馆喝茶。聊天不去酒吧,不符合老丁的风格嘛。我依着短信上的提示,找到了那家别致的小店。包间里就两个人,丁磊和 dingdang 。dingdang 从不泡酒吧,他不喜欢喝酒,这我是知道的。

后来聊了什么完全不记得,我只是知道,以后的工作由 dingdang 来主持了。这次长谈,颇有些战事不利、临阵易帅的味道。

之后,渐渐的,micro 没有什么事情可以做了。几年前,他就在办移民加拿大的事情,需要定期坐移民监。没多久,micro 回了加拿大。dingdang 坐进了那间办公室。不过他的笔记本通常放在外面的老地方,我们还是很晚一起回家。

dingdang 工作很勤奋,也依旧在工作间隙褒着电话粥。桌子上放着 Nokia 5110 的手机,很古老的型号,上大学时我用过。打久了电池很热,但想必没有心里头热。第二年的某一天,有人提醒我看看对面 dingdang 敲键盘的手,赫然多了一枚戒指。

没有见他请婚假,没有通知同事,没有办酒席,没有度蜜月。只是接下来一个周末,我在家附近的世贸楼下吃面条。丁磊的女朋友瞅见了我,给我打了个电话,说他们正在楼上日本料理呢。我打包了面条上楼。只见四人两对,相谈正欢。那天我认识了 dingdang 的妻子。从谈吐中就能识得,真是天造地设的一对。

dingdang 上任后,寻了三个人来。一个是他的堂弟詹东,据说时下在北京网易工作,也是写程序的。另两个从 36 楼挑选的两名程序员,都是网易技术部最优秀的程序员之一。kyo 和 ruiheng 。

kyo 和我同届,暨南大学学物理的,未毕业便在网易兼职,做公司最早的产品:邮件系统;ruiheng 高我一届,华南理工计算机科班毕业,稍晚一些入职网易,他早期的产品对网易也颇为重要:网易社区论坛。此二人,完成大话二之后,kyo 转去做天下的主程;ruiheng 则任技术部经理。

我们四人开始重新制作大话西游的新版 client ,谓之曰:2.0 ,项目代号 xy2 。


在 ruiheng 的推动下,我们从 vss 移到 cvs 下工作,不久之后又转到 svn 。这次,我们每人每天都要求 update 到最新的 client 代码,保持和主干同步。

服务器那边听说也在重构,我不清楚是否犹如 client 这样彻底。但新的版本是由 dingdang 和 ten 一起主持的,并加入了新的人员,比如 陈 。大话的服务器开发历程我不了解,不便多说,暂且搁在这里好了。

继续谈新版的 Client 。

UI 模块的问题,我已经在最后那两个月完全解决了。UI 的底层是个非常繁杂的东西,要求设计人有足够多的经验才能把接口设计的好。做了这么些年软件,我觉得最复杂的东西莫过于此了。稍有不甚,就会把接口弄的污秽不堪。就连 Windows 的最为出色的界面系统,不也是发展了 20 多年才成现在这个样子,依旧被开发人员所诟病。虽然那个时候,我的想法也不成熟,可也经过一年多的思考沉淀,比大话一立项初期有把握的多了。

这次是由詹东取代古越的位置做逻辑那块东西,我依然写底层。只是这次范围更广一些,不仅要实现图象和声音这些的基本驱动(其实在大话一里已经很稳定了,延续下来用即可),还要负责 UI ,以及游戏中的逻辑对象的管理,消息分发等。

大家不约而同的想法是,新版的 client 一定要嵌入一个脚本语言,以应付连绵不绝的后期需求变化,以及用于描述多变的界面。

我首先想到的是自己实现一个解释型 C 语言,这个在北京时就着手做过。但是考虑到时间不允许,也就放弃了。当时也想过使用 CH 一个解释型的 C ,大家觉得不够好,作罢。

甚至我考虑过 java ,但网上尚没有成熟开源的 java VM ,我甚至想自己实现一个。这个想法来至于前几年一个叫做《吸血鬼》的 3d 游戏,如果你解开它的数据包,就会发现大量的 java class 文件。

还有 javascript ,因为被 IE 的事情弄出些恐惧症来,大家也不支持。

kyo 给我推荐了 python ,说是跟 java 齐名的语言。还有 ruby 等等。那时我们对这些日后名声大振的动态语言,都没有什么特别的感觉。一视同仁的去评估。因为嵌入式脚本,在国内同行中没有什么先例可供参考(早期大多数开发团队都是自己开发脚本语言),只能是靠自己的感觉来办。

最后大家一起看中了最为小巧易于嵌入的 lua 。网上比较多 lua 的相关工具,不过是针对 lua 3.2 的,当时 lua 4.0 发布不久,我们最终决定选用最新的版本,不去理会配套的第三方工具。

詹东开始研究 lua 的 C API ,以及怎样嵌入,这个工作很顺利,得益于 lua 的简洁。kyo 琢磨如何把 lua 和我写的底层桥接起来。当他最终用纯粹的 lua 代码驱动起第一个游戏内的界面对话框,我们都很高兴。ruiheng 则作力于 lua 的控制台调试器,他是 unix 背景的程序员,做出来的那个东西更像 gdb ,挺好用。哦,我做了个控制台的模块,支持彩色的信息输出。前一版的惨痛经历告诉我,一定要有一个好用的调试控制台。

说起 bug ,《大话西游一》的教训是非常惨痛的。最让我心痛的是,明明知道 bug 在那里,就是不知道该怎么改。往往改动一处,会引发新的问题。我想找到一种方法可以杜绝这种现象。所以在新版本里,引入了一种新的机制来解决。那就是给引擎加入录象功能。

所谓录象,就是让引擎记录下所有输入的消息以及发生的时刻。由于游戏 client 可以严格按帧来区分时序,时刻即帧序。所谓输入,无外乎网络包输入和键盘鼠标输入。这些只需要按次序写入记录文件即可。当有了这些数据,就可以无限制的回放给引擎。每次操作 client 玩上一段时间的游戏,只产生极少量的输入消息,而回放即可再现第一次游戏时的种种(甚至可以加快速度播放,只需要关闭和逻辑无关的显示模块即可)。这个功能是纯粹实在在引擎底层的,更上层建筑无关,顾而能为开发人员方便的使用。

如果不懂技术的读者看到这里还不明白,请联想暴雪游戏中的对战录象,星际和魔兽都支持的。

ps. 这一点是我以后做项目必须要求的基础设施。不支持录象功能的引擎是不合格的。我曾几次三番的要求服务器也加入录象功能(这比 client 更简单)但都没能如愿,直到我自己开发服务器。也有 3d 项目抱怨 3d engine 的复杂度而不能加入录象,其实没有什么道理。录象仅仅是记录操作,能不能加进去只跟 engine 处理外部输入的设计有关,跟图象呈现方式没有联系。

简单表述录象对调试的重要性,可以这样来解说。

即使我们拥有交互式单步跟踪的调试手段,当错误发生时,我们也只能向后运行程序,观察计算机内部的状态变化。而对之前发生的事情,仅仅只得一个内存快照而已。这是静态的信息,而变化的过程已经丢失。当然,内存快照已然非常有价值。比如在 unix 系统上,一个进程挂掉,可以生成一个内存快照文件,被称之为 core dump 。gdb 这种调试工具则可以分析 core dump ,还原当时的现场,程序员可以根据现场情况进行分析。

录象的威力则更进一步,不仅可以轻易拿到错误现场的快照(只需要重新回放一次),还可以让时光倒流,让你看到之前发生了什么。因为只要设计合理,每次回放,内存里任何一个对象的地址空间都不会有变化。如果我们拿不准出错时的问题是由什么前导因素造成,只需要重新回放一次在更早的时机中断下来观察即可。

有了这么一样利器,我们遇到的每个 bug 几乎都可以在当天找到根源,并修正。当 bug 是单个的出现,并迅速一个个的解决时。比同时面临多个 bug 要轻松的多。每次解决问题也都是从根源入手,而不是简单的使用 walk around 的方案。每解决一个 bug 当然不会引发新的问题了。

大话西游 2.0 的 client 非常稳定,以知的 bug 都已排除。那些日子,每天下班时我都可以这样骄傲的宣布。


那几个月,工作有条不紊,大家意气风发。我们甚至每天可以乘坐公交车回家。kyo 没结婚前住的很远,和我有一小段同路,当他转车赶上末班地铁,基本上我已到家。而他的归途一半都没走完呢。我们不再需要加班到太晚。

詹东常住北京,只是需要交流的时候才来广州住几天。大家分工明确,甚至不需要每天在一起写程序。(我想,异地合作也是我们抛弃 vss 的一大原因)所以,初期的设计比后期的实现更为重要。设计的好了,甚至缺少沟通都能把项目做好,反之,再多人再好的沟通也没有用。

甚至我都在想,这不三个月就把活干完了吗?赶快把大话换下来吧。但是 dingdang 说,不急,还不到时候。


渐渐的,开始有旧人陆续离开,先是古越接着 micro 而去,然后是果子。

古越的离开有些无奈,我没有问,因为新的项目已经没有让他参于,我想离开是必然的吧。(后来回头看,他有网易不少股票,公司股价涨到那么高,我想即使从收益上权衡,在网易干的一年也值了。可能让他遗憾的是,没有一起参与大话的起死回生吧)

果子辞职,还是有些舍不得的。他是个挺有想法的人,动手能力也很强。当时说想回家休息一下。等到再来看望我们的时候,手上居然拿着车工教材。我是学机械的,很好奇他怎么干这个起来了。他说他买了个小车床,放在家里做些东西玩。果子是个军事迷,喜欢仿真枪械。当时下载了一张德国二战时期的手枪图纸,在家自己摆弄。那天,他还给我欣赏了他自己车的枪管,很精细,比我的手艺强多了 :D 。

时不时的总能收到一些他的消息,先是说他买了部 polo ,整天大街小巷的乱窜,一天能在市区开 400 公里,堪比出租车司机;而后说是开车时用笔记本不方便,自己设计制作了一个笔记本支架,固定在坐驾里。听起来过的挺开心。

几年后,我介绍大学室友去他和古越一起开的经营短信业务的公司里写程序,果子请我吃过一顿饭,之后就联系不多了。

我不喜欢照相,相片很少。不过找到一张那段日子留下来的。好象是果子买了个摄像头,我拿过去试试拍的一张。纪念一下:


谢绝转载

那些日子(目录)

May 09, 2008

那些日子(十)

2001 年的国内网游市场上涌现了不少的游戏,有些昙花一现,现在估计都没什么人记得了,例如我依稀记得的一款三国题材的游戏,运营没持续多长时间。还有一些一度风靡全国,拥有不少玩家,如《千年》、《红月》、《龙族》等。

《传奇》就是在这个背景下横空出世的。

陈大年是我大学时期结交的网友,跟我一般年纪,我们时常在 icq 上聊天。在我还在读书的时候,他已经辍学闯荡江湖了。他也是个程序员,似乎写 delphi 的,我早年也玩这个。我们那时候共同的爱好是想做游戏。在我还没毕业的时候,他给我看过他的公司做的网站,记得叫归谷,主推一只可爱的漫画狗。小狗叫 stammy 还是 stame 我是记不太清了,投资方有中华网的背景。

大年告诉我他们转做网游的时候,我丝毫不奇怪,游戏这么火,做网络的不做游戏才是奇怪呢。(我想,即使在那个所谓网游起步的时候,看的到网络游戏有赚钱潜力的公司根本算不上有什么独到的眼光,看不出来的没眼光才是)他和他哥哥一起做的公司,据说去韩国找了个小公司谈了个游戏,这个游戏就叫做《传奇》。

网易的《大话西游》定在了 10 月底上市(一开始大家都没有公测,也就是给大家免费试玩,这个概念),《传奇》也是这个日子左右,稍早一些。

我没有想到《传奇》会在商业上如此的成功,正如陈大年一开始也不会想到《大话西游》的未来。我把《传奇》看作是跟《千年》、《红月》这般的韩国游戏一样,一个普通的产品,没有什么特别之处。

有如网易找到了智冠,盛大也找了上海的育碧做合作发行商。一切都是按惯例循规蹈矩的进行着。《大话西游》正式发行的前几天,大年在 icq 上几次兴奋的告诉我,他们的游戏达到了多少多少人在线了。当然也试探我们的情况,我没有怎么说,因为实在是不好意思讲。


《大话西游》发布前,在广州的天河电脑城前办了一个热闹的活动。星爷过来捧场,智冠的老总致辞,好象还有一个广东什么地方的一个牙膏厂老板,不知怎么也混在里面,有些商业上的联系吧。星爷的到来,牙膏厂的老板就被大家起哄哄走了,每人愿意听他讲话,弄了个没趣。不过更没趣的时,不知道公司什么地方没有打点好,活动搞了一半,就有人(城管?)过来拆台。

就是这样,一切就在匆匆忙忙中拉开了帷幕。

正式上线前的那天,几乎所有开发人员都一夜未眠。尤其是程序,还在临时修补着 bug 。玩家在论坛上唾骂着可恶的 cd-key 制度。不管有没有 cd-key 的人都在拼命的下载更新包。当时还没有利用 BT 技术分担带宽。公司几乎把所有的带宽都增援过来用了。

client 最后还有许多已知 bug 没有解决。dingdang 说留到最后吧,到开服务器前再让大家下载最新的 client 执行文件。就这样,已经更新完补丁的玩家,甚至连 client 都不能启动。

拖延了几个小时后,古越说,好了。client 主程序放出。只隔了几分钟,便有玩家涌入。

ten 已经累的不行了,他写了一个监控脚本,当监视到服务器挂掉后,会自动重启服务器。然后就回家睡觉去了,之后是 dingdang ,慢慢的,一个个都走了。我是比较能熬的,不知为啥,选择留在了公司。其实也没太多事情好做,只是刷刷论坛。

没过多久,玩家就集体掉线了。服务器崩溃。不久,自动重启。又过了大约 10 分钟,再次崩溃。就这样一直循环下去。服务器这边的负责人全都回家了,完全无能为力。我实在看不下去了,也只好打车回家做鸵鸟。


接下来的几天,无论是 client 还是 server 的程序都不停的加班。问题一个个的解决,又一个个的蹦出新 bug 来。服务器稍稍稳定一点后,客户端又不断的报错。其中跟我有关的,是一个声音播放模块的问题,又是多线程惹的祸。

我们的这第一版 client ,居然使用了多达 4 条线程,地图处理、逻辑处理、网络处理、声音处理,大家又没有多少多线程编程的经验,一不小心就犯错误。好在底层的问题查起来容易,解决起来也快。可逻辑层面上的东西就没那么容易搞定了,古越压力很大,总看他在那里调程序,仿佛永远也做不完。

另外,用户的浏览器 IE 的版本千奇百怪,小版本的区别很多。不知道为什么,我们的 UI (借助 IE 实现的那个)在不同的机器上就是表现不一致,总会蹦出一些脚本出错的对话框。多年之后,我再回忆,可能也不完全是 IE 的毛病,跟我们写的不规范和用的不规范有关。

浏览器出错倒也不是开发期没测试出来,QC 人员很耐心的安装了各种版本的 windows 系统测试机,只是我们自己测试出错的概率要小很多。可是,一旦玩家量巨大,小概率事件就频频发生了。这种问题又实在不好重现,基本上是不了了之。

记得我还接过一个客服转过来的电话,说是一个玩家不好对付,让我帮着解释。那个略带上海口音的男性玩家,死命缠着我让我解释为什么游戏不能在他的机器上正常运行,反复申明他花了钱购买的正版游戏,要求我负责任。我想我很无奈。

丁磊也需要一个解释。对于不写程序的他,太多的 bug 导致了程序不稳定这个理由很难说服他。后来我想了个简洁的说法统一口径:IE 兼容性问题,导致了我们 client 的在不同的机器上容易出错。其实我们做程序的都明白这是个推卸责任的说法。只是太多的开发人员已经背负了很大的压力,我想选择 IE 做 UI 的这套方案是我提出来的,把责任推到 IE 上,我能帮大家多承担一些骂名。

结果令人哭笑不得的是,老丁倒是很轻易的接受了这个说法,就没怎么责怪开发团队,也没有怪我这个“罪魁祸首”。只是接下来的这么多年,时不时的拿这个段子奚落我一下:“看吧,别看我不懂程序,当时你提出来用 IE 的时候我就觉得不好,不过还是随你们去做了。让你犯过错才知道改”。(._.!)


并非我事后想推卸责任,因为无此必要。大话二最后只用了半年重生,追究大话一的责任都是没有意义的事情了。在后面的故事里,我们会看到,大话一花的这半年多的开发时间,开发人员投入的精力 80% 以上都被复用起来,如果我们把大话二的上线当做项目正式的完成,距离大话一开工前后也不过一年时间。真的是没什么遗憾了。

今天写这些故事,除了给自己做一个总结外,也是想让更多的开发人员可以借鉴到其中的经验和教训。对于“嵌入 IE ”这个貌似重大的技术决策失误,如果只看到表面,就和我写这些的初衷南辕北辙了。这里有必要展开来写一下。

如同前面在第五篇中所写的那样,选择嵌入 IE 做游戏的 UI 呈现,仅仅是从节省人力着想。因为我们当时只有 3 人做 client 开发,后来大话 2 使用的底层的 UI 模块并没有开始写。如果 4 月里动手写 UI 模块,只会拖累整体的项目进展。而选择使用 IE ,可以额外的增加人手,不至于影响已有的 3 人的开发工作。

复杂度隔离,是我这么多年做项目中悟出的最重要的一个道理。当多人合作开发时,应该尽量隔离不同的人之间的工作,每个人都专心做自己的一块,各人的工作中的失误,都不至于影响到其他人的工作,这样软件项目才能顺利开展下去。如果当初不做此决策,可能到现实中大话 2 开发完毕,大话一都完成不了。由于项目开发时间过长,本就不稳定的军心会更加涣散。所以这个技术决策,更多的考虑的就不是技术上的因素而下的。

从结果上看,大话的 client bug 非常严重,导致程序时常崩溃的,是本身程序的不稳定,而不是 UI 系统。UI 仅仅是弹出类似“脚本运行时错误”这样的讨厌的对话框而已,玩家只是部分功能不能正常使用,而不会完全不能玩游戏。而且理论上还可以指导玩家安装最新版的 IE 来解决。所谓木桶短板原理,大话西游一的短板可能在服务器,可能在玩法设计,数值设定,可能在客户端逻辑,根本轮不到 UI 这个模块。

话说回来,IE 也不是如此的不堪,我们只是用 IE 显示几条文件,几张图片,并使用 html 和 css 做一些格式排版而已。根本不会去使用网络部分的功能。所谓 IE 的安全补丁升级,大多和这部分无关。如果 IE 真的连这点事情都做不好,微软就别混了。现在使用 IE 内核做界面的软件比比皆是,也是一支潮流。IE 报告脚本出错,多半是在我们自己的开发人员身上。在经验不足,项目进度压力大的日子里,写这些 javascipt 会犯的错误,留下的 bug ,若是改成原生的代码写到 C++ 程序中,同样会出现,后果更严重。

所以,不要局限于表象,轻易得出结论:怎样的选择是对的,怎样的选择是错的。

11 月里,几乎没我多少事。因为大家的工作都是修改 bug ,而我的那块基本没有什么问题,很稳定。经过一年的开发,我想我至少在 C++ 和设计模式方面领悟了不少东西。开始回头审视整个项目。其实游戏的 client ,并非一个庞大的工程。只要合理的设计,应该能做的很稳定。

开始一个人闷头写程序。

要来了通讯协议文档后,大约花了一个月时间,我做了一个简化版的 client 。虽然只是个雏形,但很多基本功能都有了。代码很小巧,我给他起了个名字,“小话西游”。设计上最主要的地方是,把游戏 client 逻辑做了严格的分层。把对象的管理、画面精灵动画的控制等等都隔离开,并将网络包以及画面无关的逻辑部分提取出来(这点为以后引入嵌入式脚本铺平了道路)。

丁磊看到了我做的这个小玩具后,第一个反应是,“能不能压缩客互端,做一个图形聊天室?”。我想他是对《大话西游》的现状失去信心了。当时人心也比较散,开始有人离开。有些开发人员甚至私下里谈论过大家散伙。

但是我不甘心。这是我毕业后全心投入的第一个项目,我不想看着它失败。不想我那些朋友们,那些 bbs 上相互调侃的网友们,觉得云风只会口上说说,真做起项目来不过如此。我想的是,其实做这么一个“简单的”软件,只要好好规划一下,不至于程序上弄的如此的不稳定。比如 UI 的问题,当时只是项目进度和人手上的不足使用的一个权益之计。而现在,我已经全部构思好该怎么实现了。

按丁的想法,把《大话西游》保留所有的图象资源,而将程序改成一个图形聊天室,体积缩小到 100M 以下是绝对不现实的。要知道,如果我们不做那些我绞尽脑汁的方法去压缩,客户端根本塞不进一张 600M 的光盘中。程序可以再写的短小精悍一些,但图象资源却小不了了。

我想的是,重新推翻再来一次。

做大话西游的 2.0 版是 dingdang 拍板下的决定。倒不用我去主张,程序员的心是共通的。dingdang 怎么说服丁磊的我不清楚,但我想不算太困难。网易只有两条路可以走:解散游戏开发团队或是重新再来一次。

是的,一开始,我们想做的只是 2.0 版,以此作为对老版本的升级,而不是后来的《大话西游II》。我那么的想重新来过,不是因为喜欢这个游戏,而仅仅出于一个自私的理由:要证明自己可以把这件事情做好。


那时的网易可以说相当的不顺利。九月里,公司被 nasdaq 停牌。最后一天甚至跌到了五十多美分。在美国,公司面临着诉讼,因为最近的一期财报被认为掺假。历史上,惹上这种官司最终停牌的公司都没有好下场。

自主研发的游戏上市后,问题多多,反应平平。最高同时在线人数只有 5000 多,还是头几天创下的。

而国内几款韩国游戏却做的风风火火,在这个背景下,丁磊带着大猫猫去韩国寻找可以代理的游戏。丁磊在韩国的那几天,我明显感到他承受的压力。有一晚,我在写程序,他在 icq 上蹦出来,没头没脑的说了句,“失眠了,睡不着”。

我还记得大猫猫归来那天,从韩国抱回了大包小包的流氓兔,我抢到了两个。对了,公仔上有个小标签,赫然印着“Made in China” :) 。

不过正题是之后我们一起看的三个韩国新出的游戏。都是 3d 的,丁磊赞不绝口。一个叫做“Ragnarok Online”,一个叫做“MU”,还有一个是“Priston Tale”。让我也发表一下意见。我说,单看画面的技术含量和操作感,我最喜欢 MU ,其次 RO 不错。丁没说什么,不久,我们代理了 Priston Tale ,给他起了个中文的名字 ——“精灵”。


补充,我努力回忆了一下,记不请最后这段发生的具体时间了。精灵后来是 02 年夏天上线的,谈合作应该更早一些。丁从韩国回来那天,天气不算太凉,他还带了件 T shirt 送人。我不记得那是 01 年的秋天还是 02 年的春天的事情。对比精灵的运营时间来看,是 02 年春天也有可能。但这里行文方便,我假设的时间背景是 01 年秋。有机会再求证好了。下面会接着写大话二的开发,而暂时不再谈精灵,先作一个说明 :) 。

今天在家居然翻出当年大话西游一发行前夕,公司送给每位开发人员的一套网易点卡。制作非常精美。主题是网易早期的那套形象广告。我想丁更多的是想借游戏收费的契机给网易其他产品找出一条收费渠道(第一套点卡上完全没有突出游戏这个主题,可以看成一种单纯的现金卷),只是因为游戏的失败没能成功罢了。


谢绝转载

那些日子(目录)

The Implementation of Lua 5.0 中译

读者向海飞给我 email 了一份他翻译的《The Implementation of Lua 5.0》这篇 paper。原文可以在 lua.org 上下载

这篇由 lua 作者们写的 paper 对理解 lua 非常有帮助。有兴趣的朋友在 这里下载译文

译文最后附有译者的 email 大家可以直接向他反馈。

写了个简易的 web server

根据昨天留下来的思路 ,我今天做了个 web server 。只用于给本地程序做配置界面用。

这个想法其实是以前用 google desktop 时明白的,gds 和 google 很多桌面软件都用浏览器做配置界面。其实就是自己做了个简易的 web server 而已。我也不需要太多,支持 GET 即可。仅监听本地端口,本质上没碰网络。windows 都不会弹安全警告。整个代码用 C 写的,才 200 来行。

做成了 lua 的一个模块,require 进来即可用,很方便 :) 再用上点 ajax 技术,操作感也不错呢。

一开始想干脆在本机架一个 kepler ,连文件服务都不需要提供,专心实现 ajax 需要的必要接口。后来失望的发现,xmlhttp request 这个玩意,居然不支持跨域请求。哦,我不该用居然这个词,人家浏览器也是为了安全性考虑的。

又加了十几行代码让我的 web server 支持获取文件的请求,其实也满简单的。


白天里同事非要用 web service 做一个,他已经实现出来了,感觉也满好。不过我有点反感 SOAP 这个东西,不想把我们游戏引擎搞的太臃肿了。明天再接着商量商量看吧。

May 08, 2008

那些日子(九)

在网络游戏还没有盖过单机游戏的风头之前,大家都认为网络游戏只是电脑游戏的一个小分支。制作、销售的流程也还停留在旧的思维上。

我们都觉得,费劲心力做了这么一套东西出来后,应该先收玩家一些费用。简单说,也就是卖客户端了。7 月里,《金庸群侠传 online》上市,卖出了 10 元的低价。这个游戏吸引了不少玩家,玩家后期的开销远远不只 10 RMB 这么一点。运营商其实也不在乎 client 的这点收入,网络游戏也不惧怕客户端盗版,巴不得多点人进来玩呢。

不过,一开始没人去做免费的客户端。我想有几个原因。其一是固定思维所限,其二是当时网络带宽不够,拨号上网依旧是主流。还是得依靠光盘发行。既然需要走传统的销售渠道,那么也总得设个价格。

网易没有自己的销售渠道,所以选择了一家代理商,智冠。现在看起来很好笑,如今都是花钱想方设法的把新出的游戏 client 送出去,发到最终玩家的手上。那一次,智冠居然还要付我们一些版权费用。不过,我们必须给每份 client 附加一个 cd-key ,没有 cd-key 就不准激活游戏。这是从暴雪的 battle net 模式学来的,可却是一个失败的抄袭。等到游戏上市那天,许多玩家下载到了 client 却不能进入游戏,论坛上怨声载道。

也因为要为光盘制作的周期预留一段时间的缘故,我们的项目 dead line 比预定的运营期要早一点。一开始定的 9 月中旬显然是干不上了。micro 向上面申请延期,结果只增加了一个月时间。我觉得,即使多这么一个月,也是不可能完成的了。


九月里,游戏大概有个雏形出来。虽然 bug 百出,但勉强算是做全了名义上的那些功能。我试玩了一下,非常的不满意。我想,这样的产品是不能拿出去的。大家做的实在是太仓促了,感觉只是为了完成那些功能而去完成,不能算是一个游戏。太多细节没有去推敲。

当然,我没有细玩,不知道到底有些什么玩点。单从 client 的操作感来说,已经是很差了。一个很明显的问题就是,一旦玩家在场景中跑动,屏幕抖的要命。不停下来,根本看不清屏幕上那些玩家的名字。我仔细研究了这个问题,判断是屏幕卷动速度不均匀导致的,便着手改进。

简单的说,就是不要把主角固定在屏幕中间。无论他以怎样的速度移动,都只用一像素每帧的速率顺势卷动镜头,同时严格限制帧速率。当玩家向一个方向连续移动速度过快时,就加大镜头移动速度拉回来。这里的要点:不要让镜头速度切换的频率过高。

真正调的舒适还是颇费了一番工夫的。我在家折腾了两晚,写了个小 demo 拿给大家看。其实我心里还有另一番用意。当程序人员围坐在我的座位周围时,我迟疑了一下还是说了出来,“不如我们把客户端重新写一遍吧”。

这个想法显然是吓到大家了。所剩的时间已经不多,以大家当时的能力,就算不吃不睡估计也干不完。古越的反对声音最有代表性,他说,如果只是要把镜头控制这部分改过来,参照我写好的 demo 代码,花几天就可以搞定。如果别的地方有问题,也可以如此照办。看不到什么特别的需要全部推倒重写。我也实在找不出什么理由坚持我的观点。这件事就这么过去了。

大家继续加班,几个程序的工作压力都很大。而我负责的引擎部分已经没什么事情可以做了。就自己一个人窝在那想,如果重新设计,这个 client 应该是怎样做更好。也随手搭点代码试试。


在 client 压盘前,我们做了一个内部测试。这次测试直接招募了一批玩家长驻公司。很多外地来的玩家,干脆就在公司的空位上打起了地铺。这批可爱的玩家每天给我们提意见,并对游戏的 bug 做出了极大的包容。他们中的很多人,日后都成了网易的员工。QC 部门也是那个时候成立的。

说是 QC 部门,但不完全是做质量控制方面的活。因为当时的项目,解决 bug 的速度远远低于发现 bug 的速度。想来 QC 部门不需要做太多事情,就足够开发部门的人忙了。所以我们也找出一些活儿分给他们的人做。

比如果子就写了个简单的编辑器,让 QC 的头儿侯燕去校对并修正在 photo shop 里标记出来的人物行走区域。这个编辑器做的太匆忙,以至于后来只有侯燕一个人会摆弄。我也做了另一个编辑器,向场景上放置一些动画装饰,以及为每个场景设定背景音乐。随便拎了个有兴趣弄这个的人(似乎那小子网名叫游子,呵呵,其实我还是有记性的)过来就让人家做。

其实后期这些事情多半是我没事找事搞出来的,不在原来计划内。凑着画面,感觉画面不够生动,就想点办法弥补。做美术的头儿周云倒是挺配合我的工作,帮着做了许多动画。天宫中的云彩、花果山的瀑布、长安城那护城河中的流水……

到了压盘前的那几天,古越忙着改 bug ,果子在做一个 mp3 播放器。果子的最后这个任务来的很突然,原本 client 的声音播放程序是我老早就写好了的,关于音频压缩格式解压,直接调用的 windows 自带的 codec 。没想到后期测试的时候发现, windows 95 的系统并没有默认安装 mp3 的 codec 。临时改动 engine 来不及了。果子说可以找到一个开源的东西弄弄。但那时 client 代码比较乱,不好向里面插新代码。我出了个馊点子,不如单独写一个 mp3 播放器。当 client 切换场景时,向这个播放器发送消息切换背景音乐。反正别再大动 client 的代码就好了。(这个临时拼凑起来的播放器也有很多问题,在游戏发行后,我们就把它换掉了,是安宁写的 mp3 解码器,一直用了好多年)

我也没闲着,开始审核 client 的各种数据资源。

要说整个《大话西游》的 client ,除了主程序部分,我想没人比我更熟悉那些资源数据的数据格式,以及各个 dll 的用途了。基本上,我设计了所有的磁盘上的文件数据结构。又因为是第一次实作,这些东西在开发期改动了很多次。各种生成转换工具几乎都是赶时间随手写的,异常混乱。几乎每样东西,离开了制作它们的相关人员,只有我可以检查出是否有毛病了。检查方法也是各种方法一起上:写程序检验、用 16 进制编辑器打开肉眼查看,等等。

这些校验的活,因为项目后期的混乱,没有人去做,甚至没有人想到去做。大家只想把表面上看起来要做的时间做完,回家能多睡会觉就好了,光就那些看起来必须完成的工作,已经累的人够戗。我想,若不是养了我这个闲人,《大话西游》的第一版上市估计会更糟(实际上已经糟透了,更糟也是无所谓的吧)。也因为这些琐碎工作,我从最闲的人变成了最忙的一个。

最后一周,做不完的事情啊。我坐在自己的位置上,不停的干活。用最快的速度写着一些自动化,半自动化的工具。觉得可以了,无论白天黑夜,在办公室里随便找出一个貌似闲着的活人,把东西交给他,说,现在需要你帮点忙,应如何如何去做,有问题回头来找我。

那几天,公司的洗手间坏了,正在翻修。需要方便的时候要下楼走出去老远。不想浪费时间,干脆就不怎么喝水。每一个通宵只用上一次厕所。就这样,不知道时间过去多久。只觉得,身边的人来了,拍打着键盘,身边的人走了,安静下来;天黑了,显示器特别的亮,天亮了,从窗外射进阳光。

每当项目最紧张的时候,我都觉得自己的精力一下子变的特别旺盛,虽然疲惫,但是不会发困,脑子也转的很快。记得那最后的一天深夜,突然发现有一张地图的阻挡层信息做的不对,需要修改。可第二天上午就要把 client 打包送去压盘,等不到负责人第二天过来上班。

这个活一直是候燕在做。而那时,她已经回家,在番隅的家,离公司很远,显然是赶不过来的。果子因为困的不行,回家睡觉去了。我们都不会用他写的那个编辑器。打了几通电话,还是没问明白。我想了几秒,估算了一下距离天亮的时间,和手头上需要做的活儿。立刻下决定重新写一个工具。交互式编辑器当然没那么快能完工,但是我熟悉文件的数据格式,所以写了个一次性程序将内部出错的数据导出成文本。再写了个导入工具,可以将修正后的文本编码导回。做好工具后,便可以交给其他人去修改了。需要交代的只是那些中间文本的含义。这次的经历,让我看到了文本数据的秒处。以后我自己的项目里,所有资源一律要求在开发期制作成可读的文本结构,当考虑到效率时,再写转换工具生成二进制格式。

接下来制作了几段视频的播放程序:制作人员名单、合作方智冠的动画 logo ,还有大话西游的片头动画。是的,最早的大话西游是有一小段片头动画的,因为我们觉得,只要是电脑游戏,都必须要有片头动画。当时周云做好了交给我的时候,我还觉得它过于简陋了点。

我没时间写视频的播放器,干脆把他们压缩成一张张静态的 jpg 顺着显示,倒也简单。当我看到离天亮还有几个小时时,居然多花了些心思制作制作人员名单的播放模块,被称为 Credit 的那个恭喜。我想还有时间,应该让它绚一些。甚至还放了个彩蛋进去。

天终于亮了,熬了三天还是四天,我已经分不清了。给早上来报道的同事交代了哪些数据应该打包,头也不回的上了出租车。几乎在对司机交代目的地的那句话说出口时,睡着了。

今天,我找出了当年那天做的那段程序,是几个月后把代码和数据提取出来重新制作的一个独立包,没有代码,只有执行文件。里面用的背景音乐是网易购买了使用权的大话西游电影主题曲《一生所爱》,我很喜欢。里面还有早期同事的集体照,参与制作的所有人的名单,只要为这个游戏工作过哪怕几天的人都列了进去。那是很多回忆。只可惜刚刚试了一下,程序在 xp 上似乎不能运行 :( 就不给大家推荐了。


临近发行时,2001 年 9 月 27 日,周星驰过来公司,他是游戏的代言人。这个日子这么明确,是因为那天我约了牙医补牙。结果没赶上大家合影,有点遗憾。昨天翻出病历,找到了这个时间 :) 。第二天,星爷又到 36 楼,我也在。我凑上去聊了许多。别的不记得了,就记得光在说《南方公园》(当时很流行?) 。星爷的普通话讲的很好,人也和善,没什么明星架子。他的粉丝太多,大家又不好意思凑过去要签名,看我混的挺熟,一个劲的让我递签名本,星爷都一一的签了。

我抽屉里刚好有样东西感觉挺有纪念意义:《大话西游》客户端的母盘 :) ,让他签上了名字。有点可惜的是,公司的数码相机碰巧没电,始终没能没留个影。


哦,对了。说起这张母盘,还有点故事。今天时间还早,随便写写。

当时我想,什么游戏发行后都免不了盗版,何况以后激活帐号另需要 cd-key 。让别人盗还不如让兄弟盗。我在广州有个好兄弟,tarcy (很奇怪他怎么用个女性英文名做网名),做盗版行当的。这个家伙研究软件加解密出身,水平挺高,但在软件破解的圈子外估计没什么人知道。不过他有个小弟名气很大。dingboy ,不知道有人有印象否?呵呵,不知 google 之,我就不介绍了。

我把盘交给 tarcy 让他压几千片卖。那个年代走这个渠道比正规的卖场要有效率的多,几天就在全国铺开了。

接下来的一年多,单机游戏迅速没落,加上互联网带宽的快速发展。tarcy 他们没过多久就洗手不做盗版盘。我想有一技之长的聪明人不会被埋没,他们改行写网游外挂,又赚了不少钱,差点投资自己做游戏。此乃后话,放到以后再写吧。


谢绝转载

那些日子(目录)

May 07, 2008

那些日子(八)

今天工作上的事情弄的比较晚,没留出足够时间来继续写这个。本来打算直接回家睡觉的,想了想还是继续写点。凡事可以坚持做下去,往往靠的不是兴趣,不是责任,而是习惯。我不想让这些对过往的记录成为今天的负担,但也担心一旦放下就会拖上好久。反正腹稿都已经打好了,无论内容多少,还是保持着一天一更新的习惯吧。让我顺利把这件事情做完。


Dingdang 具体哪天加入的游戏开发组我已经记不清了。因为他做的是服务器那块,我不太关心。大约是在《大话西游》项目中后期吧,他说,服务器这边进度太慢,就过来了。他以前玩过 mud 挺有兴趣。但是其工作主要还是在底层。

大话的服务器最早是搭建在 mudOS 上的,一个开源的东东,用在各种文字 mud 上。做文字 mud 通常还会用一个中间层,叫做 mudlib 。早年传说中的方舟子一帮人等做《侠客行》,就是指做了一套 mudlib ,被后人用在各种中文文字 mud 上。听说大话的开发人员也自己做了套 mudlib (听说而已,micro 似乎跟我提过他们没用侠客行的代码,太久远的事情不想证实了),不过我对使用 mudOS 却不以为然。什么年代的东西啊,都 21 世纪了,还在用。也就那么点代码,就不能放弃掉自己写一个吗?而且原本为几十个人同时游戏设计的框架,用在这么多人同时在线的网游上合适么?

网易的同事们完全扔掉 mudOS 这根拐杖是到 大话3 的事情了。主要还是因为太多逻辑代码用 LPC (mudOS 内置的一种类 C 的脚本语言)实现。大家一点点的改造,先是将文本通讯协议改成对数据流量更节约一些的二进制方式,为特殊的需求添加一些代码(例如定时数据持久化),再做一些底层的优化,把 select 的网络模型改为 epoll ,等等。直到全部更替。这些工作持续了 4,5 年。

一开始,当然做不了这么许多。大家还是主要在完成游戏的进度。dingdang 坐我的旁边,中间靠走道的拐角处。桌子上没什么东西,上班时就带一个笔记本,在那里敲敲打打。

我对那段时间在工业园的记忆不多。因为每天,周围的人都是一个情景,闷头做事。晚上,走的晚的人倒不是很多,我和 dingdang 加班的次数比平均水平高一点。

他那个时候好象在热恋中,晚上经常窝在椅子上,捏着手机很小声音的讲电话,每次都很久很久。工业园的办公室晚上都是不开顶灯的,大家都很享受在黑暗里办公,显示器亮亮的,四处安静的很。

也偶有喧闹的时候,那是古越的 client 和 ten 以及 dingdang 联合调试。我没关心技术细节,只是从他们的对话中感觉有无数的 bug 改不完。有点忧虑,但无能为力。从一开始就没有参加到这块的逻辑中去,我只能好好做我那块东西。

记得当时 client 和 server 都有严重的内存泄露问题。client 这边我想了很多方法帮古越定位。server 那 dingdang 也在想办法。我们讨论过这个问题,渐渐的就谈到了内存管理器。dingdang 说他实现了一个 伙伴(Buddy)算法的内存分配器,主要是想减少一些内存碎片。自己写的内存管理器也可以有效的侦测到内存泄露的发源地。另外希望以合理的内存布局,让一些 bug 引起的内存越界访问时,减少服务器崩溃的几率。我在这方面是完美主义者,觉得根本就不应该允许 bug 的存在,但是 dingdang 显得很无奈。绕开这个有争议的话题,我们还谈了许多。只是现在都不记得了。


client 这边的分工倒是慢慢的很明确了。古越在配合服务器组实现 client 对应的逻辑。我来做底层,几乎不用搭理游戏是什么。比如大话西游那么丰富的场景和人物角色,开发期间只看过两三个,都是用来调试engine 用的。果子做了一部分跟图形无关的 client 底层,主要是网络包的分发处理。现在的眼光来看,设计的并不好,采用了多线程结构徒增了一些复杂度。如果追究原因的话,我想是因为当时我们 client 没有一个好的软件架构人员统筹安排,基本上都是各个人想怎么做就怎么做造成的。

UI 部分的呈现是郭斌负责,而跟 IE 接口的地方则是果子和另一个程序黄东海在做。说起后面这个人,也是游戏圈混迹多年的老人了。本来是做 3d engine 的,不知怎么就来到的网易。来之前我听过一些圈内的朋友说他脾气不是很好,比如老是敲着桌子抱怨美术没按他的思路去做。不过来到网易后可能没有啥担纲挑粱的工作,也见不出他的脾气。他只工作了一个月就离开了,那个月神龙见首不见尾,突然就出现在工位上,而后有几天见不着人。悄然辞职(或者就没正式入职)后又回家去做 3d ,几年后还有一面之缘,暂且不表了。

还有一块,是李鑫做的。那就是 client 外挂的聊天室。在时间紧张的日子,我拼命的找方法可以减少一些程序量。既然我们已经嵌了 IE ,那么就干脆做到底。这种实现方式在后面的产品里取消,但外挂聊天室的形式却保留了下来,成为网易游戏的一大特色。

网易当时的 web 聊天室做的不错,丁磊特别得意。记得他曾对他的朋友们吹嘘,我们的聊天室做的是中国技术最好的,一台机器可以支持 4000 人同时在线。这块东西是李鑫的作品,参照 IRC 协议实现的。client 部分用的 HTML ,server 用 C++ 完成。

李鑫在我刚进网易时就有人介绍给我认识。介绍人是 freemind ,我读大学时就认识的好朋友。多年的网友。我想 freemind 这个网名还会有许多人有印象吧 :) (前几天有读者来信说,让我怎么也要提一下 freemind ,说早年游戏圈里这么有名的人怎么能忽略掉。哈哈,我不会忘记这位老朋友的,有机会以后再写一次)他和李鑫曾是《电脑报》的同事,一起做过《电脑报》的多媒体光盘。在没有互联网的年代,那可是样好东西。

不知是什么缘分,我居然记得读过李鑫的聊天室源程序(是从一个开源的 IRC 服务器代码改的。那段时间,项目组其他人的代码都是没什么精力去看的)。印象比较深刻的是,他在许多地方的类接口传递的 CString 而不是 const CString & 。我们就此还讨论过一些 C++ 代码的性能问题。他表示是老代码一直拷贝用下来,没太在意。

项目就这样由许多人分头做着,一天天临近死亡线。


话说那段日子,还有另外一些事情。给我的记忆比开发大话要深刻许多。

北京的那帮哥们倒是做的有声有色起来。我离开北京后,他们也更改了一些计划。做手机游戏引擎的事情搁浅了,改为先做一些有特色的软件,几个游戏和一个 mp3 播放器。后者是安宁在优化,汇编是他的专长,有时电话里聊聊,他对他在好几款低端硬件上实现了 mp3 的流畅播放甚是满意。

Nokia 在广州开一个什么会议,庞鑫和安宁来到广州。我们少不了要聚一下。庞鑫给我看了他在 Nokia 9100 上做一个伪 3d 的模拟空战游戏,非常刺激。让我想起了天惑。据说游戏让 nokia 的家伙们看傻了眼,原来这机器机能这么强啊。嘿嘿,安宁跟我说,他们 hack 了 9100 的系统,用官方的 sdk 自然是做不出这效果来的。

丁磊说想请大家吃饭,让我先订了个房间,带大家先去坐着。主人没到,大家都不敢点菜。好在我们有的是话题聊。

这时候手机响了,我一看,是丁老大的。庞鑫在一旁嘟噜着,早着呢,那家伙刚出门。接起来,老丁在里面大声的说,“我已经出门了,马上就到”。又等了大约半小时,手机铃声再次响起。还没等我接呢,庞鑫再次插了一句,“他在停车呢,当大老板的就这样。”“你们再等等,我停好车就上来”,听到这句,大家都笑了。

这是 2001 年 7 月中旬的事情。不是我特地记下了这个日子,是因为第 2 天,我们在我家旁边的小山酒吧庆祝北京申奥成功。安宁喝了许多,我也是。大家特别的高兴,街上满是欢腾。2008 ,好遥远啊,等奥运真的在北京召开的那一天,大家会是怎样的境遇呢?

过了几个月,庞鑫和安宁来到了广州,还有徐创(逆火的另一创始人)。丁说,我们可以开始做 3d 游戏了。这是 天下 2 的开始。虽然那个项目的头几年,完全没有想到会重新以《天下》来命名,但我想庞鑫等的到来是网易开始在 3d 领域尝试的第一步。比官方记载的《天下贰》的开发历史早上许多。


谢绝转载

那些日子(目录)

数值调整、模拟器、编辑器

最近做游戏数值有点头大。也研究了一些游戏的设定,有点心得。举个很小的例子来谈谈:

wow 里的护甲对物理伤害吸收是乘一个百分比的,其公式为:

min (护甲/(护甲 + 400 + 85 * 敌人等级) , 0.75)

怎样理解这样一个公式的内在含义?为什么会设置成这样?

和敌人等级相关很好理解,对手越强,吸收的越少。这样可以方便伤害公式的设计。

因为,一个人的物理抗击打能力和两个基础值有关,HP 的长度,和护甲伤害吸收率。(暂且不考虑回避率和特别技能伤害等的影响)

随着玩家等级的提高,基于成长性考虑,系统一定会让玩家的 HP 更长,护甲更厚。但是对应的伤害输出则只有一项数值。这样,要么以更快速度提升玩家的伤害输出能力,要么就要削弱面对高等级对手时的伤害减免能力了。

由于 wow 里各种人物之间有护甲差别(板甲、锁甲、皮甲等),为了平衡起见,不至于拉大高等级玩家见护甲差别优势,又保留护甲升级空间,暴雪选择了根据对手等级来削弱护甲能力的方式去做,这是最自然的选择。

至于 75% 吸收封顶,应该是受 D&D 规则影响。保留实力相差过大时,不至于让弱势方毫无还手之力的可能。(D&D 规则中,投出骰子 1 就一定 miss ,wow 同样也设定了这样的保底 miss 率)

重点来看看这个伤害吸收公式的框架,为何要采用一个倒数曲线来描述其变化呢?

我们来看常见的另一种涉及百分比变化的数值设定方法,那就是逐步累加百分率。很多游戏都有使用。(比如还是 wow 中,对致命一击率的设计)但是,对于宽泛的百分比变化,这样的设计是不太好做平衡的,因为价值很难直观凭估。

我们来看这个伤害吸收率,假定有一件装备可以增加 1% 的伤害吸收率。那么你如何评价其价值?跟许多玩家的数字直觉不同,在你的基础吸收率不同时,其价值可能截然不同。

举个极端的例子,假设对手的伤害是 100 点,而你原来毫无伤害吸收能力(护甲为 0%)。那么增加 1% 的伤害吸收率后,你就可以只承担 99 点的伤害。这种改善是微乎其微的。但是,如果你一开始有 98% 的伤害吸收率呢?那么再没有加这件护甲前,伤害是 2 点,一旦穿上后,吸收率增加到 99% ,就只会受到 1 点伤害了。护甲性能因此提高了足足 1 倍。

这就是 wow 把护甲值和伤害吸收率设计成倒数关系的缘故。

当玩家的 HP 固定长度,对手的伤害输出能力一定时,HP 的抗击打次数和对手单次伤害成正比。当对手的单次伤害被削弱一个百分比 d ,那么防御方的抗击打次数(或理解为存活时间)就提高了相同的百分比 d 。

经过公式换算过的护甲点数,1 次线性的描述了玩家抗击打能力的提升。这样,同样一件加 200 点护甲的装备,给任何人,任何职业,任何等级的人装备上,提升的防护能力就可以(在抵抗同一对手的攻击的时间长度这个意义上)保证一致。在此基础上,衡量护甲加成的点数的内在价值,就变得容易估算了。

OK 。如果要做护甲点数增加一定百分比,甚至翻倍这样的技能或职业设定怎样?wow 里的熊德就是这样的。如果这种技能多了,一定破坏平衡,理由正是上面分析过的。wow 这个护甲吸收伤害公式和数值增量的值密切相关,收益和增量成一次线性关系。百分比则会破坏这个平衡。

如果想做呢?比如有职业有技能是增加护甲点数百分比,天赋可以再增强这个百分比,饰品也可以对护甲点数以百分比增强?

好办,用幂函数曲线去拟合护甲点于吸收率的关系就好了,这就不展开讨论了。


这两天想写个战斗模拟器来调试战斗数值计算公式。本来想快速出个原型而不必等 client 细化后再做。想来想去,找不到特别快速的方法。考虑了一下做 web ajax 版的。前段时间玩过,感觉用以前写的代码改改也满好,做好了可以方便我们几个策划去试验。不过做起来还是满心烦。

C# 的版本倒是有同事弄了一个,觉得还是不太方便。另外有人说这几天想用 logo 做一个,我等着看效果吧。


这两天还有人在做 3d 粒子编辑器,也是想快速做出来。我提议说,界面的需求这么复杂,还是做个 web 接口的吧。3d engine 不必嵌入到过于复杂的软件应用中去。

其实我的意思是,写个超级简单的 httpd ,甚至不用支持完全。我们只需要听一个本地端口,只支持 GET 就好了。读入请求的第一行,看是 GET 开头的,就把 URL 那行文本读进来,当作控制指令分析就够了。足够满足基本的 ajax 应用。然后随便架个轻量成熟的 httpd 处理静态文件来描述控制界面。

我想顶多不超过 200 行 C 代码就可以搞定这个框架。

不过某人还是用 web service 做了一个 :) 看起来还是满 cool 。

今天折腾这些个东西到这么晚了,还在考虑要不要继续更新回忆录。但愿睡个好觉。

May 06, 2008

那些日子(七)

01 年的夏天到来的时候,《大话西游》跨过了一个里程碑。古越发了一个内部的 demo ,没有网络功能,只是一个主角在两个场景间转悠。一个长安城,一个化生寺。回想起来,整个 demo 就是被逼出来的,没什么太大意义。老板说,要有一个 demo ,那么就有了。

我的场景管理模块完成了,角色精灵的显示完成了,其实要做的工作只是粘合一下,没什么实质的东西。这种 demo 更像是无数国内开发小组忽悠投资用的玩意,秀几个人物,来两个场景转悠一下。只要美术做的足够漂亮,就足够可以蒙过那些不玩游戏的投资人了。这样的 demo 多如牛毛,相互之间不同的是,图象上能表现出来的技术含量高低:2d 的还是 3d 的,有多少特效,画面刷新率多少等等。其实离游戏还远着呢。图象表现上的技术,是游戏开发中最简单的技术了。倒不是技术含量低,而是一旦有人克服了技术点后,都是成熟的玩意。接口简单易用,也容易独立的更新换代。从工程角度上讲,可以正交分解的模块都是简单的东西。

不过话说回来,在上个世纪,国内就连这些简单的部分也做不好。随便发行个(单机)游戏,不在底层出点 bug 就可归为上成佳作了。多少好的游戏就毁在引擎的不稳定上。离开一个稳定的引擎支持,就不要奢谈游戏性的调整。妄图在一个不稳定的引擎基础上设计出一个好的游戏出来,那是空中楼阁。绝对不存在一个游戏,单单只是程序有太多 bug,而游戏设计却非常棒的。程序这块做坏了,不仅仅影响玩家的感觉,同样影响策划的工作。等到《梦幻西游》出现在这个故事中,我会展开来谈谈这些。


对于这个 demo ,不光是在游戏部门内展示,为网易工作的大多数人都见过了。既然,这个 demo 根本不应算是这个游戏项目的里程碑,自然也没有收集到多少有价值的意见。许多人只是表示,如果护城河里的水可以动就好了,岸边的柳树应该随风摇摆一下…… 是啊,谁不想更生动一些呢?

就在那几天,游戏开发团队全部搬离了市中心,迁入处于城郊的天河工业园。今天,那一带热闹多了,甚至有了四星酒店,高档商品楼,满街的饭馆。科韵路那条小街也被改造成有中央隔离带的主干道,只是当年,我第一次到工业园区的时候,只觉得:荒凉。

一开始我不想搬到工业园去上班,因为不想住在那边。而每天从市中心奔过去的话,来回又会浪费太多时间。广州网易财务部的头儿 Rose 大姐在离职前嘱咐道,给云风在 36 楼留个位置吧,我就留了下来。有时就在 36 楼写代码,除了大猫猫,只我一个游戏开发的。好在网易技术部的人也混熟了几个,倒是不寂寞。有时也去工业园看看,micro 给我在那边留了个工位,添了台机器。

没人知道我今天在哪里,明天去何方。如果我不在工业园,那么就在 36 楼;不在 36 楼就在工业园。如果我在家里办公而不去任何一间办公室报道,恐怕没人会知道。只是我从没这么做过。

只到半年之后,工作越来越忙,接连两周,我每天都赶去工业园。到了第三周再回去 36 楼的办公室时,发现抽屉里已不是我的物件了。旁边的同事对我说,“以为你不来了呢,现在有人坐这儿了。你的柜子在储藏室里。”。我在储藏室没找到我的东西。那使我遗失了许多私人物品,一些信件,笔记,相片之类的。有点怅然若失。但不久就想开了。人活在这个世界,没有什么不可以失去的。即使记忆、纵然生命,百年后,尘归尘、土归土。


建华路 25 号 2 楼,1500 平敞开的几大间屋子。网易游戏部新进驻的时候,只坐了一半(一个大开间)。装修很别致,据说是丁磊从硅谷学来的风格。铺着地毯,大家都穿拖鞋,甚至打赤脚。天花上没有吊顶。楼上是住家,粗大的下水管道只是用彩色的塑料胶布缠了一下。偶尔能听到抽水马桶的冲水声,大家笑称,都是肥水呢。

另外空着的三间大房间,很久很久以后摆上办公桌。一间里放了张乒乓球桌,晚饭后,大家排着队打球。据说古越的老爸是乒乓球教练,曾经发明了一种碟形球拍,有专利的。服务器的主程 ten 是乒乓好手,我水平一般,陪他们练练球而已。另一间里吊了一个沙袋,有人在里面拳打脚踢。累了,就去一间有电视的小休息室,在 ps 铁拳上继续。

给我们搞卫生和做饭的阿姨有两个,一个胖胖的,我们管她叫胖阿姨;另一个瘦瘦的胡阿姨。阿姨挺牛的,不讲卫生或是浪费粮食会被教育的。她们不算正式员工,但绝对是游戏部门的元老。

刚到新地方的时候,大家都很兴奋。第一天音响开的很大,震的屋子乱颤。而写服务器的 ten 是个极需要安静的人,有点噪音就干不下去活。最终,立下了规矩,大家一律带耳机,上下班都不准用音箱。呵呵,我配的机器是个例外,有一对音箱。只是我没有听歌的习惯,从来不开它们。其实环境嘈杂或是安静,我都无所谓,估计是耳朵对声音不敏感,也怪不得我五音不全,不爱唱歌了:) 。其实大多数程序员还是需要一个安静的环境吧。


micro 有一间小的办公室,他是游戏部门的头儿,也是《大话西游》的项目经理兼产品经理。办公室里有六张桌子。我不记得还坐了谁,应该不只 micro 一人,但也没有坐满。他有时候出来转转,问些问题。我很奇怪项目经理到底应该做些啥,制定每个阶段的目标吗?但我看到的都是些形式。什么时候完成什么全系在负责的那个程序身上(单从程序角度上来看)。做的人慢点,进度就慢了点,快一点,那么进度就快了点。旁人影响不了什么。项目经理在后面嚷嚷,快点快点,加班加班,似乎起不到什么作用。写程序不是记件的活儿,多干一个小时就能达成完成度一分的。

micro 那时也表现出一丝无奈。记得他对我私下里讲过,他很想写些服务器方面的程序,就像他以前做 mud 巫师那样,但是实在是无从下手了。我想那个时候他陷入很多事情里,正如今天的我。不过我现在好那么一点,至少时间上宽松一些,而且多了这么多年的技术积累。

很大程度上,我所能看见的 micro 的工作都是在招人。他向我征询意见,问我对某某的看法,我直言不讳。

刘铁是当时圈子里小有名气的策划了,据说 95 年就混迹于国内的游戏制作圈,新疆人,能写文章能作诗。为人豪爽,特能喝酒。我们第一次见面,他就拉着我灌白酒,喝的醉熏熏便开始豪言壮语。几年后离开网易销声匿迹了很久,我一直听说他在搜狐做《天龙八部》只是产品怎么也出不来。今年,《天龙八部》一鸣惊人,张朝阳扬眉吐气,丁磊垂涎不已。我想此人功不可没。林广利曾经这么评价他,刘铁的思想过于天马行空,想的太多,所以做出来就少。可买下《天龙八部》这个题目,把人限制在一个小圈子里,反而可以让他反反复复研究个透彻,东西也就做的好了。呵呵,姑且听之。

我曾经诧异一个网游(天龙)能憋这么久才出来,等我自己做时,今天回首过去三年,不也一样吗?

萝卜是之后大话2后期的产品经理,到如今已经是游戏部门的领导了。他是那个时候入职网易的。挺偶然,他弟弟在游戏部门做 QC ,他过来看看,觉得不错,就留了下来。第一份工作是做大话的界面设计,偏美术一些,离策划较远。萝卜是游戏部门公认的好人,好脾气。听他聊过他的过去工作经历:自己卖过电脑,做过三星显示器的地区总代。最终赔了钱后又只为学点东西,在家小店面帮人用 photoshop 做平面设计,被人剥削了还乐呵呵的满不在乎。曾经四处游玩,只因到了一处,碰见一拨人吃完晚饭在街上踢毽子,一起玩的开心,就跑去他们公司干了半年 …… 一个随性,谦虚,豁达的人。

还有一人(这里隐去名字,因为要谈点人家的糗事),不拘小节。有天白天我在写程序,旁边传来鼾声,四处寻觅不见。突然身边站起一美女,婉婉而去。原来我们的办公桌的侧隔板和窗台边留有半米距离,刚好能放下一睡袋。平时打地铺,外面看不到,无损形象。估计是夜里工作的晚了,此人白天怀抱女友入睡,一直睡着,mm 才离开。我就这么记住了这个新来的策划。

他成天的在公司,夏天里没回家洗澡。可想而之,这日子久了,周围的人哪堪忍受。后来此人离职,阿姨拿着火钳夹出工位下的拖鞋扔掉,根本无人敢碰。

ten 是个极爱干净的人,每每跟我说起,都捂着鼻子。只要是策划开会需要程序参加,他都勒令某人回家先洗了澡再来。:D

好在我是个百无禁忌的人,跟谁都相处的很好,啥毛病都能忍。倒是没觉得太多不是。


天气最为炎热的那几天,我跟果子在弄 client 更新的模块。我设计了一种数据包的格式,其实并不复杂,只是把零碎的数据文件连起来而已。关键在于,我们希望日后的更新可以尽量的不影响旧的数据。因为我们已经预料到以后 client 会频繁的更新。更新包的数据下载,网络带宽是一部分制约因素,而下载更新包后,怎么合并到原有数据文件中也是一个会影响用户观感的问题。

如果让玩家只是简单的把下载的更新数据包解开,然后重新打包进硬盘上的旧数据包中,很可能这个过程会随着 client 的迅速膨胀而变的异常漫长。

所以我优先考虑的是,如何追加新的数据进数据包,而尽量不影响旧数据在硬盘上的物理位置。其次,就是帮助玩家节省硬盘,而不能每次都把新数据追加在老的数据包之后。

这块东西最后是我和果子合作完成的,我设计了数据包的数据结构和更新数据包的规则和方法,他制定了 patch 包的规范,并编写了代码。

虽然当初做的草率,可大体上却是没什么问题。这套系统沿用了好多年,今天网易的新产品还在继续使用。恐怕只有我目前的这个新项目才在翻新重新设计吧。相比很多别的公司的产品,在 patch 更新方面,我想我们做的还是相对不错的。比如 wow ,每次下载完大的 patch 包,打 patch 的时间都远长于下载时间。如果 wow 也一周一个 patch 的出,估计玩家要郁闷死的。

唯一不能被打包的是当时的 UI 系统用到的资源。那些图片、js 文件、超文本等等。本应是有办法的,只是我们没有时间去找。郭斌不想让最终用户可以看到那些 js 文件的源代码,他写了个程序做扰码。把那些发行版中的 html 和 js 都弄的面目全非 :) 。可惜没有解决上百个小文件的问题(js 文件过大后,在早期的 IE 版本上还有些毛病)。

最终大话的发行版安装时,大部分时间的等待都消耗在了 UI 系统的安装上,不停的拷啊拷啊的。可能那些扰码还有点浏览器兼容性故障,有些版本的 IE 会时不时蹦出脚本出错的对话框。

我已然意识到用 html 来实现界面的诸多问题了。比如显而易见的内存消耗,IE 控件吃掉了大量的内存。不象我们自己的引擎可以控制内存中的图象让他们压缩存放,浏览器放置那些图象素材时一定是平坦的扔在内存中的,也无法做动态加载。

但是没有时间让我们放弃这一方案,甚至从一开始,这就是个帮我们节省开发时间的方案。

我依旧住在市中心,每天公交车收班后才回家。住在那一带的同事拼辆 taxi 回家,走对路的话,是 28 块,虽然有点远,但路上随便的聊聊就到了。四人一车,我、郭斌和刘国斌。还有一人,此人对日后的网易游戏部举足轻重。Ding dang ,从肖海彤的办公室也搬到了工业园。


谢绝转载

那些日子(目录)

May 05, 2008

那些日子(六)

和大部分原创游戏一样,游戏定名总是晚于项目启动的。01 年 4 月我正式入职网易时,大家还并不知道这个游戏会和周星驰的著名影片《大话西游》同名。micro 他们只是想做一个以西游记为背景的网络游戏。这个想法来至于当时有名的 mud 《西游记》。我对国内 mud 的历史没有什么了解。大约知道有《西游记》的巫师(yesi)被招聘进来工作,大家对《西游记》情有独衷并不奇怪。

月心是 micro 的合伙人,也是最早天下的策划。理所当然的承担了新项目的设计任务。因为我对网络游戏本身没有兴趣,所以我对这个人也不太熟悉。倒是和另一个策划私交不错,大猫猫。严格意义上来说,他不是大话西游的策划,进入网易前,我想他的身份多半是一个资深玩家。他以前做什么的也不记得了。不过我倒是很早听过这个人,似乎混迹过 sina 的游民部落和后来的 mop 。他的朋友圈子里的人见过不少,salala 、commando 还有后来加入网易的 ali 等等,大多是做游戏媒体的人。

《大话西游》这个名字是大猫猫的主意,马上得到了大家的认同。一开始我们有点担心版权的问题,丁磊说网易有个董事认识周星驰,而后大猫猫就去香港找星爷去了。两年后,大猫猫离开网易,据说在跟星爷混,不知道现在咋样了。


初到广州的那段日子,虽然工作比较紧张,但是进行的有条不紊。我绝不主动过问游戏方面的事情,只做 engine 。这一快其实没太多东西好做,至少我的进度比大进度要来的快。大都是早就深思熟虑过的东西,只需要把细节完善一下,补上缺少的模块就好了。偶尔有些技术点要攻克的,突击几个晚上,剩下来的大多数时间,并不需要加班。

丁磊很喜欢泡酒吧,而公司附近就有许多。他带我去各个酒吧转,介绍一些他认为有特色的吧,和各式各样的朋友与我认识。我想那些朋友于他也只是点头之交,跟我也不会有啥关系,往往记不住名字。他喜欢的吧都很喧闹,比如公司对面的 wine flower ,去的很多。

我不喜欢太吵的地方,不明白为什么有人喜欢。据说是为了放松一下紧张的神经?或是找个宣泄的场所?可我不觉得自己有什么放松和发泄的需要。从来没觉得什么叫紧张,什么叫压力,什么叫累。平常写写程序挺有乐趣的,写累了,睡觉是最好的放松。我也不喜欢用酒精把自己灌的神智不清,思考是人最重要的能力,脑子烧坏了可不太好玩。

不过有时候老丁也专门约些朋友聊天,当然不能去那些需要对着耳边大喊的场所。这就需要找个安静之处喝点红酒。有一次,我们学来了杀人的游戏,一伙聪明的人在一起,玩的特别带劲。后来的几年,我都很喜欢这个游戏,并且自行扩展了诸多规则,几乎每周玩一次,直到腻味。

喝酒的时候,丁最放的开,像一个大孩子。当然他也喜欢在我这样比他小上七八岁的同事面前摆出老成的样子,讲一些道理。但总的来说很随意,他有些别人没有的优点,也有点不至于让人讨厌的缺点。他是个普通人,一个好人。


肖海彤曾经跟我提过一次,能不能以后上班也打一下卡,因为公司需要整顿一下风纪。其实,我在北京上班时都很守时的。不过这次,我想了下说,能不能少点约束。胖肖几乎没有考虑就回答,公司得有个规章,但一两个人的例外倒没太大问题,而且对于自律的人,的确也不需要约束。所以我再也没有打过卡。

的确,我自信对的起这份工作。那段时间做了许多事情。没有人给我分配工作任务,没有人告诉我该做什么,项目需要什么。我想,我写点程序会有用,那么就写了,结果也就用上了。一个最重要的模块就是在最初那段时间完成的,一直用了很多年。

昨天提到网游客户端对内存占用量控制的问题。我们定的最低配置要求 64M 内存(实际上,最终放宽到了 96M )。最占用内存的是那些角色动画。因为希望有好的效果,我决定让所有图片都使用 alpha 通道。这可以让精灵的轮廓和背景融合在一起,没有锯齿。现在这几乎是 2d 游戏的标准配置。但那时,由于硬件限制,采用的游戏并不多。

实现的困难在于处理速度以及内存消耗,尤其是内存。假设一个人物的单帧图片为 64 * 128 像素大小,采用高彩模式带 8 bit 的 alpha 通道,那么这一帧图就会消耗掉 641283 = 2.5 K 内存。若是有 8 个朝向,做行走的动作,一组动作 8 帧。那么合计的图片量就达到了 1.5M 。这还仅仅是一个人物的一组动作而已。

网络游戏中,由于玩家的个性化需求,以及内容的丰富,我们需要数以百倍的数据量。用 64M 内存储存下这些数据,简直是天方夜谭。

许多人会联想到图片压缩技术,莫说非技术人员,前段时间连我们公司的程序员都在 maillist 上询问,为什么我们公司的游戏都使用自己的图片压缩格式。他极力推荐 gif 和新版的动画 png 。

其实,图片压缩算法往往都是为了节省硬盘空间和缩短加载时间而设计的。进入内存后,这些标准格式大多还是展开为平坦的数据结构 —— 非压缩数据,方便图象引擎处理。而我们亟待解决的问题是内存的消耗。(这个问题到了今天 2G 内存已是标准配置时依然存在,因为暂时还是主流的 32bit 操作系统,虚拟地址空间依旧有限,容不下日益扩大的 client 图象数据。这是 2d engine 需要处理的一个难点)

我的解决方案是设计了一种可以把解压过程推迟到渲染时再进行的压缩数据格式。原理很简单,RLE 行程压缩算法而已。只是让数据结构组织的更适合实时解压。甚至比不压缩的图象数据处理的更快(因为总的数据量减少,降低了内存总线带宽的需求)。图象也采用了 8bit 调色盘技术,对于 alpha 通道则只保存轮廓线的少量部分。

即使《大话西游》的后继维护人员意识不到,我自己倒是觉得早期的这些精打细算,在内存占用和 CPU 处理速度上的平衡估量,为日后的资料片连续推出铺平了技术道路。策划们肆无忌惮的向资料片里添加素材时,client 不至于膨胀的过快。我们的最低硬件配置要求可以随着玩家的硬件水平提高,需要控制的只是不要增长的太快就行了。《大话西游》一直可以在低配置的机器上流畅运行(包括同一机器上多开客户端,多重登陆,针对这些,我也花了些工夫优化),是它可以顺利推广的一个原因。

图象格式设计好之后,渲染代码花了半个月实现。并额外用了半个月时间用汇编重写,在当时的机器上较之 C 版本提高了 1.5 倍的速度(如今的机器可能差不了这么多了)。图象压缩的工具初版是果子做的,后来我也当学 MFC 而练手做了一个替代品,其中复制了果子代码中的一小部分。如今,网易的许多 2d 项目还在用我那个简陋的工具,点出 about 会看见当年留下的一行字:“云风出品 质量不能保证”。

游戏之作会用这么久,是我编写之时没有想到的,而道理很快就想通了。大多数人都有一种习惯,只要工具还能用,就会一直将就下去。项目开发中,需要做的事情永远比完成了的事情要多,那么只要老的东西还能用,就无心去改进它了。

明白这个道理后,让我以后的工作都特别谨慎。因为写的每一行代码,做的每一个决策,都可以一直被用下去,除非自己想重新来过。指望有人改进它们,是不切实际的想法,即使你在 log 中标上 todo 写的明明白白也不例外。

那个时候,大家还在用 vss 做代码管理。我没怎么用,因为我不太相信有人会来和我一起来共写一块代码。所以我一直自行维护那块相对独立的 engine 部分。稳定了就送去古越那里让他使用。稳定的接口很重要,不至于让大家疲于奔命的重构代码。直到后来做大话 2 时,我才和大家一起移到 cvs 下,一起维护。

那时我对内存的锱铢必较甚至反映到对美术的抱怨上。例如,当时游戏里有四种女娲的形象,其实是用的同一套模型和动作渲染出来的。只是四种颜色,美术人员在渲染时换了四种光源而已。我看到后,抱怨着为什么这样浪费,其实 engine 已经提供了调色盘更换技术,可以方便的用程序做到同样的效果。

最终并没有执意要求换掉这四色女娲。因为我在和大猫猫聊这件事时,自己明白了一个道理。当时他并没有立刻理解我的想法。如果他都没有马上明白,那么,解释给众多人听将是一个浩大的工程。当多人合作做一个项目时,应该为每个参与人员保留最简单的要求和规范。因为一旦项目人多,沟通成本远大于技术成本。一切复杂的手段都是不切实际的。如果真的想按我的想法去做的话,也应该由我自己来写一个额外的程序去自动化处理美术提供的冗余数据(这个案例中,四色女娲共同拥有的模型就是冗余数据),而不是增加制作规范的复杂度(要求美术人员额外去调调色盘,并输出成指定格式,再交给 client 开发人员调用)。


老实说,我觉得当时的工作做起来比今天闲的多。白天总有时间在办公室瞎转悠。我喜欢跟同事打交道。不管是不是我的分内的事情,都爱关心一下。我想这也是我的历任上司们都对我的工作放任不管的原因之一。当我的事情做完,总能找出点活儿来做。我在网易乃至游戏部门一直没有安什么特别的职位,手下没有兵,头上没有将。很多东西都是随口问问,看看能不能帮上忙,或是提一些自己的看法。同事们也不会有太多的排斥,反正我不是他们的上司,不会指责他们的失误。偶尔起兴趣了,还可以帮忙写点程序辅助一下。因为我天生看不得有人做重复机械劳动的苦力,宁可自己多花点时间写程序自动化一下,也不愿意见人一整天在那白辛苦。忙的要死,其实没做什么东西出来。

那个时候,游戏的 server 比 client 更晚进入轨道。记得随口问过写 server 的同事(忘记是谁了)的进度。4 月底的时候,他们还在弄一些相当基础的模块,内存分配之类的,让人有点担心。更晚一点,我参加过一次他们 server 组的讨论会,讨论服务器的架构。那个时候,我对 server 开发没什么概念,也没什么兴趣。只是觉得白板上圈圈和连线过于花哨,不觉得有太大意义。最终 dingdang 的加入拍板说,就用单进程单服务器结构好了,这是后话(几个月以后的事情),而且我也记不太清细节了。

micro 挺喜欢让我参加他们的各种讨论会议。这倒不是我特别主动要求,因为开始的几个月,游戏项目不足以引起我的兴趣。

策划的会议参加过一次,乱糟糟的,大家商量游戏里的战斗模式。即时制起先就被我给否决掉了,因为我更喜欢回合制的 RPG 。说起即时战斗模式,我只说 engine 不支持,并摆出大堆理由。其实支持也不是太难,但是我就是不喜欢。而正好当时石器时代正处在上升期,听说已经为华义赚入大量钞票,足够让丁磊流口水的。石器是一个典型的受玩家欢迎的回合制网游,正面典型在前,大家也不怀疑它的潜在用户数量。

剩下的问题是,做一个怎样形式的回合战斗系统。似乎大家都倾向于做的特别一点,比如黄华,当时的另一个策划,提出来要做成在战斗场景上移来移去有方位感的形式。我和大猫猫比较反对,我认为,徒劳增加一些表现力,而不增加对应的游戏系统是没有什么意义的。当时黄华找不到一个合适的游戏系统来支持这种玩法,最后也就作罢。月心是一帮策划的头儿,很沉稳,慢条斯理的,不跟大家吵。他主持了那次策划会议,但没有结论。这可能是我参加的唯一一次《大话西游》的策划讨论会。最终,游戏的战斗系统就是现在这个样子了。

其实回合制的游戏也可以做的丰富多彩,形式多变。我想说,起初大话的策划们也想过很多,只是最终没有实施而已。有很多因素:项目进度、技术因素、硬件限制、等等一些我知道和我不知道的原因。

比较遗憾的是,这么多年,包括我们公司自己的开发团队在内的许多国内开发组,制作回合制网游时,都不敢越雷池一步。在根本形式上少有创新,是让人很可惜的一件事。也许我当年能多点兴趣,支持一些有趣的想法,并做出技术上的支持,在没有定型的网络游戏市场上,会出现别样的回合制战斗形式来。谁知道呢?很多事情也不是一个人可以改变的。

甚至在开发的前两个月,我还参加了一次美术的审核会议。起因是我在调试地图加载模块时,指出了一处场景中的图象错误:有两个建筑的影子方向不一致。其实也不是什么大不了的问题,玩家多半不会在意。micro 决定让我和大家一起统一审一下做好的图。我不是美术人员,也不会跟人争论美术风格应该是怎样,哪里做的不好。但是,一些诸如影子这样的小毛病挑了不少。建筑的力学结构,墙壁上的花纹,哪些植物不应该长在一起之类的。后来觉得这些其实都不太所谓,追究的太多对项目也没多少益处。之后也没再干了,美术的队伍越来越专业和成熟,也勿须我这样的外行插嘴。

那段时间真是过的挺快乐。我对整个游戏开发项目的影响很奇怪,人的职位是属于网易技术部的。游戏项目中名义上的专职工作是做 client 引擎。但实际上做了大量万金油的事情,挺琐碎,以至于自己都记不清干了些什么。就是没让自己闲着而已。


早期的那帮同事都混的挺熟。micro 也定期组织大家聚餐唱 K ,我一点不会唱歌,就知道跟人摇骰子。美术部的刘琪周云他们都是爱玩的主,我虽然自己不会晚上主动出去娱乐场所玩,但也不反感有大帮认识的人一起闹腾。哦,古越倒是顾家的好男人,每次我们出去玩,他都不去,要按时回家。这代表了网易游戏开发团队中截然不同的两种性格。我想,一直以来,网易游戏的程序和美术部门都没能完全融合到一起,除了后来的部分行政划分的原因,还缘于最早的这种性格差异。

日子过的挺快,甚至都没觉得项目有什么进展,就这么过了。除了我自己做的那块东西还比较满意,我想我对项目没有信心,当时谁有信心?


谢绝转载

那些日子(目录)

May 04, 2008

那些日子(五)

今天已经开始上班了,最近很忙很忙。在调游戏的数值,很繁琐的事情,还要写程序去模拟。整个项目也需要人去照看。

这个系列,我想会坚持写下去。但是不想成为自己的负担,我想这样才能写的自然。因为都是写一些真实发生的事情,和身边的朋友,按记忆按自己的理解去写就好了。不像写小说,会担心有逻辑上的漏洞,会困扰于故事中每个人的结局该怎么安排。所以,挖了坑不知道该怎么填上这种事情多半不会发生的。

已经开始有朋友写 email 跟我聊这几天我写的这几篇东西了,有人抱怨为什么没写谁谁谁 :) 。这个问题其实上次解释过了,我是个不善于回忆和叙述的人,每次从记忆深处挖点东西出来,都会涌出一大堆的人和事。精力有限,只能挑选几个来写。

与其说这是我自己的故事,不如说是国内游戏圈中大家的故事。带着大家从我的眼睛,去看周遭的人。也有朋友抱怨,写的人太多太散,理不清头绪。其实,我也尽力去单独的一段一段描写那些熟悉的朋友,顾而不一定顺着时间的次序让他们入场。

关于国内游戏圈早年的一些事情,有兴趣的朋友可以 google 一下“北外隐形人”写的“中国游戏年代记”。是我读过的最全面的一个记录。从叙事角度看,猜想这个“北外隐形人”是游戏媒体圈子里的人。对于制作圈子来说,有一点点距离。有些东西写的有点偏差,比如 99 年时庞鑫大学还没毕业,不可能结婚的 :) 。同样,我的回忆也可能失实,尽量少写道听途说来的故事吧,呵呵。

一直以来写东西比较随性,有时候节奏慢点,有时候快点,跟心情有关。写这些基本不打稿子,想到哪写到哪。读的朋友得多加忍受了。记下这些往事,不是因为我喜欢缅怀过去,只是发现若再不总结一下,都快分不清好多事情的先后因果了。同时,也是帮身边的朋友们留下点滴,大家一起分享这小段美好的时光。

好了,以下是今天的正文,谢绝转载:


四月的广州,天气不错,甚至有点夏天的感觉。几年后,一个毕业实习生也是这个季节来到网易,住在我的家中。记得他曾感慨的说,知了怎么这么早就开始叫了,这里连空气里都充满着夏季的味道啊。我想那时我也是这个感觉,到处都是湿湿的,身上有点腻。和北方那种干燥真是截然不同呢。

网易的办公室在写字楼的顶楼,从卫生间门口的通道走出安全门,可以顺着外墙铁扶梯爬上天台。我很喜欢那里,吹着风,俯瞰繁华的广州。偶尔也有人出来抽根烟,我从不抽,但也不用担心吸二手烟。大家偶尔聊上两句,很惬意。

办公室里很拥挤,我想是因为新加入一大帮人的缘故。虽然额外租下了楼下第 18 层,但是没有多少改善。按网易一贯的风格,大家都坐在敞开的大办公区里,隔板不高,方便交流。我被安排在一角,前后都是原天夏工作室的程序。

micro 对于我能再次回到广州很高兴。兼职期间我写的那些模块尚未用上,因为毕竟那些是我自己的一些新想法,还没有和其他人沟通。client 的程序定下来三人,古越、我和果子。

果子,以我当时的眼光去看,是天夏的程序中编程水平最高的一人(不过他不是天夏的股东)。跟着天夏进入网易。第一天我们似乎讨论的是游戏中 UI 的问题。除了“天下”,大家都没有做过游戏,不知道游戏里的 UI 该怎么实现。果子给我看了几个用 gdi 写的 UI 小 demo ,做的不完整,也没有什么头绪用到游戏里。

接下来一两个月,UI 的问题也困扰着我。如果 engine 是由我负责的话,这种 client 的基础设施就理当给出一个解决方案。而我只有一点单机游戏的经验,在我的头脑中,游戏的 UI 都不复杂,简单的硬写出来就够了(比如古越在“天下”中干的那样)。但是直觉又告诉我,网络游戏会不一样,UI 的复杂度会高上一个数量级,不能简单对待。事后证明,我的直觉是正确的。大话西游 client 后期工作一半以上都是围绕 UI 展开的。


我在北京时,自学过一小段时间的 javascript 和 css ,曾惊叹于 web 页面可以达到如此的描述能力。虽然那个时候还不曾听说日后日趋成熟的 ajax 技术,但是我想,总有一天 web 页面上也会出现相当于传统客户端程序那样复杂的应用的。

网易有的是做这方面的技术人才,比如郭斌。我发现这个家伙对 javascript 很熟时,就老是跑过去缠着他问些相关的东西。比查 msdn 好用多了 :) 。郭斌这个人不错,听说对丁磊很是崇拜。所以很想安心在网易做一番事业。据说他入职网易后,立刻就结婚买房,在广州安家落户,一心做下去了(听人转述的)。

接触了好些新同事,以及评估了我们的进度计划日程后,我下了一个决定。这个日后反复被丁磊拿出来损我,当作是人都会犯错误的样本来教育新程序员的决定,我至今不认为它是个错误。那就是,在 client 中内嵌一个 IE ,实现游戏中的 UI 。

当时的计划是在 2001 年 9 月 15 日推出游戏。虽然我不认为 5 个月可以完成,但是我想我们的时间终归不是太多。一群没有多少经验的人做这样一个项目,没有多少头绪的情况下,找到任何一个可以分割项目,让它成为独立子项目的方案都是可行的选择,即使有技术难点,也是可以独立克服的。何况网易有许多做 javascipt 的熟手,甚至有成熟的 web 聊天服务,这些都是可以尽量利用的。

软件项目并不是人多就可以做的更快,《人月神话》里已经讲的够透彻了。让更多的程序员可以参入项目并做出贡献是非常困难的,比跨过特定的技术门槛更难。大多数情况下,增加人手只能帮倒忙。而这次,我们可以拉郭斌甚至更多网易的同事(后来做这一块时还加上了刘国斌)来做。而我们 client 组原有的三个人,可以专心于更小的一块工作。

为了嵌入 IE ,我花了不少精力做研究。那段时间读了 COM 的书,看了 ATL ,学到不少知识。不过最终问题并没有很好的解决。在那些紧张的日子里,留给我的时间不多,我不知道怎么做这些。不知道怎么从程序中直接拿到 HTML 页面上的鼠标键盘事件。最后是果子想了一个我们都公认很愚蠢的办法。写一个额外的控件注册进系统,在 javascript 里向这个控件发消息,然后由控件转发进我们的主程序。这个方案明显不符合大家的审美观,但是我有更多的事情要做,其他人也是。它可以工作,那么就那样了。


同期,我做了一件影响了后面很多年网易游戏 client 开发的事情。那设计游戏地图的数据格式,以及开发期这些数据的构建方式。

之前,几乎所有的游戏,都需要做一个场景(地图)编辑器。被业内简称为“地编”的工具,往往担负了超过一半的程序工作量。在我大学还没毕业的时候,曾经去珠海金山拜访朋友。剑侠情缘2 的主程王炜给我展示过他做的地图编辑器:游戏即编辑器,编辑器即游戏。发行给玩家的版本只是一个屏蔽掉编辑功能的编辑器而已。

这种方式并非不好,我也曾想这么做一个。但是时间不允许。所以我想到了另一个方法,直接出整图。

整图的方案不是没人干过,但是很多人做的不好。因为出整图是需要占用运行期大量的内存资源的,在当时的机器配置下,就不可能把场景做的太大。而且场景上一样有许多素材会和人发生前后遮挡,也需要编辑器去编辑他们。

我的思路很简单,能不做的工作我们就不做。如果只是描述一个 2d 场景,那么 photo shop 可以干的足够好,而且美术人员习惯用。遮挡关系的处理,我发明了一种简易的方法,用一个 mask 罩住背景图片,当角色需要绘制在后方时,engine 把背景上 mask 罩住的部分扣出来重新盖在角色图片上。这样,我们只需要做一张整图就够了。mask 也只需要用 2bit 描述一个像素(如果单单需要把场景上的一颗树这样的图素扣出来,mask 只需要 1bit 。但还需要一些额外信息描述前后关系,细节这里不展开介绍了),这些信息还可以很方便的压缩。我们需要额外设计的是,如何在 photo shop 里表达出这种 mask。最终的方案是为每个遮罩物创建单独的图层,选用黑红蓝等颜色区分出来。

这套方案是我在家时就想好了的,兼职期间也一直在做这种特殊 mask 的实现。来到广州后,果子帮我研究了 psd 文档的格式,并写程序提取出相应的 psd 文件中每个图层里的数据。

当每个人都可以专心做特定的一件事,比如美术人员可以专心用他熟悉的工具制作一张大的图片时,工程才能合理有序的进行下去。额外需要做的事情是有专人去勾勒出遮罩,分出图层,按事先约定的规则起好名字。

关于内存占用的问题,如果把整个场景的图片全部载入内存显然是不合适的。假设游戏场景有 6400 * 4800 像素那么大(实际上我们后来设计出的游戏场景比这还要大),单单一张背景高彩图片就要占掉 58M 内存。而我们的设计目标是让 64M 内存的机器也可以流畅的运行游戏。况且,60M 的数据加载也是个大问题,我个人作为一个玩家,非常痛恨游戏中缓慢的加载进度条。

最后,我决定尝试分割游戏场景数据,采用运行时动态加载的方式工作。经过测算,为了达到目标,为场景数据预留的内存不应该超过 12M 。我把图片和其它数据拆分成 320 * 240 的小块,当玩家操作主角奔跑于游戏场景中时,engine 根据他的移动方向,预估 client 即将需要显示的场景,最多会把 5 块预读到内存中(游戏的分辨率被固定在 640 * 480 高彩模式)。

为了提高加载速度,我权衡了 IO 速度和压缩图象的解码时间。结论是,如果直接保存未压缩的图片在硬盘上,以当时普通的硬盘,绝对做不到流畅的无缝读取(玩家移动于存在于内存和外存中场景块之间的缝隙)。如果使用高压缩比的压缩格式,比如 jpeg ,又会占用太多的 cpu 时间,同样会影响游戏感。最终我稍微改造了 jpeg 的数据格式,并简化了解码流程(牺牲了一点图象质量),使用大学期间自己用汇编写的一个 jpeg 解码器解决了这个问题。

地图加载这一块使用的多线程技术。不知天高地厚的我,没有任何多线程实战经验的情况下,开始编写这块代码。多线程编程出现的各种问题把我折腾的头昏脑胀,难度远远超过预想。前后花了 1 个半月时间才基本稳定下来。事实上,还遗留了一些 bug 。当程序崩溃时,地图加载的模块会蹦出一个对话框,标题栏上是我挑选的最喜欢的几句《大话西游》电影中经典台词中随机选出的一句。如果还有大话1的第一批老玩家读到这里,应该能想起早期那时不时蹦出的对话框,“悟空,你又调皮了”。

不少玩家曾经猜想过那些句子背后的含义,甚至有人投诉过网易,程序出错还蹦个对话框羞辱玩家 。哈,借唐僧的口我自嘲而已。

当这段代码最终稳定下来,已经惨不忍睹。后来很多年,我们几个产品轮替,大多数代码被重写。但一直没人敢把这块东西推翻。据说这两年做大话 3 的同事终于下决心重新弄了一遍,不简单啊。不过也有一定原因是,我们现在不再需要那么精心推敲内存的占用,硬盘的加载速度了。当硬件上升一个档次,程序员们就可以站的更高,在更高的层面考虑优化问题,反而让系统工作的更好。

当年 windows 95 就是一个例子,微软为了能让它在 4M 内存的机器上跑起来,颇费了一番工夫。结果也严重的制约了操作系统的发展,windows 98 ,windows me 走了不少弯路。直到 windows 2000 才回归正轨。


那段时间,感觉新加入网易的众多人都处于一种复杂的心理中,不知道未来,焦躁,不安……

这与大环境有关。nasdaq 股市爆跌,网易生死不明。高层似乎也发生了几起人事变动。刚进网易时,我参加过一个大型的会议,CTO 给大家讲话,抚慰大家的不安,我刚刚去,不知道是些什么。

后来传出一些谣言,说是公司会被并购,中华网或是金山,具体是哪家公司我已经不记得了。那几天,nasdaq 上的 ntes 涨到了 2 美金。似乎古越和 micro 都挺高兴,还说要出去喝酒庆祝一下。我想是因为他们手头上卖掉天夏得到的一些网易股票。我没去跟着庆祝。不久以后,股价又跌了。

公司有 7000 万美金的存款,但市值已不到这个数字。也就是说,如果有人肯掏上几千万,就可以立刻拥有银行里超出他付出的现金额。但是这是个赔钱的公司,每一分钟都在花钱,7000 万看起来很多,可总有花完的一天。

记得刚去网易没多久,美术的负责人刘琪曾经去我家坐过,随便聊聊。虽然没明说,但我能感觉到他的一丝不安。刚换公司的人大多这样,内心不安定。如果这个团队散了,如果游戏做不出来,如果游戏做不好,大家需要一条退路。我不需要退路,我只是做我应该做的事情,尽可能做好,这就够了。如果尽了全力却失败,非人力所能阻挡。

人的能力有限,其实每个人能做到的事情都差不多。就看你投入多少。如果你全心投入也做不了,那么换一个人基本上也不可能做到。

我想我要做的是解决团队里暂时无人有精力去解决的一些技术问题。还有有些问题大家觉得无所谓(比如运行效率,比如内存消耗),但是我却认定它们会对未来游戏运营起来有影响,默默的去做。不需要别人知道你做了些什么,但求以后没有人指责你做错了什么。

我们总把一些问题归咎为“历史原因”,以表达一种无奈。其实当时再多花那么一点时间,就没那么多“历史原因”了。

项目的成功正在于:少犯错误。

我的想法就这么简单。所以身再累,心不累。每天还可以很有规律的干些别的事情。比如爱上了飞镖运动。跑遍了广州买到了镖盘和钢制的飞镖,挂在屋子里。每天晚上练习。没过多久,就能连续投中 20x3 的那块小区了。


后记:

这一篇本来预备了很多内容,甚至连项目定名都没写(下篇补上)。因为在项目筹备期,有很多的人和事应该记录下来。大话西游是个很多人合作的大项目,不是哪一个人或几个人的功劳。我在这段不长的时间也解决了好几个技术问题,鉴于写太多技术上的东西会让故事过于枯燥,我想,还是分开成几篇来记述,一次提一点,同时可以留下篇幅写一些人,一些朋友,一些我的生命中的匆匆过客。

前面有朋友留言说,故事节奏太慢;又有朋友跟我说,还可以写的再慢一些。我比较偏向后一种观点,多记录些细节吧,可能更有趣。对喜欢快节奏的朋友只好说声抱歉了。

希望能够写完写清楚,又不至于太过冗长。

那些日子(目录)

May 03, 2008

那些日子(四)

2001 年的春天,我用 C++ 把“风魂”重写完毕。这个工作在北京时开了个头。起初是和余雪松聊 kele8 的 engine 时,萌生的一些想法。老余告诉我,他做过一些评测,发现大部分 CPU 时间消耗在了 flip backbuffer 上,大约占 50% ,其次是字符串的处理。(后来这一块的优化,我离开北京后老余也做了,应该是和我的思路类似,做过以后,就能发现更多可优化的热点)

我考虑了几天,突然有了些灵感。我想我找到了方法解决这个问题。只是古老的脏矩形算法而已,好多人尝试过,可惜都没有用好。我想我可以换条思路解决的好一些。

再就是阅读了 MFC 中 CString 类的源代码。因为吴东黎说,好多人不用 MFC ,但是离不开这个 string类。他把这个类从整个 MFC 中剥离了出来用。我也不用 MFC ,不过还是想,有这么好用吗?随即读了一遍。因为正好在重新学习 C++ ,我就自己开始写一个 string 类。

这两块东西让我把“风魂”的代码用 C++ 翻新了一遍。如今回头来看,代码很混乱,没有章法。但是我想它们见证了自己的历史,至今仍放在主页上供人下载。

没有哪个程序员的代码一开始就能写的成熟稳健,我们都经过幼稚的年代。


古越在网上告诉我,他想用我新完成的风魂 C++ 版本来写新项目的 client 。不过还需要我做几个扩展模块。我想总是要练练手的,何况可以拿兼职工资。在家这么混下去,总不能一直吃爹妈的。古越还是想让我加上 Z-Buffer 的支持,但我觉得那不是一条正确的路。想了一下,决定实现另一种解决 2d 场景中前后遮挡关系的方案。可以不增加太多额外的数据量,而且处理速度比较快。

在此之前我估算了一下整个网络游戏 client 需要的图片资料的数据量,得到一个吓人的数字。对于当时主流的 64M 内存配置来说,不花点心思,是跑不起来的。

大约做了一个月,我把一堆代码和几个 example 提交给广州,并拿到了 4000 块的兼职工资。这让我很欣慰,至少我在家没有白吃白喝。而且,天夏被网易收购以后,micro 明显大方多了,呵呵。

这种悠哉悠哉的日子也只过了这么一个月。另一个人找到了我,胖肖,肖海彤。

肖海彤这个名字,96 , 97 年的时候在 cfido 网上很出名。我老在全国的技术区里看他发信,有过一些笔谈的经历。写程序这行当,他绝对是我的前辈。那些天,我们在网上聊了许多,他直言是因为网易才跟我联系,但我们聊的都是些别的。我记得他给我转了一些旧邮件,关于民主啊宪政之类的。我本不关心政治,可读了后对政治也有了兴趣。我想我是从那个时候开始仔细考虑“自由”和“个人意志”这些问题的。

肖海彤是丁磊的同学。网易当时还设有 CTO 这个职位。CTO 在北京,似乎跟广州有隔阂,基本管不到广州来。肖海彤正负责广州网易的技术部门,广州也几乎是网易全部的技术力量所在地。

丁磊一定是受不了我们这么一天天闲聊,没过几天就直接给我打了个电话。我想丁磊的口才并不出众,至少当时对我没有什么特别的感染力。只是我在家待的实在是有点无趣了,我说,那我去广州帮帮 micro 的忙,不过我想自由一点。丁说没问题,帮你在公司附近租套房子,有阿姨帮你打扫卫生,屋子里也配好电脑,上班不用打卡。就这么定了,机票明天 ems 到。

事实上,后来我只让阿姨去我那打扫过一次卫生,而我自己连周末也是泡在公司里。我想既然要做,就一定要做好。


网易 97 年成立,当时只有 7 名员工。当 2001 年 4 月 8 日,我在入职单上签字的时候,工号是 92 。员工离职,工号是保留的,即使日后再回来,也是领个新的号码。我认识好几个离开网易又回来的同事。而我的工号,从 92 到 0092 再到 G0092 ,没怎么变过。

我猜,当时网易的北京上海广州三地的正式员工加起来差不多只有五六十人吧。但实际上办公室里看起来的人更多一些。micro 他们天夏的收购手续还没有完全办完,许多人拥挤在 36 楼,而我是直接入职网易技术部的。

在胖肖的办公室里,他满是歉意的对我说,由于制度上的原因,只能给我一万一个月的工资。因为我的级别是 6 级,在新员工里已经很破格了,如果再高恐怕影响不好。而 6 级员工薪资最高这么多。至于住房,房租是 1600 一个月,如果公司来支付的话,手续上不好办,所以得我自己承担,额外会有 800 一个月的住房补贴。扣完税以后,可能比一开始许诺的少许多。

我说无所谓的。这么说也真是这么想。而且,这个数字听起来不错,5 位数耶,可以小小的满足一下虚荣心。这也是我最后一次关心自己的薪资,后来再也没注意过。直到今天我也不知道到底每个月公司给我发了多少钱,银行的户头上从来没刻意去查过帐。

入职的那一天,天夏的 fishman 离开了。我跟他就那么一面之缘,没什么印象,也没太多好印象。我在 36 楼底下的农行办工资卡的手续时,天夏原来的行政 mm 也在,她跟着 fishman 离开。很清秀的女孩,漂亮,所以印象深刻。她也是在那办些公务,或许是转帐吧。我们闲聊了几句。我知道网易大约花了 10 万美金收购天夏。今天看来这个数字很便宜,但在那个时候,我想至少 fishman 觉得赚了。我也觉得赚了,就这么忽悠一下,然后全身而退。人和人的想法还就是不一样呢,有人就想做点事情,有人就想赚点钱。

赚钱为了什么呢?我仔细想过这个问题。钱是一种媒介,代表了一种对社会资源的调动能力。所有的不公平,都是缘于资源分配。我们需要有思想有能力的人来更加合理的调配社会资源。

晚饭是丁磊请客,在隔壁的蕉叶吃泰国菜。丁是个没有架子的老板,略微有些霸道。饭桌上还有 dingdang ,跟肖海彤一个办公室的。我们聊起来挺投机。其貌不扬,据说应聘网易时失败了几次,不得伯乐。我看是因为过于谦虚了的缘故吧 :) 。我们聊到我的个人主页,说起 N-SPACE 这个网易的产品,很可惜,那个时候已经停止注册了。dingdang 说其实应该好好弄下去,后来网易的个人主页又开放注册了好长一段时间。

夜里,我回到了属于自己的小窝。就在公司对面的一条小巷子的尽头。与外面的繁华截然不同,这儿非常的安静。一对和善的老夫妻租给了我,虽然外观破旧,但内部温馨,甚至有一口金鱼缸。

很累,床很舒服。第一次一个人住这么大一间屋子。当从清脆的鸟叫中醒来,赤脚踩着清晨地板上的那一缕阳光时,我想这是一个新的开始。


五一假期快过完了,不知道忙碌起来还能有多少时间继续写。

照例补充一句:谢绝转载。 :)

那些日子(目录)

May 02, 2008

那些日子(三)

2001 年新年过的很忙碌。我想从大学里毕业出来的学生,第一个新年都是如此。从学校迈入社会,什么都很新奇,想和人分享自己对这个世界新的看法。大多数老同学不会太快结婚,日后离开祖国的也大多没走。所以新年里,那些儿时的玩伴、少年的同学,都会回到老家。只需要有人说声,“我们聚聚吧”,那么一定是和声一片。那个时候,女生们还不够花枝招展,男生们也没人挺着啤酒肚。

狂欢之后,各自散去。在本地工作的,也开始忙忙碌碌,留下我一人。有时候可以去一下老同学读研的校园,跟他们吃吃食堂,打打台球,听他们聊一下自己的老板,还有一些八卦。我觉得我还存在于这个社会。

我想许多人在年老之前,很难有这么一段时光。脑子里什么都没有,没有想做的事情,没有应负的责任,没有什么人什么事让你必须去做点什么。哦,那段时间还发生过点事情。我对追求了很多年的那段恋情绝望了。除了心口的绞痛,不记得什么细节。

有那么一瞬间,我了解到什么是空虚。人在虚空中,四周什么都没有,无所触及。声音也传不出去。不喜欢这种感觉,然后我开始读书。


大学毕业以前,我是不读历史的。高中会考,九门课,8 A 1 B ,就是历史那一科得的 B 。我痛恨一切要求背诵的课程,顺带厌恶了历史。当然我数的出夏商周,春秋战国秦汉,分的清六朝五代唐宋元明清。这归功于小时候爱看各种历史演义小说。三国演义就读了四五遍,以至于中学老师还没教到出师表时,已经背的朗朗上口了。不过演义不是历史,对吧 :) 。

我想,给我上历史启蒙课的是柏杨(老人在前几天去世,让我感慨了好久)。我倒是先读的《中国人史纲》再看的《丑陋的中国人》。后来又读了《皇后之死》等等很多很多。还有,在网上追看着的潇水的《青铜时代的恐龙战争》。

第一次发现,其实历史这样的有趣。不是因为有趣的故事,而是人性,以及人性促成的社会。历史总是在重复自己,又总也不会呈现相同的面貌;人总以为自己了解过去,可以回避那些前人犯下的错误,可他们总是掉进同一个坑中。这是为什么呢?

读大学时,我玩过一个游戏《恺撒 3》,更早的版本中学时也玩过,不过没有深入。那天夜里,是一门重要科目考试的前夜。躺在寝室的床上,瞧着他们几个人围在电脑边不亦乐乎。终于,有一关他们犯了些错误,引起了恺撒军团的大规模进攻,无法收拾残局。时间很晚了,因为第二天有考试,人就散了。

我觉得有趣,就试着载入存档,看看能不能扭转乾坤。一个晚上过后,我成功了,白天的考试却挂了。满不在乎的我,爱上了这个游戏。

特别喜欢这个游戏系列,胜过《文明》和《模拟城市》。从这里面,让人体验到了古罗马人到底怎样在生活。虽然只是游戏,许多设定是为了游戏的娱乐性而设,但是就是让人觉得,那种生活方式是合理的,恰如其份的,真实的。罗马城里那些高悬在空中的输水管道,街头的公共浴池,给了我无限遐想。

在家的那段日子,我买了份正版的《法老王》,在家里盖金字塔。看着那些小人在尼罗河泛滥后留下的肥沃的河床上耕种,农闲时大量的人力被调配去盖金字塔。哦,奇迹原来是这么诞生的。这就是文化呀,游戏是多么好的文化载体。

我想做一个承载中国古文化的游戏。

所以我开始啃史记,读资治通鉴,还有一些学术研究方面的书,比如人口,风俗方面的专著。很多大部头虽然只是翻翻,但也觉得自己似乎不那么无知了。不过成天读书,人也显得疲惫不堪,没有人和事管着,一天要睡 12 小时才够。白天也总是睡眼惺忪的。我想,长期这样下去也不行,得有个计划。


古越打来一个电话,先是很神秘的说他们找到了投资,说对方是个大公司,暂时还没谈完,需要保密。吱吱唔唔了一下,忍不住告诉我,那家公司正是网易。

聊起网易,倒是让我有了一些兴趣。我的第一个 email 就是网易提供的服务。大多数志同道合的朋友,都是在网易的服务器上建立个人主页之后才陆续认识的。那时觉得网易是中国最大的网络公司,嗯,大公司,据说还在 nasdaq 上了市。

不过我对古越说的网络游戏,没有丝毫兴趣。mud 我怎么都没玩进去,UO 显然不如 diablo 有趣,EQ 就是一群傻鸟在那里围着几个多边形按鼠标,隔一会儿还要坐地板。据说丁磊眼红上了《石器时代》,这个游戏我没玩过,不过看起来也是日式 RPG 的末流产品吧。

我说,现在全中国都在做网游呢,才开始做是不是晚了点?

真的,的确全中国那个时候都在做网游,后来那么多人给《天下》和《大话西游》带上了首款国产网游的桂冠,让我唏嘘不已,真的是成王败寇啊。

那几天,另一个朋友也在和我联系,王华逵。


认识王的时候他在金字塔做程序员,书生气质。我那时还在上学,假期里去深圳找他玩儿。金字塔对员工管的挺严,我进了金字塔的办公室的时候,他跟我说老板不在,还没下班,等下班我们出去边吃边聊,现在得坐岗。我看了他先前做的一个网络俄罗斯方块,据说在他们办公室里很流行。甚至因为大家上班打游戏,而被老周给禁了。当时他在做一个网游:《人在江湖》。我想,这是我知道的第一款图形 mud ,至少比《天下》早上许多。只不过更 mud 一些,一个个的小区域场景,正如 mud 中的文字被图形化出来。client 是 3d 的,很早期的 3d ,技术不太成熟,打斗的时候有些简易的动作,但主要还是靠文字拓展玩家的想象力。之前的《江湖》这款游戏很糟糕,所以我对人在江湖也没什么特别好的印象。

晚饭时我们聊了许多,王华逵还叫了几个朋友一起。有一个据说是江湖的程序员,已经离开金字塔了。明显他自己也觉得自己在程序方面没什么造诣,说了一些很搞笑和低级的程序 bug 。反正,江湖这个产品没做好是应该的,卖的很好,不是吗?老周应该挺满意。好象还有个做游戏网站的朋友,说起网站的流量之类的事情,我那个时候的个人主页的流量相对还不错的呢。

因为只有我一个人是学生,大家讨论了一下关于毕业生最喜爱的几个南方热门的公司的情况,比如华为的待遇。我饶有兴趣的听着,没有什么想法。

晚上,窝在金字塔的办公室里看动画片。一个胖子的电脑在放《攻壳机动队》,片子和人都给我留下了深刻的印象,胖子说他叫陈重,人如其名,一下就记住了。他还给我看了他画的《江湖》里的大侠,动作很帅。这个人后来负责了天下二的美术,世界真小。

夜里很晚了,我被带去员工宿舍睡觉。全是上下铺,天气很热,没有空调。桌上的电风扇呜呜的吹着,我觉得比学校的寝室好,因为不熄灯。

上铺是个新毕业的大学生,说是找工作找过来的,没想过做游戏,只是找工作而已,目前试用期,1500 一个月。我随口提了些技术方面的话头,感觉对方很茫然,就把话题绕过去了。心里想,这个世界真奇妙。好多有志于游戏开发的热血青年不得门而入,觉得国内做游戏的公司都是些神圣的地方,很难进入。而另一边,人才市场上随便摆个摊,收几份简历,会写几行程序就来做游戏了。有些游戏产品做不好,还真不是什么奇怪的事。


王华逵说他现在东莞有个公司,正在开发游戏。还有,给游戏写剧本的是个名人呢,我跟他提过我喜欢《悟空传》,正是今何在在那里。冲者猴子的名头,我说好吧,我去你那看看,散散心。

南下的第一站是广州,下了飞机是古越接的机,我第一次见到真人,大家很开心的聊着到了公司,micro 执意给我报销了机票。我倒真的没点积蓄,有人报销路费自然是高兴的,不过有点困扰的是该让广州的公司买单还是东莞的。

网易的办公室在广州最豪华的地段。狭窄的街道,高耸的大楼,橱窗里玲珑满目的商品,墙壁的装潢有点陈旧,我觉得我处在电视剧中的香港。办公室就在那个川流不息的十字路口边的楼顶,36 楼,我们一直称呼这个办公点。

透过落地玻璃看那楼下的小车,火柴盒似的,感觉很奇妙。

许多人拥挤在不大的办公区里,micro 给我一一介绍。他们一伙人已经确定并入网易,然后新招了许多人,主要是美术。不过在文件上,大多数人暂时还不算网易的正式员工。大家似乎和老网易的人有点隔膜,我想刚合并的公司就是这样。

聊起美术部门里那些五颜六色的头发,听说还有一段趣闻。丁磊起初很不高兴电梯里有人指指点点,不知道顶楼的公司正在做什么,都是些奇装异服的人。曾经“下令”说,你们把头发剪掉、颜色洗掉,再来上班,结果却不了了之。因为有个白发的哥们道,要么我们都不过来上班算了,一呼百应。

这天我认识了刘琪和周云,都与我同年,小我几个月份。我很奇怪为什么美术部会有两个头儿,不过没问。周云的性格我很喜欢,为人很讲义气,长的很帅,一看就是很得女人缘的那种。多年之后他和我讲他的故事,居然他女朋友最后因为迷上大话而最终分手,网游啊,祸兮福兮 。

晚上我住在古越家,他刚买的新房(我猜是因为天夏卖给了网易,股东都得了些好处吧)。他的女朋友正在武汉读大学,学文的。时值寒假,也住在他那。我随便聊了两句,提到想读读范文澜的《中国通史》,她说她正好在学校图书馆里借了一本,就拿给我去看了。


micro 和 ten 说想一道去拜访同行,他们在国内游戏圈里没什么人脉,随我一起去多交一些朋友。ten 是天夏服务器部分的主程,挺有想法的一个人,是天夏工作室的元老了。聊起来就知道是个 mud 迷。我猜想天夏的几个人就是因为 mud 走到一起去的吧,我不玩 mud ,这方面没什么共同语言。

我们乘火车去的东莞樟木头。micro 提了个很奇怪的要求,让我别跟王华逵说他是谁,只说是个朋友。我说,讲了也没关系吧,最后还是从了他的意思。或许 micro 当时觉得,被网易收购的事情还需要保密,不方便说。只是最后让王猜出了他们的身份,好不尴尬。

在樟木头我倒是如愿见到了今何在。只是一面之缘,打了个招呼,没有聊什么。他们在做《不灭传说》,剧本是今何在的《若星汉天空下》。这是个网络游戏,据说主打欧美市场,首先做的英文版。

王倒是风光了许多,两年前他陪着我乘公交逛深圳,与我一起挤火车站的售票厅,陪我买车票。如今他只需要打个电话叫来司机,乘上公司的小车带我们转悠。去到当地一个新开的楼盘,谈起来,说是公司的员工工作满十年都能得到一套房子。从小到大一直住在一排排火柴盒一样死板的社区里。我第一次见到公园般的小区,欧式的花园,清澈的池水,从狮子头样的雕塑里喷出来。环绕着花园的房间,明亮的落地窗。我想,以后一定要让父母住进这样的地方,享受生活。


聊到《不灭传说》这个游戏,我从自己老本行的角度提了些技术问题,想知道他们怎么解决的。国产游戏到那个时候还没有什么成功之作,大多数卡在技术上。比如内存占用的问题,王说的很轻松,我们打的是欧美市场,人家早已经普及 128M 内存,不用太考虑这些。我心里笑笑,国内 64M 内存已经挺奢侈了。毕竟那个时候我刚从学校出来,烂机器用惯了。

华奎在饭桌上私下里跟我说,过来一起干吧,一个月工资 7k ,另外再算别的待遇。我说,我考虑一下,但自己知道那只是礼貌。条件挺好,但不是我想要的。

晚上,华奎让公司的行政帮我们在一家四星酒店开了房间休息。我和 micro 一间标间。micro 跟我说,他们想了好久新项目做什么。最后考虑到西游记的 mud 挺有人气,一些做西游记 mud 的巫师也过来了。可能会做一个西游题材的网游。

我说我可以帮忙,但还是想在家里自由一些。反正我主要也只是做引擎,稳定了后就没多少事了。不如给你们再做次网络兼职吧。

就这样,第二天我去了深圳转了转,见了几个老朋友,然后就回家了。


谢绝转载 :)

那些日子(目录)

May 01, 2008

那些日子(二)

我在北京生活了半年。接触北京这个城市要更早一些。大约 85 年的时候去过,一周时间几乎玩遍了北京所有的景点。小时候的记忆特别美好,我在那个时候爱上了北京。记忆中,天安门广场是那么的大,紫禁城的宫殿如此雄伟…… 以至于回到学校时,不知道用怎样的形容词才能形容。

10 多年后,我在学校的机房上网,泡 bbs ,做个人主页,写一些关于游戏的自己的想法。交了许多的网友。大家都是业余的,年轻气盛,想自己做出好玩的游戏。王欣是第一个给我发 email 的职业游戏人。更早的 97 年,国内有两家大的游戏公司,前导和腾图,有如台湾的大宇和智冠。可惜生不逢时,前导做不了大陆的大宇,腾图也远不及智冠。

腾图命中注定的散掉,王欣的八爪鱼工作室从腾图分的出来。98 年,王欣邀请我在假期去北京玩,他把我带进游戏这个圈子。我又有机会站在天安门广场,原来并没有那么大。我想,如果毛泽东纪念馆挪一下地方的话,广场会更宽广一些,和我儿时记忆中的一样。小时候怎么就没这种感觉呢 :) 。

那个年代,我成月成月的逃课,去北京帮王欣做些兼职工作,并听他说些早年北京游戏圈子有趣的八卦,有如今天我给新人说起往事。回忆起来,自己其实什么也没做,似乎又做过点什么,反正最后一次,我拿了一小笔兼职工资。不过没有花掉,因为回到学校的时候,一个同班同学缺钱交学费,我全部借给了他,毕业那天他才凑起来还我。

当然,身在北京,我就有机会四处拜访网友同好。随即发现,其实许多网友都已经专职在做游戏了。有些人后来再没怎么联系,比如曾经在金洪恩做《自由与荣耀》的 3d engine 的 rick huang ,我还记得他在那个晚上,他抱怨他的后继者让代码从几万行膨胀到十几万;又比如做《独闯天涯》的郭巍,他念叨过来北京前没有钱吃饭,小组里每个人一个冷馒头就可以啃一天,脑子里只想着把游戏做出来 ……

两个很重要的朋友,也是在那段时间见的面 —— 余雪松和吴东黎。我们通过在网易个人空间(当时叫 N-SPACE)交换链接认识的。他们搭档了很多年(直到今天),经历很传奇。

刚在网上认识他们的时候,他们还是业余在做,个人网站上放着一个 RTS 的 demo ,看起来很火暴。

据说早年他们在做别的软件,有个自己的小公司。做完个项目后,分了钱大家去北京散心,看看专业做游戏的公司是什么样子的。去过前导也去过腾图,不是去应聘,只是转转。这些“专业”的公司得到的业余者之评价是:不过如此。跟自己业余做的 demo 也差不多水准。

不过腾图把他们留了下来(有八卦说,前导的头儿追悔莫及)。就是那种很随性的,“不如你来上班吧”,旅人结束了自己的旅途。据说那个时候腾图偌大的公司,已经快散伙了,留了许多半拉子产品,补不完的 bug 。这是我听过国内游戏圈的历史中最传奇的故事,余雪松一个人修补了四个产品,把它们做到基本可以摆上货架。我是听别人转述的,但我相信那不是件容易的事情。

见到老余的时候,他们小组已经接受一家台湾公司的小额投资在做《烽火三国》。小组没做垮,产品上了市,那家台湾公司却先垮了。等我毕业再次来到北京,老余他们跟着谢成鸿在做 kele8 。


老谢,用过笔名“小谢”。我们居然很早就有过交情,在我的个人主页创办早期,他给我 email 来了几篇稿子,让我放上去。有兴趣的朋友可以看看怀旧 :)

老谢早期最有名的作品是一个 web 象棋,不需要下载就可以在网上和人对弈。这个东西曾经挂在 sina 的游戏版面很久,我想他是用这个淘到的第一桶金。当然更大的资金注入来至于当时如日中天的联众。btw, 第一次见到鲍岳桥的时候,我有种奇怪的感觉,中学时就在 UCDOS 上看到作者名字,我心目中的名人,原来也是个普通人。这种感觉在碰见求伯君时还有,等到日后见到丁磊时已经没有了。

老余听说我正闲着没事做,甚至也没有收入。他请我吃了顿饭。一共四个人,老谢、老余、老吴,还有我。一家很小的馆子,大家骑着自行车过去,点了些家常菜。2000 年的 9 月,老谢对 web game 充满信心。北京的夏天已到末尾,冬天不远了。当他邀请我去 kele8 的时候,我没有太犹豫。我不知道自己能做些什么,该做些什么。我知道这些朋友都有很好的技术,都有火热的激情,看起来不错,不是吗?

我的工资是 6k/月,第一个月发工资时,信封里装了 5500 ,我没有问,我想是扣了 500 的税吧。工资数字对我是无所谓的东西,真的。大学没毕业时,有个朋友说,来我这里干吧,一年 10 万。我在心里吐了吐舌头,这么多啊,父母为我读大学的学费和生活开销,攒了十年的钱,也不过四万而已;我和庞鑫等哥几个去忽悠风投的飞机上,庞鑫说,别不好意思,以后报自己的薪酬,只管写上五位数;我想我一个月吃饭不过几百块,一年难买两件衣服,能用上几个子呢,真的是无所谓的一件事情。


在北京的后几个月,我和安宁(以及嫂子),李民(庞鑫的同学)四个人租的屋子。在西直门外,出门就是北京最著名的西直门立交桥。老实说,并没有传说中的那么恐怖啦,我只迷路过一次而已。论可恨程度,远不及紫竹桥那个,南北不通,每次过都需要把自行车搬上搬下。

房租 2800 ,大约每人摊 1000 。我无所求,所以住的最小的一间。屋内空空,只有一张床和一口箱子。每天早上 9 点起床去上班,逆火的兄弟们在白石桥租的高层写字楼,我在魏公村。都不远,大家骑车即可。我的车是来北京后朋友送的,价值 20 块。没有后档泥板,一下雨,背后就是一条黑线。有一天下班时,魏公桥下没有人也没有车,我被黑暗角落窜出来的交警拦下,闯红灯,罚款 20 。他瞅了一眼我的破车,怎么没有车牌?我很想把车留给他,然后自己走回去。但是我没有,兜里只有 20 块,换了一张罚单。后来离开北京的时候,我把这辆破车停了某个天桥下,一年后等我再次到北京时,车居然还在,口袋里的钥匙也在。

在 kele8 的日子很闲,老谢不知道可以安排我做什么。老余说,等下一个版本,全部交给我来做。我就自己给自己找事情做。我去的时候,办公室里就 7 个人。两个美术,一个专心做 3d 模型,一个只会画平面的东西,但是画的真好。我原以为做游戏需要很多很多的美术,其实不用。合理的调配人力,帮助美术节省一些不必要的机械劳动,两个人也能做很多事出来。

程序算上老谢有 4 个。不过老谢写 java 的,老余写 C++ ,他们技术上合不来,而老余的技术和经验高很多,所以整个底层都是老余在做。吴东黎是个很有趣的人,年纪不小,没谈女朋友。和我一样,成天待在办公室。除了打 quake (技术真的很棒),没太见他玩别的游戏。你不可以说他的技术到底是好还是坏,讨论语言的细节他或许不行,但是他做东西就是来的很快。无论是用什么。他和老余是天生的搭档,余雪松设计出脚本语言,他就拿过来用,用的很好。另外一个哥们也是写脚本的,在 kele8 ,包括以后的大部分程序员都是工作在老余自己设计出来的脚本语言和开发集成环境上。


起初,我想写个 C 编译器玩儿。因为我觉得游戏做大了还是需要嵌入脚本,除了 C ,我对别的语言都没什么兴趣。写了一半,我又莫名其妙的喜欢上 javascript 和 css ,觉得设计的挺有趣。实现个 javascript 的解释器也不错,不过也没能实施这个想法。后来我读到了一本书:《 C ++ 编程思想》,海淀图书城里看到的。伫立在书架边,读了一个小时,而后就抱回了家。大约用了 2 天时间,没日没夜的啃,仔仔细细的读完了每一个字。

按理说,读初中那会儿,我就喜欢上了 C++ 。不过我的认识也就停留在了 92 年的国内翻译的一些 C++ 书籍上。2000 年底,《 C++ 编程思想 》这本书对我的冲击很大,我觉得我重新认识了 C++ 。我想我应该把“风魂”重新做一遍,用 C++ 。甚至我还觉得 kele8 的引擎做的不够 C++ ,比如我们应该用巧妙的继承和类层次关系去取代那些函数指针。而且老余那个时候跟我一样,不知道可以用 ->* 这样的操作符去用指针调用成员函数,const 这个关键字也没有被准确的使用,等等。

做产品毕竟不是研究技术,这些都是想想而已。我们只是每天在骑车回家的路上聊聊。

只记得那段时间做了两件事:一是把原来“风魂”里的声音播放的模块移植到 kele8 的引擎中,让那些 web game 能够发声。还有就是做一个台球的游戏的技术研究。

写了一个 2d 下 3d 效果带光照的球面渲染;以及做了一些碰撞方面的 demo 后,真正的 kele8 台球程序还是老余自己重新写的。我那个时候思维总停留在 C 和 C++ 上,用不惯那些脚本。老余倒是对自己的东西使的游刃有余,就在一个阳光明媚的早上,他兴冲冲从包里拎出硬盘,推入活动硬盘匣,给我展示了一晚上的成果:一个台球游戏基本可以玩了。

kele8 的台球这个游戏无疑是成功的。那段日子,我去台球俱乐部里打 snooker ,听到有人谈论它,心里都一阵得意,我也贡献了代码呢。


那个冬天还有什么?我给远方那单恋了 5 年的 mm 送了一大束百合,是在她的生日那天,没有留下我的名字。虽然她已有男友,但是后来我依然固执的打了一个月的电话。我本以为那个月的手机话费会爆掉,可实际上也不过 400 块多点。看来我不够疯狂,不知道李民怎样让话费一个月超过 1000 块的。吴东黎给我讲了老余过去的故事。那个时候他们两个单身汉合租,老余的女朋友还没有升级成妻子。一下班,就瞅见他就躲进屋子,到第 2 天早上要上班时,居然还没挂电话呢。

我想我不够疯狂。

在北京过的最后一个冬天,满是落魄。这是种内心的感觉。我觉得对不起给我发工资的人,对不起朋友。我没做出什么更有意义的事情。而大多数人都做的比我好。

2001 年的新年来的特别早,1 月 23 日是除夕,我们的春假放的更早。

事后我想,估计老谢明白我想离开。旧年里最后一个月的工资决定等年后再发。不过我领到了 800 元的新年红包。

我实在不好意思说辞职,因为似乎我没为团队做点什么就要走。回到家,我在网上留了言说想休个长假,好好的想想未来的计划。

每次我觉得对不起周遭的朋友们时,大家都表示出莫大的理解。我真的是一个幸运儿,拥有这样多的好朋友。每个人都能体谅我的自私。

那个时刻,我已打定主意离开北京了。


争取在 5.1 假期内多写一点,应该能写到大话西游项目的开始。原本还有很多的人很多的故事可以写,这里略过了许多。比如那些年出没在 sina 游戏制作论坛上的众多 id :小箭2000 (每年还在给我寄贺卡)、做模拟飞行的黄海、写“我的游戏梦”的指顾江山等等。那两年,在北京我见了许多人,跟许多朋友彻夜不眠的长谈。听了许多故事。自己也经历了许多。

每当我努力回忆一点,就会有如泉涌般的冒出来。甚至让我夜晚睡不着。我想人的记忆其实不会遗失,只是藏在那个角落里,等你努力挖掘的时候自然会蹦出来。

对想出现在这个故事中,却没能露脸的朋友说声抱歉了(我挺喜欢出现在别人的故事中,我想很多人都喜欢)。不是我已经忘记你们,也不是故事里的人对我更重要。我只是随机选择了一些片段记录。

10 年前的事情,真的是很模糊了。

最后,还是那样:谢绝转载。因为不能保证没有记忆的偏差,我希望有机会纠正。

那些日子(目录)