• 全部 专栏 Game Jam专区
    • 红茶君 2007 5

      为什么要关注虚拟现实,因为所有现实都是虚拟的

      这次要推荐给大家的是今年FacebookF8大会上,Oculus的首席科学家Michael Abrash关于VR的演讲视频。比起WWDC和Google I/O,F8大会中引人注目的内容不算多,但Michael Abrash的这个演讲却非常值得一看,它或许能够告诉你为什么如今微软、索尼、HTC……等大小厂商都迫不及待地进入了VR领域。Michael用「黑客帝国」中Morpheus的名言来说明虚拟现实的核心——"What is real? How do you define 'real'? If you're talking about what you can feel, what you can smell, what you can taste and see, then 'real' is simply electrical signals interpreted by your brain."(“什么是真实?你如何定义‘真实’?如果真实指的是你所感觉到的、所闻到的、所尝到的和所见到的,那么‘真实’就仅仅是被大脑所编译的电信号。”)如果用工程式的思维方式来思考「真实体验」的实现,那么虚拟现实几乎就是一件不可能的事情;但从「如何欺骗感受器」的角度入手,却可以发现很多可探索的可能性。我们所感知到的并不是世界的全貌,我们是通过感受世界的模型来理解世界,体验的真实性在于感知——这种思路对于任何针对「体验」的设计,都是有启发性的。如果你还没有听过Michael Abrash的这场演讲,推荐你观看下面这个视频,感受一下这位传奇人物对「现实」的理解。视频较长,建议在WiFi环境下观看视频。没有中文字幕,但不算难听懂。你也可以关注indieace微信公众号(IndieAce)后回复「F8」查看Michael Abrash演讲中一些精彩的片段(文字版)。

    • 红茶君 2028 9

      有人说中国玩家品味差,然而「品味」究竟是什么?

      导语:在市场上劣质游戏风行的时候,我们会经常听见这样的论调:「中国的大部分玩家品味就是如此,这是市场的选择。」然而「品味」究竟是什么?是什么让人能够确信,神秘海域系列就是比国产页游更好的游戏呢(在两者同样满足了某一群体不同需求的情况下)?我们这次翻译了Paul Graham一篇讨论艺术品位的文章——《How Art Can Be Good》。作为一个创作者,这篇文章可以让你看清我们习以为常的相对主义,诚实地面对自己的创作。而如果你相信「好」有一个普适的标准,那么你也会相信,我们如今一切把游戏做得更「好」的努力都是有意义的。 [indent]How Art Can Be Good
      作者:Paul Graham[/indent]小时候我一直相信品味只是个人偏好问题:每个人喜欢的东西不同,但没有谁的偏好比其他人高尚。所谓「好品味」是不存在的。和其他许多我小时候深信的东西一样,这个想法是错误的,现在我来解释一下为什么。这里存在一个问题:如果说好的品味不存在,那么也就是说好的艺术并不存在。如果好的艺术确实存在,那么喜欢它们的人就应该比不喜欢它们的人拥有更好的品味。所以如果否定了品味的存在,也就否定了艺术、以及艺术家之间存在优劣之分。沿着这个思路想下去,我小时候的相对主义信念就坍塌了。当你打算创造些什么时,品味就成了一个实际的问题。你必须决定下一步该做什么。比如:如果我修改一下这里,整幅画会不会更好看些?如果不存在「更好」,其实你做什么都无所谓。事实上,你画不画也无所谓。你完全可以出门买一张现成的空白画布就算完事。如果好坏之分不存在的话,空白画布就和西斯庭教堂的穹顶画同样伟大。当然,其中包含的劳动少了许多,但如若你能够付出更少的努力达到同样的效果,那自然更令人敬佩,而不是相反。但这看起来并不合理,不是吗?受众我认为解决这个难题的关键在于,要记住艺术有其受众。艺术有其目的,这目的就是令受众感兴趣。好的艺术(和其他所有好东西一样)是那些极其优美地实现其目的的艺术。「令人感兴趣」这句话有许多含义。有的艺术作品是要震慑受众,有的则是为了取悦受众;有的主动地扑向你,有的则静默在背景之中。但所有艺术都要作用于受众,并且——这里是关键——「受众」这个群体中存在着一些共性。例如,几乎所有的人类都容易被人类的面孔吸引。这似乎是与生俱来的。比如婴儿一出生就能辨认人脸。事实上,面孔也随着人们对它的兴趣一同演进,面孔是身体的广告牌。所以,在其他所有条件相同时,一幅包含人类面孔的画,会比其他的画作更容易吸引人们的注意【注释一】。「品味只是个人偏好」这种说法之所以受欢迎,是因为如果它是错的,你要如何辨别哪些人品味更好?地球上有数十亿人,每个人都有自己的观点,要凭借什么判断一个好于另一个呢【注释二】?然而假如受众有共性,你就不是从一组随机的个人偏好中选择其一,因为这个组并不是随机的。所有人类都容易被面孔吸引,这是被事先定义的:面孔识别能力在我们的DNA当中。那么,即使承认「好艺术」的存在(就是那些顺利实现其目的的艺术),你也并不需要被迫选出几个个体,并为他们的观点贴上「正确」的标签。因为无论你怎么选,选出来的人都容易被面孔吸引。当然,外星生物大概不会对人类的面孔有兴趣。但他们也许和我们在其他方面有共同之处。最有可能的领域是数学。我认为,对于两种数学证明哪个更好这样的问题,外星生物在大部分情况下会与我们意见一致。厄多斯(译注:Paul Erdös,二十世纪著名数学家)就是这么认为的。他把最优雅的证明称作上帝的杰作,一般来说上帝的杰作在全宇宙中具有普世性【注释三】。一旦开始讨论受众的问题,就没必要再争论品味有无标准了。品味这时成了一系列的同心圆,就如同池塘里水的波纹。有些东西你和你的朋友都会感兴趣,有些东西大部分与你同龄的人都会感兴趣,有些东西则是大多数人类都会感兴趣,另外,或许还有一些东西会让大多数有知觉的个体(各种意义上的)产生兴趣。现实要比这更复杂一些,因为池塘中的水波也会相互重叠。比如,有些东西尤其能吸引男人,还有一些只会吸引处于特定文化当中的人。如果说,好的艺术是那些令其受众感兴趣的艺术,那么当你谈论艺术好坏时,也是在谈论它对于某个群体而言是好是坏。那么,简单地谈论「艺术的好坏」是否毫无意义?不是的,因为某一群受众是全人类的子集。我认为,当大家说一件艺术品好的时候,受众的概念是暗含其中的,也就是说,他们认为它会令任何人类感兴趣【注释四】。这是一个有意义的测试,尽管和所有日常概念一样,「人类」概念的边界比较含糊,但全人类还是存在许多共性。除了对面孔感兴趣之外,三原色对几乎所有人来说都比较特殊,因为我们的眼睛就是围绕三原色来工作的。大部分人类也会对3D物体产生兴趣,因为那似乎是我们的视觉认知机制的一部分【注释五】。除此之外,还有「寻边」的倾向,相对于那些模糊的图像,人类对有着确定形态的图像更感兴趣。当然,人类的共性远不只这些。我的目的并不是要总结一个完整的共性表,而仅仅是为了证明论证基础的存在。人们的偏好并不是随机的。因此,一位正在创作的艺术家,在决定是否改动画面中的某一部分时,就不需要想「有什么改的必要?不如投个硬币决定好了。」他会问:「怎么画才能让人们更感兴趣?」你随便出去买块空白画布,并不能因此成为米开朗基罗,这正是因为西斯廷教堂的穹顶更能勾起人们的兴趣。很多哲学家很难相信艺术有客观标准。比如说,他们相信美并不是事物的一种属性,而是存在于欣赏者的心中,这似乎是显而易见的道理。因此,美是「主观」而非「客观」的。实际上,如果把美的定义限制在「对人类产生一定作用」,同时意识到人类具有共性,那么就会发现它归根结底还是事物的一种属性。如果所有主体对某样事物的反应相似,那么就没必要区分某属性是属于主体还是属于这一事物。如此一来,好的艺术就成了事物的属性,就好比对人类来说,「有毒」是一种属性:如果某件作品持续以某种方式影响人类,那么它就是好艺术。错误那我们是否可以通过投票来指出什么是最好的艺术呢?毕竟,如果说好艺术的标准在于它对人类的吸引力,那么我们可以直接问问人们就够了,不是吗?并非如此。这种方法对于自然产品是可行的。我愿意去吃全人类投票选出的最美味的苹果,也可能愿意去他们选出的最美丽的海滩旅游,但并不一定愿意欣赏他们投票选出的最好的画。人造物是不同的。首先,艺术家不同于苹果树,他们常常故意捉弄人。有些小把戏是比较狡猾的。比如说,任何作品的完成度都为其定义了一个期待值。看到一幅似乎是随手画的素描时,你不会期待它的图像有摄影般的精准性。所以,一个常用的把戏(在插画师中尤为常见)就是故意让一幅画看起来没花多少时间。一般人看了会想:画家的技巧真是娴熟啊。这就像是在谈话中说了句貌似即兴说出的聪明话,但实际上你在之前一天就准备好了。另外一种把戏是品牌效应,它的作用更大。你要是去看《蒙娜·丽莎》,你很可能会失望,因为那幅画被放在一块厚玻璃中,周围是闹哄哄的人群,争先恐后地在画前拍照。你最多只能像在拥挤派对里隔着人群望房间另一头的朋友那样,望着这幅画。卢浮宫完全可以用一个复制品代替真迹,没人能发现得了。何况《蒙娜·丽莎》的尺寸不大,色泽也比较暗。如果把它和其他画一起放在博物馆里,标签上注明这是一个不知名的十五世纪画家的作品,然后叫从没见过它的人去看,我想大部分人看一眼就会走掉。对普通人来说,在对艺术进行评判时,品牌效应的影响比其他任何因素都大。如果他们见过某幅画的副本,那么见到并辨认出真迹的体验会让他们激动,甚至淹没他们对于该作品的真实反应。此外,当然还有人们自身的把戏。大部分成年人在看艺术品时,都会担心如果自己不喜欢自己应该喜欢的东西,就会被人当成是缺乏文化修养。这不单影响他们关于自身喜好的对外说法,而且确实会让他们喜欢他们「应该喜欢」的东西。这就是投票的方法行不通的原因。尽管检验一件艺术品的吸引力确实是有意义的,但从实践的角度来说,你无法测量这种吸引力,就像你无法通过一个摆在磁铁旁的指南针来确定方向--错误源的影响过于强大,依靠投票的方法,你只能得到错误的结果。不过,我们可以试着从另一个角度解决这个问题,用把自己当作小白鼠的方式。你是人类的一员,如果你想知道普通人对于某件艺术品的反应,那你至少可以尽量减少你自己的判断中的错误源影响,尝试去公正地评判。例如,虽然任何人面对一幅名画时都会被它的名气所影响,但我们可以用一些方法减少它的影响。其中一个方法是反复观看。看了几天之后,名气的影响会减弱,你就能够把它单纯当作一幅画来看。另一个方法是靠近一些:从十英尺外望过去,真迹看起来会更接近于你所熟悉的复本,一旦靠近,你就会发现许多在复本中丢失的细节。观看艺术作品的阻碍主要有两类:一是源于所处环境的偏见;二是艺术家的把戏。要避免这些把戏的影响并不难,通常,只要你能意识到它们的存在,它们就不会对你起作用。比如,我十岁的时候曾迷恋喷枪效果的字母,它们看上去像是闪亮的金属。然而一旦你研究过它的做法,就会明白这是种廉价的小把戏,靠的是不断地按下某几个视觉按钮来暂时取悦观看者,就像是通过大声喊叫去说服对方。避免被骗的方法是主动去找寻把戏,并将他们分类。当你在某种艺术中感受到一丝不诚实时,停下来想想问题在哪。当有人明显在迎合容易上当的观众时--不管是用闪闪发亮的东西取悦十岁小孩还是用看似前卫的东西取悦自我感觉良好的知识分子--你需要保持敏锐,弄清他们是怎么做的。看多了特定的把戏,你就会成为把戏鉴定高手,就像职业魔术师一样。什么样的东西算是把戏?简单地说,把戏是轻视受众的产物。例如,一九五零年代法拉利的设计师应该是根据他们心中的好车进行设计。但我怀疑通用汽车公司市场部的人是这样对设计师说的:「大部分人买 SUV 是为了看起来有男子气概,而不是为了越野。所以,不用担心避震,把它搞得尽量大、看上去尽量彪悍就行。」【注释六】我认为通过努力,我们能使自己对这些把戏几乎免疫。要摆脱环境的影响虽然比较难,但你至少可以朝那个方向去努力,方法就是多旅行,包括时间和空间上的旅行。看过其他文化的人喜欢的各不相同的东西,了解过去的人曾经喜欢的各不相同的东西之后,你的喜好多半也会改变。全然地无所不知大概不可能,因为时间上的旅行只能有一个方向。但如果你找到一件作品,对于你的朋友、对于尼泊尔人、对于古希腊人都同样具备吸引力的话,那你算找到了不得了的窍门。我主要论点不在于如何获得好品味,而在于论证好品味确实存在。我想我已经证明了这一点。艺术的确有优劣之分。好的艺术是那些能够引起人兴趣的艺术,既然人类有很多共性,引发他们兴趣的东西就不是随机的。既然艺术分好坏,那么品味也就有好坏,好品味指的是辨识好艺术的能力。如果我们讨论的只是苹果的味道,我同意品味只是个人偏好这个观点。每个人喜欢的苹果不同,哪里有谁对谁错【注释七】?问题在于,艺术并非苹果。艺术是人造物,艺术承载着许多文化的包袱。另外,做艺术的人经常用把戏混淆我们的视线。大部分人对艺术的判断是由这些无关的因素决定的,就好像把等量的苹果和墨西哥辣椒放在一起,让人们判断苹果的味道是好是坏--但他们只会记得辣椒的味道。因此,我认为判断哪些人品味好是可能的:他们就是那些把艺术当成苹果来品尝的人。更准确地说,他们具备两个特点:一、不容易受骗;二、喜好广泛,不受他们成长环境和经验的限制。如果你发现某些人能够排除影响他们判断的一切因素,那么你会发现他们还是倾向于喜欢不同的东西。但由于人类有太多共性,你也会发现他们有许多相同的观点。他们几乎会一致同意西斯庭教堂的穹顶比空白画布要美。做出好的艺术我写这篇文章是因为我已经厌倦了「品味是主观的」这种说法,想一次性将这种观点驳倒。任何有创造经验的人直觉上就知道这是不对的。当你进行艺术创作时,偷懒的诱惑和进行其他工作时一样强烈。当然,做出好东西是重要的。然而你看看人们谈论艺术好坏时的焦虑,就会发现即便是在艺术的领域,「品味是主观的」这个说法也很流行。那些以评判艺术为职业的人(比如策展人)面对这个问题的方法是尽量委婉,如「意义深远」、「十分重要」或(已经很接近了)「实现了」【注释八】。我不会天真地幻想,直言艺术的好坏会让论艺之人的谈论更有内容。其实,「品味是主观的」之所以流行,正因为过去人们关于好品味的一些论调多半是胡说。我的观点并不是为那些谈论艺术之人准备的,我想说服的是做艺术的人。如今,野心勃勃的年轻人进入艺术院校学习,就好像是撞上一堵砖墙。他们入校时都怀抱希望,希望某天如同那些被写入书中的艺术家一样优秀,而他们学到的第一个观点就是艺术分好坏这种想法已经过时了。每个人只要探索属于自己理想的艺术境界就好了【注释九】。我在艺术学校读书时,有一天,大家一起看一张十五世纪的名画的幻灯片,一位学生问:「为什么现在的画家画不出这样的作品?」教室里顿时安静了。虽然很少人这么问,但这个问题潜藏在每个艺术系学生的心中。就像在菲利普·莫里斯烟草公司内部会议上突然有人提起肺癌话题一般。「怎么说呢,」教授回答,「我们现在关心的问题不同了。」教授是个好人,但当时我忍不住想把他送回十五世纪的佛罗伦萨,让他向达芬奇等艺术家解释一下,他们当年的那种有局限性的艺术观是如何被后人超越的。想象一下这样的对话吧,多有趣。事实上,十五世纪佛罗伦萨的艺术家们之所以能创造伟大的杰作,原因之一正是他们相信人能创造出伟大的作品。【注释十】他们互相激烈地竞争,抢着超越对方——就像今天的数学家或物理学家那样。大概所有成就非凡的人都是如此。「你能创造出好东西」这个想法并不仅仅是一个有用的幻想,它是一个事实。因此,承认艺术有优劣之分的最重要的结果,就是让艺术家有可能做出好艺术。我要对当今心怀志向、希望做出好作品而走进艺术院校的学生们说:不要相信别人的说法。你的希望并不天真,也不过时。好的艺术确实存在,如果你努力创作好的作品,总会有人注意到。作者注释【1】:当然,这不是说好画当中一定包含人的面孔,而是说每个人的视觉反应里都有这么一个键。有些情况下,你会在画中避免使用面孔,正因它太容易吸引注意力。但从面孔在广告中的频繁使用,就可以看出它的普适作用。【2】:这种说法容易让人相信的另一个原因是,它令人们自我感觉良好。对于孩子来说,这个说法很可笑。在其他任何领域,我们都对小孩子说你还有许多东西要学,但在这个领域他们是完美的。他们的意见和任何成年人的意见分量相同。对你小时候相信的东西大都应该质疑,但这个问题例外。【3】:数学证明的优美是可量化的,或许会有一些正式的测量方法,其结果和数学家的判断一致。或许应该尝试为证明发明这样一种形式语言:越优美的证明越短(比如在宏扩展或被编译之后)。【4】:外星生物创造艺术或许是可能的,但这里不讨论,因为一、这问题太难回答;二、能证明对于人类来说艺术有优劣之分,我就已经很满足了。【5】:如果说早期抽象画比后期的更有意思,也许是因为最早的抽象画家受到的训练是绘画源自生活,因此他们的手的动作和我们日常用来代表实物的动作类似。他们画的东西尽管非同寻常,但依然不是完全没有生活中的参照物。【6】:事情比这要复杂一些,因为艺术家有时在模仿那些玩小把戏的艺术时,是无意识地玩了把戏。【7】:我举苹果的例子是因为如果人们能看到苹果的样子,就有被骗的可能。我小的时候有种叫蛇果的苹果,种植者用了一些方法,让它们摆在店里时显得很漂亮,然而并不好吃。【8】:公平地说,做策展人不容易。如果他们跟近来的艺术打交道,那就不得不把一些烂作品纳入展览中。因为决定展出哪些作品的因素基本就是市场价格,对于近来的艺术来说,成功的商人及他们的太太很大程度上决定了这一切。因此策展人和画商使用中性语言并不总是说明他们不诚实。【9】:现实的情况是,大家都很擅长谈论艺术。随着艺术变得越来越随机,本应投入艺术创作中的努力被用在了艺术背后那些听起来很高深的理论中。例如「我的作品展现了都市语境中对于性别和性问题的探索」等等。不同的人群都在这场游戏中得到了好处。【10】:还有些另外的原因,比如佛罗伦萨是当时全世界最富有、最有文化的城市。另外就是当时的艺术家们活在一个摄影还没有发明的时代,摄影不但使肖像画家丢了饭碗,也使品牌效应成了艺术买卖中的决定因素。顺带提一句,我并不是说只有十五世纪的欧洲艺术才是好艺术。我不是说我们应该模仿他们,我的意思是我们应该像他们那样工作。在如今的某些领域里,人们的工作热情与诚恳度并不输给十五世纪的艺术家,但艺术不在这些领域当中。感谢 Trevor Blackwell, Jessica Livingston 与 Robert Morris 阅读初稿,感谢 Paul Watson 允许我使用放在页顶的图片。

    • sywgk 1226

      游戏圈业内Podcast聊天节目《游戏的人》节目链接汇总(持续更新)

      大家好,我是雅文。新浪微博是 @游戏领航员JY。 从读书期间开始,我一直有在不定期的翻译一些海外和游戏有关的视频节目:
      如《额外加分》系列(http://www.indieace.com/thread-7817-1-1.html)TUN高品位低调宅系列(http://bbs.a9vg.com/thread-4491430-1-1.html)
      并且在悉尼大学读电影期间,作为学校作业之一还拍摄了一部关于悉尼游戏制作人的小纪录片 (http://v.youku.com/v_show/id_XNTgyMzU4NTYw.html)
      通过制作和发布这些视频,有幸结识了一些在游戏业工作的朋友。
      我很喜欢和这些对游戏有热情的游戏从业者进行交流,通过跟他们聊天能了解很多原先不知道的信息,感觉受益良多。所以从今年年初起,我开始用闲暇时间录制这档叫做 《游戏的人》的Podcast聊天节目,每期节目录制前我都会在我新浪微博,QQ群或微信公众号上发布信息,所有对话题感兴趣的网友都可以通过YY或QQ群收听直播,并通过文字与我们互动。希望能够通过将游戏圈不同领域的游戏人联系到一起进行交流,来为听众带来有价值的信息。
      还望大家多多支持!
      PS:论坛中额外加分的帖子已经很久没有更新,所有额外加分系列新的翻译欢迎直接关注我的优酷频道和Youtube频道
      最新一期:《游戏的人》第十一期:游戏新媒体
      嘉宾:神奇陆夫人,女流,黑桐谷歌
      随着社交网络与网络视频技术的发展与普及。许多游戏主播逐渐的崛起,成为游戏界一股全新的影响力。今天我很荣幸的邀请到三位在国内游戏界已经有一定影响力的人气主播,让他们分享下自己的经验与故事。大家一起来探讨一下这种新兴的游戏网络自媒体,对于游戏界会有着什么样的影响。
      腾讯:优酷:Youtube:https://youtu.be/cw9uLE6Avb0?list=PLPreL_74nAEhGNUkLn6EoJ4i2kuBmQa17A站:B站:荔枝FM音频版:http://www.lizhi.fm/1448168/20582217515750150

      第一期 温故知新
      大家新年快乐,在春节即将过去之际,大家一起来辞旧迎新,温故知新吧。
      这是我第一次尝试录制Podcast节目,经验非常不足,望大家多多指教。如果大家喜欢,欢迎关注我youtube频道,通过Youtube Comments多多交流~
      嘉宾:拼命玩三郎,熊拖泥,大猫咪F
      优酷:http://v.youku.com/v_show/id_XOTA1ODU5Nzk2.html腾讯:http://v.qq.com/page/n/l/d/n0148qlwxld.htmlYoutube:https://www.youtube.com/watch?v=uWFJGnhbwrQA站:http://www.acfun.tv/v/ac1795053B站:http://www.bilibili.com/video/av2080123/荔枝FM音频版:http://www.lizhi.fm/1448168/18758731704296966
      第二期:游戏杂志
      本期我们很荣幸的请来了大众软件资深主编八神经,UCG游戏人杂志主编稀饭及游戏研究学者大猫咪F一同来聊一聊《大众软件》及UCG这本对国内游戏圈影响深远的游戏杂志~
      嘉宾:大猫咪F,八神经,稀饭
      优酷:
      上:http://v.youku.com/v_show/id_XOTEzNTcyNTI0.html?from=y1.7-2中:http://v.youku.com/v_show/id_XOTE0MjcxNzE2.html?from=y1.7-2下:http://v.youku.com/v_show/id_XOTE1NzIyMzYw.html?from=y1.7-2

      腾讯:上:http://v.qq.com/page/y/o/y/y0149glvsoy.html中:http://v.qq.com/page/e/g/g/e0149pkzjgg.html下:http://v.qq.com/page/d/j/9/d0149jlnnj9.html
      Youtube:
      上:https://youtu.be/paujjW2_444中:https://youtu.be/68yqUVhR0XU下:https://youtu.be/p1rIPCZHQeE

      A站:上:http://www.acfun.tv/v/ac1795056中:http://www.acfun.tv/v/ac1795368下:http://www.acfun.tv/v/ac1798337
      B站:上:http://www.bilibili.com/video/av2117691/中:http://www.bilibili.com/video/av2120619/下:http://www.bilibili.com/video/av2126087/
      荔枝FM音频版:http://www.lizhi.fm/1448168/18757219338918918
      第三期:Unreal VS Unity
      2015年美国GDC刚刚过去不久,本次GDC上Unreal引-擎宣布免费,游戏开发界再度弥漫起引擎之战的硝烟。本期节目我们-邀请到国内独立游戏开发者张翰荣,椰岛CTO Bowie,Flash开发者熊拖泥以及拼命玩游戏站长拼命玩三-郎,一同来探讨Unity与Unreal这两家目前对游戏开发影-响力最大的两个第三方引擎究竟各自有何不同。
      嘉宾:张翰荣,Bowie,熊拖泥,拼命玩三郎
      优酷:
      P1:http://v.youku.com/v_show/id_XOTE4NjMzMDMy.html?from=y1.7-2P2:http://v.youku.com/v_show/id_XOTIxODQ4OTE2.html?from=y1.7-2P3:http://v.youku.com/v_show/id_XOTI1NDI2Mzcy.html?from=y1.7-2

      腾讯:
      P1:http://v.qq.com/page/s/l/f/s0149x394lf.htmlP2:http://v.qq.com/page/o/0/0/o0150y9vl00.htmlP3:http://v.qq.com/page/p/p/d/p01508trppd.html
      Youtube:
      P1:https://youtu.be/RQLTM8TT8ZEP2:https://youtu.be/a7UGLyZ9WicP3:https://youtu.be/SmYRBT1UV3g
      A站:
      P1:http://www.acfun.tv/v/ac1804297P2:http://www.acfun.tv/v/ac1812003P3:http://www.acfun.tv/v/ac1821053
      B站:
      P1:http://www.bilibili.com/video/av2141070/P2:http://www.bilibili.com/video/av2156202/P3:http://www.bilibili.com/video/av2172786/
      荔枝FM音频版:http://www.lizhi.fm/1448168/19060716761234950
      第四期 GDC游戏开发者大会2015
      2015美国旧金山GDC已经结束,作为一年中对于游戏开发者最重要的游戏展会之一,我邀请了一些参加了今年GDC的朋友一同跟大家分享下他们的见闻和感受。今天的嘉宾有中国GDC负责人姚安,Steel Media亚洲商务总监Simon,火星时代游戏事业部总监JadeWus, 美格方互动CEO张翰荣 与独立游戏开发者陶文。
      嘉宾:姚安,Simon朱,JadeWus,陶文
      优酷:
      P1:http://v.youku.com/v_show/id_XOTI4MDk1MjEy.html?from=y1.7-2P2:http://v.youku.com/v_show/id_XOTI5OTQwNTIw.html?from=y1.7-2P3:http://v.youku.com/v_show/id_XOTMxMzAxNDI0.html?from=y1.7-2P4:http://v.youku.com/v_show/id_XOTMxMzAxNjAw.html?from=y1.7-2


      腾讯:
      P1:http://v.qq.com/page/u/4/k/u0150ailx4k.htmlP2:http://v.qq.com/page/s/x/n/s0151441jxn.htmlP3:http://v.qq.com/page/q/x/v/q0151ib5yxv.htmlP4:http://v.qq.com/page/e/k/t/e0151tdzkkt.html
      Youtube:

      P1:https://youtu.be/RpOt7bqdEGsP2:https://youtu.be/S2obwo8VJ7MP3:https://youtu.be/MHJQg_V7lSUP4:https://youtu.be/moLvPhQLPmo
      A站:P1:http://www.acfun.tv/v/ac1826266P2:http://www.acfun.tv/v/ac1830635P3:http://www.acfun.tv/v/ac1833058P4:http://www.acfun.tv/v/ac1833579
      B站(分P):http://www.bilibili.com/video/av2192370/
      荔枝FM音频版:http://www.lizhi.fm/1448168/19252829306151686
      第五期 闲聊游戏化
      本期节目的话题是Gamification游戏化,即游戏机制运用到现实生活中。对这个概念陌生的朋友可以参考之前额外加分关于游戏化介绍的节目
      额外加分:游戏化中文字幕链接:http://v.youku.com/v_show/id_XNjU5Njg3Nzg4.html
      同时本期节目的主持大猫咪F(刘梦霏)是在为数不多的在中国研究游戏化的学者,他本人还有一个专门用作讨论游戏化的QQ群,感兴趣的朋友可以加群一同探讨。
      嘉宾:大猫咪F
      优酷:http://v.youku.com/v_show/id_XOTM3MTM4MTY0.html?from=y1.7-2腾讯:http://v.qq.com/page/v/2/4/v0152unkg24.htmlYoutube:https://www.youtube.com/watch?v=Ut0_rIcPuIMA站:B站:http://www.bilibili.com/video/av2231349/荔枝FM音频版:http://www.lizhi.fm/1448168/19414549320138502
      第六期:Flash游戏
      相信很多人或多或少都接触过Flash游戏或Flash动画,但在游戏越来越普及的今天,似乎Flash也越来越变得小众起来,很多开发者可能都会和我一样对Flash似乎既熟悉,却又很陌生。今天我们有幸请来了U77前站长陆家贤,拼命玩游戏站长拼命玩三郎,Flash游戏专家自爆君和Flash技术开发者熊拖泥和大家一同分享所有关于Flash游戏相关的信息,希望本期节目能让大家对Flash的现况能有更深的了解。

      嘉宾:拼命玩三郎,熊拖泥,阿光,自爆君
      优酷:http://v.youku.com/v_show/id_XOTQwNTY4Mjcy.html?from=y1.7-2腾讯:http://v.qq.com/page/i/k/u/i0152s3j2ku.htmlYoutube:https://youtu.be/Ut0_rIcPuIMA站:http://www.acfun.tv/v/ac1919930B站:http://www.bilibili.com/video/av2245352/荔枝FM音频版:http://www.lizhi.fm/1448168/19504678940592134
      第七期:台湾游戏业
      一直以来台湾有许多游戏作品对整个中文游戏产业都有着重要的影响力。仙剑,轩辕剑,金庸群侠传,武林群侠传这些几乎不管是在大陆还是在台湾都能耳熟能详的作品几乎都是出自台湾的工作室。然而我相信许多大陆的游戏开发者都和我一样,对台湾的游戏业还是非常陌生的。所以今天我有幸邀请了两位目前在台湾从业的朋友Mark和小黑 和 一位目前在大陆从事游戏商务工作的朋友Simon,一同来交流一下两岸游戏业目前的现况与不同。

      嘉宾:Marc,小黑,Simon朱
      优酷:http://v.youku.com/v_show/id_XMTI0ODIxMDc2OA==.html?from=y1.7-2腾讯:http://v.qq.com/page/f/x/i/f0154d121xi.htmlYoutube:https://youtu.be/l-CciqfDqxwA站:http://www.acfun.tv/v/ac1919925B站:(不知什么原因,本期节目腾讯链接转载B站时会出现链接格式错误导致无法上传B站)荔枝FM音频版:http://www.lizhi.fm/1448168/20227087607377158
      第八期: 游戏茶话会
      今天这期节目有些特殊,没有特定的主题。只是邀请一些在国内做游戏开发的朋友一起交流和探讨游戏开发相关的话题,做些经验上的交流。所以命名为游戏茶话会,希望这种闲谈式的节目也能为大家提供有营养的信息内容。
      嘉宾:穆飞, 囧囧囧囧, 熊拖泥, 陶文,拼命玩三郎, 加尔福特
      优酷:上:http://v.youku.com/v_show/id_XMTI0OTQ1MjcyMA==.html?from=y1.7-2下:http://v.youku.com/v_show/id_XMTI0OTQ1NjkwOA==.html?from=y1.7-2
      腾讯:上:http://v.qq.com/page/h/a/m/h0155h97iam.html下:http://v.qq.com/page/l/6/3/l0155zlm963.htmlYoutube:上:https://youtu.be/jmwgzSvSG0s下:https://youtu.be/un_mmpVqdcIA站:上:http://www.acfun.tv/v/ac1931387下:http://www.acfun.tv/v/ac1931389B站:上:http://www.bilibili.com/video/av2379074/下:http://www.bilibili.com/video/av2379290/荔枝FM音频版:http://www.lizhi.fm/1448168/20391405003384198
      第九期:游戏人在日本
      日本游戏产业一直以来都有着举足轻重的影响力。即使在整个传统的日本游戏业大环境都不是很景气的今天,也依然能看到日本厂商开发出像血源这样的优秀作品,其实力还是有目共睹的。今天我请来两位目前正在日本生活的游戏开发者极速,谨聪,和两位马上就要去日本学习的知名主播Chimera君和他的好友VIP,一起来和大家交流日本的游戏文化,与生活状态。 其中极速是某知名游戏公司在职企划,出于公司协议不便公开公司名称,还请大家多多理解。
      嘉宾:Chimera君,极速,谨聪
      优酷:腾讯:http://v.qq.com/page/j/a/n/j0155nswlan.htmlYoutube:https://youtu.be/m22auWOBQBYA站:http://www.acfun.tv/v/ac1938490B站:http://www.bilibili.com/video/av2395569/荔枝FM音频版:http://www.lizhi.fm/1448168/20490276761298182
      第十期:主机游戏
      随着中国大陆地区主机游戏解禁,PS4与Xbox One也陆陆续续进入了国内的市场。这给国内的游戏开发者带来了新的机遇与展现自己实力的平台。本期节目我请来了三位有一定主机游戏开发经验的开发者,和大家一起分享和交流主机游戏开发相关的经验与信息

      嘉宾:张翰荣Vision,院长,囧囧囧囧
      优酷:腾讯:http://v.qq.com/page/t/e/5/t01554yrle5.htmlYoutube:https://youtu.be/Pv7wR9Te6m8A站:B站:http://www.bilibili.com/video/av2402496/荔枝FM音频版:http://www.lizhi.fm/1448168/20534783627691782

    • Bowie 2206 1

      IL2CPP 深入讲解:代码生成之旅

      IL2CPP 深入讲解:代码生成之旅
      IL2CPP INTERNALS: A TOUR OF GENERATED CODE


      这是IL2CPP深入讲解系列的第二篇博文。在这篇文章中,我们会对由il2cpp产生的C++代码进行分析。我们会看到托管代码中的类在C++中如何表示,对.NET虚拟机提供支持的C++代码运行时检查等功能。
      后面例子会使用特定版本的Unity,随着以后新版本的Unity发布,这些代码可能会有所改变。不过这没有关系,因为我们文中将要提到的概念是不会变的。
      示例程序我将用到Unity 5.0.1p1来创建示例程序。和第一篇博文一样,我创建了一个空的项目,添加一个文件,加入如下内容:































      using UnityEngine; public class HelloWorld : MonoBehaviour { private class Important { public static int ClassIdentifier = 42; public int InstanceIdentifier; } void Start () { Debug.Log("Hello, IL2CPP!"); Debug.LogFormat("Static field: {0}", Important.ClassIdentifier); var importantData = new [] { new Important { InstanceIdentifier = 0 }, new Important { InstanceIdentifier = 1 } }; Debug.LogFormat("First value: {0}", importantData[0].InstanceIdentifier); Debug.LogFormat("Second value: {0}", importantData[1].InstanceIdentifier); try { throw new InvalidOperationException("Don't panic"); } catch (InvalidOperationException e) { Debug.Log(e.Message); } for (var i = 0; i Debug.LogFormat("Loop iteration: {0}", i); } }}

      把平台切换到WebGL,并且打开“Development Player”选项以便我们能得到相对可以阅读的函数,变量名称。我还将“Enable Exceptions”设置到“Full”以便打开异常捕捉。
      生成代码总览在WebGL项目生成之后,产生的C++文件可以在项目的Temp\StagingArea\Data\il2cppOutput目录下找到。一但Unity Editor关闭退出,这个临时目录就会被删除。相反的,只要Editor还开着,这个目录就会保持不变,方便我们对其检视。
      虽然这个示例项目很小,只有一个C#代码文件,但是il2cpp还是产生了很多文件。我发现有4625个头文件和89个C++文件。要处理这么多代码文件,我个人喜欢用Exuberant CTags 文本编辑工具。它可以快速的生成代码文件标签,让浏览理解这些代码变得更容易。一开始,你会发现这些生成的C++文件都不是来源于我们那个简单的C#代码,而是来源于诸如mscorlib.dll 这样的C#标准库。正如我们在第一篇文章中提到的,IL2CPP后台使用的标准库和Mono使用的库是同一套,没有任何区别。需要注意的是当每次构建项目的时候,il2cpp.exe都会把这些标准库转换一次。貌似这没啥必要,因为这些库文件是不会改变的。
      然而,在IL2CPP的后端处理中,通常会使用字节码剥离(byte code stripping)技术来减少可执行文件的尺寸。因此游戏代码的一小点变化也会导致标准库引用的改变,并影响最终剥离代码。所以目前我们还是在每次生成项目的时候转换所有的标准库。我们也在研究是否有其他更好的方法可以加快项目生成的速度,但目前为止还没有好的进展。
      托管代码如何映射到C++代码
      在托管代码中的每个类,il2cpp.exe都会相应的生成一个有着C++定义的头文件和另外一个进行函数声明的头文件。举个例子,让我们看看UnityEngine.Vector3是如何被转换的。这个类的头文件名字叫UnityEngine_UnityEngine_Vector3.h。头文件名的组成:一开始是程序集名称(这里是UnityEngine),然后跟着命名空间(还是UnityEngine),最后是这个类型的名字(Vector3)。头文件的内容如下:










      // UnityEngine.Vector3struct Vector3_t78{ // System.Single UnityEngine.Vector3::x float ___x_1; // System.Single UnityEngine.Vector3::y float ___y_2; // System.Single UnityEngine.Vector3::z float ___z_3;};

      il2cpp.exe对Vector3中三个成员都进行了转换,并且适当的处理了下变量名字(在成员变量前面添加下划线)以避免和保留字冲突。UnityEngine_UnityEngine_Vector3MethodDeclarations.h头文件中则包含了Vector3这个类中所有相关的函数。比如我们熟悉的ToString函数:


      // System.String UnityEngine.Vector3::ToString()extern "C" String_t* Vector3_ToString_m2315 (Vector3_t78 * __this, MethodInfo* method) IL2CPP_METHOD_ATTR

      请大家注意函数前面的注释,它能很好的反应出这个函数在原本托管代码中的名称。我时常发现这些个注释非常有用,能让我在C++代码中快速定位我想要寻找的函数。由il2cpp.exe生成的函数代码有着以下一些有趣的特性:
      所有的函数都不是成员函数。也就是说函数的第一个参数永远都是“this”指针。对于托管代码中的静态函数而言,IL2CPP会传递NULL作为第一个参数的值。这么做的好处是可以让il2cpp.exe转换代码的逻辑更加简单并且让代理函数的处理变得更加容易。所有的函数还有一个额外的MethodInfo*参数用来描述函数的元信息。这些元信息是虚函数调用的关键。Mono使用和特定平台相关的方法来传递这些元信息。而IL2CPP出于可移植方面的考虑,并没有使用这些和平台相关的特定代码。所有的函数都被声明成了extern “C”,这样一来,在需要的时候我们就可以骗过C++编译器让其认为所有这些函数都是一个类型。托管函数中的类型会被加上“_t”的后缀,函数则是加上“_m”后缀。最后我们加上一个唯一的数字来避免名字的重复。这些数字会随着项目代码的改变而改变,因此你不能把数字作为索引或者分析的参照。前两个指针暗示着每个函数都至少有两个参数:“this”和“MethodInfo*”。这些额外的参数会加重整个调用的负担么?理论上是显而易见会加重的,但是我们在实际的测试中还没有发现这些参数对性能产生影响。
      我们可以用Ctags工具跳转到ToString函数的定义部分,位于Bulk_UnityEngine_0.cpp文件中。在这个函数中的代码看上去和C#中Vector3::ToString()的代码一点也不像。但是当你用ILSpy 获取到Vector3::ToString()内部的代码后,你会发现C++代码和C#的IL代码是十分接近的。
      为什么il2cpp.exe不针对每一个类中的函数生成单独的一个cpp文件呢?看看Bulk_UnityEngine_0.cpp,你会发现它有惊人的20,481行!之所以这么做的原因是我们发现C++编译器在处理大量的文件时会有问题。编译四千多个.cpp文件所用的时间远比编译相同的代码量,但是集中在80个.cpp文件中所用的时间要长得多。因此il2cpp.exe将所有类的函数定义放到一个组里并为这个组生成C++文件。现在让我们看看函数声明头文件的第一行:

      #include "codegen/il2cpp-codegen.h"

      il2cpp-codegen.h文件中包含了用来调用运行时库libil2cpp的代码。我们在稍后会谈谈调用运行时库的一些方法。
      函数预处理代码段(Method prologues )让我们再仔细的看下Vector3::ToString()函数的定义,你会发现函数中有一段特有的代码,这段代码是il2cpp.exe模板产生的,会插入到任何函数的最前面。







      StackTraceSentry _stackTraceSentry(&Vector3_ToString_m2315_MethodInfo);static bool Vector3_ToString_m2315_init;if (!Vector3_ToString_m2315_init){ ObjectU5BU5D_t4_il2cpp_TypeInfo_var = il2cpp_codegen_class_from_type(&ObjectU5BU5D_t4_0_0_0); Vector3_ToString_m2315_init = true;}

      代码的第一行是一个局部变量StackTraceSentry。这个变量是用来跟踪托管代码的堆栈调用的。有了这个变量,IL2CPP就能在Environment.StackTrace调用中正确的打印出堆栈信息。是否产生这行代码是可选的,当你在il2cpp.exe命令行中加入--enable-stacktrace开关(因为我在WebGL选项中设置了“Enable Exceptions”为“Full”),就会生成这行代码。我们发现对于简单的小函数来说,这行代码的加入对代码的执行性能是有影响的。所以对于iOS或者其他有内置栈信息的平台来说,我们不会加入这行代码(而使用平台内置的栈信息)。但是对于WebGL来说,由于是在浏览器中执行,所以没有系统内置的栈信息可供调用。只能由il2cpp.exe加入以便托管代码的异常机制能正常运作。
      代码序的第二部分是数组或者和类型相关的元信息的延迟加载。ObjectU5BU5D_t4实际代表的是System.Object[]。这部分代码永远只执行一次,如果这个类型的元信息已经加载过了,就直接跳过这段代码,啥也不做。所以这段代码不会带来性能下降。那么这段代码是线程安全的嘛?如果两个线程都同时进行Vector3::ToString() 调用会发生什么?实际上,这不会有任何问题,因为libil2cpp运行时中的类型初始化函数是线程安全的。不管初始化函数被多少个线程同时调用,实际的执行是同一时间只能有一个线程的函数在执行。其他线程的函数都会被挂起直到当前的函数处理完成。所以总的来说,代码是线程安全的。
      运行时检查函数的下个部分创建了一个object数组,将Vector3的x存在局部变量中,然后将这个变量装箱并加入到数组的零号位置中。下面是生成的C++代码:













      // Create a new single-dimension, zero-based object arrayObjectU5BU5D_t4* L_0 = ((ObjectU5BU5D_t4*)SZArrayNew(ObjectU5BU5D_t4_il2cpp_TypeInfo_var, 3));// Store the Vector3::x field in a localfloat L_1 = (__this->___x_1);float L_2 = L_1;// Box the float instance, since it is a value type.Object_t * L_3 = Box(InitializedTypeInfo(&Single_t264_il2cpp_TypeInfo), &L_2);// Here are three important runtime checksNullCheck(L_0);IL2CPP_ARRAY_BOUNDS_CHECK(L_0, 0);ArrayElementTypeCheck (L_0, L_3);// Store the boxed value in the array at index 0*((Object_t **)(Object_t **)SZArrayLdElema(L_0, 0)) = (Object_t *)L_3;


      在IL代码中没有出现的三个运行时检查是由il2cpp.exe加入的。
      如果数组为空,NullCheck代码会抛出NullReferenceException异常。如果数组的索引不正确,IL2CPP_ARRAY_BOUNDS_CHECK代码会抛出IndexOutOfRangeException异常。如果加入数组的类型和数组类型不符合,ArrayElementTypeCheck代码会抛出ArrayTypeMismatchException异常。
      这三个检查本来都是由.NET虚拟机完成的,在Mono实现中,不会插入这些个代码而是使用平台相关的信号机制来进行检查。对于IL2CPP,我们希望做到和平台无关的可移植性并且还要支持像WebGL这样的平台,所以不能使用Mono的机制,而是显示的插入检查代码。
      这些检查会引起性能的下降么?在大多数情况下,我们并没有看到由此带来的性能损失,并且好处是我们提供了.NET虚拟机需要的安全保护机制。在某些特定的场合,比如在大量的循环中,我们确实看到了性能的下降。目前我们正在寻找方法在il2cpp.exe生成代码的时候减少这些运行时检查,各位有兴趣的可以继续关注。
      静态变量我们已经了解了实例变量(Vector3)如何运作,现在让我们来看看托管代码中的静态变量是如何转换成C++代码并使用的。让我们找到HelloWorld_Start_m3函数,这个函数应该在Bulk_Assembly-CSharp_0.cpp文件中。从这个函数我们找到一个叫Important_t1的类型(这个类型应该是在U2DCSharp_HelloWorld_Important.h头文件里)










      struct Important_t1 : public Object_t{ // System.Int32 HelloWorld/Important::InstanceIdentifier int32_t ___InstanceIdentifier_1;};struct Important_t1_StaticFields{ // System.Int32 HelloWorld/Important::ClassIdentifier int32_t ___ClassIdentifier_0;};

      大伙儿可能注意到了,il2cpp.exe将生成的C++代码分成了两个结构,一个结构负责普通的成员变量,另一个结构负责静态成员。因为静态成员是所有实例共享的数据,因此在运行的时候,Important_t1_StaticFields只有一份。所有的Important_t1实例都共享这个数据。在生成的代码中,通过下面的代码来获取静态数据:

      int32_t L_1 = (((Important_t1_StaticFields*)InitializedTypeInfo(&Important_t1_il2cpp_TypeInfo)->static_fields)->___ClassIdentifier_0);


      在Important_t1的元信息结构中有一个指向Important_t1_StaticFields结构的指针(static_fields),然后通过类型转换再取出需要的值(___ClassIdentifier_0)
      异常在托管代码中的异常会被il2cpp.exe转换成C++的异常。我们再一次的选择了这个策略还是出于可移植性的考虑:去掉和平台相关的方案。当il2cpp.exe需要转换生成一个托管的异常的时候,它会调用il2cpp_codegen_raise_exception函数。在我们的例子中,生成的C++异常处理代码如下:
























      try{ // begin try (depth: 1) InvalidOperationException_t7 * L_17 = (InvalidOperationException_t7 *)il2cpp_codegen_object_new (InitializedTypeInfo(&InvalidOperationException_t7_il2cpp_TypeInfo)); InvalidOperationException__ctor_m8(L_17, (String_t*) &_stringLiteral5, /*hidden argument*/&InvalidOperationException__ctor_m8_MethodInfo); il2cpp_codegen_raise_exception(L_17); // IL_0092: leave IL_00a8 goto IL_00a8;} // end try (depth: 1)catch(Il2CppExceptionWrapper& e){ __exception_local = (Exception_t8 *)e.ex; if(il2cpp_codegen_class_is_assignable_from (&InvalidOperationException_t7_il2cpp_TypeInfo, e.ex->object.klass)) goto IL_0097; throw e;}IL_0097:{ // begin catch(System.InvalidOperationException) V_1 = ((InvalidOperationException_t7 *)__exception_local); NullCheck(V_1); String_t* L_18 = (String_t*)VirtFuncInvoker0::Invoke(&Exception_get_Message_m9_MethodInfo, V_1); Debug_Log_m6(NULL /*static, unused*/, L_18, /*hidden argument*/&Debug_Log_m6_MethodInfo);// IL_00a3: leave IL_00a8 goto IL_00a8;} // end catch (depth: 1)

      所有的托管异常都被封装进了il2CppExceptionWrapper的C++类型。当C++代码捕获了这种异常之后,会试图将包解开获得托管异常(Exception_t8)。就这个例子而言,我们期待的是一个InvalidOperationException异常,所以当我们发现抛出的异常不是这个类型的时候,代码会创建一个C++异常的拷贝并重新抛出。反之如果异常正是我们所关注的,代码就会跳到异常处理的那段。
      Goto是个什么鬼?跳转语句!?!这段代码有一个有意思的地方:大伙儿发现了labels标签和goto语句没有?这些不太使用的东西居然出现在了结构化的代码中(译注:主流观点都不建议使用labels和goto语句,因为这会破坏程序的结构化导致各种bug的产生)。为什么会这样?因为IL!IL是没有诸如for,while循环和if/then判断结构化概念的低等级的语言。因为il2cpp.exe需要处理IL代码,因此也会出现goto语句。还是看例子,让我们看看HelloWorld_Start_m3函数中的循环是个啥样子的:
























      IL_00a8:{ V_2 = 0; goto IL_00cc;}IL_00af:{ ObjectU5BU5D_t4* L_19 = ((ObjectU5BU5D_t4*)SZArrayNew(ObjectU5BU5D_t4_il2cpp_TypeInfo_var, 1)); int32_t L_20 = V_2; Object_t * L_21 =Box(InitializedTypeInfo(&Int32_t5_il2cpp_TypeInfo), &L_20); NullCheck(L_19); IL2CPP_ARRAY_BOUNDS_CHECK(L_19, 0); ArrayElementTypeCheck (L_19, L_21);*((Object_t **)(Object_t **)SZArrayLdElema(L_19, 0)) = (Object_t *)L_21; Debug_LogFormat_m7(NULL /*static, unused*/, (String_t*) &_stringLiteral6, L_19, /*hidden argument*/&Debug_LogFormat_m7_MethodInfo); V_2 = ((int32_t)(V_2+1));}IL_00cc:{ if ((((int32_t)V_2) { goto IL_00af; }}

      在这里变量V_2是循环的索引,从0开始,在循环代码的最后进行累加。

      V_2 = ((int32_t)(V_2+1));

      循环的结束检查代码:

      if ((((int32_t)V_2)

      只要V_2小于3,goto语句就会跳转到IL_00af标签处,也就是循环的一开始继续执行。你可能会想:嗯。。il2cpp.exe一定在偷懒,直接使用了IL的代码而不是使用抽象的语法分析树。如果你是这么想的,那么恭喜你猜对了。。。 你可能还会注意到在上面的这段运行时检查的代码中,有下面的情况:


      float L_1 = (__this->___x_1);float L_2 = L_1;

      很显然, 变量L_2不是必须的,大多数的C++编译器会将其优化掉。对于我们来说,我们在想办法不去生成这行代码(译注:因为il2cpp.exe是从IL进行代码的转换,没有使用高级的语法分析,所以会产生多余的代码)。我们也在研究使用高级的抽象语法树(Abstract Syntax Tree,缩写:AST)以便更好的理解IL代码从而产生更好的C++代码(译注:可能以后就会去除goto跳转语句了)
      总结通过一个简单的项目,我们初窥了IL2CPP如何将托管代码转换成C++代码。如果你没有生成测试项目,我强烈建议你做一遍并进行一些研究。在你做这件事的同时,请记住,在后续Unity的版本中,生成的C++代码可能会和本文有所不同。这是正常的,因为我们在不断的改进和优化IL2CPP。通过将IL代码转换成C++,我们能够获得在可移植和性能上的一个很好的平衡。我们能拥有高效开发的托管代码的同时,还能获得高质量的C++代码。在接下来的文章中,我们将探索更多的C++代码,包括函数调用,函数对原生库的封装和共享等。下篇文章我们将会围绕iOS 64-bit和Xcode展开。
      原文地址:http://blogs.unity3d.com/2015/05 ... -of-generated-code/


    • Bowie 4530 8

      IL2CPP 深入讲解:基础介绍

      IL2CPP 深入讲解:基础介绍AN INTRODUCTION TO IL2CPP INTERNAL
      Unity 官方博客译文(看完这篇博文非常的兴奋,第一时间想到的是翻译后介绍给大家,文章是以IL2CPP内部开发人员的角度来讲述。由于讨论的内容会比较深入,如果对Mono,IL2CPP等一系列概念不甚了解,可以先参考 Unity3D将来时:IL2CPP (上)和(下))


      大约在一年以前,我们写了一篇博客讨论Unity中脚本将来会是个什么样子,在那篇博客中我们提到了崭新的IL2CPP后端,并许诺其会为Unity带来更高效和更适合于各个平台的虚拟机。在2015年的一月份,我们正式发布了第一个使用IL2CPP的平台:iOS 64-bit。而随着Unity 5的发布,又带给大家另一个使用IL2CPP的平台:WebGL。感谢我们社区中用户的大量宝贵的反馈,我们在接下来的时间里根据这些反馈得以更新IL2CPP,发布补丁版本,从而持续的改进IL2CPP的编译器和运行时库。
      我们没有停止改进IL2CPP的打算,但是在目前这个时间点上,我们觉得可以回过头来抽出点时间告诉大家一些IL2CPP的内部工作机制。在接下来的几个月的时间里,我们打算对以下话题(或者还有其他未列出的话题)进行讨论,来做一个IL2CPP深入讲解系列。目前准备讨论的话题有:
      1.基础介绍 - 工具链和命令行参数(本篇博文)2.代码生成之旅3.代码调试之诀窍4.方法调用介绍(一般方法调用和虚方法调用等)5.泛型共享6.P/Invoke封装7.垃圾回收器的集成8.测试框架(Testing frameworks)及其使用
      为了能让这个系列的讨论成为可能,我们会涉及到一些将来肯定会进行改动的IL2CPP的实现细节。但这也没有关系,通过这些讨论,我们希望能给大家提供一些有用和有趣的信息。
      什么是IL2CPP?从技术层面上来说,我们说的IL2CPP包含了两部分: 一个进行 预先编译(译注:ahead-of-time,又叫AOT,以下一律使用AOT缩写)的编译器 一个支持虚拟机的运行时库AOT编译器将由.NET 输出的中间语言(IL)代码生成为C++代码。运行时库则提供诸如垃圾回收,与平台无关的线程,IO以及内部调用(C++原生代码直接访问托管代码结构)这样的服务和抽象层。
      AOT编译器IL2CPP AOT编译器实际的执行文件是il2cpp.exe。在Windows平台你可以在Unity安装路径的Editor\Data\il2cpp目录下找到。对于OSX平台,它位于Unity安装路径的Contents/Frameworks/il2cpp/build目录内。 il2cpp.exe这个工具是一个托管代码可执行文件,其完全由C#写成。在开发IL2CPP的过程中,我们同时使用.NET和Mono编译器对其进行编译。
      il2cpp 接受来自Unity自带的或者由Mono编译器产生的托管程序集,将这些程序集转换成C++代码。这些转换出的C++代码最终由部署目标平台上的C++编译器进行编译。你可以参照下图理解IL2CPP工具链的作用:

      运行时库IL2CPP的另外一个部分就是对虚拟机提供支持的运行时库。我们基本上是用C++代码来实现整个运行时库的(好吧,其实里面还是有一些和平台相关的代码使用了程序集,这个只要你知我知便好,不要告诉别人 )。我们把运行时库称之为libli2cpp,它是作为一个静态库被连接到最终的游戏可执行文件中。这么做的一个主要的好处是可以使得整个IL2CPP技术是简单并且是可移植的。
      你能通过查看随Unity一起发布的libil2cpp头文件来窥探其代码组织方式(Windows平台,头文件在Editor\Data\PlaybackEngines\webglsupport\BuildTools\Libraries\libil2cpp\include目录中。OSX平台,头文件在Contents/Frameworks/il2cpp/libil2cpp目录中)。举个例子,由il2cpp产生的C++代码和libil2cpp之间的接口API,存在于codegen/il2cpp-codegen.h这个文件中。
      运行时的另外一个重要的部分,就是垃圾收集器。在Unity 5中,我们使用libgc垃圾收集器。它是一个典型的贝姆垃圾收集器(Boehm-Demers-Weiser garbage collector)。(译注:相对使用保守垃圾回收策略)。然而我们的libil2cpp被设计成可以方便使用其他垃圾回收器。因此我们现在也在研究集成微软开源的垃圾回收器(Microsoft GC)。对于垃圾回收器这一点,我们会在后续的一篇中专门的讨论,这里就不多说了。
      il2cpp是如何执行的?让我们从一个简单的例子入手。这里使用Unity的版本是5.0.1,在Windows环境并且建立一个全新的空项目。然后创建一个带MonoBehaviour的脚本文件,将其作为组件加入到Main Camera上。代码也是非常的简单,输出Hello World:

      1234567using UnityEngine;
      public class HelloWorld : MonoBehaviour { void Start () { Debug.Log("Hello, IL2CPP!"); }}

      当我切换到WebGL平台进行项目生成的时候,我们可以用Process Explorer来对il2cpp的命令行进行观察,得到以下内容:"C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe" "C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe" --copy-level=None --enable-generic-sharing --enable-unity-event-support --output-format=Compact --extra-types.file="C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt" "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll" "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll" "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput"
      嗯,这个真是老太太的裹脚布 - 又臭又长......,所以让我们把命令分拆一下,Unity运行的是这个可执行文件:"C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe"
      下一个参数是il2cpp.exe工具本身:"C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe"
      请注意剩下的参数其实都是传递给il2cpp.exe的而不是mono.exe。上面的例子里传递了5个参数给il2cpp.exe:
      –copy-level=None[list]
      指明il2cpp.exe不对生成的C++文件进行copy操作[*]–enable-generic-sharing

      告诉IL2CPP如果可以,对通用方法进行共享。这个可以减少代码并降低最后二进制文件的尺寸[*]–enable-unity-event-support

      确保和Unity events相关的,通过反射机制来运作的代码,能够正确生成。[*]–output-format=Compact

      在生成C++代码时为里面的类型和方法使用更短的名字。这会使得C++代码难以阅读,因为原来在IL中的名字被更短的取代了。但好处是可以让C++编译器运行的更快。[*]–extra-types.file=”C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt”

      使用默认的(也是空的)额外类型文件。il2cpp.exe会将在这个文件中出现的基本类型或者数组类型看作是在运行时生成的而不是一开始出现在IL代码中来对待。
      [/list]需要注意的是这些参数可能会在以后的Unity版本中有所变化。我们现在还没有稳定到把il2cpp.exe的命令行参数整理固定下来的阶段。
      最后,我们有由两个文件组成的一个列表和一个目录在这个长长的命令行中:
      “C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll”“C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll”“C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput”
      il2cpp.exe工具可以接收一个由IL程序集组成的列表。在上面这个例子中,程序集包含了项目中的简单脚本程序集:Assembly-CSharp.dll,和GUI程序集:UnityEngine.UI.dll。大家可能会注意到这里面明显少了什么:UnityEngine.dll到哪去了?系统底层的mscorlib.dll也不见了踪影。实际上,il2cpp.exe会在内部自动引用这些程序集。你当然也可以把这些放入列表中,但他们不是必须的。你只需要提及那些根程序集(那些没有被其他任何程序集引用到的程序集),剩下的il2cpp.exe会根据引用关系自动加入。
      裹脚布的最后一块是一个目录,il2cpp.exe会将最终的C++代码生成到这里。如果你还保持着一颗好奇的心,可以看看这个目录中产生的文件。这些文件是我们下一个讨论的主题。在你审视这些代码前,可以考虑将WebGL构建设置中的“Development Player”选项勾上。这么做会移除–output-format=Compact命令行参数从而让C++代码中的类型和方法的名字更加可读。
      尝试在WebGL或者iOS构建设置中进行些改变。这样你会发现传递给il2cpp.exe的参数也会相应的发生变化。例如,将“Enable Exceptions” 设置成“Full” 会将–emit-null-checks,–enable-stacktrace,和 –enable-array-bounds-check这三个参数加入il2cpp.exe命令行。
      IL2CPP没做的事情我想指出IL2CPP有一向挑战我们没有接受,而且我们也高兴我们忽略了它。我们没有尝试重写整个C#标准库。当你使用IL2CPP后端构建Unity项目的时候,所有在mscorlib.dll,System.dll等中的C#标准库和原来使用Mono编译时候的一模一样。
      我们可以依赖健壮的且久经考验的C#标准库,所以当处理有关IL2CPP的bug的时候,我们可以很肯定的说问题出在AOT编译器或者运行时库这两个地方而不是在其他地方。
      我们如何开发,测试,发布IL2CPP自从我们在一月份的4.6.1 p5版本中首次引入IL2CPP以来,我们已经连续发布了6个Unity版本和7个补丁(Unity版本号跨越4.6和5.0)。在这些发布中我们修正了超过100个bug。
      为了确保持续的改进得以实施,我们内部只保留一份最新的开发代码在主干分之(trunk branch)上,在发布各个版本之前,我们会将IL2CPP的改动挂到一个特定的分之下,然后进行测试,确保所有的bug已经正确的修正了。我们的QA和维护工作组为此付出了惊人的努力才得以保证发布版本的快速迭代。(译注:感觉是版本管理的标准的开发流程,另外由文中提到的trunk branch来看,他们貌似还在使用SVN)
      提供高质量Bug的用户社区被证明是一个无价之宝。我们非常感谢用户的反馈来帮助我们改进IL2CPP,并且希望这类反馈越多越好。我们的IL2CPP研发组有很强烈的“测试优先”意识。我们时常使用“Test Driven Design”方法,在没有进行足够全面的测试的情况下,几乎不会进行代码的合并工作。这个策略用在IL2CPP项目上非常的棒。我们现在所面对的大部分bug并不是意想不到的行为产生的,而是由意想不到的特殊情况产生的。(例如在一个32位的索引数组中使用了64位的指针从而导致C++编译器失败,具体讨论在这里)面对这种类型的bug我们可以快速的并且很自信的进行修正。
      有了社区的帮助,我们非常努力的让IL2CPP既快又稳定。顺便说一句,如果你对我刚才说的这些有兴趣,我们正在招人(嗯.....我只是这么一说)
      好戏连台关于IL2CPP我们还有很多可以说的。下一次我们会深入到il2cpp.exe代码生成的细节中。看看对于C++编译器来说,由il2cpp.exe生成的代码会是个什么样子。


    • 红茶君 2386 4

      在纽约做独立游戏是一种怎样的体验

      这不是一个知乎问题。

      这是一篇采访。访谈的对象是一群在纽约做独立游戏的中国人,他们制作的游戏Gemini入围了今年的IGF ,之前看过我们整理的IGF 2015入围游戏文章的朋友应该已经见过了。(关注IndieACE公众号并回复IGF可以收到相关文章)

      游戏尚未发布,我们可以先看看视频。


      以下是访谈正文

      IndieACE:介绍一下Gemini的开发团队成员和这个游戏吧。

      张哲川:Gemini这个游戏其实很难描述,因为它并不属于传统的ACT,RPG, STG之类的游戏类型。我们一般的说法是,这是一段关于两颗星星飞向天空,点亮世界的故事。

      这个项目一开始是陈佶和张哲川在NYU Game Center MFA项目的毕业设计。不久之后在上海音乐学院读研的阎毅加入负责游戏的音乐音效,School of Visual Arts的MFA毕业生陈帅加入我们负责游戏的美术。另外我们在NYU Game Center的学弟张超也在技术和设计上给予了我们很多帮助。

      IndieACE:各位是如何凑到一块开发这个游戏的?

      张哲川:其实我们几个能凑在一起也是挺奇妙的,原因各种各样。陈佶和我是因为我们在NYU Game Center是同学,并且在讨论毕业设计的时候因为兴趣相近,所以决定组队。而我们的作曲阎毅则是我的初中同班同学,算是发小了。我一直很欣赏他的音乐,之前做的几个学生项目也用了他的部分作品,大家反响都很好。我们给他玩了Gemini早期的原型设计后他也很喜欢,就受邀加入了我们团队。陈帅加入的时候我们游戏其实处于瓶颈期,因为之前的美术都是我们自己做的,虽然我们也挺喜欢的,但毕竟不专业,而且美术能力的匮乏在一定程度上限制了我们的想象力。之前我们在别的项目上也和陈帅合作过,很喜欢他的艺术风格,于是就找他帮忙画几张概念图试一下。

      后来发生的事情大家都知道了,看到概念图我们就跪了,思路也打开了,他也就顺理成章的加入了。至于张超,他是陈佶从清华到NYU的嫡系学弟,技术和设计能力都很强,对音乐和美术都有所造诣,关键是对他艺术类游戏很感兴趣,于是他在暑假的时候就加入我们团队“实习”了一段时间,解决了不少技术瓶颈,至今还常常在各方面为我们提供帮助。

      IndieACE:Gemini这个游戏目前开发进度如何?大概什么时候、能在什么平台玩到?

      张哲川:目前这个游戏已经接近完成了,我们已开始和各发行商和平台沟通,但目前并没有确切的平台和发布时间。

      IndieACE:你们毕业之后有什么打算?感觉中国学生如果要留在美国做独立游戏,可能还会有些额外的困难,那么有人继续走在indie这条路上的吗?

      张哲川:我们现在已经毕业了,目前的计划就是先把Gemini做完并发售。我们的同学中毕业之后做Indie的人还是挺多的,至于中国学生的话,额外的困难就是签证问题了。尤其是如果自己成立工作室做Indie,不去找工作的话就很难申请到工作签证(H1B),也就没法留在美国工作。当然你也可以去为Indie Studio工作,这样还是有可能拿到工作签证的。我们目前的解决方案是申请O-1签证,很多艺术家都是用这个签证留美工作的,但它需要你通过各种材料(获奖,媒体曝光,行业认同,商业成功等)来证明你的艺术成就。这个签证我们目前还在筹备,由于申请这个签证的人大多是电影、设计行业的,游戏领域的比较少,所以我们在结果出来前也不确定成功的几率如何,但至少是一个选择。

      陈帅:开始做Gemini的时候就已经毕业了呢,对于我来说未来要走的路一定是自己真正喜欢、擅长并且坚信能成功的。我从小到大一直是美术专业,选择游戏其实是偶然,和朋友们机缘巧合地认识到一拍即合的创业做游戏,开始也只是抱着尝试的想法却意外地发现了作为game artist的快乐。不同于其他艺术,游戏是唯一一项可以将叙事、动画、音乐、视觉、交互以及更多新媒体新技术完美结合起来创作的领域,我是一个享受思考创造和分享乐趣的人,也许选择indie game就是我内心潜在追求的必然结果。对于一个刚开始起跑的人来说,我只会选择不顾一切地加速,困难肯定是有的,无论在哪个国家都会有不同的阻碍,担心却是多余的,不卸下负担怎么跑得快,前提是认定了方向就坚持下去。

      IndieACE:在去年的Babycastles的showcase中就见过Gemini这个作品,感觉纽约做独立游戏的氛围似乎不错,能不能谈一谈你们在NYU学游戏的所见所闻?

      张哲川:我们都很喜欢纽约游戏圈的氛围。也是由于纽约并不大,大家相对集中,所以组织一些游戏相关的活动就会有很多人来参与,气氛很热烈。NYU目前算是纽约独立游戏活动的一个中心了,我们每周四晚上都有Playtest,不止在校的学生,纽约本地的开发者都可以把自己的游戏带来测试。几乎每周都会有游戏相关的讲座,嘉宾来自游戏行业的方方面面,像SE的前社长和田洋一,龙腾世纪的制作团队,Giant Bomb的创始人都来过。每年年末我们还会组织一个以游戏设计为核心的学术会议:Practice: Game Design in Detail,里面的讲座质量都很高,主讲人很多也是业界大牛,像万智牌的制作人Richard Garfield,时空幻境(Braid)的制作人Jonathan Blow等。每年都能学到很多东西。

      陈佶:在NYU学习游戏的感觉就是这里非常重视“游戏”、“设计”和“个性化”。在“游戏”这方面,我们在游戏研究课上会刨根究底地探寻诸如“游戏的定义是什么”,“游戏和叙事的关系”,“游戏与宗教仪式、艺术的人类学历史脉络”,“游戏中的失败和戏剧中的悲剧的联系”等哲学问题,会有大量的阅读和论文写作要求,是真正严肃地把游戏作为一门完整的、独立的学科去研究的,而不是把游戏简单归为“交互艺术”或是“新媒体”的一个分支。这对我们对游戏理解的深度和广度都很有帮助。同时我们研究的覆盖面也很广,除了电子游戏以外,桌游、户外游戏、体育运动、古代棋牌、赌博等都是我们研究的内容。

      在“设计”这方面,游戏不仅仅是程序加上美工加上音乐音效,规则和体验的设计更是核心。NYU有很有深度的“游戏设计”课程,在一个学期内要设计五六款非电子游戏(桌游或户外游戏),因为不需要编程和复杂的美工,主要的时间就是在讨论想法、制定规则、反复测试和修改,每个人都是花大部分时间在设计上,这对我们的设计师思维(创造性解决问题的思维)的形成和对游戏的规则、玩法、体验的把握非常有帮助。至于“个性化”,这里的老师非常鼓励每个学生做自己想做的东西。招生的时候学生的背景就非常多样化,电影、数学、哲学、宗教学、人类学、社会学、音乐等等,几乎没有见到重样的。这些多样性在学生的作品中很快表现出来,会出现许多实验性质的游戏作品,和这些同学一起学习的两年间,真的是眼界大开。

      张超:来到美国会发现这边的独立游戏圈比起尚未成形的中国独立游戏圈确实要成熟很多。这边的圈子有很多厉害的游戏设计师和游戏学者,大家互相之间经常交流,对于游戏设计也形成了一定的准则和方法。除此之外,也能经常见到入木三分的游戏评论。做游戏很难,但是有很多游戏人可以互相交换意见会让人少走很多弯路,也得到更多的见解。时间久了,也能逐渐感受到不同地区的游戏设计圈,理解游戏的视角也有轻微的不同。除了 IndieCade East 游戏节和 PRACTICE 游戏会议以外,纽约还有很多设计师聚会以及小型游戏展。这边大多数见到的游戏都以新颖以至于奇怪的游戏性,以及本地多人游戏的乐趣博人眼球。

      NYU 渐渐成为纽约独立游戏活动的中心。作为一个艺术硕士项目,这里相对要更加学术性一些。我们将桌面游戏、运动、视频游戏等各种类型的游戏串联在一起,提炼出游戏设计元素融汇贯通并加以运用,对游戏的眼光也越来越独到并能够认识到很多商业游戏的优点和问题。对于游戏创作而言,我们从文化、游戏性甚至是游戏理论出发,建立一个长远的或实验性质的设计目标,并通过不停地原型迭代,解决设计问题逐渐逼近最终的目标。

      陈帅:我觉得做游戏的核心是要热爱游戏,纽约作为一个全球多元文化和思想交融的发达城市之一,游戏文化的交流自然是有广泛的受众和发展群体的,也许资深的game developer和game studio没有西部那么多,但热爱游戏、关注游戏的人和组织还是不少的,常见的NYU game center、playcrafting NYC等纽约本地学校或组织都会有定期的game test nite、demo&play nite以及分享技术开发的各类平台的workshop。同时纽约每年各种高规模的展会、艺术节、电影节都会给游戏开发者和玩家带来丰富的展示和交流的机会,比如New York Comic Con每年都会聚集大量的动漫和游戏fans。之前和朋友们参加过不少这样的活动,每次看到玩家们开心的反馈和真诚的交流表达对我们游戏的喜爱的时候,都会觉得是莫大的鼓励。

      IndieACE:就像许多独立游戏人一样,你们也有学生时代摆弄游戏制作、在商业公司工作、到美国学游戏……等等各种不同的经历。那么在这个过程中,心态上、对行业的看法上有什么变化?有什么东西是一直坚持想做的吗?

      陈佶:我从十二岁开始制作《帝国时代2》自定战役,加入了国内的飞翔之鹰战役制作小组(翔鹰帝国)。从最早的幼稚的强力英雄匡扶正义,到广纳北欧、希腊神话架空了庞大世界观的英雄史诗(《海蓝》),到最近实验性的“无失败条件”的自传体传奇(《凯斯拉要塞》),算来到现在也是大半辈子闯荡游戏江湖啦(笑)。从小做帝国战役开始,我一直把游戏制作作为一种探索和表达。探索的是游戏的可能性和自我内在的心声,表达的是自己所追寻、敬仰的意义。我希望通过我的作品,除了难忘的游戏体验,还能够给玩家带来一些思考和领悟。随着自我的成长,我通过作品试图表达的内涵从最早的惩恶扬善,到忠正无畏的骑士精神,到直面现实然后仍然爱这个世界的英雄主义,到对生命不息的赞美,是一直在不断的变化的。但是把游戏制作作为探索和表达,却一直没有改变。

      我想在纽约的近三年时间,我对自己所坚持的道路应该是更加执着了——在NYU的学习开拓了我对游戏的理解,同时在这里产生的对游戏独特的美的领悟解决了我“为什么不去从事其他艺术创作”的自问,而最近初步接触了商业之后,也更看清了自己的兴趣是在游戏创作本身。

      张超:相信很多人深受《仙剑奇侠传》影响从而走上游戏创作之路。我也是其中之一。尽管只有粗糙的像素和精简的对白,仙剑呈现给我的世界却让我产生无穷的联想。就像80年代欧洲的游戏爱好者在 Commodore 64 等游戏机自学编程,我十四岁开始在文曲星上摆弄最简单的 BASIC 编程,尝试仿照一些现成的游戏加上自己的想法做出更有趣的游戏。后来相继接触了 RPG Maker,DirectX 等技术,也同时在自学音乐和美术,希望有一天能做出属于自己的游戏,把自己的感情和人生体悟放进其中。在那时对游戏的理解还只停留在 RPG、射击游戏、动作游戏和战略游戏,而我并不想拘泥于单纯的玩法,想从故事与体验出发创作游戏。我的很多想法是没有办法放到一个游戏的模版里面的,在创作之路上很是困惑。那个年代因为游戏制作工具还没有普及,游戏开发的困难还是蛮大的。

      后来大学的时候发现了独立游戏,启蒙游戏便是 Braid,仿佛打开了新世界的大门:原来游戏可以这样做!于是决定从小的想法出发,以“做梦”为核心做了一款动作解谜游戏《Reverie》,发到 Newgrounds 收到了不错的评价——与很多独立开发者类似的经历。这个阶段的想法是在思考如何用游戏这个媒体将一个好的故事和道理,并有很多自己探索的心得。

      来到 NYU 之后开始接触到海量的游戏,有了更多的设计手段可以运用。参加了很多游戏会议,也开始思考自己创作游戏的最终意义。我希望电子游戏可以帮助玩家成为更好的“人”,让玩家思考,让玩家沟通,让玩家与非玩家彼此交流。

      独立游戏已经逐渐形成了一个产业。海量的独立游戏中,有很多“独立”的,也有越来越多“商业”的。不过还好每年都有 IGF 这样的活动奖励游戏人的创新精神,激励着人们向游戏设计领域的广阔天地中未知的风景去探险。中国的独立游戏起步较晚,缺乏一个良好的环境,尽管有一些有才华的人做出了不错的游戏,但很多开发者都或多或少走了许多弯路。不过像 IndieAce 这样的组织也在慢慢壮大,一个交流的环境正在慢慢形成。另外一方面,中国的游戏文化熏陶相对欧美比较短,而且也相对单一,多样性的缺乏也抑制了游戏的创意。但中国人,或者亚洲文化圈对游戏有着不同的关注点,一定能探索出游戏设计中新的领域。

      陈帅:其实团队里的其他成员接触游戏创作都比我早呢,我最早接触的游戏基本都是局限在pc端,以multiplayer的形式为主,从高中到大学基本上是被暴雪垄断了(哈哈)。那时候基本上没有接触过indie game,玩得更多的是杀戮、对抗或者合作,我不喜欢pve,觉得只有pvp的形式才能取悦我的热情,因为人是活的,程序是编死的。来到纽约后,我开始接触电脑艺术,开始慢慢体会到程序也是可以有情感的,也许所有的表达都是“计算”的结果,但那些真正地被作者投入情感的“程序”,观众是体会的到的。乏味的代码也可以改写成诗,取决于作者如何去组合、塑造和表达。

      我觉得在这一点上游戏美术和游戏设计是相同的,或者更宽泛地说,艺术和游戏是可以共鸣的,核心都是“如何人为的创造一个虚构却真实的灵魂”。对于游戏来说,这个灵魂可以是角色,可以是故事,可以是音乐,甚至可以是game mechanic本身,这是让我开始重新认识并且更加热爱游戏开发的原因之一:游戏的世界是可以摆脱人类现实所有科学理论和常识的束缚,以上帝的身份去创造一个崭新的次元,为现实世界的人打开一扇通向新世界的门。游戏可以不只是为了娱乐他人,也可以像艺术一样是为了自我表达,为了改变腐朽和无限创造。如果说坚持地话,我会坚持作为一名游戏开发者,和更多地人分享我们的游戏世界。


    • 小彩虹大彩虹 1758 4

      话说三消游戏生成是完全随机的?

      拿企鹅帝的开心消消乐来说,每个关卡都需要达成目标(消除不同数量、颜色方块)才会胜利,那么每个关卡都是随机生成的方块么?

    • 红茶君 1969 3

      经济环境是如何塑造游戏形式的?

      这次我们翻译了一篇长文章,文章是Daniel Cook去年在博客上写的,原名是「How game forms are shaped by their environment」。你可能会发现,大多数媒体报道独立游戏和开发团队时,常常带着一种理想主义的眼镜,大概是因为大多数人都乐于见到坚持自我的小团队逆袭的故事。然而这种视角未必真实,或者说,它并不能反映游戏开发的全貌。一个直面市场的游戏团队必定要面临经营企业的问题,在泥沙俱下的游戏市场中冒头的团队,必定发现了真实的市场需要、利用了合适的策略。剥开一切独立、艺术、理想的外壳,你永远能看到这些属于经济属性的纹路。本次分享的这篇文章讨论的就是这个问题,Daniel Cook一向非常诚实和犀利,大家可以感受一下。How game forms are shaped by their environment作者:Daniel Cook人们常从创意及文化的视角谈论艺术创作,但我发现,如果从经济与演进的角度去审视它们,会得到更多的启发。游戏开发者所身处的经济环境究竟是如何塑造游戏的艺术形式的?我试着研究了一些实际例子,发现有一类专注于内容的游戏,在成熟的移动、PC和主机市场,都找到了稳定的利基市场(IndieACE注:利基,niche;利基市场,指那些被市场中占绝对地位的企业忽略的某些细分市场。)。移动平台上,Sword & Sworcery,Device 6和纪念碑谷都是典型的例子;在PC上,则以Kentucky Route Zero, Proteus ,Gone Home这样的游戏为代表;在主机上这种趋势虽不算明显,但Journey和Flower在某些方面也属此类。这些游戏通常有如下特点:1,极其注重能唤起玩家的内容
      这些游戏的叙事弧线传递给玩家许多负载,它们经过精心的设计和撰写。玩家的精力是被游戏中演绎的刺激所消耗,而不是把精力消耗在执行事先计划好的行动。2,轻量化的系统从机制上看,这些游戏中的交互循环较少,留给机制的发挥空间不大。它们采用的系统都是其他类型游戏中使用已久的、十分传统的系统。3,游戏时长短:一般在1~3小时之间。这类游戏的成功不是由于人类艺术鉴赏力突然爆发,也不是由于什么真善美的普适性。这些游戏之所以成功,是因为它们充分考虑当今的社会经济环境,并且非常恰当地执行了相应的开发策略。
      游戏形式是被环境风险所塑造的艺术形式是艺术作品公认的、标准化的结构。挂在客厅墙上的油画是绘画的一种形式,俳句则是写作的一种形式。与许多媒体不同,游戏采取的形式更加灵活。文学创作者可能受限于诗歌、短篇故事、散文或小说既有的形式,但游戏的形式更加广泛,局限性也更小,它们在机制、规模、主题、参与者数量和硬件使用上都更加灵活多变。俄罗斯方块和猜字游戏之间的差别,远远大于莎士比亚戏剧与百科全书条目之间的差别。游戏设计师经常会为自己的游戏选择一种独一无二的形式。风险是如何塑造游戏形式的?然而,不同的游戏形式有着不同的风险权衡,有设计风险、技术风险、制作风险这样的内部风险,也有发行和市场等等外部风险。如果项目的任何一个方面失败了,开发投入就会遭受损失。任何游戏设计必须评估开发成本、成功收益和失败的负面影响等因素。这些并非抽象的决定。大多数开发者(包括大型开发商)都要通过经营收入来避免破产,毕竟衣食住行是非常现实的需求。因此精明的团队会选择最合适的项目形式,以最小化整体风险,增加未来的生存几率。所以游戏开发者有极大的动力适应去当下经济压力、去改进游戏形式,如果环境改变了,增加了某种类型的风险,那么你会看到,开发者们会从更多的潜在形式从选择那些风险更小的选项。市场上总有成百上千的开发者漫无目的地在各种游戏类型间摇摆不定,而另一些明白市场倾向的开发者则从中吸取教训、总结出有用的策略、投奔正确的方向。利用市场上的幸存者来决定主导战略游戏形式演化的进程是不可见的,大量的游戏没能正确地平衡风险,于是在文化意识中失败沦陷。多数开发者都没能意识到自己的影响力和所受限制。为我们所知的只有那些市场上的幸存者。当你看到市场上新类型的游戏取得成功时,你可以问自己一些有趣的问题:使这些游戏得以存活的选择机制是什么?是怎样的策略使他们相较于其他设计更有竞争优势?这些通过市场筛选的产品,能让你搞懂当下的筛子是什么形状。什么因素在起作用是什么力量使得当今的独立开发者用某一固定价格预售游戏呢?数字分发和廉价工具:这种新现象的核心就是小团队有能力以低成本开发和发行游戏。然而,这个市场在变得越来越成熟。大量用户有消费内容的习惯:在过去的十年里,AAA游戏通过过场动画、关卡设计、画外音等等完善了一系列的二级内容传递标准,游戏玩家非常熟悉和理解这套理论。许多年来,我们培养了一批训练有素的、熟悉这套语言的用户。单个产品的平均收益正在下降:事实上,在移动游戏市场上,它们已经接近于0,市场整体的收益图形状像是L字母,小部分产品获得了大部分的收益,中端市场已经不复存在。你的产品要么大卖、要么失败,没有中间道路可走。单份游戏预售价格低于0.99美元:随着Steam进一步开放,打包销售模式的流行,以及主机引进更多的免费游戏,付费游戏的预期售价将不得不被蚕食,你需要用更低的价格去获取更多的用户。产品很难被发现:游戏曝光机制很弱,门槛很高。各渠道充满大量游戏,用户却难以辨别其质量。每款游戏只有1~30秒的曝光时间,这短短的时间决定了它的一切。制作成本不断上升:更廉价的工具让制作成本下降了,但是劳动力成本却不会下降,对制作质量要求的提高也会造成制作成本升高。5年前,一个成功的付费游戏的制作成本可能是5万美元(包括人力投入),但现在,你需要花费20万~100万(甚至更多)去制作一款游戏,收益甚至还不如从前。 这全都是因为内容和功能的竞争愈演愈烈:更多的美术、更多的动画、更多3D的使用、更多“必须加入”的功能。因此游戏难以脱颖而出、难以赚钱、却很容易让你入不敷出。专注内容的游戏的生存策略基于这种情况,什么样的游戏能够生存呢?我们需要针对上述问题寻找解决方案,并找到用相同的资源解决多种问题的方法,有效率的建议才能使人存活。注意,以下方法并非唯一路径。如果你看看其他成功的开发者,你会发现有很多成功的模式,并不存在最好的方案。这个策略除了功能性的益处之外没有内在价值。这些普遍的策略是在不知不觉中汇聚在一起的,像是被一只无形的手牵引。无论我们是否足够明智,能够事先预料形势,最大的收益一定包含在环境中。专注于内容的小团队该采取何种策略呢?*缩减成本瞄准一个较小的规模:内容是很昂贵的,但如果你做一个流程1~3小时的游戏,而不是20~30小时的游戏会如何?这样简单的改变也许能让你的成本变成原来的1/10,这是由游戏形式定义的经济属性。去掉系统和功能:尽可能剔除许多标配元素,专注于一个或两个的亮点。在Dear Esther中,你只需要到处走,在Gone Home中,你只需要到处走然后点击物品。NPC们?砍掉,战斗?砍掉。分支剧情?砍掉。保持一个小规模的团队:鉴于人力是你最大的成本,保持一个小规模的团队意味着更低的投入。团队成员应该是一群多面手,这样你就不需要雇佣兼职的专业人士。保持较短的开发周期:在一个作品上花费9~12个月,而不是18~24个月。在你抱期望的方面做到卓越:如果能在一个或几个方面拥有一些顶级高手,会很有优势,你可以围绕着他们的个人风格去制作游戏。这些可以弥补一人身兼数职、开发周期短等小团队开发带来的缺点。减少分发风险准备极有冲击力的视频和图片:由于你能与潜在用户接触的机会有限,你需要用最少的东西打动他们。卓越的美术、动人的叙事能够在几秒钟内做到——太多的玩家看到纪念碑谷的截图就决定买下它。建立关系以获得更多曝光:对于市场预算不多的小团队来说,免费的推广是一个理想的方式。与媒体人、Steam用户、各平台管理员建立关系,你或许能够得到一些推荐和曝光。当然,你能给与什么回报、你能说出什么样的故事是宣传时永远的问题。“游戏是艺术”是最近人们常用的一种方式,通常这类专注于内容的游戏也是这么说故事的。*减少设计和制作风险更多依赖静态内容:从功能方面说,美术和视频很少失败。与一些创新的艺术家合作是有风险的,但一旦成功,一个有能力的艺术家会不断创造有价值的艺术。尤其是制作时间紧的时候,你还是需要用高质量的美术去吸引眼球,所以这是需要综合考虑的。使用既有的机制:新的机制需要时间去发现,且往往不如人意。发明是困难的。利用既有的已经被验证的传统机制,你的游戏就不太会被这个系统拖延,就像打开一个页面或者点击超链接是很值得信赖的那样。减少意外:计划外的事会拖延你的时间并浪费你的钱。减少技术风险:使用既有的技术,那些已经被很好证明的、简单的技术。避免复杂的技术:那些需要很强专业知识的技术,例如多人服务器或者先进的3D渲染都很容易出问题,所以避免这些。*减少受众风险让游戏更容易通关。你需要让人们玩游戏、通关然后在意犹未尽时和他们的朋友谈论它。这像是一种快速的病毒传播,而不是慢速的,挑战虽然在其他一些情景中是有效的策略(比如Dark Souls, Spelunky),但在对那些需要流畅地展现其精妙内容的游戏来说,难度是一种阻碍。让游戏易于理解:为了弥补游戏较短的缺陷,你需要补充一些能够容纳多种解释的内容。如果任何人都无法准确描述你的游戏内容,意味着它就是低质量的。一定的神秘感可以让游戏在讨论时获得一些加成,玩家需要一些因为信息残缺而造成的疑惑。与玩家社区互动:在理想的情况下,在玩家和社区评论家开始发表他们对作品的解释时,你就要开始第二轮的社区活动。注意把这一切整合为一个紧凑的战略。拥有强力美术或文案伙伴的小团队可以制作一个拥有轻量级叙事、短小而具有吸引力的游戏,这也恰好是一个合适这种团队的项目规模。这样的游戏已经足够吸引人,也容易让玩家口口相传,对玩家而言,购买游戏的风险也不大——他们可以获得超值并具有相当质量的游戏,并且随之得到一种相对于书籍或电影等其他消费品而言,更为丰富的体验。一种极度保守的游戏策略这个策略并不新鲜:廉价的、易消费的内容才是大多数媒体市场的核心(而不是那些质量把控严格的)。在种类繁多的游戏中,精品游戏内容是最保守的开发策略。如果有评论家认为游戏的历史始于2007年,那么他可能会为这些精致作品感到兴奋。但是,对比过去30年里,游戏在系统和叙事上丰富的实验,这些形式实际上是一种倒退。缓解生存风险的妥协被宣传为一种时尚的文化进步,这种游戏策略性地放弃了游戏有别于传统媒体的理念,并全面承袭了与传统媒体类似的方法及其局限。其中最粗糙的一种游戏形式,就是像书籍一样,你翻页,就看到内容。但我们不应该简单地将这种现象定义为“糟糕的”变化,发展并没有什么判断标准。如今这种战略是奏效的,那么,优秀而满怀激情的开发者就能从中盈利,并得以创造另一种形式的游戏。在无情的资本主义社会中,我们能对游戏开发者抱有的期望也仅止于此。未来如何?我们要如何应对这样保守的产品策略?可参考的市场告诉我们,情况可能会在未来的5年内发生变化。*市场饱和迅速:由于当前游戏制作技能和技术的门槛降低了,并且尝鲜者通常没有任何竞争风险,新入场的人们会很快涌向市场,从而降低大家的平均成功率,大多数人都无法盈利。*成本增长:随着更多竞争者的出现,品质变得更加重要。资金雄厚的厂商能够获得并留下更多的付费用户,导致行业形成以最大投入获得最多用户的风气。*更短的游戏长度:成本的增长也给游戏时长带来压力,可能某些时候,玩家甚至会认为20分钟的美妙体验也不值99美分。*组合销售:用选集、组合包或订阅的方式来销售内容,在游戏这个以热门作品驱动的生态圈中,是一种普遍的推广方法。如果这种策略使市场结构发生变化,由中介决定用户口味的倾向就会更明显。*口味差异化:市场分化非常明显。用户会逐渐习惯这种新的形式,他们会开始找到特定的偏好,就像有人喜欢爱情小说,有人喜欢悬疑小说一样。首先进入相关题材领域的人,可以发现一个新的次级利基。*脆弱的专业型公司:开发者必须打磨记忆,生产更优秀的特定形式的内容。但这也会使开发者在适应新形式的时候缺乏灵活性。我们在冒险类游戏的历史中,就看到了类似的情形。似乎在此种游戏数量还不算多的情况下,预测未来市场饱和或崩溃是一件很蠢的事情。但市场并不是一成不变的,这些缺乏竞争者的市场都会快速饱和,任何市场黄金期都将迅速地结束。从某种意义上说,更短更小的游戏形式像是在与魔鬼交易,他们缩减自己的创新机制规模,并通过经过精致打磨的内容传递自己的价值。但在游戏行业中有一件事始终不变:既有平台上的内容成本一直在攀升,成本曲线是吞食我们行业的猛兽。将游戏中的内容削减1/10以降低制作成本是个好办法,但制作内容的成本上升10倍时又该怎么办呢?这种短暂的优势终将重归于零。反思虽然我本人并不在制作内容驱动型的游戏,但我发现用这个视角来理解自己的游戏将怎样影响世界是很有用的。所有的艺术都是由特定的时间、地点的经济环境所塑造的,所有标准化的艺术形式,不过是社会经济生态中利基。他们都不是恒久的,他们随世事迁移。认识到普遍形式并不是绝对真理,能让聪明敏锐的开发者受益。我们要反思:谁在赚钱?是什么让开发者、媒体记者、博物馆、评论员或是其他中间商从他们推广的作品中获益?任何依赖于盈利机构的作品(无论大小)都是一件商品,它的形态都由经济条件所塑造,其实我们没有任何一个人是真正的独立创新的存在,这是一个令人愉悦的幻觉、一句谎话。我们都在一个残忍而务实的、打磨创意棱角的系统中创作。无论你喜欢与否,我们也一直在通过自我审查的方式,在环境的剪刀下努力抢占先机。另一方面,我们的分析要从失败入手:看看谁做了些不一样的事,然后失败了?是何种体制或环境因素导致他们无法生存?在你分析出问题所在后,可能找到一个新的生存策略吗?当你看到一种新的游戏形式成功时,问问为什么。试着去理解它背后的原因,然后用这些理解去创造属于你自己的、独特的游戏形式。接下来,做你该做的事——为着那永不停滞的游戏进化浪潮。

    • Bowie 2087 5

      创意游戏方块:Sifteo

      创意游戏方块:Sifteo
      Sifteo是啥?说到游戏机,大家脑中首先想到的可能是一个方方正正的游戏主机和手柄,连接电视显示画面、或者是把屏幕,机器,手柄做到一起的便携设备。Sifteo cube和这些传统的游戏设备非常的不同:它没有传统的输入手柄,屏幕也不只是单一的一块。
      Sifteo是由多个Sifteo cube, 每块单独的cube拥有自己的屏幕,并可以和其他cube块产生互动的电子娱乐系统。
      听着很拗口?想知道这套电子玩具怎么个玩法?我们先看官方介绍视频:
      Sifteo特点:和传统的游戏机不同,Sifteo和玩家直接互动的不是手柄,而是这些cubes。它兼顾着用户的输入和游戏的输出。除了多个cube,Sifteo还有一个本体:Sifteo base。它是整个系统的计算中心,游戏代码运行在base中,而图像和输入则由cube完成。 Sifteo base内置了一块32bit的ARM计算单元,并且集成了8MB的Flash储存游戏。另外还自带一个小喇叭输出游戏音效。
      我们再来看看每块Cube的具体参数:
      1.7英寸,128*128 彩色TFT单点触摸屏3轴加速感应边界感应2.4G无线通讯
      由此为我们带来触碰cube(触摸屏),倾斜,摇晃,翻转cube(三轴感应),或者把两个或者多个cube连接起来(边界感应)这样传统游戏里没有的真实物理世界的互动功能。
      Sifteo游戏从技术指标可以看出,Sifteo的机能基本上和任天堂的掌机Game Boy Advance差不多,因此在此之上的游戏画面表现也和GBA上相近。但是游戏的玩法却相差巨大:Sifteo带来完全不一样的游戏感受。下面就单独列出几个有特色的游戏说明。

      Chroma Splash:益智三消游戏,与传统三消不同,你需要合理选择,旋转cube到特定位置,按一定顺序触碰才能完成关卡。


      Turtles:Ninja Slide :获得忍者神龟授权的解谜游戏,游戏中需要依靠cubes换位来进行地图的探索以及道具的使用。


      其他有意思的玩法参考最后的一段视频:

      Sifteo商店和硬件配套的,sefteo在Mac和Win上有一个应用程序。程序有两个功能:1.在程序中充值购买上面说到的这些游戏。2.游戏的管理:由于Sifteo base内部flash的限制,不能把所有游戏都装下,Sifteo商店还负责把游戏同步或者删除base本体中的内容。
      Sifteo开发模拟器于传统游戏一样,Sifteo要想取得成功,多样化的游戏必不可少,因此Sifteo平台也是对外开放的。我们可以在官方页面上下载到SDK和相应的模拟器进行游戏的开发。完成之后可以提交上架供大家付费购买。开发采用C++以及GCC工具连。SDK中模拟器做的很到位,有兴趣的朋友可以安装SDK运行模拟器来感受下Sifteo整个系统。

      Sifteo优缺点
      Sifteo独特的玩法非常适合亲子互动或者大家一起Party的时候Happy。作为小孩子的寓教于乐器具或者自己一个人淡淡的打发闲暇时间也很适合。但是出于成本的考虑,Sifteo的机能非常的弱,本体由于wifi带宽限制最多只能和12个cube进行互动,游戏的体量不能太大,形式局限在2D为主。但即使是这样,也能给大家带来游戏上愉快的享受。


    • 红茶君 1826 1

      动作游戏的设计语法

      本文根据去年11月IndieACE沙龙上禹石游戏的蔡建毅先生的分享整理。禹石游戏是《剑无生》的制作团队,他们对动作游戏的理解十分有意思,无论你是游戏开发者,还是单纯的动作游戏爱好者,这篇文章都值得看一看。文章比较长,但非常值得看完。
      独立游戏的重点在于做小做精,规模不应该太大,但是国内的团队、尤其是动作游戏团队,容易把游戏规模越做越大,这是个常见的问题。而我个人觉得,我们讨论动作游戏时,大多处于“只见树木不见森林”的状态,这个演讲就希望从整体上对动作游戏的设计方法做一个介绍。
      动画师们都知道,在制作动画时,有两个必须遵循的条件:Time(时间)和Space(空间),动作游戏的设计也是如此。比如在动作游戏中有取消(Cancel)和硬直(Stun)的概念,前者是新动作取代当前动作的机制,后者是行动不能的时间惩罚,这就是动作游戏中时间上的玩法;而空间上的玩法则涉及移动(Movement)和范围(Range),玩家在游戏时需要进行空间上的预判,这对游戏爽快感有很大影响;而范围则涉及我们常说的判定框,判定框有的和打击有关,有的和防御有关,判定框的大小和出现的时间点是游戏好玩不好玩的关键。
      如果我们继续演绎Time和Space这两个条件,就会发现加入机制是必要的。因为动作游戏不是纯考验感觉和反应能力的游戏,而是重视机制的。剪刀石头布就是我们常见的简单机制,这种互相克制的机制在动作游戏中也常常出现。三方相克的机制是一种静态平衡,确保游戏中不会有哪一方能够由于先天优势一直赢下去;但如果这个静态平衡的规律一直成立,游戏也就无聊了,所以我们需要加入一些balance breaker,使更多的选择出现,比如发生破坏时加入补偿之类,这种动态的平衡会让游戏更加耐玩。我们在经典动作游戏中会看到动作的帧数表,帧数优势定义了角色特色和游戏系统,反过来,通常还会加入反击系统,作为帧数优势的补偿,因为不是所有人都对时间判定那么敏感。
      我们来看一种互相克制机制的改进思路。首先,在动作游戏中有快速攻击克制慢速攻击的特点存在,谁先打谁会获得先机的优势,但如果单纯强调这种克制,游戏就会让玩家陷入走位大战:抢先攻击成了唯一目标,没有游戏深度。针对这一点,设计师进行改进,加入回避和防御的机制,可以克制先出手对后出手的占优地位,让回避或者防御成功的一方可以利用反击达成反制效果——但这样又会让双方陷入龟缩大战中,玩不下去;进一步改进,设计师就加上了回避风险和防御风险的设计,比如在猎天使魔女中,你不能无限闪躲下去,闪躲5次就会有1次僵直,让敌方有机可乘;常见的防御到达一定次数会被破防的设定,也是出于这个考虑。再加上一些克制设置:比如攻击克投掷、投掷克防御,会让游戏内的克制达到比较平衡的状态。
      顺便说一下,动作游戏里的防御机制并不适应于所有游戏,一些追求快节奏的动作游戏,甚至会把这个要素砍掉,因为防御会破坏游戏的节奏感。鬼泣和猎天使魔女都是几乎不要防御的,全是回避,让人觉得流畅爽快。这种游戏玩的是策略或运气,你需要在回避后预测对方的动作做出相应操作。
      以上的设计只是静态的平衡,那么动态平衡是如何产生的呢?举个例子,有个动画叫赌博默示录,这个动画里给剪刀石头布加上了个有趣的变化,把剪刀石头布变成了卡牌游戏:每种卡牌的数量固定,每种类余下卡牌的数量会显示在记分板上,这样就把玩运气的剪刀石头布变成了玩策略的游戏。这就是静态平衡加上有意义的条件,会产生有趣变化的例子。
      动作游戏中一般是什么情况呢?这里有一个表。 表里把防御分为上段和下段,攻击分为上段下段和投掷,再加上跳跃,我们可以看到在这种情况下,下段防御的失败几率是0%。玩家玩到一定次数,就会总结出这个表,发现一个比较高赢率的玩法。为了让游戏多一些变化,我们加上一个条件——中段攻击(威力强、容易连招的攻击),这个表就成了这样。 于是没有哪种防御是占绝对优势的,上段防御成了玩家必须考虑的选择,并且出现了一些高风险高回报的玩法。这样是为了造成一个动态效果,让玩家有更多策略选择,这时,干扰对方预判的假动作玩法也会出现,游戏会更加好玩。
      所有的动作游戏都包含类似设计,游戏设计师在填写这个表的时候很花心思,会认真考虑什么元素才是自己游戏表现的重点,所以每个游戏玩起来感觉都不太一样。
      然后要说的是动作游戏另一个重要的设计——帧数优势。在攻防过程中,防御成功可以让攻击方陷入硬直,防御方获得帧数优势,可以进行反击。玩街霸的时候一个常见的战法:轻攻击用于试探,一旦对方出现硬直就用大招——这就是一个例子,这是街霸核心的东西。这样的设计会出现一种状况:通常情况下防御方是有利的,但出大招或者破防的话,防御方就崩溃了。
      在动作游戏中,硬直时间通常通过停止或者动画来表现,2D游戏可以通过停止来表现,3D就必须通过动画了。3D游戏另一个常见的做法是玩连招,由于防御会让连招节奏改变,所以这种游戏会把防御要素的影响缩小,比如在连招中间对方没法防御。
      另一个是反击系统。一般情况下,对帧数非常敏锐的高手很少,为了解决帧数优势系统学习曲线过高的问题,动作游戏加入了反击系统。这时玩家不需要在意时间、不需要背帧数表,只需要看对方的动作表现,然后按对按键就可以。以猎天使魔女为例子,闪躲成功后,敌人进入慢动作模式,想怎么打就怎么打,很有爽快感。
      出招方式也是一个重要概念,在以前,根据输入内容决定出招(俗称搓招)是一种常见的出招方式,现在这种方式已经略显麻烦,再加上3D游戏中这种方式应用困难,所以现在变成了根据条件判定出招(当在空中时发什么招、当在地上时发什么招等),这种处理可以缓冲掉对出招表的记忆,也可以使出招更加直观,减轻玩家在输入上的负担,让轻度玩家也可以接受,但仍旧可以保留玩法深度,不会变成无脑打法。
      接下来讲一下攻击中的动作,在日本是用下图中的这个东西来说明的。 攻击动作从Neutral状态开始,Neutral是待机状态,接下来是准备攻击的状态,然后就是蓄力、蓄势动作,之后则是Impact,这是攻击动作中最大、最帅的部分;接着是用完力量、力量消失的过程,Stop是力竭阶段的停止时间。
      在蓄势状态时的动作,是在告诉玩家敌人会用什么招打你,比较友好的游戏蓄力时间会比较长,另外,一些假动作和变化也出现在这个时间;攻击判定的开始和结束位置,则可以暗示玩家攻击判定框有多大,这一点做不到位,玩家会觉得莫名其妙。而在Stop状态会有个强调重量感的停顿。这三段时间的长短会影响动作表达的感觉。
      攻击还涉及攻击效果。攻击的对敌效果包括造成伤害和硬直,以及受击效果;攻击的范围涉及判定框的设置,攻击方向可以是水平、垂直、斜向或者冲刺,范围形状包括点、线、面、圆柱体等等都有;攻击距离也分为远、中、近等。
      顺便说一下追尾的设计。我们知道在怪物猎人里面,玩家攻击的时候,游戏是不会自动做调整的,所以对玩家在攻击时对准的要求高,但战神这种游戏就会帮忙调整,在玩家开始动作之后,主角会追着敌人打,以此带来爽快效果。追尾的距离、角度和速度的参数对游戏体验影响很大,是3D动作游戏里很重要的一块。
      受击反应。这部分和动画师关联很大,因为是通过动画来表现的。需要通过符号化的方式,来让玩家知道敌人受击力度的大小(而不是通过物理拟真的方式),否则玩家会迷惑、无法辨析造成伤害大小。
      冲击的方向和打击感有关系,攻击动作如果和受击动作吻合度高,即使不用特效,也会有很棒的打击感。这里需要和动画师说清楚,敌人会受到来自哪些方向的、怎样的伤害,要让玩家觉得打到敌人时,敌人觉得痛,这样效果才会好。
      然后才是拟真化的部分,比如我们可以让击飞击倒时的感觉贴合真实的自然感觉,但这里是纯粹演出的部分,不涉及反馈表现。
      在受击种类的部分尝试在表现上做一些变化,比如击退、击倒、击飞等,就能让玩家在攻击成功时能采取对应的方式达成连击。一些特殊的状态,比如击倒重置、受击免疫、坚硬无敌等等,也会让游戏充满变化性。
      这部分设计得好,表现不用特别华丽,游戏感觉也会很好。
      理解了以上方法的原理,国内团队在做动作设计的时候,就没有必要生搬硬套国外动作游戏大作的具体设计了,而可以做一些符合实际情况的原创设计。比如设计一个彪形大汉的敌人可以这样:蓄力长,但active时间短,以此表达强力的感觉;追尾不强,但攻击判定大,攻击造成强制的击飞击倒效果等。甚至我们可以用这些原理把中国武术剑术融合进来。
      再说一下一对多时的敌人配置。在动作游戏中,杂鱼的作用是让玩家宰、让玩家爽,而小BOSS是给玩家一个小挑战,BOSS则是玩家必须尝试抓住规律、全力干掉的敌人。这些和动作、数值、关卡设计相互结合,会产生一些功能分担上的改变,比如游戏中后期,原来的小BOSS变成杂鱼兵之类的。动作游戏大多没有等级概念,玩家的成长就在这些地方体现。
      用组合的方法来配置敌人,这种方式是国内的团队比较少使用的。如果你记得鬼泣1代的话,可能会记得鬼泣1的敌人种类并不多,但前期的怪物在后期出现,还是会让你觉得有挑战性,这就是因为挑战组合配置得好。动作游戏不是要折磨玩家,这些设计的目的是给玩家挑战。常见的组合比如远攻、近攻组合,近处怪物攻击,远处法师放法术;效果组合,地方一些怪物把主角石化之后,弱小的杂鱼也能消灭你,组合可以造成意外性,给玩家新鲜感,同时让玩家去思考如何去克制敌人。用这种方法,我们不需要制作很多的资源,也可以造成很丰富的游戏变化。
      团体AI则可以让敌人变得有组织性,比如在敌人群攻时,玩家打一个敌人的时候,其他敌人会等着,这样的感觉会让玩家觉得挑战是接二连三出现的,不会太混乱;而多个敌人同时攻击的情况,则可以鼓励玩家使用群体攻击,让玩家觉得爽。
      敌人补充的方式,常见的也有两种,一种是敌人死一个就补一个,还有一种是阶段性的补,到一定时间就会补充,强迫玩家在一定时间内干掉所有敌人。在补充的过程中加入多种类切换,补充不同种类的敌人,也会让玩家觉得感觉不一样。用群体AI来指挥怪物站位,则可以防止敌人凑着站一堆显得傻,让玩家觉得敌人有组织性。
      利用多种变化和组合,就可以使用少量的怪来产生丰富的变化。
      最后,则是关卡、镜头、BOSS和叙事演出的部分,这些部分处理好也很加分。比如灵游坊的作品,他们能说出一个完整的好故事,就是游戏的亮点。
      现在这个时代,纯动作的3D动作游戏已经不是潮流所向了,因为在纯动作方向上的技术探索可能已经达到一个瓶颈。我们就希望研究在这种状况下,如何让动作游戏能够老树发新芽,做出些不一样的东西,同时让国内玩家能够更好地享受动作游戏这个品类的作品,这些是我们今后要做的事。

    • 红茶君 1736

      怎样成为PlayStation和Xbox的开发者?

      2015年3月20日,索尼的PlayStation4和PlayStation Vita中国大陆行货终于上市。虽然都经历了一些波折,但Xbox One和PS4两大主机总算都正式进入了国内市场。
      对于国内主机玩家来说,这或许只是一件纪念意义大过实际意义的事,毕竟这十几年来,即使官方销售渠道长期缺席,市场也总能自发地提供越来越丰富的解决方案,让我们玩到所有的主机游戏。但对于国内的游戏开发者来说,这件事情的确是意义重大:因为随着主机行货的进入,大家终于能够以中国开发者的身份拿到开发机、在主机平台上开发游戏。
      为什么要为主机开发游戏?就目前的情况来看,这可能是一个吃力不讨好的选择:虽然主机平台对于国内开发商来说是一个崭新的平台,但事实上,它早已沉淀了许多高品质的成熟内容,所以你不太可能像几年前移动游戏刚刚流行时那样,凭借一款斗地主之类的小游戏,就能借着快速增长的平台优势分得红利;你也不太可能满足玩惯了3A游戏的核心玩家,因为并不具备制作3A大作的经济实力和制作能力。
      对国内小型团队来说,做一些有创意有质量的独立游戏是相对可行的选择。但想要做到单凭主机软件销量就能赚钱的程度,也并非易事。毕竟你的许多竞争对手,依然是从国外3A大厂或优秀院校中走出来、带着丰富的制作经验、又不缺创意的同行。
      如果你准备好迎接这种Hard模式的挑战,那么我们可以分享一些经验。
      首先,国内独立游戏团队如何申请PlayStation和Xbox的开发者资格?
      比较有效率的方法是直接联系相关的负责人,负责PlayStation的是SCE上海,而负责Xbox的则是百家合(百事通和微软的合资公司)。除了通过同行介绍之外,你还可以在索尼或者百家合举办的线下开发者活动上联系到他们,这些活动也会介绍相应主机的开发准入政策、开发环境等等信息,对主机开发有兴趣的开发者请留意类似活动。
      Xbox有一个专门针对独立开发者的ID@Xbox项目,可以在Xbox官方网站的申请页面提交申请,也可以邮件联系百家合(IDXbox@ehedco.com)进行申请。PlayStation这边暂时还没有一个专门的页面,但预计后续会公布相关的联系方式。
      一般来说,开发团队的作品如果有过一些成绩,比如参加IGF拿过奖、在众筹平台众筹成功、作品在其他平台上有出色表现等等……会让你更容易通过申请、拿到开发机。如果是正在开发中的作品,那么一个有说服力的demo也能够帮助你。总之,在申请的环节你需要做的就是尽量证明你所做的是一个适合主机平台的靠谱作品。
      申请通过之后,完成相应的商务流程,开发商会收到开发机和测试机。提供给开发者的这些设备算是租借给开发者的,需要通过认证才能使用,而且它们的认证有时效限制,要定期重新激活认证,而当开发商退出时,要把设备归还给索尼或微软。
      主机是一个相对封闭的平台,并且对于大部分国内开发者来说,也不是一个熟悉的平台,所以你基本上不可能像做移动平台开发那样,能在网络上找到大量的相关资料。但是,主机厂商会给开发商提供很多的文档给开发者自行研究,也会有专门的技术支持人员,在开发者遇到困难的时候提供一些帮助。
      如果你的游戏是用一些支持PS4和Xbox的引擎开发的,比如Unity、Unreal等等,那么把游戏移到主机平台就比较方便。你只需要向索尼或者微软申请相应引擎的license,有了这个专用的license,就可以将游戏编译到相应的主机平台上。但假如你的游戏是自制引擎开发的,那么你就需要研究文档、自己手动解决这个问题。
      然后你还需要针对主机平台对你的游戏进行调整和设计,比如合理地设计手柄操作、调整UI和重要元素的排布以保证它们不会超框、按照相应主机平台的标准配置成就或奖杯等等。这意味着即使手上有一个现成的作品,你通常也要花不少的时间去修改才能让它登上主机平台,所以一定要为这些工作预留充足的时间。
      测试也是一个重要的环节。索尼和微软都有专门的QA团队,为要登上自家主机的游戏做测试,在测试流程中通不过的话,游戏是无法发售的。PlayStation和Xbox都有专门的测试文档,你可以把它们理解为一堆Checklist,开发者在提交游戏前,需要自己对着这些测试文档逐条测试,以保证游戏质量合格。在这个过程中你可能需要修正许多繁琐的问题:从游戏进行时玩家插拔手柄的弹框提示,到操作说明中正确使用每个设备的标准中文名称……游戏对应的功能越多,测试时需要花费的精力和人力就越多,所以在一个游戏流程几十小时的3A大作背后,一定有专业的测试团队支持,而规模较小的独立游戏测试起来虽然相对简单,也仍然需要开发者耐心、细致地去应对。
      测试流程通过之后,就需要按照相应提交文档的规定,准备好所有材料。在通过审核、拿到版署的版号之后,游戏就可以发售了。如果希望让自己的游戏登上港服、日服等等其他地区的商店,开发者也可以向索尼和微软提出申请。
      近年来,PlayStation和Xbox平台对独立游戏的接纳度都变得越来越高,而对于国内开发者来说,两大主机的进入,也让主机开发者资格不再可望而不可即。然而在面对前景无限的移动平台、以及更多丰富的选择时,我们也许会再次回到一开始的问题:你为什么还要为主机开发游戏呢?你可能得不到太多金钱上的收益,也收获不了太多来自玩家或业界的赞美,除了「玩主机长大」的情怀得到小小的满足之外,你似乎没有太多具有说服力的理由。
      然而我们相信,如今选择为主机平台付出时间精力的国内开发者,在各不相同的商业考虑之外,还带着一份不计功利的初心。也许我们恰好被放在一个探索和开路的年代,所有不尽如人意的环境,都可以成为我们努力的理由。期待有一天,我们能在主机平台上看到来自国内开发者的佳作。
      欢迎关注IndieACE微信公众号:IndieAce,可以看到IndieACE定期分享的好内容。
      需要转载IndieACE的文章请与我们私信联系。


    • 红茶君 1391

      「你是否还记得那场战争?」

      这是一篇GDC的听课交流笔记,作者是University of Utah的学生董晶晖。 “你记得离你最近一次的战争是哪一次?”Pawel Miechowski 抬起头,似乎在问我也似乎在问他自己。这位来自波兰 11 Bit Studios的游戏制作人,此时正坐在GDC 2015 会场外的台阶上,抽着烟,谈论着他参与制作的游戏“This War of Mine”。几个小时后,他即将站在 IGF 2015 的颁奖台上,领取 IGF Audience Award。不过此刻,他却没有谈论这款游戏是如何的成功。我甚至无法从他身上感觉到丝毫的喜悦。这款游戏对他来说,有着别样的意义。“人们总是很快忘记战争的本质。对他们来说,战争最后只剩下英雄主义。这不是真正的战争”。正如 11 Bits Studios 的 Director Jakub 对我提到的,他们的父辈经历了太多次战争。其刻骨铭心的经历让他们始终无法接受被美化的战争历史观。他们想通过制作一款有别于枪战射击的战争游戏,让人们认识到被英雄主义和肾上腺素所掩盖的战争的本质。他们希望玩家通过情感共鸣,体会到战争的残酷与疯狂。“This War of Mine”的确做到了这一点。当玩家终于熬过了四十多个日夜,迎来战争的结束时,其心情恐怕只剩下沉重。在我看来,这款游戏中并没有胜利,它只关乎开始和结束。 而我有幸在一天前,聆听了Pawel的讲座。在二十多分钟的讲座中,他阐述了“This War of Mine”是如何利用独特的叙事方式来引起玩家的情感共鸣(Raising emotions from unique narrative)。他一共分享了五点心得。1. 忘记游戏类型,专注游戏本身Pawel 讲到,在你开始设计游戏之前,你需要忘记游戏所属的类型,更多地专注游戏想法本身。你不能因为想做一个战争游戏,便将其设定为Call of Duty 模式。你必须明白你想通过这个游戏表达什么,你期望玩家从你的游戏中获取怎样的体验。只有做到这点,你才可以着手设计你的游戏。2.观察测试者,提取信息。在游戏早期原型测试中,一个小女孩测试者的奇怪举动引起了开发者的注意。游戏开始不久,她选择偷光了一户人家的所有物资。这些物资包括绷带、食物等重要稀缺物品。然而不久后,她再次回到那户人家的住处,将偷来的物资归还了一半。这种看似矛盾的行为,原因其实很简单。她之所以会盗窃,是因为她想要生存下去。于是她选择盗走物资。但是当她偷窃后,她意识到这是不正确的行为。所以当她发现自己只需要一半物资就可以存活时,她便选择归还剩下的物资。从这个例子中,我们可以发现,小女孩是通过自我评断来决定自己接下来的行为,而不是通过游戏中的直接提示。这正是开发者想实现的“Player must judge themselves”(玩家必须评断自我)。接下来的测试中,开发者发现一个问题。整个游戏过程中,玩家更倾向把游戏角色当做收集物资的工具,而不是一个有血有肉的人。玩家和游戏角色之间并没有建立情感上的联系。为了解决这个问题,开发者为每个游戏角色设计了独有的性格。比如 Roman 脾气暴躁,尽管单兵作战能力很强,但是很容易和队友发生冲突,以至于队友经常被他打成轻伤。而 Katia 则很有同情心,如果队友做了违背道德的事,她很容易陷入悲伤。通过这种方式,每个游戏人物都拥有了自己独特的性格。玩家可以从这些人物身上找到自己或者他人的影子,这加深了玩家与游戏角色之间的联系。玩家不再仅把他们当做工具,而是将他们当做队友来看待。在这种情况下,每当有游戏角色遭遇不幸时,玩家内心也会悲伤。而情感共鸣正是 “This War of Mine” 不可或缺的部分。另外,游戏早期版本中,游戏角色的背包都有额外的空间用于携带武器。然而这种设计导致了玩家更倾向扮演一名士兵而不是一位平民。以至于每晚外出搜集物品之前,玩家会花很多时间思考如何搭配武器和分配弹药,而不是思考如何收集物资。因此,开发者删除了背包中的额外空间。有限的背包空间促使玩家从“士兵”变回“平民”。而“平民”角色的回归,意味着更多的合作。玩家将会重新思考如何带领这群不同性格、不同能力的平民,在这场战争中生存下去。3.决策的不确定性在 “This War of Mine” 中,玩家需要每个晚上外出搜集物资。而游戏提供了很多地区以供选择,比如废弃的公寓,市区的医院,郊外的小屋等等。玩家必须在众多地区中做出选择。这便涉及到游戏中的决策。Pawel提到,他们为游戏中的决策添加了很多不确定性。尽管很多游戏中,决策都和利益紧密相关。但是这样做的结果,便是玩家总是选择获益最大的选项,这并不是 Pawel 他们所想看到的。Pawel希望玩家体验到的,是战争的残酷,这种残酷具体体现在玩家可能面临的道德困境。一般来说,某地区的回报度和危险度成正比,但每个地区的不确定性让玩家无法计算出利益最大化的地点,任何地点都可能成为噩梦的开始。作为一个平民,玩家无法和游戏中的军队和匪徒正面抗衡。因此,违背道德的行为便成为了降低危险度并获得回报的最快方法。 然而这也让玩家陷入了道德上的困境,玩家必须在道德和生存之间做出选择,而选择结果的反馈,又会促使玩家评断自己的行为。游戏设计者就是想通过这种方式,还原一个平民在战争中的真实感受。4.我们都是程式化的玩家都是被程式化的,他们非常熟悉某种特定游戏的常见设计,明白如何在游戏中找到最佳的解决方案。如果游戏中的设计是非程式化的,玩家有可能完全不知道该做什么。所以,Pawel 提到,你需要利用玩家被程式化这一点,让玩家在游戏中找到程式化的流程,从而让玩家明白他们应该做什么。5.利用符号“This War of Mine" 中的各种事件都是以真实照片的形式呈现出来。比如,若有队友自杀,玩家会看见一张照片,照片中只有一双脚悬在空中。设计者之所以选择这种符号化的表达方式,是为了激发玩家的想象力。游戏不需要向玩家提供任何事件的具体信息,所有的事件内容都在玩家脑海中得到了重建。为此Pawel举了一个例子:玩家会在游戏开始时,遇见两位上门乞讨药品的小孩。如果玩家选择了施舍药品,那么三十多天后,他们会再次上门并表示感谢,然而玩家并不知道这期间两个小孩经历了什么。每个玩家都会根据自己的经历,对这两个小孩的经历进行不同的构建。整个讲座历时二十五分钟,尽管音频出现了问题,但这毫不影响观众的热情,现场座无虚席。游戏主题的沉重并不影响玩家的敬意,IGF Audience Award 就是最好的证明。我承认“This War of Mine”夹带了很多“私货”,可它本不应该被私有。然而战争中的幸存者永远是少数,而人又是健忘的生物。当我向 Pawel 谈起我在游戏中是如何挣扎时,他准确地说道:“You found something you didn’t like, but you engaged in it.”痛苦的回忆总是被回避,然而人的情感不应该只包含欢乐与幸福。尤其是对于一个战争的幸存者来说。正如二战幸存者埃利·维瑟尔写下了大屠杀回忆录《夜》,而Pawel和11 Bit Studios,则完成了“This War of Mine”。
      欢迎关注IndieACE微信公众号:IndieAce,可以看到IndieACE定期分享的好内容。需要转载IndieACE的文章请与我们私信联系。

    • Bowie 4219 1

      Unity3D将来时:WebGL

      Unity3D将来时:WebGL

      随着Unity5.0的发布,WebGL平台的部署也正式登场(目前还处于Beta状态)。WebGL是一项利用JavaScript API呈现3D电脑图形的技术。区别于其他需要浏览器加载插件的形式(比如Flash和Unity的Web Player),通过使用WebGL技术,我们只需要编写简单的网页代码即可以实现3D图像在浏览器中的展示。使用WebGL的好处是显而易见的:在玩游戏之前无需下载任何插件,打开浏览器,输入游戏地址,就可以直接进行游戏了。而且WebGL的这套JavaScript API透过浏览器直接和系统的显卡打交道,效率也可以得到保证。

      WebGL在Unity中的实现具体到技术细节,WebGL在Unity中是通过IL2CPP,Emscripten和asm.js这几大关键技术来实现的。

      IL2CPP:将脚本代码翻译成C++代码的模块。具体细节在上两篇有详细的讨论(上、下)这里直接略过。


      Emscripten:
      将编译后的Byte Code翻译成Javascript,通过这个步骤以后,代码就可以在浏览器中直接运行了。虽然Emscripten大多数情况下是翻译c/c++的代码(在Unity中的使用情况就是如此),但是它也可以接纳任何由符合LLVM标准的编译器生成的其他语言的Byte Code,将其转换成JavaScript。

      asm.js:相比前面两个模块,asm.js是最有趣的部分。也是Unity用来保证WebGL游戏运行效率的关键。他的主要作用就是对Javascript进行优化!提高JavaScript在浏览器中的运行效率。后面我们就具体的讲讲asm.js是如何做的。


      ASM.JS这次我们先直接看代码比较:先来个简单的C代码:

      相应的asm.js代码:

      可以看到我们在每句后面都”比特或”上了0,这个操作对原来的变量里的值没有任何影响,看上去是无用的操作。但是它却保证了我们代码里的i和(i+1)都是整数而不是其他类型。
      另外一段:计算字符串长度

      相应的asm.js:

      在代码中,MEM8是一个Byte类型的“View”,用来操作实际的”typed buffer”。(在这个例子中是ptr指向的内容。有关View和typed buffer的概念请参考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays)
      类似的处理出现在asm.js的各个地方:asm.js中包含了JavaScript的一个严格子集 —— 包括严格类型的整数、浮点数、数值计算、函数调用和堆访问,使得其在被执行的时候跳过了导致JavaScript变缓慢的动态转换和其他一些操作,大大加快了速度。
      我们可以在代码中加入“use asm”开关开尝试开启asm.js模式。

      asm.js有一套自己的规范(具体可以参考这里),你完全可以自己手写asm.js代码,但更多的情况是利用上面提到的Emscripten自动的生成代码。
      如果浏览器支持asm.js,那么程序的代码会得到加速,但是如果浏览器不支持asm.js,也无需担心。asm.js本质上是JavaScript的一个子集,它用到的所有语法和JavaScript完全一致。在不支持asm.js的浏览器上执行的效率和一般的JavaScript脚本是一样的。目前支持asm.js的浏览器只有FireFox一家。IE和Chrome也在积极跟进。按照微软的说法,在Windows 10中所使用的Chakra引擎将支持asm.js,并且微软正与Mozilla进行合作,以争取尽快实现它。Chrome则将通过TurboFan这一在V8上经过优化的编译器提供对asm.js的支持。如果你的Chrome版本是41,这意味着其已经内嵌的TruboFan Beta版,可以加速asm.js了。

      Unity例子测试首先你得有Unity5.0,使用官方或者自己的项目,切换到WebGL平台。我这里用的是官方的Space-shooter,将编译好的整个包放入到Web Server的目录中,然后在浏览器访问。

      在浏览器中打开项目的Html页面,找到并打开WebGL_Build.js,发现其中除了少量可以阅读的函数以外,文件的绝大部分内容都是类似用汇编形式写出的asm.js代码。




      我们游戏的绝大部分逻辑代码就出现在此

      总结Unity5.0中的WebGL平台部署是一个令人激动的选项,纯html的方式运行游戏意味着我们可以把更加复杂和有趣的游戏直接部署在网页上。让其在诸如微信这样的平台上直接传播。
      这个魔术的背后离不开IL2CPP,Emscripten和asm.js。asm.js有着化腐朽为神奇的力量,通过一套工作流转换,使我们获得高效的代码。

      高效的代码只是其中的一个好处,另外一个好处是代码混淆:由于asm.js的天性使然,这些看上去像极了汇编的代码很好的解决了html5游戏客户端源码直接暴露的风险。这一点对于商业游戏来说也非常重要。可以说asm.js天生就是为了WebGL游戏准备的!而从各大浏览器厂商对其支持力度也能看出以后的流行非它莫属。其实Emscripten+asm.js不光光是Unity可以使用,其他引擎也一样可以使用。例如Unreal3也使用同样的方法来将游戏带到浏览器上。而cocos2d-x也有尝试使用该技术。WebGL的前景一片光明。



    • Bowie 3036 1

      Apple Watch -- 作为游戏开发者的你准备好了么? (下)

      Apple Watch -- 作为游戏开发者的你准备好了么? (下)


      限制种种
      Apple Watch作为iphone的第二屏,有那么点WiiU gamepad中手柄屏幕相对于电视机那样的感觉。 WiiU手中的屏幕可以显示游戏中玩家的装备界面,让玩家在战斗时方便切换。 可以显示小地图,在探索时不至于迷路。 或者在多人游戏中可以作为其中一个玩家独有的屏幕, 从而创造独特的玩法......
      看了WiiU对屏幕的使用是不是觉得很激动呢,原来双屏可以有这么多有趣的玩法啊。 嗯, 我只想说...你高兴的太早了! 前文讲到WatchKit App本身并没有运算能力,也就是个没有想法的女神而已。 这还不算完, 在Apple Watch的小小屏幕上,以目前的WatchKit而言,,也不能让你随心所欲的进行控件的排布。 具体来说,所有的控件只能一个接着一个的垂直排列, 加上对Group的运用,可以将多个控件水平排列。 而且这些排布目前只能在storyboard中完成,不能在代码运行的时候动态的添加或者改变其大小。WatchKit 的对于界面做出的种种限制使得一般的App应用都要好好的考虑设计一番,对于没有定式的游戏来说就更加难以满足需求了。



      那么游戏又能怎样利用Apple Watch呢?
      游戏中的通知
      随身的手表相对iPhone来说,更适合通知消息的弹出, 游戏可以将原本在iPhone端弹出的通知消息放到Apple Watch上。 让用户快速得到游戏的最新动态。 如果愿意,也可以点击通知启动iPhone上的游戏。 此功能使用简单的Glance或者Actionable Notifications就可以胜任了。
      游戏中的游戏
      在WatchKit这样有种种限制的设备上开发一个复杂的游戏显然是不行的,但是做为游戏的衍生则完全可行。 有些游戏为了打发长时间无聊的loading等待,会事先加载一个无关痛痒的小互动。 Zelda为了让你拿到心之碎片,也会在游戏中加入有一定难度的小游戏。
      我们可以根据自己的需要,在Apple Watch上放上游戏中的小游戏。 举个例子, 我们的iOS游戏是个很有特色的rpg,你带着你的宠物在魔幻世界闯荡,获得各种奇珍异宝。 在手表上,完全可以做一个宠物养成的扩展。 你可以在手表上和随你战斗宠物发生亲密互动:抚摸宠物,给宠物喂食,给宠物洗澡。这样宠物的体力可以更快的恢复,参加到下一场战斗中。 又或者我们可以在手表上制作一个777开宝箱的游戏,玩家把钱投进老虎机,转出宝贝。



      WKInterfaceObject 筛选就目前的AppleKit Framework而言,可以看出苹果一贯的套路:一开始别想得到那么多功能。给我老老实实的从简单的做起。 在Apple Watch上跑3D程序是不可能了。我们能用的,只有Framework里面提供的这些控件而已。
      看看上面这些WKInterface类和里面提供的函数吧, 是不是有想哭的感觉?没错! 这些类无法进行式样自定义,无法动态改变大小,无法动态添加或者删除,在游戏中几乎都无法使用。 试问谁会在游戏中放入系统提供的呆板且格格不入的控件呢?拜托,我们又不是在做MUD游戏...
      能用控件做的大体也只能是类似于拼字游戏这样的吧....




      这些控件中,唯一可以大作文章的,就是image,对于image的内容,苹果没有限制,也做不了限制。 而且WKInterfaceImage和WKInterfaceButton还支持Image动画。谢天谢地,这样我们还能利用这些特性做出些像样的东西出来。
      还记得我们在前篇文章中说到的三种加载图片的方式嘛:我们可以从WatchKit App本地加载, 从Extension中加载,或者绕个大圈子,从iOS App那里加载。 下图是上篇中的例子,分别对应这三种方式。

      对于游戏中固定不变的图片,完全可以放到WatchKit App或者Extension中,这样需要使用的时候立刻加载,非常方便。 但是游戏中的内容并不是一成不变的,很多时候,需要能反应出当时玩家在游戏中的状态。
      接着上面的例子, 你在游戏中的宠物可以有很多,形态各异,如果游戏做的复杂些,你甚至可以给你的宠物换武器,换衣服等装备,穿出你宠物独一无二的样子来。 如何让这些也能如实的反应到WatchKit App中呢? 又或者,作为一款在iPhone上的3D游戏,你想让玩家可以在手表上360度全方位的检视刚刚获得的宝贝。 这个时候,静态图片就不能满足需求了,你要做的是:让主程序(在这里是游戏程序)根据玩家的数据动态的生成图片,然后在放到WatchKit App上显示。
      技术探讨, WatchKit和Unity的结合鉴于Unity的流行,这个例子也是基于Unity之上,但是其思路却可以适用于任何其他游戏工具引擎。
      具体的工作流程: 当WatchKit App有需要的时候,通过其代理老爹,也就是Extension向iOS App发起请求,iOS App根据当时玩家的数据,生成相应的数据(在例子中是一系列png图片,形成帧序列),然后传给Extension, Extension再通过蓝牙同步到WatchKit App中进行显示。


      在Unity中,我们创建一个RenderTexture并附在一个单独的Camera上以便将场景中的内容保存到图片中。
      图片捕捉代码:[code]
      void _CaptureFrame()
      {
      recordInfo.enabled = true;
      RenderTexture.active = camera.targetTexture;
      Texture2D texture2d = new Texture2D(camera.targetTexture.width, camera.targetTexture.height, TextureFormat.RGB24, false);
      texture2d.ReadPixels(new Rect(0,0,camera.targetTexture.width, camera.targetTexture.height), 0, 0);
      texture2d.Apply();

      filename.Length = 0;
      filename.AppendFormat(Application.persistentDataPath+"/watchanimations/animation-{0}.png", saveindex);
      byte[] data = texture2d.EncodeToPNG();

      System.IO.File.WriteAllBytes(filename.ToString(), data);
      recordInfo.text = (maxfiles - (saveindex%maxfiles)).ToString();
      saveindex++;

      }

      [/code]

      在主循环中,按照一秒30帧的速度来捕捉,一共捕捉60帧[code]
      void Update () {
      //save render texture to png
      escapedTime += Time.deltaTime;
      if(escapedTime >= 0.0334f)
      {
      escapedTime = 0.0f;
      if(NeedRecord() && saveindex {
      _CaptureFrame();
      }
      else if(saveindex>=maxfiles*(frames+1))
      {
      waitingTime += Time.deltaTime;
      recordInfo.enabled = false;
      if(waitingTime>=1.0f)
      {
      System.IO.StreamWriter sw = System.IO.File.CreateText(recordIndicator);
      sw.WriteLine(frames.ToString());
      sw.Flush();
      sw.Close();
      newAnimation = false;
      frames++;
      saveindex = maxfiles*frames;
      waitingTime = 0.0f;
      }
      }

      }

      }

      [/code]

      这样在程序的Documents目录下就准备有我们的图片了。

      当WatchKit App有需求的时候,Extension就会向iOS App,我们的游戏发起请求:[code]
      -(void) _RequestData {
      NSDictionary *request = @{@"request":@"PIC"};
      [InterfaceController openParentApplication:request reply:^(NSDictionary *replyInfo, NSError *error) {

      if (error)
      {
      NSLog(@"%@", error);
      }
      else
      {
      NSData* data = [replyInfo objectForKey:@"PIC"];
      if (data != nil)
      {

      NSArray* picarray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
      NSMutableArray* imagearray = [NSMutableArray arrayWithCapacity:[picarray count]];
      for (int i=0; i UIImage* image = [UIImage imageWithData:[picarray objectAtIndex:i]];
      [imagearray addObject:image];
      }

      _Animations = [UIImage animatedImageWithImages:imagearray duration:8.0f];
      //remove all cached images
      //[[WKInterfaceDevice currentDevice] removeAllCachedImages];

      [self StartAnimation];

      }

      }

      }];


      }

      [/code]
      游戏收到Extension的请求后会检查Documents目录下是否有新数据,如果有,就将所有的png放到一个数组中返回给Extension
      [code]
      #define PICCOUNT 60
      - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {

      NSFileManager *fileManager = [NSFileManager defaultManager];
      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      NSString* indicatorpath = [NSString stringWithFormat:@"%@/watchanimations/recordFinished", [paths objectAtIndex:0]];
      NSError* error = nil;
      if ([[userInfo objectForKey:@"request"] isEqualToString:@"PIC"] && [fileManager fileExistsAtPath:indicatorpath])
      {

      //read index number
      NSString* content = [NSString stringWithContentsOfFile:indicatorpath
      encoding:NSUTF8StringEncoding
      error:NULL];
      int picindex = [content intValue];

      NSLog(@"containing app received message from watch");

      NSMutableArray* marray = [NSMutableArray arrayWithCapacity:PICCOUNT];
      for (int i=picindex*PICCOUNT; i NSString* pngfile = [NSString stringWithFormat:@"%@/watchanimations/animation-%d.png", [paths objectAtIndex:0], i];
      UIImage* image = [UIImage imageNamed:pngfile];
      NSData* imagedata = UIImagePNGRepresentation(image);
      [marray addObject:imagedata];
      [fileManager removeItemAtPath:pngfile error:&error];
      }

      //UIImage* animations = [UIImage animatedImageWithImages:marray duration:4.0f];
      //NSArray* finalarray = [NSArray arrayWithObjects:animations, nil];
      //NSData* imageData = [NSKeyedArchiver archivedDataWithRootObject:finalarray];
      NSData* imageData = [NSKeyedArchiver archivedDataWithRootObject:marray];

      //NSData* imageData = UIImagePNGRepresentation(animations);
      NSDictionary *response = [NSDictionary dictionaryWithObject:imageData forKey:@"PIC"];//@{@"response" : @"Watchkit"};

      reply(response);


      [fileManager removeItemAtPath:indicatorpath error:&error];

      }
      else
      {
      reply(nil);
      }
      }

      [/code]
      在Extension中,收到游戏App发过来的UIImage数组后,依次取出并放入一个UIImage中形成序列帧动画。 然后在通过WKInterfaceImage中的函数设置播放帧动画。
      [code]
      - (void) StartAnimation
      {

      if (_Animations == nil) {
      return;
      }

      [self StopAnimation];
      [_WatchImage setImage:_Animations];
      NSRange range = NSMakeRange(0, 59);
      [_WatchImage startAnimatingWithImagesInRange:range duration:4.0f repeatCount:0];
      }
      [/code]

      作为演示,例子中的机器人一共有4个不同的动画,每次切换到新动画的时候,都会自动记录60帧的png图片。 当按下Watchkit App中的Sync Data按钮的时候,会通过Extension将最新的动画同步到手表上并播放出来,(演示Gif较大,请耐心等待)

      通过这种方式,几乎可以把任何需要显示的内容放到Apple Watch上。
      注意:为了尽量的缩小文中Gif的尺寸,我将从按下Sync Data到播放新动画这之间的等待时间去掉了。 按照我初略估计这之间有大概30秒左右的间隔。
      Unity中设置的RenderTexture有256*256大小,生成png一张大概在35k左右, 60张png也就大概是2.1M。 如果按照每秒30帧这么粗暴的设定,那也就是2秒的播放时间,但是却要用到将近30秒的时间才能在Apple Watch上显示。把贴图减小到128*128,我们还是暴力计算,时间也相应的缩短到30/4=7.5秒,离2秒也差的太远。(当然目前我们拿不到实机,这个数据只是在模拟器上得出的结论)。 也就是说如果想要实时的从iOS App生成数据并传输到Apple Watch上进行显示的同学可以洗洗睡了。我们所能做的就是事先生成好数据,传输给WatchKit App,并反复使用。 在这里。WatchKit的Framework还给了我们一个很好的API:
      设置Image的Cache,以便以后使用,而且还支持序列帧动画!但是需要注意的是这里只有20M的空间,如果空间满了,你必须手动进行释放,否则函数会失败返回。

      总结让我们看看Apple Watch作为游戏设备来说,到底表现如何
      先说限制:1:控件排布不能随心所欲2:控件无法动态创建或者改变3:Apple Watch本身没有运算能力4:Watch和iOS设备之间用蓝牙传输有速度瓶颈5:只能获得点击输入信息,无法获得具体点击位置6:无法发声
      可利用功能:1:播放动态图片,实现帧动画2:按钮的背景图片也可以播放动画3:简单的按钮输入,列表选择输入4:可以有20M的Cache供程序使用
      适合展现的游戏内容:1:游戏中的各种提醒2:简单的文字游戏,如"民国教育委员会"四选一问答3:拼字游戏4:电子宠物类游戏,简单的宠物互动5:777老虎机或开宝箱游戏,只需要适当时机点点点,戳戳戳.

      Apple Watch将来时其实光就苹果公布的Apple Watch技术参数来看,我们就会发现还有很多的功能在现有的Framework中并没有提供。 Digital Crown的输入我们无法使用。
      革命性的Force Touch数据我们不能获取
      更有甚着,Apple Watch上的心跳数据和Siri我们也无缘享用。
      但相信随着时间的推移,这些功能都将开放给开发者,让我们能做更多有趣的事情。说不定等第二代,第三代Apple Watch产品推出的时候,其性能已经强大到可以在上面直接执行代码,成为独立设备。到那个时候,说不定还可以直接移植一个精简版的Mono上去,用Unity直接开发Apple Watch原生程序呢。
      虽然说有这样那样的限制,但是只要精心设计,还是可以以简单有趣的形式提供游戏在手腕上的扩展。拉近游戏和玩家之间的距离。 苹果公司已经开放了第一版的WatchKit SDK, 对于Apple Watch这个女神,主动接纳或者是保持观望,作为游戏开发者的你,准备好了吗?
      本文中的例子程序可以在https://github.com/CoconutIslandStudio/UniWatch.git下载
      注意:由于Github的限制,项目中的一个大于100M的文件(libiPhone-lib.a)无法上传。
      这个文件可以在Unity生成的iOS项目目录中找到或者由后面的连接下载 http://pan.baidu.com/s/1qWuPUo8
      然后放在项目中的UnityWatch/UnityWatch/Libraries/目录中即可


      参考连接:http://www.patentlyapple.com/patently-apple/2014/10/apple-patents-reveal-work-on-displays-with-two-dimensional-touch-sensors-and-a-universal-dock.html



    • Bowie 2561 8

      黑科技 之 臂环MYO

      黑科技 之 臂环MYO

      介绍MYO:是由THALMICLABS研发的全新体感输入设备。将此设备佩戴在手臂上,它就能感知佩带者手的各种手势,并以此来控制各种设备。
      研发MYO的THALMICLABS是一家位于加拿大的公司。公司前不久完成了1450万美金的融资。而其产品MYO在开始预定的头几个月,预订量就达到了惊人的370万份!
      通过官方视频,让我们看看MYO都能做些什么

      原理MYO运作的核心是EMG和IMU。
      人类的肌肉运动是靠神经的电信号触发的,而肌肉的运动也可以产生微弱的电流。通过电极感应设备可以读到这些微弱的电位信息。利用各种手段获得肌肉中的电位信息,并形成图片,这就是所谓的EMG(electromyography),中文叫肌电图。 一般来说,光靠一条肌肉的信息是不足以进行手势的判断的,这也是为什么MYO做成环形的原因:读取多条肌肉的信息,然后汇总综合判断佩带者的手势。
      而IMU其实就我们俗称的6轴感应或者9轴感应(9轴相比6轴多了三个方向的磁场感应)。这个和我们现在智能手机用到的技术大体是一样的。有了IMU后就可以检测出佩戴者手臂的移动,加速度,弯曲等操作。

      实际使用感受前面的官方视频看着很牛X,不过宣传视频是一回事,MYO实际使用起来情况如何呢?这里说说我拿到MYO后的使用感受。MYO包装很简约,拿到手一个很小的盒子,里面除了MYO本体以外,还有一个蓝牙接收器和usb线

      MYO本体被分成了8个等分单元,每块中都有感应电极,在其中的一块上有一个mini usb口,在有usb口的这块单元上还附带MYO的标记和工作指示灯。 大冬天的,把袖口撩起来然后带上MYO,瞬间感觉手臂凉凉的。按照官方视频介绍,MYO应该戴在手肘稍下一点的位置。由于自带伸缩带,MYO可以紧贴皮肤,手臂较小的女孩子可以用附带的卡扣进一步调整MYO的大小。而MYO在能正常工作前,必须预热,也就是用人肉加热器让MYO暖和起来。这个过程大概2-3分钟。 之后打开程序,按照教程进行设备配对
      连接上设备后最重要的一件事自然就是校准了,这里MYO会有很详细的视频教你该如何做,进行校准的这5个手势,也是目前MYO默认支持的手势。加上前面说过的IMU的支持,MYO还可以感应手臂平移和手臂转动。

      5个手势分别是:双指捏合(为了避免误操作,需要类似双击的快速两次才有效),摊掌,手掌左挥,手掌右挥,以及最后一个握拳。
      这个过程完成之后MYO就可以使用了。目前阶段MYO商店的内容还不是很多,有待开发者丰富。 商店里的应用分成两种类型:Connector和Application。Connector类似于程序的插件,需要依附于主程序才能工作,这样可以让原来不支持MYO的程序方便的接受MYO手势指令。而Application顾名思义就是一个完整的支持MYO的程序。在开发社区里,MYO还提供了iOS和Android的SDK,可以说是对现今流行的移动设备在开发上支持的最好的硬件设备之一。
      很想知道MYO操作手机是什么样子,所以第一时间下了一个支持MYO的2048版本,感受了一把。对于简单的上下左右四个操作来说,MYO还是工作的很好的。
      现阶段问题1.佩戴必须直接接触皮肤,不能有衣服,夏天还好,冬天室外怎么办?只有穿好后外面再包衣服了。2.在一个上午的使用过程中,MYO时常中断连接,需要重新同步才能读取手臂数据。3.五个手势的识别率不高,不能精准识别。而且识别很不稳定,有时候能够比较好的识别,有时候无论怎么操作,就是没有反应。看看我最后这蛋疼的操作视频就知道了。4.支持的手势不多,目前默认的就5个,其他手势有待开发。
      游戏控制探讨相比LeapMotion,MYO的识别精度更差,远远不能达到LeapMotion那样的迅速和精准。但是它无需LeapMotion那样一直把双手举起在感应区间内。时间长了也不会感觉太累。对于游戏而言,不能作为主要操作手段。作为简单辅助命令式的操作,还是可行的。


      我们正处于人机交互发生变革的激动时刻,各种输入设备不断小型化并且售价降低,让我们得以进行各种尝试。MYO作为不同于摄像头成像识别的手势输入设备,也是很值得研究的一个方向。后续有时间我会尝试给大家带来更多MYO的新玩法和探讨在实际项目中的使用。












    • 红茶君 1514

      IGF和Game Developers Choice Awards获奖名单

      GDC和IGF的颁奖礼刚刚结束,与往年一样,这依然是一个向奇妙的创意和探索的勇气致敬的盛会。相信现场所有的笑声和掌声,都发自游戏开发者们对这个行业的热爱。让我们来看看今年的获奖名单。第17届独立游戏节(17th Annual Independent Games Festival)获奖名单最佳美术奖:Metamorphabet (Patrick Smith of Vectorpark) 下载地址最佳创新奖:Tetrageddon Games (Nathalie Lawhead) 下载地址最佳音效奖:Ephemerid: A Musical Adventure (SuperChop Games) 下载地址:App Store,Steam最佳叙事奖:80 Days (inkle) 下载地址最佳学生组游戏:Close Your (Goodbye World Games - University of Southern California) 游戏视频玩家选择奖:This War of Mine (11 bit studios) 下载地址最佳设计奖:Outer Wilds (Team Outer Wilds) Alpha试玩版下载地址Seumas McNally 大奖:Outer Wilds (Team Outer Wilds) Alpha试玩版下载地址---------------------------------------分割线----------------------------------
      第15届游戏开发者之选(15th annual Game Developers Choice Awards)年度游戏奖:Middle-earth: Shadow of Mordor (Monolith Productions/Warner Bros. Interactive Entertainment)最佳出道奖:Stoic Studio (The Banner Saga)最佳创新奖:Monument Valley (ustwo)最佳技术奖:Destiny (Bungie/Activision)最佳音效奖:Alien: Isolation (Creative Assembly/Sega)最佳美术奖:Monument Valley (ustwo)最佳叙事奖:Kentucky Route Zero: Act III (Cardboard Computer)最佳设计奖:Hearthstone: Heroes of Warcraft (Blizzard)最佳掌上游戏奖:Monument Valley (ustwo)玩家选择奖:Elite: Dangerous (Frontier Developments)先锋人物奖:David Braben代表人物奖:Brenda Romero终身成就奖:Hironobu Sakaguchi(坂口博信)附赠一张坂口博信在领取终身成就奖时的美照,祝福各位开发者。