[imagemagick]10 有个男孩子谈了快两个月,开房间聊天然后去外面网吧过一晚上

&img src=&/50/v2-11edc3a4cdb6ad0a655a2_b.jpg& data-rawwidth=&617& data-rawheight=&367& class=&origin_image zh-lightbox-thumb& width=&617& data-original=&/50/v2-11edc3a4cdb6ad0a655a2_r.jpg&&文/&a href=&/people/wu-sheng-chang-you/answers& class=&internal&&无声畅游&/a&&br&&br&&p&今年《网络创世纪》(UO)将迎来它的20岁生日,无独有偶,在新年伊始,UO的创造者之一理查德·加略特出版了一本自传,名为《探索/创造》(Explore/Create),讲述了他的很多不为人知的新奇故事。&/p&&br&&p&上世纪的单机游戏“创世纪”系列属于当时的欧美三大经典RPG之一,作为该系列的缔造者,加略特后来带队开发了《网络创世纪》(UO),于1997年上线,是第一款在市场上取得巨大成功的图形化MMORPG。在UO之前,网游市场主流还是Mud这种文字游戏,可见UO在网络游戏发展史上的深远影响。&/p&&img src=&/50/v2-54b0fa38fcf27dc44a92f4_b.jpg& data-rawwidth=&600& data-rawheight=&337& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&/50/v2-54b0fa38fcf27dc44a92f4_r.jpg&&&p&由于加略特曾在UO中自称“不列颠之王”,这个称号也伴随其终生,无论是媒体还是玩家都习惯于这么叫他。&/p&&br&&p&和一些早年功成名就的西方游戏设计者一样,掘得第一桶金的加略特这些年已经淡出了人们的视线(特别是在2009年离开NCsoft之后),他的个人生活丰富多彩,让普通人望尘莫及。2008年,加略特自费参与俄国联盟TMA-13号前往国际太空站的任务,成为世界上第六位太空游客——是不是让你想起一位喜欢玩火箭的游戏名人了?&/p&&img src=&/50/v2-f92630fabe6fa49239ec2_b.jpg& data-rawwidth=&660& data-rawheight=&440& class=&origin_image zh-lightbox-thumb& width=&660& data-original=&/50/v2-f92630fabe6fa49239ec2_r.jpg&&&p&前文提到的自传目前还没有中文版,我们的一位特约作者在读完这本书后写了一篇简评,你可以通过下文对书中的内容做一个直观的了解。&/p&&br&&p&● ● ●&/p&&br&&p&熟悉理查德·加略特的人都知道他是一个爱好广泛而又性情古怪的人,其举止总是异于常人。他喜欢收藏,但收藏的都是些稀奇古怪的东西;他花上千万美元去太空旅行,却拿不出区区几百万开发资金而求助于众筹,甚至搞出了卖血这种行为艺术;他顶着不列颠之王的头衔加入自己设计的游戏参与玩家互动,却被别人给搞死了;他给自己造了一座山尖庄园,从外面看去气宇非凡,内里却暗藏着一座阴森恐怖的地牢,里面摆满了各种惊悚骇人的物品道具,包括五件吸血鬼狩猎套装、三个干缩人头、两个木乃伊、三个棺材中的骷髅,还有人的心脏和胚胎。&/p&&br&&p&最近这位已逐渐淡出玩家视野的不列颠之王又出版了一本新书《Explore/Create》,其中为我们讲述了更多他不曾为人所知的新奇故事。有一次,一位狂热的粉丝贸然闯入了他的私宅(事后这位粉丝坚称是UO中的信息指引他到这儿来的),加略特匆匆跑到本来作为装饰用的藏枪室,操起一把乌兹冲锋枪,在得到警方的许可后开了枪,当然,他把子弹射进了墙里,而不是侵入者的脑袋,对方自然也知道加略特只是想吓唬一下他,他对于加略特的警告射击只是耸了耸肩,就不知跑到庄园里的哪一个角落去了,消失得无影无踪。&/p&&img src=&/50/v2-7eaa6eab55c9b5b6bfe076d8f8c369fc_b.jpg& data-rawwidth=&540& data-rawheight=&816& class=&origin_image zh-lightbox-thumb& width=&540& data-original=&/50/v2-7eaa6eab55c9b5b6bfe076d8f8c369fc_r.jpg&&&p&加略特还曾被困在泰坦尼克号里面差点出不来了,不开玩笑,我说的就是埋葬于大西洋四千米海底的真实版泰坦尼克号残骸。他当时乘坐一艘小型三人潜艇潜入这里,结果却被卡住了,他当时真的以为自己就这样完蛋了。他也去过正在迅速枯竭的亚马逊河,与鳄鱼和食人鱼为伴,没被吃掉实属命大。他甚至还在一场WBC超轻量级头衔争霸战中当起了著名拳手Jesús Chávez的场角指导。&/p&&br&&p&遨游太空无疑会是这本书中浓墨重彩的一个章节。实际上,加略特的父亲就是一名宇航员,身为一个标准的航二代,他却发现要想追随父亲的脚步并不容易,因为他的太空旅行计划从一开始就受到了NASA的阻扰,好在缺钱的俄国人帮他圆了这个梦想,为此他还学会了一些俄语。&/p&&br&&p&在太空中,他不仅欣赏到了迷人的景色,还积极参与各项科学研究项目,并与传奇宇航员Buzz Aldrin通话,他甚至毫不讳言在空间站上拉屎是件多么麻烦而又特别的体验。作为一名上过太空的名人,他后来还主持了世界上第一次在失重环境下举行的婚礼(一架万米高空的波音727)。他还在书中主动请缨,自愿参加未来的火星移民,或是探索土星和木星的卫星。“在最好的情况下,我将带着我的家人一起前往那里。”&/p&&img src=&/50/v2-11edc3a4cdb6ad0a655a2_b.jpg& data-rawwidth=&617& data-rawheight=&367& class=&origin_image zh-lightbox-thumb& width=&617& data-original=&/50/v2-11edc3a4cdb6ad0a655a2_r.jpg&&&p&&i&在国际空间站上度过的12天成了加略特一辈子的谈资&/i&&/p&&br&&p&书中自然也提到了他那著名的恐怖庄园,这是加略特花费数百万美元聘请数百名工人耗时六个月打造而成的,这里面有喷着火焰的排球场;类似于惊悚游乐设施那样的走廊,它以气动方式上升到空中然后又猛地撞向地面;以及由巨大的特斯拉线圈幻象环绕的囚笼,据说那些被特意关在这种囚笼中的游客都有一种濒临死亡的感觉,最起码也是吓尿了。&/p&&br&&p&他举行的派对也常有惊人之举。在他结束泰坦尼克海底探险返回家乡之后,在一个湖上精心准备了一顿以这次冒险为主题的船上午宴,甚至连当地的市长都应邀出席了。至于接下来发生了什么状况,请允许我这里卖个关子。但联想到加略特刚刚死里逃生的经历,你也许不难猜出他会整出什么幺蛾子。&/p&&img src=&/50/v2-6d8deccd5aa85fa02b05e_b.jpg& data-rawwidth=&549& data-rawheight=&745& class=&origin_image zh-lightbox-thumb& width=&549& data-original=&/50/v2-6d8deccd5aa85fa02b05e_r.jpg&&&p&&i&加略特庄园地牢中的恐怖一角&/i&&/p&&br&&p&当然,书中最有参考价值的部分还是他对自己青年时代和游戏从业经历的回顾,他理想中的游戏业绝不存在任何障碍和束缚,而只有尚未探知的领域。但现实中的游戏业,在他早年成名,一夜暴富之后变成了一个充斥着可卡因和跑车的名利场。他为金钱斗争过,挣扎过,也失去过朋友,甚至与兄弟为一点小利大打出手。&/p&&br&&p&UO无疑是加略特职业生涯的巅峰时刻,然而这个项目一开始根本无人在意,在公司内部还被戏称为“Multima”(创世纪原名为Ultima),处于EA食物链的最底端,开发员工挤在一个过道里办公,周围连墙面都没有,就用那种聚乙烯的板子隔着。即使在UO获得成功之后,他们的环境也没有改善多少。EA只想着如何以最短的时间从他们身上榨出更多的作品卖钱,如果榨不出,就把加略特架空,直到他彻底离开的那一天。在他从自己一手创建的Origin公司被炒掉之后,他开车来到了一家杂货店,坐在停车场里大哭了一场。&/p&&br&&p&Tabula Rasa是加略特离开EA加入NCSoft后开发的第一款游戏,然而这个项目从一开始就陷入了百般不顺的困境之中。NCSoft本来想把它树立为东西方开发商之间的一次合作典范,但实际上双方根本就无法沟通。&/p&&br&&p&“我们本来应该先关停这个游戏,清点我们的损失,然后换一个新的名称重新来过”加略特事后检讨说。然而,Tabula Rasa还是以半成品的状态发售,运营了才一年即告关服,而加略特也再一次被赶走。&/p&&br&&p&&strong&NCSoft巧妙利用加略特刚从12天太空旅行返回地面接受隔离调整的真空期,在游戏社区假以他本人的名义发表了一封公开信,称自己是自愿离开,&/strong&活脱脱地上演了一部“总有刁民想害朕”的现实版。&/p&&img src=&/50/v2-25d0baaad5bcf8_b.jpg& data-rawwidth=&635& data-rawheight=&291& class=&origin_image zh-lightbox-thumb& width=&635& data-original=&/50/v2-25d0baaad5bcf8_r.jpg&&&p&&i&即使在他最新的作品Shroud of the Avatar中,仍然少不了山尖庄园的身影&/i&&/p&&br&&p&《Explore/Create》这本书并没有谈到他最新的游戏Shroud of the Avatar,但通过这本书对他过往生活和工作经历的总结,我们不难发现加略特在经历了大起大落的职业生涯后(一如他从太空到深海的探险经历),现在急需这样一部新作为自己正名,而他写下这本书的目的,恐怕也不是为了缅怀自己辉煌的历史,而是给过去的自己做一个了结,继而开启人生的下一个篇章。&/p&&p&&img src=&/50/v2-c464f59afca5beea07f1ff_b.jpg& data-rawwidth=&655& data-rawheight=&436& class=&origin_image zh-lightbox-thumb& width=&655& data-original=&/50/v2-c464f59afca5beea07f1ff_r.jpg&&&i&如今已头须花白的加略特颇有几分而今迈步从头越的味道&/i&&br&&/p&&br&&br&&p&&u&关注我们的公众号“游戏研究社”,可第一时间接收优秀文章与原创视频的集中推送。&/u&&/p&
文/ 今年《网络创世纪》(UO)将迎来它的20岁生日,无独有偶,在新年伊始,UO的创造者之一理查德·加略特出版了一本自传,名为《探索/创造》(Explore/Create),讲述了他的很多不为人知的新奇故事。 上世纪的单机游戏“创世纪”系列属于当时的欧美…
&img src=&/50/v2-1bab96fe5da7497_b.png& data-rawwidth=&1336& data-rawheight=&540& class=&origin_image zh-lightbox-thumb& width=&1336& data-original=&/50/v2-1bab96fe5da7497_r.png&&&b&以下内容节选自知友 &a href=&/people/507bf143a3caf2ad4fd6129ebc3aa278& data-hash=&507bf143a3caf2ad4fd6129ebc3aa278& class=&member_mention& data-title=&@桥东里& data-editable=&true& data-hovercard=&p$b$507bf143a3caf2ad4fd6129ebc3aa278&&@桥东里&/a& 的新书&a href=&/publications/hour/& class=&internal&&《我不了解人类:12 个真实的人类故事》&/a&&/b&&p&2015 年有一部日本小说被译成中文,是讲一群编辑用十五年时间编了一部词典《大渡海》的,名字叫《编舟记》。小说几年前还拍成了电影,口碑非常好,在日本拿到好几个大奖。&/p&&p&《大渡海》只是一部中型词典,完成它也花了十五年。&/p&&p&前几年还有一件事触动了不少人。1978 年,车洪才接受了编写《普什图语汉语词典》的任务。2012 年,他把 5.2 万个词条、15 万张卡片、200 多万字的词典原稿交付商务印书馆,那里的工作人员竟然完全不知道是怎么一回事。&/p&&p&车洪才为此付出的是三十多年的劳动。在这三十多年里,没有人过问他的工作。&/p&&p&要说世界上最漫长、最寂寞、最耗费人之生命的工作,莫过于编写词典。&/p&&p&古往今来,最著名、最伟大、最能成为词典之万世典范的,如果只能有一个选择,那肯定会是——《牛津英语词典》(Oxford English Dictionary,简称 OED)。&/p&&img src=&/v2-39bc2a1693_b.jpg& data-rawwidth=&600& data-rawheight=&259& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&/v2-39bc2a1693_r.jpg&&&p&OED 的编纂,是一项历时七十年的庞大工程。1857 年,一群饱学之士在伦敦决定要编一部规模与复杂性远远超过一切前人成就的「大词典」。过了二十二年,词典的正式编纂工作才得以起步。他们之中没有人能够看到这部词典最终完成,因为那是七十年后的 1927 年。12 巨册,414825 个词条,1827306 条引语,词典由手工排版,全部活字的总长度为 178 英里,相当于从伦敦到曼彻斯特郊区的距离。不算标点符号和空格,共有
个字母和数字。&/p&&p&别种语言的词典有费时更长久的,但是没有一本词典比牛津大词典更雄伟壮丽,更具有权威性。它是发明印刷术以来最伟大的印刷品,是最长的、最激动人心的书系。&/p&&p&在编写 OED 的漫长岁月里,发生了很多为人津津乐道的故事。而「教授与疯子」,则是其中最离奇的一桩。&/p&&p&这个故事有两个主人公。一个是美国人威廉·迈纳。他于 1834 年出生在锡兰,就是今天的斯里兰卡,直到成长到十四岁,大到足以对海滩上年轻的当地姑娘产生情欲,他才被送回美国。&/p&&p&这预示着他的一生都会被性欲和负罪感苦苦折磨。&/p&&p&三十岁,他作为军医参加了南北战争。在一次惨烈至极的战役中,他被迫给逃兵行烙刑,就是在逃兵的屁股、大腿或脸上用烙铁印上字母 D。&/p&&p&迈纳吓坏了,又不得不执行命令。这也许就是触发他精神病发作的原因。他开始过上乌七八糟的生活,流连于酒吧和妓院,染上了性病,神志也发生了问题。1868 年,医生指出他的心智开始失常。在精神病院住了一年半之后,他只能退役。&/p&&p&用今天的眼光来看,困扰他的也许正是在经历过战争的人身上大量发现的「创伤后应激障碍」。《阿甘正传》的丹中尉就是一个典型案例。&/p&&img src=&/v2-6c91c36f7bccfdbd68ae48e193bf584d_b.jpg& data-rawwidth=&390& data-rawheight=&540& class=&content_image& width=&390&&&p&迈纳买了一张去英国的船票。&/p&&p&1872 年 2 月 17 日凌晨,陷入疯狂的迈纳在伦敦郊外用手枪打死了一个有六个孩子的司炉工,当场被捕。&/p&&p&他告诉审问者,连续好几个月,每天晚上他一睡着,就有不认识的人钻进他的房间里,用无法形容的方式侮辱他,虐待他,折磨他。&/p&&p&出事那天晚上,他突然惊醒,觉得有一个人站在床头。他伸手到枕头下面去摸枪,那人就跑了,他追出去,看见一个人在路上跑。他冲那个人叫喊,然后开了四枪。&/p&&p&他的律师在法庭上只说了一句话:「很明显,当事人有精神病,因此陪审团应该把他当精神病人对待。」&/p&&p&陪审团裁决迈纳无罪。但主审法官的判决是这样的:&/p&&p&「迈纳医生,你将受到安全的监护看管,直到女王陛下乐意变更之时为止。」&/p&&p&所以,他就被关进了布罗德莫刑事精神病院。永久关押。&/p&&p&不过,迈纳只是失去了自由而已。因为他本身是个医生,没有癫痫病,不太可能自杀,也不至于会伤人,所以得以住得比较舒适而体面,院方也给予他一定的活动自由。&/p&&p&他还有每年一千二百美元的退休金。很丰厚,足够满足他的最大癖好了。那就是——读书。&/p&&p&他要求把家中的藏书全部寄来,又从伦敦的各大书店订购了一批又一批的新书和旧书。没事就读书。&/p&&p&迈纳依然会被幻觉所困扰。一到晚上,他就用家具顶住门,用绳子系住门把手。但没用,早晨醒来,他就会抱怨晚上有人把毒药灌进他嘴里。有一次,他还对人说,他被带到遥远的君士坦丁堡,在那里被迫当众进行淫秽表演。&/p&&p&但是在此之外的时间里,他表现得清醒而理智。读书、画水彩画、吹笛子、做园艺。他安心地在这座精神病院里生活。&/p&&p&发展到这里,还只是一个中年男人斗心魔的故事。这和编词典有什么关系吗?&/p&&p&有,直到有一天迈纳看到一份类似传单的印刷品。&/p&&p&这时候该另一个主人公出场了。他是英国人詹姆斯·默里,在一生的后四十年里他是 OED 最伟大的主编。&/p&&img src=&/v2-80d761bec86e7c48650e_b.jpg& data-rawwidth=&468& data-rawheight=&338& class=&origin_image zh-lightbox-thumb& width=&468& data-original=&/v2-80d761bec86e7c48650e_r.jpg&&&p&默里比迈纳小三岁。他是穷人家的孩子,十四岁就离开学校,但十七岁就在家乡当了小学副校长,二十岁成为正校长。后来他搬到伦敦做银行小职员,业余研究语言学。&/p&&p&他的知识广博得吓人。他在一封写给大英博物馆的求职信里这样自我介绍:&/p&&blockquote&我应当说,语文学,不论是比较语文学或是专门语文学,都是我毕生爱好的学问。我一般地掌握了雅利安语系和叙利亚-阿拉伯语系的各种语言与文学知识,不是说我样样都精通,而是说我掌握了普遍的词汇和结构知识,只要稍加努力,便能熟悉运用。我比较熟悉其中的几种,例如罗曼语支系中的意大利语、法语、加泰隆尼亚语、西班牙语、拉丁语,也稍懂一点葡萄牙语、瑞士沃州方言、普罗旺斯语,以及各种方言。在条顿语支系中,我相当熟悉荷兰语(我在商业来往通讯中要接触到荷兰语、德语、法语,偶尔还有其他语言)、佛来芒语、德语、丹麦语。对于盎格鲁-撒克逊语和密西哥特语我作过较深的研究,写过若干论文准备出版。我懂一点凯尔特语,目前正在学习斯拉夫语,对俄语已稍能运用。在古代阿契美尼德王朝波斯楔形文字以及古印度梵文方面,我为了研究比较语文学也懂得一些。我对希伯来语和古叙利亚语的掌握程度,使我能够读懂希伯来语的《旧约圣经》和伯西托本《圣经》。我也略知阿拉姆的阿拉伯语、科普特语、腓尼基语,是格泽纽斯语法入门的水平。&/blockquote&&p&作为学渣,只能颤抖着献上膝盖了。&/p&&p&不可思议的是,默里的求职被大英博物馆拒掉了。他差一点就只能终身做一个业余学术爱好者。还好,他结识的两个朋友推荐他加入了语文学会。之后,他发表论文,顺理成章地崭露头角。&/p&&p&1879 年,42 岁的默里终于成为那部词典的主编。当时看起来这不是多大的荣耀,因为对工作难度的严重估计不足,词典的编纂停滞不前,可以说是一个烂摊子。&/p&&p&除了显而易见的巨大工作量之外,这部词典到底有什么难编的?&/p&&p&首先你要知道,它要做什么事。它要——&/p&&p&描述英语的全部词汇:每一个字,每一点细微的差别,每一点意义、拼法、读音上的差异,每一个词源演变的转折,每一位英语作家可供阐释词义的引语。&/p&&p&它要——&/p&&p&为了查清每个词的生活史,写出它的传记,重要的是知道这个词是何时产生的,给它作个出生记录。不是说它何时出现在口语中——在没有录音带留下的条件下,无法知道这一点——而是说它何时首次被写下来。&/p&&p&其次你要知道,它要怎么做——阅读与每一个词发展过程有关的一切资料,从中找出最古老的引语来。&/p&&p&「一切资料」,这简单的四个字意味着什么?&/p&&p&默里当上主编之后写过一篇征求志愿者的呼吁书(就是迈纳读到的那一份),粗略地描绘了需要做的事情,以下就是「一切资料」之中在当时当务之急的部分:&/p&&blockquote&从英语的早期到印刷术发明,已经阅读或正在阅读大量书籍,因此不需要外来的协助。然而,早期印刷的书籍——卡克斯顿及其后继人印出的书,还没有人阅读过,如果有人有机会或有时间读到这些书的原本或复制品,将给我们提供极有价值的帮助。16 世纪后期的文献已经大体读过,但还有几本书等待阅读。17 世纪的作者大为增加,自然就留下更多尚未探索的空间。19 世纪的书籍,大家都容易接触到,所以读到的书很广泛,但是也有不少未读的书,不仅是在词典工程停顿的近十年内刊行的新书,也有一些早期的书籍。然而,最需要帮助的是在 18 世纪。美国曾许诺将 18 世纪的部分在美国完成,但这项许诺……未曾实现。我们必须呼吁英国的阅读者来分担这个任务。这个时期几乎全部书籍,除了柏克(Burke)的著作之外,都尚未读过。&/blockquote&&p&知道了吧?简而言之,他们要做的,就是在浩如烟海的用英语写成的一切文献之中,找出某个词第一次出现的那句话。&/p&&p&这需要庞大的人力。所以 OED 不可能是由一两个人或一个小型班子全部做得来的,从一开始它就需要发动群众,需要一批志愿者挺身而出。&/p&&p&志愿者的责任很简单,也很繁重,就是告诉语文学会他们愿意读哪些书,然后从读过的文献中列出词汇表,编辑再请他们专门寻找某些用得着的词。志愿者使用纸条,在纸条左上角写上那个词,往下一行写出引文出现的日期,再顺序写出书刊名称、卷数和页码,再往下一行,写出阐明词义及用法的句子。&/p&&p&迈纳觉得他能行。&/p&&p&他马上写信给默里,报名参加。地址只写着「伯克郡,克劳索恩,布罗德莫」。条件符合,默里回信表示感谢,并且寄来进一步的工作说明。&/p&&p&默里后来说:&/p&&blockquote&&p&我从来没有想过迈纳到底是什么人。我以为他也许是一个有文献爱好和大量闲暇的开业医生,要不就是已经退休,没有别的事情干的外科大夫。&/p&&/blockquote&&p&迈纳接到默里的信,花了几周来考虑什么是完成工作的最佳途径。最后,他想好了,开始动手。&/p&&p&他有很多书,又有很多时间,而且他还是一个很有创造性和独立见解的人,做这件事真是再合适不过了。他采用自己的一套方法,做完一本书的词汇表就接着做下一本,在接受任务之后的三四年里,一直没有把哪怕一条引语寄给默里。词典的编辑们可能都已经忘记他了,也可能以为他觉得工作太艰巨,自动退出了。&/p&&p&OED 的第一分册在 1884 年 1 月 29 日出版。一共有 352 页,包含从 A 到 Ant 的词语。解释最简单的单词「a」就占了四页篇幅。&/p&&p&这一年年底,迈纳终于要正式入场了。他积累了一定数量的材料,手头有大量带着适用引语的词汇。他写信问编辑们他们正在进行哪些词语的工作,如果他记录了这个词,他可以立刻找出来,随时供应最适用的引语。&/p&&p&别的志愿者只是「我找到什么给什么」,只是按照指示阅读指定书籍,然后寄出纸条。迈纳却是「你想要什么我给什么」。&/p&&p&1885 年春天,第一个从布罗德莫寄出的包裹到达 OED 的编辑们手上。以后他们每个月都能收到,再后来是每周。每周超过一百条引语,全部抄写得整齐清晰。这样的馈赠一直持续了二十年。&/p&&p&在 OED 这个大工程之中,迈纳一共寄出了一万多张纸条。这个数目看上去不算很大,但是质量高,几乎条条有用,是「私人订制」,所以他的贡献比那些每年投出一万条的志愿者要大。&/p&&p&OED 的编辑部对他深怀感激。1888 年,词典第一卷出版,前言中有一行提到了他的名字。迈纳对此可开心了。&/p&&p&但每个编辑内心也越来越疑惑:这从来不露面的神秘医生到底是何方神圣?&/p&&p&默里也很奇怪。刚巧有一次,他的一个美国朋友和他聊天,无意中说到:「你在词典序言中提到了可怜的迈纳医生,这使美国人很高兴。他的事情很令人伤心。」&/p&&p&默里大吃一惊。这才知道了事情的真相。&/p&&p&一个对人类最重要的智慧结晶发挥了如此重要作用的人,同时却是一个在非理性的幻觉之中沉陷多年的人,一个曾经被欲望驱使犯下如此骇人罪行的人。&/p&&p&人的复杂与不可理解,于此可见一斑。&/p&&p&1891 年 1 月,我们故事的两个主人公终于进行了历史性的会面。默里去了精神病院探望迈纳。&/p&&blockquote&我发现他的头脑和我一样清楚,至少我见到的是如此。他是一位很有修养的学者,艺术兴趣广泛,有着基督徒的良好性格,对于自己悲惨的遭遇已经听天由命,只是由于发挥作用受到限制而感到悲哀。&/blockquote&&p&让后人惊奇的是,两个人的相貌出奇相似。都是高个子,瘦身材,秃脑门,胡子又白又长,末端分开。&/p&&p&这也是故事的传奇性之一吧。&/p&&p&故事的尾声令人感伤。&/p&&p&理性已经越来越难以控制迈纳的妄想了。1901 年,他没有给默里寄去任何 Q 字母的引语。&/p&&p&1902 年 12 月 3 日,在他身上发生了骇人听闻的事件。&/p&&p&我说过,在他的一生里,强烈的性欲和负罪感一直在折磨他。他憎恨自己的生理反应。&/p&&p&因此,唯一的解决办法就是——&/p&&p&自我阉割。&/p&&p&他用一根细线紧紧扎住丁丁的根部,防止血液流通,用院方特许他拥有的削笔刀把丁丁割了下来,然后扔进壁炉里。&/p&&p&他躺了一会儿,再走到门口,呼叫护理员。&/p&&p&在医务室里住了一个月,他就痊愈了。问题解决了。&/p&&p&但他对 OED 没有再做过什么贡献。精神病院的新院长对迈纳的态度很差,对他的优待被收回了。他年老体衰,在异国他乡孤独地生活了三十多年,他该回家了。&/p&&p&1910 年 4 月 16 日,迈纳被送往伦敦,他将从这里出发回美国。他和默里见了最后一面,他们俩握手告别,闪着泪光,心里都明白这是两人生命中的最后一次见面。&/p&&p&迈纳带走的是到那时候为止出版的 OED 的六个分册。&/p&&p&他回到华盛顿,住在华盛顿公立精神病院,身体非常虚弱,直不起腰,抬不起脚,牙齿和头发全掉光了。他再也没有性功能,但仍然有小女孩潜入他的梦中,强迫他做下流的动作。&/p&&img src=&/v2-bfab_b.jpg& data-rawwidth=&250& data-rawheight=&191& class=&content_image& width=&250&&&p&1920 年 3 月 26 日,迈纳在睡梦中去世。&/p&&p&默里比他早死了五年。1915 年 7 月 26 日,他死于胸膜炎。直到去世,他一直在做着 OED 的编辑工作。&/p&&p&OED 的最后完成,比迈纳的死还要晚八年。1927 年的除夕,经历了七十年间无数人的艰苦工作,OED 终于全部付印,大功告成。&/p&&p&只有一个词被遗漏了。bondmaid 这个词在以前的词典里曾经出现过,但默里把它放错了地方。&/p&&p&当然,1933 年的增补卷不会再忘记它。&/p&&p&1972 年至 1986 年又出了四本增补卷。1989 年发行了电脑编排的第二版,二十卷。现在正在编纂第三版,但据说第三版只会以电子形式发行。&/p&&p&所有出现过的智慧的、冷静的、疯狂的、邪恶的心灵和头脑,都会随着时间的流逝而烟消云散。&/p&&p&那个伟大的时代,再也不会回来了。&/p&&p&&b&欢迎移步购买知乎电子书:&a href=&/publications/hour/& class=&internal&&《我不了解人类:12 个真实的人类故事》&/a&&/b&&br&&/p&&h2&目录&/h2&&ul&&li&他是精神错乱的杀人犯,但他编了历史上最伟大的词典&br&&/li&&li&他以天才小说家的才能愚弄了整个国家,以及这个国家最有势力的人&br&&/li&&li&阿波罗 13 号:一次失败的太空任务,却失败得很伟大&br&&/li&&li&她死了,但她的细胞永远不死,而且是几百年来最重要的医学成就之一&br&&/li&&li&他着迷于收集诺贝尔奖得主的精子……这位古怪的亿万富翁说这是为了全人类的进步&br&&/li&&li&他是脱离了低级趣味的太子党,成就领先世界,却被我们遗忘了&br&&/li&&li&被抨击、被压制、被漠视,可过了半世纪,他用诺贝尔奖证明自己是对的&br&&/li&&li&整整 32 年,他战胜了精神分裂症,还推动了一场民权运动&br&&/li&&li&这个叫福尔摩斯的不是神探,倒是连环杀手的祖师爷&br&&/li&&li&谁都不准把烂尸体放在拖把柜里!人类学系主任也不例外&br&&/li&&li&全世界的专家都想不通的问题,被他一个挖土的破解了&br&&/li&&li&你们不能因为我读书少,就这样欺负我啊&/li&&/ul&
以下内容节选自知友
的新书2015 年有一部日本小说被译成中文,是讲一群编辑用十五年时间编了一部词典《大渡海》的,名字叫《编舟记》。小说几年前还拍成了电影,口碑非常好,在日本拿到好几个大奖。《大渡海…
首先声明这并不是一片朋友圈文章,标题中的“世上最难”不是我说的,是wikipedia说的(见&a href=&/?target=https%3A//en.wikipedia.org/wiki/The_Hardest_Logic_Puzzle_Ever& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Hardest Logic Puzzle Ever&i class=&icon-external&&&/i&&/a&)。&p&故事的开始是苦逼的博士狗们一起赶作业,然后&a href=&/people/75a2edc58ed3e8fd89df5ecf7f8f872d& data-hash=&75a2edc58ed3e8fd89df5ecf7f8f872d& class=&member_mention& data-editable=&true& data-title=&@尘锐案& data-hovercard=&p$b$75a2edc58ed3e8fd89df5ecf7f8f872d&&@尘锐案&/a& 突然就把这个东西搬了出来,然后大家瞬间两眼放光,纷纷抛弃了作业……当然主要的讨论都是&a href=&/people/055e67cff14ec9b20cceccf& data-hash=&055e67cff14ec9b20cceccf& class=&member_mention& data-title=&@Y. Huang& data-editable=&true& data-hovercard=&p$b$055e67cff14ec9b20cceccf&&@Y. Huang&/a& 和&a href=&/people/75a2edc58ed3e8fd89df5ecf7f8f872d& data-hash=&75a2edc58ed3e8fd89df5ecf7f8f872d& class=&member_mention& data-editable=&true& data-title=&@尘锐案& data-hovercard=&p$b$75a2edc58ed3e8fd89df5ecf7f8f872d&&@尘锐案&/a& 进行的,我只是听懂并且理解了他们的做法,不过实在是很有意思,所以记录一下:&/p&&h2&1.问题&/h2&&p&问题的是这样的:世上存在三个神,分别是True,False和Random。其中&/p&&ul&&li&T神只说真话&/li&&li&F神只说假话&/li&&li&R神每次在听完问题后,抛一枚硬币来决定说真话还是说假话&/li&&/ul&&p&它们现在就在你面前,但是你不知道哪个神是哪个神。你有三次机会来试探,每次机会你可以说出一个Statement,并找其中一位神来给出判断(true/false)。 神总是能听懂你的语言,并给出按照它设定的回答,但是它会用自己的语言来回答,它会回答X或Y。你知道其中一个代表true,另一个代表false,但是并不知道哪个代表哪个。&/p&&p&问题来了:你能在用完三次机会后,判断出三位神各自的身份吗?&/p&&br&&p&下面是答案 &/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &/p&&p&&b&&u&先仔细考虑之后,再看答案!&/u&&/b&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &br&&/p&&p&下面是答案 &/p&&p&下面是答案 &/p&&h2&2.答案&/h2&&p&答案是:可以。&/p&&br&&p&甚至我们可以做到更强:每次都可以随机问一个神(In particular,可以做到每次都问同一个神,或者依次问完所有神)&br&&/p&&p&事实上,我们有如下定理&/p&&p&定理:对于任意一个Statement &img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&,存在一个Statement&img src=&/equation?tex=P%28Q%29& alt=&P(Q)& eeimg=&1&&,使得任意一位神对&img src=&/equation?tex=P%28Q%29& alt=&P(Q)& eeimg=&1&&给出的判断,在我们自己给定的翻译下,都是对&img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&正确的判断。&/p&&p&而这个&img src=&/equation?tex=P%28Q%29& alt=&P(Q)& eeimg=&1&&的存在性,是我们反推出来的。当时的情况是:&a href=&/people/055e67cff14ec9b20cceccf& data-hash=&055e67cff14ec9b20cceccf& class=&member_mention& data-title=&@Y. Huang& data-editable=&true& data-hovercard=&p$b$055e67cff14ec9b20cceccf&&@Y. Huang&/a&不知道从哪里知道了有这个定理,于是我(ta)们(yi)一(ge)起(ren)把这个&img src=&/equation?tex=P%28Q%29& alt=&P(Q)& eeimg=&1&&推导了出来。&/p&&p&事实上,考虑如下的一个图:&img src=&/equation?tex=Q%5Crightarrow+P%28Q%29%5Crightarrow%5E%7B%5Ctext%7BGod%7D%7D+%5C%7BX%2CY%5C%7D%5Crightarrow%5EI+%5C%7BT%2CF%5C%7D& alt=&Q\rightarrow P(Q)\rightarrow^{\text{God}} \{X,Y\}\rightarrow^I \{T,F\}& eeimg=&1&&。这里,God箭头表示神给出了判断,&img src=&/equation?tex=I& alt=&I& eeimg=&1&&是我们自己对神的语言的解释,我们希望最后这个复合函数给出了&img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&的判断,也就是说,我们希望如下的复合是一个恒等映射&/p&&img src=&/equation?tex=%5C%7BT%2CF%5C%7D%5Crightarrow%5EP+%5C%7BT%2CF%5C%7D%5Crightarrow%5E%7B%5Ctext%7BGod%7D%7D+%5C%7BX%2CY%5C%7D%5Crightarrow%5EI+%5C%7BT%2CF%5C%7D& alt=&\{T,F\}\rightarrow^P \{T,F\}\rightarrow^{\text{God}} \{X,Y\}\rightarrow^I \{T,F\}& eeimg=&1&&&p&所以我们有&img src=&/equation?tex=I%5Ccirc+%5Ctext%7BGod+%7D%5Ccirc+P+%3D%5Ctext%7Bid%7D& alt=&I\circ \text{God }\circ P =\text{id}& eeimg=&1&&,我们对God函数唯一知道的事情是:它是一个双射。也就是说,它一定会把&img src=&/equation?tex=T& alt=&T& eeimg=&1&&(true)映射到&img src=&/equation?tex=X%2CY& alt=&X,Y& eeimg=&1&&中的一个,然后把&img src=&/equation?tex=F& alt=&F& eeimg=&1&&(false)映射到另一个。所以我们可以写下如下等式:&img src=&/equation?tex=P%3D%5Ctext%7BGod%7D%5E%7B-1%7D%5Ccirc+I%5E%7B-1%7D& alt=&P=\text{God}^{-1}\circ I^{-1}& eeimg=&1&&&/p&&p&我们好像几乎做完了(因为找到了&img src=&/equation?tex=P& alt=&P& eeimg=&1&&的表达式),但是又好像什么都没做(&img src=&/equation?tex=%5Ctext%7BGod%7D%5E%7B-1%7D& alt=&\text{God}^{-1}& eeimg=&1&&是个什么鬼!)&/p&&p&我们作如下观察:&/p&&ol&&li&&img src=&/equation?tex=I& alt=&I& eeimg=&1&&是我们&b&自己选择&/b&的解释,所以我们可以给出自己的规定,比如:&img src=&/equation?tex=I%28X%29%3DF%2CI%28Y%29%3DT& alt=&I(X)=F,I(Y)=T& eeimg=&1&&。也就是说,God说X,我们就认为它说False;God说Y,我们就认为它说True。&br&&/li&&li&假如&img src=&/equation?tex=I%5Ccirc+%5Ctext%7BGod+%7D%5Ccirc+P+& alt=&I\circ \text{God }\circ P & eeimg=&1&&把&img src=&/equation?tex=T& alt=&T& eeimg=&1&&映射到&img src=&/equation?tex=T& alt=&T& eeimg=&1&&,那么它已经是个恒等映射了。因为每一步都是双射,而一共只有两个元素,只要一个元素对,另一个元素就一定是正确的。&/li&&/ol&&p&所以我们只需要&img src=&/equation?tex=%5Ctext%7BGod%7D%5Ccirc+P%28T%29%3DI%5E%7B-1%7D%28T%29%3DY& alt=&\text{God}\circ P(T)=I^{-1}(T)=Y& eeimg=&1&&,下面是睁大眼睛的时刻:&/p&&p&假如&img src=&/equation?tex=P%28T%29& alt=&P(T)& eeimg=&1&&是true statement, 也即&img src=&/equation?tex=P%28T%29%3DT& alt=&P(T)=T& eeimg=&1&&,我们有如下等价&/p&&img src=&/equation?tex=P%28T%29%5CLeftrightarrow+P%28T%29%3DT+%5CLeftrightarrow+%5Ctext%7BGod%7D%28P%28T%29%29%3D%5Ctext%7BGod%7D%28T%29+%5CLeftrightarrow+Y%3D%5Ctext%7BGod%7D%28T%29& alt=&P(T)\Leftrightarrow P(T)=T \Leftrightarrow \text{God}(P(T))=\text{God}(T) \Leftrightarrow Y=\text{God}(T)& eeimg=&1&&&br&&p&所以!&img src=&/equation?tex=P%28T%29& alt=&P(T)& eeimg=&1&&这个statement就是在说&img src=&/equation?tex=%5Ctext%7BGod%7D%28T%29%3DY& alt=&\text{God}(T)=Y& eeimg=&1&&,翻译一下就是:你对“truth”的判断是&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&。&/p&&p&我们来考虑一下真值表,假设神的语言是&img src=&/equation?tex=X& alt=&X& eeimg=&1&&代表true,&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&代表false&/p&&ul&&li&假如是True神,那么对它来说: truth的判断是&img src=&/equation?tex=X& alt=&X& eeimg=&1&&。所以我们的statement是假的,从而它要说&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&。经过我们的解释函数&img src=&/equation?tex=I& alt=&I& eeimg=&1&&,我们得到了回答&img src=&/equation?tex=T& alt=&T& eeimg=&1&&。&br&&/li&&/ul&&br&&li&假如是False神,那么对它来说:truth的判断是&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&。所以我们的statement是真的,从而它要说&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&。经过我们的解释函数&img src=&/equation?tex=I& alt=&I& eeimg=&1&&,我们得到了回答&img src=&/equation?tex=T& alt=&T& eeimg=&1&&。&/li&&p&现在我们可以把&img src=&/equation?tex=T& alt=&T& eeimg=&1&&换成我们想要的任何statement &img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&了。&/p&&p&比如,&img src=&/equation?tex=Q%3D& alt=&Q=& eeimg=&1&&你是True神&/p&&p&延续上面的语言设定(&img src=&/equation?tex=X& alt=&X& eeimg=&1&& for ture,&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&& for false),那么我们问神的statement是:你对“你是True神”的判断是&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&,然后&/p&&ul&&li&假如是True神,那么&img src=&/equation?tex=Q%3DT& alt=&Q=T& eeimg=&1&&,根据我们上面的分析,我们可以得到&img src=&/equation?tex=T& alt=&T& eeimg=&1&&的回答,注意这个&img src=&/equation?tex=T& alt=&T& eeimg=&1&&是针对&img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&的判断,所以我们知道这个神就是True神&/li&&li&假如是False神,那么&img src=&/equation?tex=Q%3DF& alt=&Q=F& eeimg=&1&&,所以它对&img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&的判断是&img src=&/equation?tex=X& alt=&X& eeimg=&1&&。再看我们的statement,发现我们的statement也是假的,所以它要说反话,从而给出&img src=&/equation?tex=X& alt=&X& eeimg=&1&&的回答,而我们的翻译(&b&注意这里是&img src=&/equation?tex=I& alt=&I& eeimg=&1&&函数而不是上面的语言设定&/b&)说&img src=&/equation?tex=X& alt=&X& eeimg=&1&&代表false,所以这个不是True神&/li&&li&假如是Random神,那么&img src=&/equation?tex=Q%3DF& alt=&Q=F& eeimg=&1&&。假如它选择说假话,那么和False神一样的推到给出它的回答是&img src=&/equation?tex=X& alt=&X& eeimg=&1&&;假如它选择说真话,那么它对&img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&的判断是&img src=&/equation?tex=Y& alt=&Y& eeimg=&1&&,从而我们的statement是对的,所以它会说&img src=&/equation?tex=X& alt=&X& eeimg=&1&&。但是解释函数告诉我们,这意味着&img src=&/equation?tex=Q& alt=&Q& eeimg=&1&&是假的,所以这个也不是True神!&/li&&/ul&&p&我们看到,只有True神会给出true的回答,其余都是false,所以接下来我们只要一个个问就行了。&/p&&br&&p&Remark:我们可以看到,我们的提问方式保证了不仅仅可以无视问的是哪位神(因为总是可以得到正确的回答),而且不依赖神的语言!即使说神互相之间的语言也可以是不一样的,比如True神对true说&img src=&/equation?tex=X& alt=&X& eeimg=&1&&,Random神对false说&img src=&/equation?tex=X& alt=&X& eeimg=&1&&,而我们可能两个神都会问到,甚至用同一个解释函数&img src=&/equation?tex=I& alt=&I& eeimg=&1&&去解释它们的回答,我们仍然可以得到正确的答案!&/p&&br&&p&Generalized Problem:上述问题中,Random神是在回答问题前,选择接受True神或者False神的设定,再作回答。可以看到我们的答案完全可以忽略Random神,因为当它抛完硬币后,它就被归到True神或者False神的情况里。所以呢,Random神很不高心,现在它要秀一下存在感:它决定通过抛硬币来决定它的回答(而不是回答方式)!&/p&&p&也就是说,每次Random神给出的判断完全就是抛硬币的结果,而和你问什么完全没有关系。它完全不给出任何信息量。现在还是三次机会问三个神,请问:你还可以找到一个方法区分这三位神吗?&/p&
首先声明这并不是一片朋友圈文章,标题中的“世上最难”不是我说的,是wikipedia说的(见)。故事的开始是苦逼的博士狗们一起赶作业,然后 突然就把这个东西搬了出来,然后大家瞬间两眼放光,纷纷抛弃了作业……当然主…
&img src=&/50/v2-775ad1daeb8de_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/50/v2-775ad1daeb8de_r.jpg&&&p&[按] 在上个月 [] 的 2016 金山技术开放日上,俺做了一个游戏引擎相关的分享。结束之后,俺断断续续地在零碎时间里把分享的内容整理了一下,为每张幻灯片配上了简单的文字注解,就形成了这篇小结。&/p&&p&参与了现场交流的同学可能会发现,这篇文字版跟现场版相比,虽然幻灯片保持原状,但文字注解部分略有出入 (增加的内容主要是第二部分“评估,运用和改造”,这一部分在现场时因为时间关系说得非常简略),还请见谅。 &/p&&h2&内容提纲&/h2&&img src=&/v2-f6edb96c23e_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-f6edb96c23e_r.jpg&&&ul&&li&游戏引擎的&strong&十年变迁 ()&/strong& (对过去十年的游戏引擎发展的简要小结)&/li&&li&游戏引擎的&strong&评估,运用和改造&/strong& (对一次技术迭代周期内的主要实践的归纳)&/li&&li&游戏引擎的&strong&下一个十年&/strong& (一些很零碎的对未来十年可能值得深入的技术的思考和启发点)&/li&&/ul&&h2&第一部分:游戏引擎的&strong&十年变迁 ()&/strong&&/h2&&p&在这次分享中,我着重对比了个人相对有所了解的五款商业引擎,分别是 Unity、Unreal、CryEngine、Gamebryo 和 Torque。而下面划掉的开源引擎 OGRE/Irrlicht/cocos2d-x 性质不同,放在一起对比并不公平,所以排除在这一回讨论的范围以外。&/p&&p&&img src=&/v2-2df611f59a7fb0cb577fc9d_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-2df611f59a7fb0cb577fc9d_r.jpg&&前几个 (Unity、Unreal、CryEngine) 比较知名,就不多做介绍了。这里简单介绍一下 Gamebryo 和 Torque。&/p&&p&Gamebryo 是当年 () 国内非常流行的商业引擎之一,业内不少大厂都曾拿这个引擎做过各类项目,也培养出一批熟悉 Gamebryo 的引擎程序员 (包括我在内——虽然我是经由 Unreal 2 启蒙,但只有在 Gamebryo 上的工作才让我看到了自己曾尝试着去实现的理想中引擎的影子)。 Gamebryo 的最强之处在于其设计上的普适性——与 Unreal 和 CryEngine 内含的 FPS 基因不同,Gamebryo 对于 MMO、赛车、休闲、动作等国内常见的游戏类型均能很好地适配。从基于 Gamebryo 的两大代表作《文明4》和《辐射3》在游戏类型上的跨度,就可以看出这种不同寻常的通用性。它的整体架构简洁有力,模块边界符合直觉,模块之间耦合性低,模块实现内聚性强。这些特性使得它的学习曲线相对平缓,新人容易培训和培养,因而也是我个人偏爱的一款引擎。Gamebryo 的弱点在于自身工具链不足,且与第三方的集成度偏低,以及由于前两者导致的引擎提升潜力受限。&/p&&p&而 Torque 则是前些年的低成本商业引擎的代表,其特色在于&strong&简单易用的编辑器&/strong&和&strong&独具特色的脚本&/strong&,基本上可以看作是 2010 年以前的 “史前版 Unity”,前述两大特色也被后来者 Unity 继承并发扬光大。&/p&&p&&img src=&/v2-d9e64f0ba74_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-d9e64f0ba74_r.jpg&&在这张基本时间线的图上,我们可以看到在过去十年里这五款引擎大致的发展轨迹。其中可以看到,贯穿始末的是 Unreal 和 CryEngine,而另外三款引擎则流行于特定的历史时期。而即使是 Unreal 和 CryEngine,在漫长的发展过程中也自有其高峰和低谷。&/p&&p&&img src=&/v2-6a7bd16cb33fccbd4973_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-6a7bd16cb33fccbd4973_r.jpg&&有了它们各自的时间线打底,我把这五个引擎各自比较有影响力的版本标注了上来,这样在以五年为跨度的单位 (垂直虚线) 上,每个引擎曾做过的大动作就一目了然了。有过相应项目经历的程序员,对这些曾经活跃一时的版本一定不会陌生。这里我们先不针对单独的版本一一细说,只是对每个引擎的大致活动情况了解一个大概。&/p&&p&&img src=&/v2-77f8c3a01ccb74fb4d981a676e0bd340_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-77f8c3a01ccb74fb4d981a676e0bd340_r.jpg&&细心的同学也许已经注意到了,看起来很凑巧的是,这些引擎的大版本或多或少地聚集在我标出的以五年跨度为单位的竖直虚线附近。而这其中最为显著的就是 Unreal。这仅仅是一个巧合么,还是说,跟其他的时期相比,这些特定的年份有什么不同?&/p&&p&&img src=&/v2-ba2b8199ddf97a589c8df575_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-ba2b8199ddf97a589c8df575_r.jpg&&站在 2016 往回看,我们意识到——在这十年中,这是仅有的两次有着整体产业级影响力的根本性的变迁和进化。如果说是两次技术革命 (Revolution) 可能不甚恰当,但要说这是两次影响范围甚广,使得游戏产业的深度和方向产生了根本性的延展的两次行业范围的演化 (Evolution),似乎并不为过。&/p&&p&其中第一次演化,是起源于 2002 年并于四年后 (约 2006 年前后) 渗透到整个行业的,被广泛应用于游戏引擎中的&strong&可编程图形流水线&/strong& (Programmable Graphics Pipeline);而第二次演化,则是起源于 2007 年的初代 iPhone 并在四年后 (约 2011 年前后) 渗透到整个行业的,改变了整个游戏行业生态的&strong&移动平台游戏开发&/strong& (Mobile Development)。&/p&&p&可编程流水线刚刚被引入到实时图形渲染的领域中时,是 3D 图形处理器发展最迅速的时期,从 Geforce 3 开始,nVidia 在硬件方面每半年就有一次较大的更新,同时期的各类图形技术一时间层出不穷,可谓是画面渲染质量提高最快的黄金时代。在2006年时,我任职于育碧上海,有幸参与了 &a href=&/?target=https%3A//zh.wikipedia.org/wiki/%25E7%25BB%%E5%E8%25A3%2582%25EF%25BC%259A%25E5%258F%258C%25E9%E9%%25E8%25B0%258D& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&“细胞分裂:双面间谍”&i class=&icon-external&&&/i&&/a& 的开发,把&a href=&/?target=http%3A///news/89.shtml& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&当时的游戏截图&i class=&icon-external&&&/i&&/a& (注意最后一张是游戏中上海关卡的东方明珠夜景图) 拿到现在来看都并不过时。得益于复杂度迅速提高的材质和各种开脑洞的特效实现的不断涌现,整个行业在图形和渲染表现方面的探索非常迅速和深入,通过真实感图形渲染出来的游戏画面达到前所未有的逼真程度。&/p&&p&而移动平台的游戏开发则是另一次重要的变迁。在新的平台上,随着大量非传统核心类玩家的涌入,人们有着与传统 PC/Console 迥异的关注点,从单一的超高画面和沉浸感追求拓展为更多元的交互和体验。可以说直到如今,我们仍处于这次演化的余波之中。&/p&&p&我们注意到,这两次演化的共同点在于:它们皆非短时间内剧烈的革命,而都是跨度若干年,并于图中所标示的年份上遍及整个行业的产业级演化。而不同之处是:前一次的演化,在图形领域内前所未有地挖掘了电子游戏作为可视化交互艺术可能触及的“&strong&深度&/strong&”,而后一次则通过全新的平台和交互语言大大拓宽了行业所能触及的“&strong&广度&/strong&”。&/p&&p&&img src=&/v2-e74efc21c4ee53a317b6df_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-e74efc21c4ee53a317b6df_r.jpg&&回到时间线中,我们可以发现,Unreal 和 Unity 对两次行业的演化有着强烈的预期和精准的判断——在这些决定命运的转折点上,他们要么在巨变来临前就做好了充分的准备,在行业变迁中始终屹立不倒,要么凭借着顺应趋势的特性集和服务乘风而起。&/p&&p&&img src=&/v2-eba4bb7d373d5932cf2ccad1afedbffe_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-eba4bb7d373d5932cf2ccad1afedbffe_r.jpg&&现在我们重点来看一看 Gamebryo 、CryEngine 和 Turque,它们是在第一次行业演化中崛起的佼佼者,在各自的量级上均是罕有敌手。Gamebryo 的标准材质 (NiStandardMaterial) 对应着可编程流水线在现代商业引擎中最简易和灵活的实现,是那个年代 (2006) 最容易上手的商业引擎之一;CryEngine 的图形表现在孤岛危机时代是最强的引擎之一 (这里的两个“之一”二字仅仅是意思一下);而 Torque 更是为小型独立开发者提供了极易上手的编辑器和非常丰富的着色器开发套件 (基本上可以认为他们自己弄了个内置的低配版 Asset Store)。所有这些让它们在第一次行业演化中脱颖而出,在&a href=&/?target=http%3A//devmaster.net/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&http://devmaster.net&i class=&icon-external&&&/i&&/a& (这是那个年代的一个专注游戏引擎和中间件目录的开发网站) 上成为提及率最高的几个商业引擎。&/p&&p&然而时过境迁,在推出了若干有影响力的版本之后,它们不约而同地在 2011 年前后平静了下来。很明显的是,它们并没有意识到时代的趋势,在移动平台崛起时,它们没有做出任何反应,反而把精力用在了事后看起来无关紧要的改进上。&/p&&p&Gamebryo 的用户希望引擎能提供更好的编辑器和工具链,而 Gamebryo 前后尽力做出的两版编辑器虽然看起来很不错但并未达到工业级的成熟度 (很像后期的 cocos2d-x) ——在拥有成功项目的支撑和回馈之前就陷入了兼容性的泥潭。而 CryEngine 似乎落入了“为了强大而强大”的漩涡,并未意识到在图形技术日趋成熟的时代,由于边际效应递减,图形上的优势越来越难以形成差异化。与老对手 Unreal 为 iOS 专门打造的瘦身版 UDK 截然相反的是,CryTek 精心打造的“新版” (Rebranded) CryEngine 甚至似乎刻意在逃避移动平台——它的主要特性是支持 Linux 和下一代主机 (PS4 / XBox One / Wii U)。&/p&&p&Torque 则是这三者中最为惋惜的。按照现在的眼光看,它是商业引擎中最便宜的 (~$200),它的目标群体是小型独立开发者和团体,它的编辑器像 Unity Editor 那样亲切好用,它的脚本 TorqueScript 神似 C#,它甚至有一个 &a href=&/?target=http%3A///products/torque-3d/add-ons& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Torque 3D Store&i class=&icon-external&&&/i&&/a& (可以看做是 Asset Store 的前身,现在仍然可以访问)。在 StackOverflow 上,你甚至能看到 (2009 年) 这样一个有趣的比较:“&a href=&/?target=http%3A///questions/1780690/unity-vs-torque-game-engines-and-ide-environment& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity vs Torque game engines and IDE environment&i class=&icon-external&&&/i&&/a&” 但是,由于对移动平台的无视,Torque 的用户源源不断地流向了 UDK 和 Unity。&/p&&p&Gamebryo 、CryEngine 和 Turque是三款定位迥异的游戏引擎,却有着极为相似的起落周期——在第一次演化中提供了各自领域最有价值的服务而崛起,和对第二次演化的无视甚至逃避导致的衰落。这三款引擎所有的有影响力的版本均在我们框定的第一次演化和第二次演化之间。在移动平台普及之后,这三款引擎再也没有推出一个有影响力的版本。&/p&&p&&img src=&/v2-8fb54d114a8a6e1aac8638_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-8fb54d114a8a6e1aac8638_r.jpg&&我们拉近视角,近距离观察 Unreal 这个贯穿十年,历经波折却仍然稳步前行的游戏引擎,看看它的步调和动作是如何与时代趋势相匹配的。在图中我们不难看出,Unreal 总是能够捕捉并提前准备好对应的发布——细究每一条细节,Epic Games 在十年里完整地向我们诠释了“&strong&与时俱进&/strong&”的真义——在行业需要深度的时候提供足够的深度,在行业需要广度的时候提供足够的广度。(呃,一不留神成了 Epic 吹了~~)&/p&&p&&img src=&/v2-171a2c32cc866540caedde_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-171a2c32cc866540caedde_r.jpg&&接下来是第一部分的结论——&strong&不是最强的,也不是最新最酷的,更不是最贵的,而是最适应变化的,活了下来。&/strong&这个结论是由达尔文的进化论金句略作修改而来,原文见下面的方框。&/p&&p&(第一部分完)&/p&&h2&第二部分:一次技术迭代周期&/h2&&p&&img src=&/v2-77e39119ecfc22b171ce31ee983a4e85_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-77e39119ecfc22b171ce31ee983a4e85_r.jpg&&如果想要各种姿势自顶向下自底向上巨细无遗地了解游戏引擎的方方面面,可以看 Milo 老师的&a href=&/p/& class=&internal&&游戏程序员的学习之路&/a&,这里就不多说了。我们抓一下挈领,把&strong&游戏引擎的评估&/strong&放在最重要的位置,试着解决一下关于 “How” 的几个问题——“How to evaluate” (评估)、“How to use” (运用)、“How to extend” (改造)。&/p&&h3&游戏引擎的评估&/h3&&p&此前我曾写过一篇文章:&a href=&/?target=http%3A///post/-tech-evaluation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& 如何判断一个技术(中间件/库/工具)的靠谱程度?&i class=&icon-external&&&/i&&/a& 这篇文章里我集中讨论了评估中间件需要注意的一些情况,在文末我写道,&/p&&blockquote&&p&“对中小规模的技术而言,上面的“望,闻,问,切”已经足以应付了。而对大型代码库/框架/引擎而言,又有一套不大一样的评估标准,另有曲径可探,咱们择日另行讨论,此处暂且按下不表。” &/p&&/blockquote&&p&当时给自己挖了个不大不小的坑。两年多过去,现在这个坑终于可以填上了。&/p&&p&&img src=&/v2-e_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-e_r.jpg&&关于引擎评估,首当其冲的是三个简短的问题,我们一个一个来看。&/p&&p&首先,“&strong&是否经受过同类产品的考验&/strong&”是一个决定性的因素,这不仅仅意味着能否按时交付,技术风险高低——更多时候,这是你的团队不会因为计划外因素而意外搁浅的重要保障。我们知道,捡到一个存折带来的喜悦远远低于丢失一个等额的存折带来的痛苦,同样的,在幻想你的游戏大卖之前,先尽一切可能确保你的项目不会因为无法控制的因素夭折显然更有意义。没有经过考验的引擎就像是&strong&一杆没上过战场真刀真枪考验过的枪&/strong&,在它有效地为你杀敌之前,先祈祷它不会伤到自己吧。这也是市场上看到的山寨产品 (对国产游戏而言) 和续作 (对 3A 游戏而言) 这么多的直接原因。&/p&&p&其次,“&strong&好招人吗&/strong&”。这个问题表面上看是一个团队管理和人员招聘问题,而实际上却是一个学习曲线和培养成本的问题。在 Unreal 推出 UDK 之前,很多用 Unreal 引擎的小团队在快速出了原型之后都难以为继,这是因为那时的 Unreal 技术人员的培养成本很高,培养时间很长,在人员快速扩充时期,小团队很难消化新手和准新手给团队带来的负担。这就造成了巨大的反差:两三个高手可以拿着 Unreal 在两个月内迅速出一个华丽的原型,在期望值迅速提高之后,弄来一大票人吭哧了一年多,在项目节点上老板一看,哎哟我去,这可不还是那个原型吗~~等等,好像还不如刚开始那时候稳定了~&/p&&p&最后,“&strong&是否有代码&/strong&”。这个问题在&a href=&/?target=http%3A///post/-tech-evaluation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&此前文章&i class=&icon-external&&&/i&&/a&里已有表述,这里引用一下:&/p&&blockquote&&p&最后说一下这里面一条俺认为比较重要的,也是当年带队的MMO项目里,被我列为头条编程规范的原则:&strong&绝对,绝对,绝对不要使用没有100%提供源码的第三方技术。&/strong&这是一条红线,不管这个技术有多强大,都绝对木有例外。程序猿们或多或少都有感触,在编程的世界里,CPU时序的不确定,存储IO的阻塞,其他进程对CPU/内存资源占用造成的扰动,后台进程如杀毒软件偶尔的锁定文件访问,公网路由的拥塞,都为运行着的程序施加了太多不可预知,不可控制的因素。而在这些不可控制的因素里面,允许在自己进程的地址空间内运行一些无法得知其本来面目的代码,是其中最危险也是最容易失控的那一类。反面例子太多,俺就不举了,也免得触物伤怀,影响心境。&/p&&p&......&/p&&p&关于“三个绝对”的问题,俺专门补充说明一下,&/p&&ul&&li&如果所谓的“软件大厂”是第一方,那通常咱们也没啥选择。就比如要在 Windows 上开发 3D 游戏,用闭源的 DirectX 也是理所当然。正如文中所说,所谓“三个绝对”是针对那些几乎总是有得选择的第三方库而言的。&/li&&li&使用软件大厂的闭源技术,也会带来不小的潜在隐患。大公司通常是不太搭理小团队的,如果你掉进的坑恰好在朋友圈里和网上找不到类似的案例或方案,那尝试跟所谓“软件大厂”交流或反馈一般都是做无用功。最终要么花更多的时间吭哧吭哧workaround,要么去掉对应模块了事。&/li&&li&作为程序员,当遇到问题时,你希望的是 a) 通过一路在源码中前后追溯,在解决问题之余,弄清楚前因后果,实实在在地增加自己相关领域的经验和认识呢,还是 b) 对着文档反复猜测和校验自己哪个参数有没有误传?&/li&&/ul&&p&其实到了关键时刻,有代码在手上,就是一颗定心丸,正所谓“&strong&源码之前,了无疑惑&/strong&”。当遇上奇怪的症状时,什么文档都比不上正在运行着的唾手可得的鲜活的代码。&/p&&/blockquote&&p&&img src=&/v2-d1d76b78b5_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-d1d76b78b5_r.jpg&&接下来是针对引擎的两种主要的开发模式的选择,明面上的优势和劣势已经标注在图中了。简单地说,如果“&strong&求快&/strong&” (往往是需求方更强势) 占了上风,往往是“钻进去改”的框架式更合适;而如果“&strong&求稳&/strong&” (往往是实现方更强势) 的占了上风,则往往会以相对严谨的工程化思维来设计架构和实现。有的团队自打一开始就压根就没考虑过这问题,管它三七二十一先改了再说。一上来堆系统堆得很爽,进度喜人,到了后期处处是改到一半改不动的烂摊子,这种时候再加班加点加人手,硬啃硬怼硬编码,拼命拿战术上的勤奋去掩盖战略上的懒惰。&/p&&p&&img src=&/v2-60dae13fcadfe96c8528c_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-60dae13fcadfe96c8528c_r.jpg&&接下来就到了具体内容的考察了。这一页上列出的三个因素是需要考虑的一级要素。为什么说 (从引擎角度看) “这三个因素直接决定了项目按期交付的可能性”呢?这是因为,对于给定的游戏类型和设计,这些因素直接影响到一个项目实际工程量的大小。&/p&&ul&&li&&strong&特性集&/strong& (feature set) 是引擎“&strong&能帮你解决的问题的集合&/strong&”。正如一个 CPU 的指令集那样,引擎的原生实现不仅能帮你省去自己实现这些特性的时间,而且往往是在特定环境下 (给定的问题域内) ,在这个引擎上所能实作出的最佳实践 (Best Practice)。有两个因素会把这种价值给迅速放大:第一,普通游戏开发团队的平均技术水准,通常是低于他们所使用的引擎的研发团队的;第二,普通游戏开发团队对引擎的熟悉程度和运用能力,在一定程度上同样也低于对应的引擎研发团队。所以&strong&已有的特性集与目标项目的匹配情况&/strong&,是我们格外关注的焦点。&/li&&li&&strong&工具链&/strong& (tool-chain) 是引擎提供的“&strong&团队工作流程的内部骨架&/strong&”。缺乏工具链或工具链不成熟的引擎是双刃剑,需要&strong&显著高于平均水准&/strong&的团队才能有效驾驭。Gamebryo 和 OGRE 这两款引擎设计优良,但在工具链上很弱,是两个很好的例子。虽然很多团队淹没在工具制作的泥潭里,但这种不成熟也恰恰给了那些强力团队一个难得的机会,围绕着特定的业务模型构建出&strong&以业务为导向的工具链&/strong&,形成了真正的团队级的核心竞争力,而这种核心竞争力是那些有着成熟工具链的引擎的团队极度难以形成的。总得来说,能力强,不怕延期,敢于投入的团队,才有机会扭转,获得业务导向的工具链带来的红利。&/li&&li&&strong&迭代时间&/strong& (iteration time) 是日常开发中无可争议的 &strong&No. 1 Time Killer&/strong&,直接影响你的工程效率。我在 Unreal 3 上工作时,有大量的场合 (如 Console Build) 是需要静态链接的,而 UE3 的链接奇慢无比,即使在中高配的电脑上也需要不下 10 分钟。而编译速度也很让人抓狂,即使有 Incredibuild 的分摊,一旦不幸改到头文件也是相当感人。运气不好的时候,一个小时改个两三次就一闪而过了 (下面这个 xkcd 真的一点也不夸张)。&/li&&/ul&&p&&img src=&/v2-27ed4c0bab8b5bfb2afe88_b.png& data-rawwidth=&413& data-rawheight=&360& class=&content_image& width=&413&&由于在&strong&头文件的包含传染性&/strong&和&strong&预编译的物理依赖关系&/strong&上有欠考虑,不当依赖导致修改时的重编传染性极强,进而导致我们深入研究出一系列“避免动到头文件就能搞定需要的功能”的偏门神功,实在是说多了都是泪。好吧,反正这里已经黑了一把 UE3,干脆再来一个,负负得正吧。UnrealScript 是 Epic 专为虚幻引擎实现的脚本语言,无奈这货跟 C++ 的关系实在太紧密了 (如只要在涉及 native 的情况下改动变量就得重编 C++),紧密到运行时的动态能力已经损失殆尽,几乎已经没法拿来当脚本用了 (比如像 Lua 或 Python 那样轻松地在运行时 make change / run / reload )。好在 UE4 里已经把它去掉了,这里就不多说了。&/p&&p&这三个方面都会直接影响到一个项目的工程时间开销,是一级的重点考察因素。&/p&&p&&img src=&/v2-aeb1a7b85dc0dd3b2bb5b_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-aeb1a7b85dc0dd3b2bb5b_r.jpg&&接下来是次一级的考察因素。这一级的考察因素侧重于引擎的工程质量,毕竟说到底,游戏引擎是一个软件项目——功能再花哨,如果根基不牢,那么做出来的游戏多半也是摇摇欲坠。团队规模越大,受工程质量高低的影响也会越大,严重时会直接影响到整个团队的节奏和士气,进而成为影响交付的难以克服的风险。&/p&&p&我们先来看耐受力 (exception tolerance) 。什么是耐受力?简单说就是对非正常流程的处理能力。能够使用系统性的策略,而不是事到临头草草地 assert 来处理非法输入;能够结构性地把自己可以识别和处置的错误从无数的未定义行为中区分出来。说白了,耐受力意味着“&strong&工程上的安全感&/strong&”。&/p&&p&举个例子,同样是使用未初始化变量,在C/C++里你可能啥事儿没有,也可能直接宕机,也可能在极为偶然的情形下宕机,也可能看起来没啥事儿而过很长时间以后宕机。而在 Lua 里却不会有问题,并不是后者比前者高明,而仅仅是因为它对这一类问题有良好的定义。&/p&&p&再比如说,一个编辑器,指定的操作稍微没有按照事先定义的流程来,立刻 assert ,非常敏感,一有风吹草动就 halt。很多程序员喜欢辩解说“尽早崩溃”是最佳实践——在遇到问题的第一时刻报错,报得越早越好,毕竟越接近问题发生的第一现场越方便他们调试。这个说法本身当然是没问题的——如果你用个默认值糊弄一下,或者是写某种容错逻辑来忍耐了破坏假定的行为,那么错误很有可能会蔓延到之后更加远离出问题的地方才爆发,那时丢失了源头和上下文,查错的成本会变得非常高。&/p&&p&以下详细说明部分节选自俺的一篇未发布的文章,详细说明了一下这个问题。&/p&&blockquote&&p&如果只考虑程序员,不考虑团队中同样依赖每日版本来工作的策划,美术和测试的话,这个思路是没有问题的。然而跟程序员不同,当发生崩溃时,团队内的其他成员能做的非常有限——以最快速度通知程序员,&strong&版本挂了&/strong& (The build is broken!!!)。如果坏的地方正好是他们工作的部分,那么他们只好停下来,等待修好才能继续工作。否则要么一直备有一个可靠的老版本 ,要么手动回滚。&/p&&p&现在请摘下程序员的帽子,假设自己是一个负责“测试多人副本,任务和活动”等业务逻辑相关的测试人员,每测一次都要花不少时间进入测试情境,偶尔甚至需要多人一起协同测试。那么一个跟你的工作毫不相关的底层崩溃,所带来的影响就会被迅速放大,很可能得完版本后的几个小时就在反复尝试和等待之中被消耗掉。&/p&&p&这是一种惊人的浪费。&/p&&p&给程序员巨大便利的“尽早崩溃”,对非程序员来说,意味着日常开发中的每一天,都要冒着被“不可控的因素”延误工作的风险。有人说,正确的姿势难道不是让程序员有更好的自律,在提交前做尽可能充分的测试,确保不要搞破坏吗?是的。可是即使是经验丰富的程序员也不能拍胸脯保证自己 bug-free, 更不能保证由若干人提交的若干“不相干”的改动集成到一起就能无缝地良好工作。让非程序员去承担这种因为版本不成熟导致的效率折扣,是&strong&既不公平也不高效&/strong&的。&/p&&p&说到“巨大便利”,不得不补充一个前缀——“本机上的”,也就是说,只有崩溃恰好发生在制造这个问题的程序员的机器上 (或可以方便地即时远程调试) 时,这种巨大的便利性才得到体现。考虑到发生在非程序员环境下的崩溃,不少情况下是由于环境配置错误等杂音所致,“有经验的”程序员往往不会浪费他们“宝贵的开发时间”,第一时间赶往现场开始分析和调试(打断自己的工作跑去协助调试,满头大汗弄了半天,发现是环境配置的问题/版本问题/别人代码导致的问题,足以唤醒一个温顺的程序猿内心的洪荒之力了)。更多的,他们会在 IM 上回个消息:“嗯,这个功能我提交前测试是正常的——你的环境干净吗?需要的数据都干净地重新生成了吗?第三方库的二进制文件更新了吗?你们几个人测试的版本一致吗?要不你 Cleanup / 重启 / 重新保存 / 重新建个账号试试?”,试图通过尽可能小的时间开销来帮助诊断和解决问题。长远来看,这些试图节省调试时间的沟通,会让“尽早崩溃”所带来的巨大便利慢慢地挥发殆尽。&/p&&p&一个不那么容易觉察却更为严重的系统性问题是,总是采用“尽早崩溃”的实践的团队所产出的代码库,随着系统内不同模块之间的交互(以及随之而来的各种假定)越来越多,往往倾向于通过更多的断言来让系统变得越来越敏感和脆弱。因为,&strong&认真细致地考虑模块间的依赖时序,并系统性地从结构上解决过深的模块间耦合&/strong&,总是比一个简单的断言要复杂得多。&/p&&p&“尽早崩溃”的主张是如此的简洁有力,以至于我们在那些应当通过改良结构,去除耦合来解决问题的时刻,往往简单地选择了使用断言来做一个时序上的约定。这种显式的指定会把系统的坏气味转化成太多的不必要依赖。的确,问题从表面上看起来变得更简单了——谁破坏了断言,导致了崩溃,谁就修呗——实质上,修来修去,把一个本质上可以剥离的简单交互,变成了严重依赖各种时序和条件的“靠巧合工作”的杂耍系统。&/p&&p&你看,“尽早崩溃”的简单性和便利性,在一些情况下反而成了一个让代码质量退化,鼓励系统熵不断增加的问题机制。那么问题来了,在满足了“必要的时候程序应当尽早崩溃”的基础上,还有什么可以选择的实践吗?&/p&&p&(以下略)...&/p&&/blockquote&&p&到这里我应该已经基本说清楚什么是耐受力了。在图中我提到的三点分别是特殊需求,坏数据,破坏性的改动。这些都很直白,通过验证一个引擎在这些方面的表现,我们很容易对它的耐受力作出判断。&/p&&p&&strong&可见性&/strong&也是重要的考虑因素。如果引擎能充分揭示自己的业务流程 (如何运作),生成的各类数据 (如何存储),关键模块的性能开销 (如何优化),那对各类基于引擎的二次开发才能更有信心,才能够最大限度地避免依赖了错误的假定。当出现问题时,也更容易查找和比对。而如何在维护最大的可见性的同时保持良好的封装和较低的耦合,同样是一个很大的话题,这里就不再细说了。&/p&&p&&img src=&/v2-a2a84b64bfba7a46ed5955f_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-a2a84b64bfba7a46ed5955f_r.jpg&&接下来的页面上这些内容是更次要一些的因素,它们大多都很直白,这里我们挑着简单说一下。&/p&&ul&&li&(&strong&teamscale-friendly&/strong&) 不少引擎的工具链适应不了团队级的开发,尤其是大规模团队的开发。这类问题会在团队规模迅速增长,对引擎的平均理解程度迅速降低时暴露出来。&/li&&li&(&strong&3rd-party-friendly&/strong&) 商业引擎通常会有不少与第三方中间件的交互。考察这种交互的一个简单方法是观察那些“三不管”的薄弱地带。此前工作在 Unreal 上时,我曾短期地维护过一个模块,那个模块的业务逻辑依赖于 Unreal / Scaleform / Bink 这三方的适配。因为它们各自为政,在两两集成时,本来就是形式胜于实质,三方交互时就更为薄弱了。当大批量数据需要高频地在不同的中间件之间传递时,潜在的问题就会很容易集中爆发。&/li&&li&(&strong&industry standard-friendly&/strong&) 使用行业标准这一条就不多说了,我曾在一个游戏项目里见过七八个有着不同的 internal representation 的字符串类 (还不包括 std::string) 。光是字符串转换之间的各种细节,潜规则,优化手段,都够得上出本书了~ 想想你的工程师把他们宝贵的脑力消耗在这些事情上,实在是惊人的浪费~&/li&&/ul&&h3&游戏引擎的运用和改造&/h3&&p&说完了引擎的评估,接下来的运用和改造是很大的题目,对不同的项目类型也不尽相同。到这里不知不觉已有上万字了,为免冗长,我们提炼出一些相对通用的考虑和实践,就不考虑在单方面深入讨论了。&/p&&p&&img src=&/v2-43f1bdfbf210ce4cd2ccab7_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-43f1bdfbf210ce4cd2ccab7_r.jpg&&在一个项目内涉及到引擎相关的部分,首当其冲的就是工作流的管理。项目是由人构成的,一个进行中的项目包含了许多显式或隐式的流程、约定和步骤,这些交互随着开发的进展不断动态变化。正如左下图那样,每个团队成员作为其中的一环或多环,有机地交互并推动项目的进展。要想让这个系统持续地有效运转,很重要的一点就是通过不断的观察、定位、梳理,来改进系统中响应速度跟不上整体节奏的环节。&/p&&p&在做阶段性回顾时,我们容易把目光聚焦在“什么做了,什么还没做”上,却容易忽略对影响响应速度和导致效率损失的因素的及时处置。如果能够持续不断地观察和优化这些敏感点,我们就能发现,抛开每个成员技术方向和能力的差别不谈,绝大多数响应问题是由于 (过多的) 依赖导致的。这些依赖既有内部的,也有外部的;既有业务逻辑需求驱动的逻辑依赖,也有物理性的资源和数据依赖——当然最多的还是由于“&strong&针对工作流的分析和梳理严重不足&/strong&” (俗话说的做到哪儿算哪儿) 导致的项目成员之间的无谓依赖。&/p&&p&有种常见的说法是 Daily Build 就是项目的心跳,保证每日构建的安全、自动和鲁棒是最重要的。然而我认为这只是工程意义上的心跳,一个游戏项目的真正心跳在于“&strong&持续的可感知的进展&/strong&” (Continuous sensable progress)。一个游戏项目内,任何一个可感知的点,不管是策划针对某个角色某个技能的构思或数值调整,还是美术对某个场景内某个特定氛围的塑造和创作,还是服务器程序对于一个特定功能 (如快速组队匹配) 的效率上的优化,都会通过或长或短的工作流程,最后在某个 Build 内以游戏内的一个可感知的点体现出来。我深切地感到,这样的&strong&基于实际体验点的持续而有节奏的交付&/strong&,才是一个健康的游戏项目的真实心跳。而这个真实心跳是否能良好运转,跟工作流的响应效率和依赖处置是直接挂钩的。&/p&&p&关于 hackers & scientists 的区分对待,也是值得讨论的一点。“黑客”式的工程师会准确而锋利地切中要害,他们敏感,敏锐,敏捷,有惊人的直觉和洞察力,对大部分问题都能在很短时间内直截了当地给出“行还是不行”的答案,相应地,他们多数时候“事了拂衣去”,不那么在意严谨和完备,不愿意陷入琐碎的工程细节,也对编写日志,测试用例等等一切“官僚主义的形式材料”满不在乎。而与此相对的是,“科学家”式的工程师们,普遍周全,周密,细心和细致,能不厌其烦地追究每一个细节并给出妥善的应对方案,他们无比在意工程的完整性和完备性,产出的代码精确、详实而可靠,充分而周祥地考虑了各种可能出现的隐患和边界条件。&/p&&p&很少有程序员能同时具备黑客和科学家的素质,所以这就要求我们能够感知并理解每个个体的行为方式,不断做针对性的调整和细化,从而让他们的积极特性在项目中能得到最大程度的放大。&/p&&p&&img src=&/v2-cdacb54e2a75b710deb4c8_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-cdacb54e2a75b710deb4c8_r.jpg&&这里是关于同步节奏的管理,图上已有表述,不再多说。&/p&&p&&img src=&/v2-48ca432134ebebcf688bed_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-48ca432134ebebcf688bed_r.jpg&&针对引擎局限性举的 Gamebryo 例子。&/p&&p&&img src=&/v2-4f468f8dbd1_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-4f468f8dbd1_r.jpg&&这是魔兽世界里的兔子,详细的材料可见这里:&a href=&/question//answer/& class=&internal&&有哪些看起来很高端的技术其实原理很暴力很初级?&/a&。&/p&&p&&img src=&/v2-b255d0e15a0cf1ff3ec76_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-b255d0e15a0cf1ff3ec76_r.jpg&&引擎不支持某个特性,并非总是坏事,也许正是你的游戏体现出差异性的好时机。有段时间,使用 UE3 开发的游戏扎堆出现,其中那些质量低下的作品,几乎总是让你一眼就能看出是在 UE3 上随便堆砌了些美术素材就放出来的昧心之作。而那些真正下功夫的 3A 之作,却总是能跨越技术的藩篱,(至少是在某一方面) 塑造出超越引擎能力的独特的体验。举个例子,如果 Android 本身在国内体验足够好的话,当时小米 MIUI 的独特本地化体验在 Android 阵营里也就没法那么出挑了。&/p&&p&什么是伪命题呢?就是那些本质上不存在,却因为某种局限性,稳定性或性能问题而浮现出来的需求。作为程序员,我们经常在提炼 xx 需求的时候发现,只要能把 yy 和 zz 弄好, xx 的问题自然而然就消解了。但机会窗口并非总是存在,也许一下没想通,没理会 yy 和 zz 的潜在问题,手一抖把 xx 做了,之后叠床架屋地做了 n 层,然后再想回来改就已经改不动了。举例的话,不少游戏的热更都是如此,就不具体说了。&/p&&p&&img src=&/v2-6dfeea573cf972e5aeb6f8_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-6dfeea573cf972e5aeb6f8_r.jpg&&关于技术负债,只要能意识到这很大程度上并非负面的因素,不要有太重的心理负担就好。在处置这些欠下的负债时,要有勇气不断地断舍离,随时扔下负重,轻装上阵。不要舍不得删代码。&/p&&p&关于&strong&删代码&/strong&有一篇非常有意思的文章,非常推荐阅读:&/p&&ul&&li&&a href=&/?target=http%3A///post//write-code-that-is-easy-to-delete-not-easy-to& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(需翻墙) Write code that is easy to delete, not easy to extend&i class=&icon-external&&&/i&&/a&&/li&&/ul&&p&如果上面的链接无法访问的话可以看下面这个 Internet Archive Wayback Machine 版本的:&/p&&ul&&li&&a href=&/?target=http%3A//web.archive.org/web/11/http%3A///post//write-code-that-is-easy-to-delete-not-easy-to& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(需翻墙) Write code that is easy to delete, not easy to extend (Internet Archive)&i class=&icon-external&&&/i&&/a&&/li&&/ul&&p&这篇文章在&a href=&/?target=https%3A///item%3Fid%3D& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& Hacker News 上的评论&i class=&icon-external&&&/i&&/a&也很有趣,一并推荐。&/p&&p&&img src=&/v2-49ce7fabe15_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-49ce7fabe15_r.jpg&&我曾不止一次地听到有项目组在一个进行中的项目里热切地讨论换引擎,当问到我时我常常会尴尬地笑笑。比较而言,这种动议的出发点往往是产品角度,一般出自项目经理或产品负责人,很少由工程师提出,故而讨论的结果不会影响到实际的执行,所以除了笑笑也贡献不了啥有意义的想法。实际情况是,更换引擎是一个难度指数显著较高的操作,一般的团队不一定能克服得了这个困难,而这种风险往往会被 (有意或无意地) 低估。哦,对了,我还发现,那些曾经投入地讨论换引擎的,往往是折腾完了之后最早开始怀念在老的引擎上的好日子的同学。当然了,他们会拿出一百个理由告诉你这么干是值得的,嗯,好吧,毕竟生命在于折腾嘛。&/p&&p&(第二部分完)&/p&&h2&第三部分:游戏引擎的&strong&下一个十年&/strong&&/h2&&p&&img src=&/v2-012fe258f1cc9fe603dcc8e_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-012fe258f1cc9fe603dcc8e_r.jpg&&这一部分主要是我个人对游戏引擎方面的一些非常零碎的和个人化的整理和推断,以幻灯片的内容为主,文字材料从略,见谅。&/p&&p&&img src=&/v2-f0af4baf220_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-f0af4baf220_r.jpg&&首先是下一代无线的标准——5G。我们可以看到,相较 4G,5G 的带宽和延时指标均提高到原来的 20 倍。用户面延时降低到了难以置信的 0.5ms。不仅仅是视频和直播类应用会从带宽和延时上受益,不少游戏引擎内的同步模块,拿这把尺子一衡量,立刻可以看出巨多的值得改进之处,就好像现代的图形引擎里,九十年代大当其道的 BSP 已经不见踪影了那样。传统引擎里的很多预测,补偿(&a href=&/?target=http%3A///post/-id-network-model-evolution& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&i class=&icon-external&&&/i&&/a&和&a href=&/?target=http%3A///post/-dynamic-prediction-and-latency-compensation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&i class=&icon-external&&&/i&&/a&),都可以用更简明的方式去处理。&/p&&p&&img src=&/v2-ef9f26e318d528a0b46b175fd872eb56_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-ef9f26e318d528a0b46b175fd872eb56_r.jpg&&在上图 (出处在这里:&a href=&/?target=https%3A///jboner/2841832& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Latency Numbers Every Programmer Should Know&i class=&icon-external&&&/i&&/a&) 我们可以看到,传统的磁盘寻道约耗时 10ms (&a href=&/?target=http%3A///link%3Furl%3DeWpj_1GfHNw9O3WnFE7n0x9D2J_AHw94ESdXmyxRKNXNIskHaAqfDUK3k1ZaKMTDbZOFV2DMGdoTQWwEY9J0X_& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&百度百科上这个数据为 7.5~ 14ms&i class=&icon-external&&&/i&&/a&),图上的问题值得思考:当你的网络连接速度远快于 (10x) 本机的磁盘寻道时,你的引擎将应该如何来设计和实现你的资源管理及网络同步机制?不夸张地说,这将是一个牵一发而动全身的问题。&/p&&p&&img src=&/v2-fdae98e4c_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-fdae98e4c_r.jpg&&在 2016 年,我们见证了首代消费级的 VR 产品。由于技术尚不成熟,在视觉呈现上有明显的纱门效应。&/p&&p&&img src=&/v2-7bbd0e9f1ad1da2bdbc0f80dbf3f89dc_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-7bbd0e9f1ad1da2bdbc0f80dbf3f89dc_r.jpg&&由于巨大的显示带宽需求,眼下的 VR 设备线材繁多,玩家行动受到颇多限制。&/p&&img src=&/v2-d9acbe3ac381_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-d9acbe3ac381_r.jpg&&&p&nVidia 的 MRS 技术,把四周的拉伸区域使用较低的分辨率渲染,用于提高渲染效率和降低带宽需求。&/p&&img src=&/v2-8c28a2d39eec8bc47669f3_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-8c28a2d39eec8bc47669f3_r.jpg&&&p&&a href=&/?target=http%3A///post/vr/-oculus-connect-3-abrash& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Abrash 在 Connect 3 上提到&i class=&icon-external&&&/i&&/a&的凹式渲染,用于动态地进一步降低需要传输和渲染的像素量。&/p&&p&&img src=&/v2-fb6ffc7ef0b6db581da0777_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/v2-fb6ffc7ef0b6db581da0777_r.jpg&&经由类似上面的技术,我们将有机会在不久后见到更细致的画面的同时,摆

我要回帖

更多关于 从来没谈恋爱的男孩子 的文章

 

随机推荐