|
文/顾煜 原文链接:https://zhuanlan.zhihu.com/p/28812106
上回说到了团队的艰难磨合,对产品标准不一。然后提出了一个重要的问题,为什么团队没散伙分行李呢?
Surprising-Driven Development
凝聚团队有很多方法,大致来说,短线靠哄骗,长线靠愿景。天刀团队有意无意间,在这几点上做得都不错。
先看看短线怎么哄,基本是靠Leader们和组员谈心。天刀几个带团队的Leader性格大多柔顺,信奉天下没有咽不下的鸟气,默默做着居委会大妈的工作,劝员工们将就着把日子过下去。
老于作为上帝之鞭,负责抽打众生,人间哀鸿遍野。弥合鸿沟,需要云南白药创可贴。我就是传说中的创可贴,主美LXP也是。
LXP,好雄辩,美术周会,脱稿洋洋洒洒数小时,席间鼾声四起,众生默然不语。尝同Lxp至成都分公司,分享业务,因公务繁忙,未备PPT,是夜三更,觉有不敬,与之拟下四行提纲,翌日,虽千万人,吾等面无惧色,侃侃而谈。
老于爽完,员工们开始抱怨,我们的工作就开始了。口才就是生产力,天刀项目组的Leader们,生产力都是不错的。
美术原画来抱怨,表示老板审美不对啊,我画得辣么好,他不喜欢。主美LXP和她谈要接地气,审美要向劳动人民靠拢,劳动人民是先进生产力的代表,曲高和寡的艺术终究是没有生命力的。你看,色情艺术是多么接地气,多么被群众喜爱。说着说着,LXP感觉哪里不对,于是他机智的转过话题,表示老于是劳动人民的代表,是劳动人民推选出来带领天刀项目的(此处似有反动言论,老于不是领导派来带领天刀的么?)。美术动画又表示动作不好做啊,老板要求太高,我们就只有这点能力,LXP和他谈人有多大胆,地有多高产,你的征程是星辰大海,怎能被区区一个老于挡住视线。
渲染的Tough哥表示新做的渲染效果又被老于砍了,多年的技术积累不能放进版本,心里不爽啊。我表示凡存在必合理,但死去也有价值。大海生生不息,孕育生命,死去的巨鲸,化作鲸落,腐化和孵化,滋养着小生态。每一行被砍的代码,每一次不甘的怨气,每一场失败的争论,终成鲸落,孵化Bug,或衍生出新功能特性,或绊倒路过的程序和美术,遥想他们的狼狈,是多么快乐的事情。Old codes never die, they just fade away。老码不死,只是凋零,有什么可抱怨的呢?加油写出更多垃圾代码才是王道。
小方表示,老板太任性了,不就是做个小Demo嘛,怎么就这么高要求,咱们快点做新功能才是王道。我和他谈开发理念,说Verticle Slice,说做的功能越多,将来我写文章时被人喷的槽点就越多,不如做好做精。
小方又表示胡乱弄点特效在动画衔接处,盖住动画,就看不出动画抽动了,我讲了Steve Jobs要求设计师把mac电脑电路板都设计整洁的案例。传说乔布斯小时候看爸爸做木工,橱柜背后也是一丝不苟,用最好的木料,乔布斯不理解,爸爸告诉他,虽然别人看不到背后的木材,但是我知道啊。乔布斯用这个案例,压迫工程师把Mac电脑内部设计的非常精美,即使用户没机会看到。
故事讲完了,我笑着问小方你懂了没?小方表示:我懂了,乔布斯那么龟毛,难怪苹果后来差点倒闭,我们会不会倒闭啊,我还小我不想死,我还没结婚呐…我只好再解释,动画有没有衔接上,特效一盖,玩家就看不到了,但是老于知道啊,如果你能瞒过他,那我也不拦你。但那还不是最重要的原因,最重要的是,我们的小团队里,并没有特效人员啊,没法做特效帮你掩盖动画问题,别给组织添乱了。
团队来自五湖四海,四面八方,工作背景迥异,摩擦总是会有的。有没有好的润滑剂,有时候能决定大家可以走多远。天刀各位Leader,都担任了润滑剂的角色。
再说长线,共同的愿景,是吸引大家走到一起来的重要因素。【注意,前方高能,可重点喷】
软件工程这门学科,发展多年,留下了好多术语。众多术语中,Test-Driven Development深得我心,测试驱动开发的理念本就不错,更好的是这种英文表达方式,特别软件工程。随便什么事情,拿这个语法一套,就是浓浓的专业范,比如咱们日常开的小车,就是一种Human-Driven Car。
天刀项目的前期,应用的最重要的软件工程实践,是Old Yu Driven Development。而Old Yu驱动的力量过猛,Leader们的短线抚慰不足以平复员工心头的伤痕。我们还需要更长线的凝聚力。
项目长线的凝聚力,来自于Surprising Driven Development,我所谓的惊喜驱动。Surprising Driven Development有两层含义,一个含义是对内的驱动力,指团队的自我激励,我们在这篇文章讲,还有一个含义是指版本对外的目标设定,下一篇再谈。
做项目不是谈恋爱,团队并不因为情投意合而相遇,也不会因为各执一词而散伙。成年人看利益,一时的荣辱那都不是事儿,团队只会为了碌碌无为而恐慌。
当他回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞耻。
《科学炼钢指南》
天刀在漫长的开发过程中,充满了观念冲突、前途黯淡、方向不定,引导大家走出黑暗的,是一次又一次的版本。面包会说话(breadtalk),产品也会,Product talk,让版本证明自己,给大家注入鸡血。很多次都怀疑这条路是不是能走通,很多次都感觉进度来不及了,整合完不成了,Bug太多了,做得不爽不想干了,但最终版本出来的时候,大家会由衷觉得,这一切苦难都是值得的。【此处应有喷】
半年后的第一次内部Demo就是一个很好的例子。Demo之前,团队疲惫而绝望,老于指挥了这么久,一地鸡毛,做了很多片段,但所有的片段都没有拼接起来,大家有质疑,有不满。整合Demo时,团队一起crunch,拼起每一个碎片,发现所有的努力都没有白费。一直低头蹒跚前行,战争迷雾遮住归途,转过山头,前方是不曾看见的风景,谢谢你带我们来这里,这里有山花在烂漫,有老于在歌唱,画面美得不可言述。
一个又一个惊喜,先激励了自己,让大家有勇气继续前行。成功的团队,不是因为彼此没有矛盾,而是业绩的快速进步,缓解了问题。
妈妈说,只要你跑得足够快,问题就追不上你。
奔跑吧,兄弟们。
初啼
【这部分有较多逻辑方面技术讨论,无技术背景可略过】
又是半年。
团队继续补人,大约有10人不到,程序为主。完成了技能衔接、强交互体系后,我们开始做一个更完整的Demo。
小方和新来的毕业生K、毕业生F等继续在技能体系耕耘。毕业生J做了个Building Dashboard,方便持续集成和快速迭代。我抽空做了点引擎的基础体系,下篇再细说。
Tough哥开始发威,渲染方面做了个FFT的水,可与技能交互,一个圆弧斩技能发出,可以在水面划出一个圆形,水波荡漾,波光粼粼,甚是好看,当时还没怎么在别的游戏中见过类似的效果。很多渲染程序员似乎都会在职业生涯的某一个阶段做一次水的表现,然后大呼过瘾,表示太好玩了,Tough哥也不例外。技术宅的生活就是这么简单和单纯。
美术蹭大项目的外包预算,又从其他项目讨了点资源,拼了一个场景。因为是武侠,大家脑补了一个笑傲江湖的场景,主角就是太白门派,但当时起名叫做令狐冲,这个Demo的背景设定,暴露了老于的年龄和喜好。当时引擎还是2.5D视角,视线不远,美术做了个华山之巅场景,够容纳Demo的机场战斗。为了炫耀Tough哥的新科技,很小的山顶,硬是不科学的放进了一片水塘,水深及膝,方便大家在水潭中战斗,撩动一池春水。
做水的时候老于又是各种抽打,表示水的果冻感太强烈了,美术要用力调参数啊。场景美术调了很久,老于还是不满意,于是老于放出了大招,表示这个东西如果再调不好,我就不要了,砍特性。
Tough哥慌了,做了这么久,说砍就砍怎么行。Tough哥哭喊着刀下留人,然后拼死在国庆期间重写了一遍水的实现,居然在五天里面就做出了一个新的版本,效果还不错。我就感觉奇怪了,怎么之前那个迭代,花了这么久呢...最后主美LXP也亲自上,难过的调了一个通宵的参数,勉强过了关。类似的经历,在后续天刀开发过程中也很常见,老于不停地提高要求,用砍特性要挟团队,团队挣扎着努力着,试图保留一部分工作结果,有些特性活下来了,有些特性就这么被砍掉了。天刀的高端特性(仅指技术实现困难程度),被砍了很多,团队竟然一次次挺住了,和制作人讨价还价,争取着微不足道的buffer time,然后拼死加班,试图把特性塞进庞大的引擎架构,Tough哥做出了第一个好的榜样。
策划开始配置技能体系,除了现在喜闻乐见的太白技能,还加了一堆返技、摔投、解摔投的技能,反正怎么难实现,就怎么做,做新技能,程序的特殊支持必不可少,把小方压榨的吱吱乱叫。
找大老板汇报前两周,老于把我拖到一边,表示主角拖火车的时候,一堆敌人会追击主角,逐渐会跑到一起去(我们的敌人互相没有碰撞),最后就挤在一起,特别丑陋。当时挺多MMO游戏都是那样的,原因是敌人追击的时候,AI就是比较简单的取直线,往主角位置跑。然后主角一般都是绕圈跑,接近主角的时候敌人会停下攻击,后方敌人还在往前跑,几个来回,这些敌人和主角的位置差别就会很小,慢慢就叠到一起去了。
老于任性的表示:你想想办法?
仿照单机游戏的做法,加个碰撞是最简单的做法,但一方面来不及,另一方面性能开销也很多,更何况网游战斗要不要加碰撞,还有玩法上的考虑,也不是我说加就能加的。
回想起之前在Warhammer 40000的GDC分享中看见过,他们如何来控制小队AI,在战斗中保持一定的队形的文章。我从笔记中翻出来重读,发现就是想要的,再延伸读了几篇相关文章,结合我们的项目考虑一下如何应用和改良,就开始动手做。
我需要做的是加个新系统,不破坏原有系统,对上层和策划完全透明。这层系统要嵌在敌人AI层面,不能改变原有太多的行为。
好在服务器后台尚未接入,AI这一层东西之前单机也常做。最终我把可攻击主角的位置均分成N个站位点,前后排,然后AI寻路攻击主角的时候,分头声明我要去哪个站位点,往那个点跑,再加上点随机扰动,时不时交换一下站位,在寻路决策前再加点包抄因素,就基本可以了。像往常一样,整个系统开放出很多参数,我随手调了一个觉得还可以的参数,找老于来看,表示东西在这里了,有这么多参数,你找人细调一下?
凡是我不想做的,就弄成灵活的参数,让策划自己去调整。
By 何老师
据说有技术背景的老于一看众多参数,就晕了。但他临危不乱,强撑内心的不适,表示现在已经差不多了,就这么着吧,别调了...终于在汇报前最后一周搞定这个问题了。
汇报前最后两天,版本已经比较稳定成型,玩法微调一下,大家都很满意,两场杂兵战,一场boss战,风景秀丽,山清水秀,画面和玩法都不错,和市面游戏比,非常有竞争力。
但有随机crash,大约每过1-2小时会随机崩溃一次…都在release版本崩溃,每次dump都莫名其妙,逻辑上绝无可能,且每次不同。又是组织大家攻坚,但进展不大。
如果事情有变坏的可能,不管这种可能性有多小,它总会发生。
墨菲定理
必须搞定它啊,否则版本一定会在找老板汇报的时候崩溃。这个汇报可以在美术上出问题,可以在策划上出问题,可以是老于出问题,但绝不可以是程序这里的问题…更何况,他们几个环节都不怎么可能出问题啊。
最后从两个互相矛盾的Crash Dump里面,我发现,如果一定要说有问题,问题只可能出在我们用的引擎的Lock-Free库上了。一般对于这样底层的组件,总是认为它是正确,这个引擎被用在这么多项目,有问题早就出大事了,而且Lock-Free算法也特别费脑,一般不愿意怀疑和盘查。但两个矛盾的Dump分明表示,Lock-Free库出问题了。
马上要汇报了,不能太任性,来不及研究算法了,直接把引擎内跨平台的Lock-Free,替换成Windows提供的Lock-Free Queue,问题迎刃而解。这个引擎给我造成了这么大的麻烦,吸引了我的仇恨,为我事后的打击报复埋下了伏笔,下回展开讲讲。
终于,版本齐备,人员振奋。老于带领大家祭天,无辜的三文鱼、海螺们献上了卑微的生命,满足了我们的口腹。我们带着版本,扛着台式电脑,飞往总部,迎接命运的挑战。
下回预告:
汇报和陷阱,大危机和大机遇。
旧引擎忍无可忍,石头汤众筹开启。
|
|