• 全部 专栏 Game Jam专区
    • totoyan 1106 1

      【活动】傅老师的Construct2引擎游戏制作工作坊(广州站)[广州]

      您想学做游戏吗?小时候就想做游戏,至今还没完成?有意学做2D游戏,却不知道如何开始?已有美术基础,但看不懂密密麻麻的代码方程? 就让我们用 3小时 教会你做手机游戏吧! 在网页技术发达的今天,HTML5游戏已成为手机游戏的流行风向标。不但简单易学,一次开发便可横跨多平台。艾空未来这次请到台湾资深游戏导师傅老师一同为大家分享,3小时内就要让你的游戏在手机与计算机上运行。让我们一起掌握最新技术,完成梦想中的游戏吧!
      * 本次课程包含上机实作,请来宾务必自备计算机(Windows系统)。

      活动时间:
      2015年8月27日 18:00~22:00 活动地点:广州市天河区员村西街广纺联创意园纺联东一路自编45号之182房
      活动内容:1、Indie Game奥义心法分享行业、环境、生活的痛点都是我们创意的入口,不断寻找并体验着身边的一切,为创意插上飞翔的翅膀创造梦想的价值。我们的游戏,H5游戏的切入,IndieGame经验分享主讲人:iconplus创始人&创意总监:刘惠斌 2、H5极速开发工具Construct 2体验分享带领来宾以Construct 2游戏引擎进行开发,让您轻松大步跨入H5游戏开发的世界。本次课程以经典平台游戏为主轴,了解原理后现场就将范例改造为无限跑酷游戏。主讲人:恒进学习中心 傅子恒老师 3、来宾发问与Debug时间来宾可将使用Construct 2开发上碰到的问题进行现场提问,我们将进行具体且详细的答疑(由于时间有限,每位来宾的问答时间约在3~5min) 4、签名时间与会人员如果带上傅老师的《Construct游戏程序设计》,也可来让老师签下大名留念哦!嘿嘿
      2015年8月27日(星期四)活动时间流程
      17:30~18:05    参会签到
      18:05~18:10    主持人开场、致辞
      18:10~19:30    iconplus创意总监刘惠斌经验分享
      19:30~21:00    恒进学习中心傅子恒老师运用C2一次完成游戏分享
      21:00~21:30    来宾DEBUG或提问,现场答疑

      参与活动的人员: 1. 如果你是努力进修的网页前/后端攻城狮2. 如果你是想成为Indie Game的热血青年3. 如果你是HTML5开发者4. 如果你是学校教师、讲师5. 如果你混迹于各大游戏论坛6. 如果你是C2论坛吧贴的粉丝7. 如果你也是傅老师的铁杆粉丝 参与活动需求:参加活动的小伙伴能带上自己的 笔记本或电脑 尤佳,可以一边听分享一边跟着傅老师的节奏嗨起来,一个属于你的游戏就会如奇迹般的诞生了! 由于本次活动是 iconplus 赞助,小伙伴们自发组织的,时间与活动安排都比较紧迫,很多不足的地方还需大家体谅,对于人数的安排,我们暂定在广州 icon.cn,如果与会人数超出将在安排场点再另发出通知,如有不便敬请见谅!另外来自台湾的傅老师工作比较繁忙,很感激老师百忙之中抽空来给我们大家做介绍与分享!^-^ 请快点来加入我们的大家庭吧,参与本次的活动,一起寻找游戏的真谛与快乐!活动联系人:
      totoyan 手机号:15920188041 QQ:2851683686电子邮件:yzt@icon.cn活动QQ群 :180911504



    • 红茶君 1313

      资深GameJam玩家告诉你,如何把GameJam游戏送上主机平台

      导语:本文根据开发者高鸣在上个月的IndieACE游戏开发者沙龙上的分享整理。他的游戏作品「蜡烛人」诞生于一次Gamejam,如今在补充和完善之后将要登上Xbox One主机。高鸣作为一个资深的GameJam玩家,对如何玩好一次GameJam这件事颇有心得。而这样的GameJam经验对于游戏开发者日常的开发,都有借鉴的价值。
      以下是他的分享。
      大家好。我今天的分享主题是「怎么把Gamejam游戏送上主机平台?」。我要讲的分为三个部分:一是为什么要参加GameJam,第二是一个GameJam游戏是如何登上主机平台的,最后分享一些玩GameJam的经验。
      首先,为何参加Gamejam?Gamejam是一个极限游戏开发的行为,通常是在48小时内单人或组队做完一个游戏;名字里有个jam,所以聚会也是它的重要属性,GameJam是一场游戏开发者的聚会。
      基于这两个核心属性,Gamejam能给我们带来什么呢?第一,因为它是游戏极限开发行为,所以可以锻炼游戏开发技术。游戏制作是一门艺术,也是一门手艺,手艺要做好就要多做。现实中,成功的团队可能做过好几款不成功的游戏,很多大公司也会组织员工开发很多游戏原型,这都是在积累游戏制作的经验。
      Gamejam给了游戏开发者一个机会,可以全方面地锻炼你做游戏的技艺。因为时间很短,要做的事又很多,所以无论你想锻炼哪方面的开发技能,都能得到锻炼机会;GameJam的另一个好处,是拓展你的边界。做游戏开发,深度很重要,广度也很重要。如果你是游戏设计师,你应该多了解各个方面的知识,不仅仅是游戏设计相关的知识,就像程序员需要不断学习新的语言和技术一样。GameJam对游戏开发者来说,就是一个拓展边界的好机会,在活动中,策划做美术、程序做策划的情况经常会出现;你也很可能因为一个特别的主题,去尝试之前没有试过的游戏风格和类型。这种活动促使你拓宽自己的边界,找到新的可能。
      我自己就在一次Gamejam上做了一个自己永远不会尝试的游戏类型,类似瓦里奥制造那样的小游戏集合,游戏画风是基于现实的照片。作为设计者,这是非常有意思的经验。
      GameJam的第三个收获是,能够获得可复用的经验,这种经验不仅可以在将来的Gamejam中使用,更可以用在将来的游戏开发中。因为Gamejam相当于浓缩版的独立游戏开发行为。
      为什么这么说呢?独立开发有几个特点:1,资源有限;2,重视创意;3,大道至简,比大作更多地做减法。反观gamejam,在任何一个方面,都非常符合这三点,所以算是独立开发的威力加强版:GameJam中时间和人员都有限;为了在众多作品中脱颖而出,你的游戏要重视创意;而在时间和资源有限的情况下,不做减法是做不完的。当你不断地参加Gamejam,你实际上是一次又一次地参加日常的独立游戏开发活动。
      「蜡烛人」的诞生就得益于参加GameJam活动的经验。「蜡烛人」那次活动的主题是「10秒」:「蜡烛人」的设计思路就是只有10秒钟的光,可以点亮自己照亮周围,点完了蜡烛就烧完了,你可以继续往前走,但是之后就是在黑暗中前进;当时除了蜡烛人之外,其实还有另一个游戏创意,按照那个创意开发的另一个游戏都已经开发得差不多了,网站上也很多人点赞,但我还是是果断地选择了蜡烛人,因为无论是在游戏的创新度上,还是在美术资源的需求量上,蜡烛人都是更有优势、更容易掌握的。
      「蜡烛人」的开发过程中还运用了很多既往的经验,比如做减法。我在进行开发前画了个故事板,一共画了6个画面,按照这个数量是做不完的,所以我砍掉了和叙事相关的开头和结尾,只保留了关卡选择和关卡游戏这两个部分。也正因如此,我能够有更多的时间开发更多的关卡来表现游戏玩法。
      另一个就是,我们最终的蜡烛人是两只腿,但是一开始是三条腿,因为在现实中实在找不到两只腿的蜡烛。最后因为三条腿不好做,所以做成了两条。
      「蜡烛人」的所有制作,包括三维贴图、关卡等等全是在48小时内完成的,如果没有之前的经验的话,这是不可能做到的。
      GameJam能够给我们什么收获呢?首先,无论如何,48小时后你会做完一款游戏。开发者们都知道「做完一款游戏」这件事有多么难得。
      因为GameJam是带有交流的属性的开发者聚会,志同道合的游戏开发者可以齐聚一堂,大聊要做什么游戏然后把它实现,这也是非常可贵的。游戏开发是比较孤独苦闷的事,所以就如同人类发明节日一样,同类聚在一起,可以排解孤独。对于开发者来说,大家聚一聚意义很大。
      参加一次成功的Gamejam还有一个额外的收获,就是能给你的游戏带来反馈。比如每次参加Ludum Dare,都能在网上收到好多条反馈。Gamejam的现场试玩也能得到很多开发者的反馈。如今,你把一个游戏上传到App store上,都无法保证能够及时地得到玩家反馈,但参加Gamejam可以立即得到其他开发者得回应。凭这一点,GameJam就是值得所有游戏开发者向往的活动。
      「蜡烛人」之所以有机会登上Xbox,也得益于Gamejam活动的评分和反馈机制。参加Ludum Dare之后,你能够得到你的游戏在所有游戏中的排名;因为Ludum Dare的参加者众多,所以能进入前100都是十分可贵的事了;而蜡烛人的排名是:总评27;创意26;画面30;可玩性40;氛围97;一共六项成绩进入前100;这个成绩之前我从来没有得过,看到之后我就有一种感觉:这个游戏和之前不一样,是不是可以做点什么?
      之后我决定给这个游戏一个机会,继续开发开发,然后动用了我所在工作室的人力,完善了这款游戏,把画面、操作、关卡、摄像机等等细节都补充完善了。这个游戏的主要特色就是:低光的游戏氛围、非常有限的亮光、主角很弱,你要努力过关。游戏氛围很不安,因为光很弱,所以有一个投机取巧的地方在于,美术资源虽然不多,但并不感觉简陋,玩起来也比较有意思。完善之后我把它提交到了国外一个在线游戏平台叫kongregate,在这个版本发布之后,获得了这个网站的首页推荐,在首页呆了两周,得到了很多曝光率和很多玩家的好评。「蜡烛人」再一次在kongregate这个平台上证明了自己的实力。
      后来也没有刻意继续开发这个游戏,因为没有想好一个合适的故事,所以没有给它继续分配更多的资源和人力。之后Xbox进入中国,我们团队在申请ID@Xbox的时候投了两款游戏,一个是花了很长时间做的一个手机跑酷过关的游戏,另一个就是「蜡烛人」,后来「蜡烛人」胜出了。现在,「蜡烛人」的Xbox One版本在稳步开发中,目前已经解决故事的问题,并且给它想了很多围绕着光与影的新玩法。今年年底或许能看到这款游戏。
      为什么「蜡烛人」能从一个Gamejam游戏变成一个主机游戏?首先,Gamejam催生了这个游戏:「10秒钟」这个主题给了它一个创意,并且让这个原型在48小时内完成;之后,Gamejam非常有效的反馈机制让我在结束后发现这个游戏的闪光点和可能性。
      在此之后并不是一个励志故事,我们没有特别对这个游戏不离不弃,毕竟我是Gamejam的常客,在类似活动中也完成过十几个游戏。可以说「蜡烛人」不是坚持的结果,而是自然选择的结果。把所有做完的Gamejam游戏扔在那,「蜡烛人」通过自然选择证明了自己的价值,使我不得不重视它,不得不把它做好。后面的发展都是顺水推舟,因为一个好的游戏原型创意想法自己会发光,会给自己机会。蜡烛人就是通过Gamejam产生的大量游戏原型,然后自然选择的结果。
      最后分享一些Gamejam的经验。首先在赛前,推荐给大家一个比较奇特的绝招:通过微博或者微信等等社交媒体告诉你的朋友你要参加Gamejam,你要在48小时之后拿出一个游戏。在参赛过程中你可能会经常觉得你的进度特别落后,第二天你会觉得你做不完,你想放弃,但是你已经把牛吹出去了,所以你必须做完。这个赛前的准备会在最后阶段逼你把游戏做完。这个招数屡试不爽,而且通过这种方式,也可以顺便推广Gamejam这样的活动;第二,在设计阶段,开始写代码画图之前,遵循keep it simple的原则,你可以天马行空地想很多想法,但是在总结的时候要列两个清单:一个清单是这款游戏必不可少的内容、那些去掉之后游戏就不成立的内容;另一个是锦上添花的内容。最后制作的时候还发现砍得不够多,那么这里有一个电梯游说原则:假如你在电梯里遇见一个投资人,能不能用一句话对他说清楚这个游戏是什么。留下这个最本质的东西,就是你的游戏。
      建议在开发前再上一层保险,就是绘制游戏流程的故事板。把你游戏可能出现的画面画出来,然后直观地通过画面的数量判断游戏的复杂程度。如果有10个画面,一定是做不完的,最好控制在5个以下,2、3个是最好的。
      在原型开发阶段,先做个最小可行化产品(MVP),核心玩法+核心画面=最低可操作可发布版本,这就是一个最小的可以玩的游戏,这个游戏之后再做更多内容都是可以的。即使后面的内容来不及,你也有一个可玩的游戏了。
      谢谢大家。
      高鸣所在的游戏团队叫做“交典创艺”,除了「蜡烛人」这样有趣的主机平台的游戏之外,他们还有两款品质和卖相俱佳的游戏在寻找代理发行资源。点击这里可以查看详细情况。感谢大家。

    • 红茶君 1464

      「快斩狂刀」开发者单隽:一个游戏人的十年

      导语:前段时间看到有媒体人写文章回忆10年前的ChinaJoy,十年间人来人往,喧闹依然。对于我们当中的一些人来说,确实亲身经历过国内游戏业的十年甚至更长的时间,见证过不同的人群有幸成名或是黯然离开,其中感受或许难以简单说清。
      在上个月的IndieACE开发者沙龙上,「风卷残云」和「快斩狂刀」的开发者单隽就稍稍分享了他在近十年中经历过的一些事。他分享的主题是「独立游戏的商业化之路」,而这个故事令人欣慰的地方在于,正是由于商业的发展,更多的人在商业环境中获得了「做自己想做的游戏」的自由。
      以下是根据单隽的分享整理的文字稿。
      2011年有个叫「风卷残云」的游戏在各平台发布,反响还不错,直到现在每个月还能提供上千块的收入,虽然这个收入显然不能支持一个20人的团队,但这件事给我们提供了制作游戏的动力。
      很多独立开发者可能都会面临一个问题:毫无疑问做独立游戏很爽,但我要不要不工作全心投入开发,我要不要拿投资让自己全身心投入?
      我分享一些自身的经历。我大学的时候就在开发独立游戏,1999年的时候,并没有独立游戏这个概念,只有游戏开发爱好者。我高中就开始开发游戏,当时是参照市面上的一些流行游戏来做的,目的是和同班同学交流。而大学的时候有更强的自我意识,希望开发出一款代表自己风格的作品。那时开发了大概4、5款游戏,拿到校级比赛大奖,其中一款就是「风卷残云」前身,当时的设想是游戏中有武器、潜入、近身搏斗等等元素,后来强化了搏斗这部分,最后就成了风卷残云。当时花了一个半月做了原型,几个同学在一起玩非常快乐,我一直觉得我想追求的就是这种感觉。
      大学最撼动我的经历是,当时做了一个以机器人为题材的游戏,游戏灵感来自于,我发现有时自己不玩游戏、光看朋友打游戏也很爽,所以想开发一款玩的人很开心、看的人也很开心的游戏。然后就花十个月的时间开发了一款机器人游戏,每人养成一个五人战队,战前配置好机器人、预先设置好机器人的行动,战斗中不能操作。
      这个游戏在校级比赛里拿了冠军,后来学校社团拿这个游戏在学校里办了个比赛,选出16个参赛选手参加比赛,活动现场全场爆满。比赛过程中,很多玩家没有按我的设计思路去正常地玩,所以在实际战斗中出现了很多非常滑稽欢乐的场面,大家看得都很开心。两个小时的比赛没有一个人中途离开,作为一个社团活动来说是一件很难得的事。
      这件事让我感触很深。我发现自己独立开发一个游戏,能影响到他人,这种感觉非常打动我。当时觉得比起考试读书,做游戏给我带来的满足感要大得多。这种感受一直影响我到如今。
      大约在2001年、2002年的时候,我要毕业了,那时刚好是中国游戏商业化开始迈向成熟的时期,有「传奇」这样的作品,也有盛大这样的网络游戏公司。当时希望从商业游戏的角度看看自己的作品,试试能不能做一款商业上成功的游戏,于是加入了上海盛大网络。
      我还记得盛大校招宣讲的时候,一个盛大的领导说他们马上要代理破碎银河系,他说,什么是破碎银河系呢?就是星际争霸里每一个小兵都是一个玩家来扮演。这件事让我觉得当时做商业游戏的人,也具备审美眼光,所以凭借之前做游戏的优势,开始了这份工作。
      当时在盛大做传奇世界,工作非常努力,希望有一天能在盛大这样的平台上开发出一款有自己风格的作品。经过了一年多的努力,有机会做主策划和项目经理,就做了一个叫三国豪侠传的游戏,在这个项目上投入了非常多的心血,但是这个游戏在商业上惨败。原因在于我们花了很多时间做兵种配合等等要素,想让战棋游戏变得更好玩,但是我们忽视了中国玩家对成长和积累需求,当玩家没法凭借等级优势等等在游戏中的积累压制别人时,就没有继续玩下去的动力。项目失败之后我就离开了盛大,这个结果也是理所当然的,当时项目中有很多比我年长、希望通过这个项目拿到奖金和期权的人,而我把它们的希望毁了。
      之后我投奔了一个朋友的公司,上海灵禅,灵禅虽然做很多外包,这段经历也和做独立游戏关系不大,但当时灵禅有很多圈内的前辈,在这里工作我学到了很多管理经验,学会了怎么协调各人利益。
      到了2006年,市场上出现了Live Arcade的模式,出现了像PopCap这样的公司,我们发现游戏可以用一个让人上瘾的核心模式+付费解锁这种形式来赚钱,这意味着有一种不用再做规模化程式化的成长和数值系统,就能养活自己的游戏模式。当时Xbox360想进中国,而我们想在海外发作品证明自己的实力,所以就合作了。我回顾自己开发游戏的方式,就想能不能尝试回到大学的时候,用独立游戏开发的方式来做这个游戏:自己亲手写demo,一个星期之内确定玩法,一个月之内把主要风险的东西解决掉。后来做到了,后来这个作品成为中国人制作的第一个上XBLA的游戏,但是项目做到一半的时候我离开了团队。这是2007年。
      然后开始做「风卷残云」。「风卷残云」这个游戏是2011年发布,但其实2007年就开始了开发,前后大约四年的时间,前三年都是拿自己的积蓄开发的。开发这个游戏的经历让我对自己的追求有了更深的认识。
      最初一段时间,团队一共只有两个人,最早的计划是用9个月做一款XBLA的游戏,无论销量如何都能支撑后续开发,但实际上做这个游戏花了三年多。
      两个人做游戏的那段时间是非常美好的回忆,在那种状态里能和很多公司进行非常坦诚的交流,可以不隐藏任何东西,因为我们做的游戏和所有人都不一样,所以大家都是朋友而不是竞争对手,感觉非常幸福。但是两个人做游戏也给商业化带来了很多门槛,我们的游戏每次比赛都获奖,但没有什么实际作用,因为运营商发行商之类的合作伙伴会不放心,担心两个人能否支撑一个游戏的持续运营。相信直到如今对于一些小的独立团队来说,这种情况也存在。
      游戏做到第三年的时候,已经弹尽粮绝了,我们和一些投资方聊了很久。我们的游戏也越来越成熟完善,看到了商业化的可能,甚至有人觉得这个品质可以用来做大型MMO游戏。对于我们那么小的团队来说,这种肯定是非常有安全、非常受鼓舞的事情。再后来带着游戏在ChinaJoy上展出,有媒体对我们进行了报道,在我们开放游戏demo下载的当天,由于下载人数太多,撑爆了服务器,在3DM上出现了一大堆关于「风卷残云」的讨论,然后出版商和运营商就都来找我们了。后来我们以一个十人的团队做完并发行了这款游戏,游戏还登上了XBLA和Steam。
      之后也经历过很多挣扎,可以说在这个过程中,商业化是不得不考虑的问题。现在我们有一个20人的团队,我们叫上海擎月软件科技有限公司,正在做的游戏叫「快斩狂刀」。找我交流可以通过邮箱联系我:19591273@qq.com。谢谢。 这是「快斩狂刀」正在开发中的PS4版本,CJ现场的玩家试玩得很开心。

    • 红茶君 1308

      雷亚的游戏制作方法论

      这篇文章是根据7月份的IndieACE沙龙上,来自台湾雷亚的开发者游名扬的分享整理的。
      小团队或者个人开发者或许经常遇到这样的状况:想出了一个很妙的点子,大张旗鼓地开始制作,却发现无法量产…或者,反复修改原型,甚至做出了完成度颇高的demo,却总觉得哪里不好玩…雷亚作为创造了Cytus、Deemo、Implosion等优秀作品的团队,其实开发中遇到的问题和大家没什么不同——这些就像每个开发者必交的学费,在经历一番摸爬滚打,创造了许多的坑之后,才能磨合出自己的感觉和节奏。
      雷亚的游总想用亲身经历告诉大家的是:看准你作品的核心价值所在,然后抓住它不要放手。
      现在IndieACE把这篇分享整理出来,希望能对各位朋友有些启发。
      我从09年开始进入游戏行业,一开始是帮游乐场做街机和大型游戏机的游戏。
      我在08年的时候做了第一款自己的独立游戏,程序美术都是自己写的,那款游戏可以说是Cytus的前身。不过大家要明白一个道理,当你的作品放到市场上,没人管你是不是独立游戏,如果画面不好看音乐不好听,就卖不出去。
      我在台大念的是计算机系,擅长做软件,硬件知识比较弱,所以11年决定出来自己开公司,重点就在做软件,开发软件的话,App Store是最好的平台,因为发行门槛低,可以把游戏发行向全世界。我们做的Cytus、deemo和Implosion,在应用商店里,在超过100个国家和地区被推荐过。
      Implosion开发了三年半,我们的合伙人从未婚到结婚到小孩出生,游戏才做出来,所以真的做了很长的时间。
      我们发布了四款产品后,苹果给了我们一个开发者专区,说明苹果在支持原创方面,还是发挥了很大作用的。
      我们玩游戏的时候经常会碰到卡关的情况。其实身为游戏开发者,在开发过程中也常常遇到卡关,甚至我们会发现,开发中卡关和解决的时间,占到了开发时间的一半以上。
      卡关了怎么办呢?我们通常把游戏开发的过程,归纳为三个阶段:prototype、pre-production和production,也就是原型制作-量产前置-量产。游戏是互动和艺术的结合,如果说电影的表达靠的是美术、镜头和剧情来给观众代入感,而体育享受的是一种纯互动的乐趣,那游戏的坐标就在他们当中,是两者的结合。所以在原型制作最重要的是确定核心玩法,在这个阶段找到游戏的核心价值;找到之后,你会发现这个核心价值不一定能量产,比如你的作品的核心价值在于非常华丽但复杂的美术,可能就是难以量产的。
      在量产前置阶段,开发者要寻找把1变成100的量产方法,想办法把制作变为可能;这个过程通常不是直线进行的,是不断互相循环的,你可能在量产前置阶段发现一些问题,最后要不断回到原型制作阶段去修改和解决。
      举个例子,Cytus是我们做的一款音乐游戏,游戏玩法描述起来很简单,就是进入主选单-选歌曲-玩歌曲-结算;最重要的是核心玩法的部分,Cytus的核心价值是全触碰的音乐游戏和它不错的美术画面;事实上,在这个核心玩法之外,游戏制作过程中的每一个改动也都涉及思考和验证阶段。
      而Deemo的核心玩法的idea就来自于,要和Cytus做出区别。我受到一款叫做Magic Piano(魔法钢琴)的App的启发,觉得音乐游戏中有自己弹钢琴的感觉会更好。虽然Cytus用到了全屏幕,但我们观察一下当下最红的音乐游戏,主要还是用落下式的玩法,所以我们确定了钢琴+落下式的法+黑白概念的游戏,因为想用极简的风格做出钢琴的感觉。
      按照这个思路做了原型,甚至进入了量产前置阶段,然后让玩家玩了一下,发现玩了一两首歌觉得很好,多玩几首就乏味了,没办法让玩家持续玩下去,总感觉少了点东西;另一个问题是游戏里的钢琴是没有力度的,力度难以表达,没有代入感。
      关于力度的部分,我们找了很多参考和音乐模拟游戏,看他们怎么做,用一个暴力的方法解决了,就是每个音都取样,取4个力度,用4组声音去还原这四个力度。
      另外一方面,除了钢琴之外加点别的,加什么呢?决定加故事,有了故事就有无限发展的可能;加角色,加了一个角色叫孤独的deemo,他原本是黑白的,演奏之后变彩色;还有一颗树,演奏后会生长。一个角色不够,就再加一个妹子给他。
      有了两个人的互动,故事就有发展了:女孩掉进这个世界里,她如何回家。正因为有了故事这个要素,每个曲子就能用两个人的互动呈现。现在网上有很多同人,也在想象两人能发生怎样的互动,画师也在画里埋梗;进行到这里,游戏在极简之外,就多了一些人文的成分。
      但音乐游戏要怎么讲故事呢?我们的做法是加入探索功能,游戏到了不同的阶段,游戏场景会变化。在场景发生变化前,强迫玩家看一段动画,这样故事就变成有意义的东西,动画播完后回到房间,场景发生变化,让玩家去探索,这样玩家就看到了故事。
      再举个例子,Cytus是我们的第一款产品,核心玩法就是全屏幕的触碰,它的判定比以往的音乐游戏都大,但正是因为太简单了,音乐游戏的大触们无法得到成就感。然而,如果我们更新一个版本把判定调严格的话,原本的轻度玩家会有挫折感。所以最后我们加了一个判定,计算TP(Technical Point),在显示上不是特别明显,在意它的人会看到,不在意的人不会发现。现在这个游戏的强者都在比这个。
      另一个例子是Implosion(聚爆),这也是我们开发过程中挫折感最大的一个故事:我们做的第一版游戏界面,元素非常多,各种副属性主属性堆在一起,还有晶片作用描述等等;选单又藏得太深,描述性文字特别多。用户体验不好,最后我们把这一版界面全换掉了。玩家最需要的体验其实是:很快看到想要的东西,方便地更换装备,所以最后设计成了左右相连滑动的画面,没有上一层下一层的跳转设计。 一开始我们的开发流程是:RD用简单的方块做了一个雏形,UI设计师再去画,完成之后再review成果是否符合预期,不行就推翻重来。这种流程会在循环中浪费很多时间,不符合敏捷开发的原则,所以当时一个选单花了四个月才做完。这是什么问题呢?是review的机制有问题,最好的是有一个负责用户体验的人,随时检查,随时给下决定的人看,这样更有效率。
      还有一个更挫折的事,一开始聚爆是给Xbox360做的游戏,但是交涉没那么顺利,考虑到在主机上也不一定能很成功,最后决定把主机版砍掉,做成了一个手机游戏。这也是导致这个游戏做了很久的原因之一。
      所以总结我们的经验就是:原型制作阶段不要怕砍掉重练,但确定原型之后在作业期要保持贪心,尽量满足所有要做的事情,尽量保持随时review的机制。最重要的是记住游戏的核心价值,核心价值确定之后,所有的工作都是为了实现它,不要因为眼前的卡关牺牲核心价值。

    • Bowie 1353

      IL2CPP 深入讲解:泛型共享

      IL2CPP 深入讲解:泛型共享IL2CPP INTERNALS: GENERIC SHARING IMPLEMENTATION 这是 IL2CPP深入讲解的第五篇。在上一篇中,我们有说到由IL2CPP产生的C++代码是如何进行各种不同的方法调用的。而在本篇中,我们则会讲解这些C++方法是如何被实现的。特别的,我们会对一个非常重要的特性 -- 泛型共享 加以诠释。泛型共享使得泛型函数可以共享一段通用的代码实现。这对于减少由IL2CPP产生的可执行文件的尺寸有非常大的帮助。


      需要指出的是泛型共享不是一个新鲜事物,Mono和.Net运行时库(译注:这里说的.Net运行时库指的是微软官方的实现)也同样采用泛型共享技术。IL2CPP起初并不支持泛型共享,我们到最近的改进版中才使得泛型共享机制足够的健壮并能使其带来好处。既然il2cpp.exe产生C++代码,我们可以分析这些代码来了解泛型共享机制是如何实现的。
      我们将探索对于引用类型或者值类型而言,泛型函数在何种情况下会进行泛型共享,而在何种情况下不会。我们也会讨论泛型参数是如何影响到泛型共享机制的。
      请记住,所有以下的讨论都是细节上的实现。这里的讨论和所涉及的代码很有可能在未来发生改变。只要有可能,我们都会对这些细节进行探讨。
      什么是泛型共享
      思考一下如果你在C#中写一个List的实现。这个List的实现会根据T的类型不同而不同么?对于List的Add函数而言,List和List会是一样的代码么?那如果是List呢?
      实际上,泛型的强大之处在于这些C#的实现都是共享的,List泛型类可以适用于任何的T类型。但是当C#代码转换成可执行代码,比如Mono的汇编代码或者由IL2CPP产生的C++代码的时候会发生什么呢?我们能在这两个层面上也实现Add函数的代码共享么?
      答案是肯定的,我们能在大多数的情况下做到共享。正如本文后面将要讨论的:泛型函数的泛型共享与否主要取决于这个T的大小如何。如果T是任何的引用类型(像string或者是object),那T的尺寸永远是一个指针的大小。如果T是一个值类型(比如int或者DateTime),大小会不一样,情况也会相对复杂。代码能共享的越多,那么最终可执行文件的尺寸就越小。
      在Mono中实现了泛型共享的大师:Mark Probst,有一个关于Mono如何进行泛型共享的很棒的系列文章。我们在这里不会对Mono的实现深入到那么的底层中去。相反,我们讨论IL2CPP是怎么做的。希望这些信息可以帮助到你们去更好的理解和分析你们项目最终的尺寸。
      IL2CPP的共享是啥样子的?
      就目前而言, 当SomeGenericType中的T是下面的情况时,IL2CPP会对泛型函数进行泛型共享: 任何引用类型(例如:string,object,或者用户自定义的类) 任何整数或者是枚举类型
      当T是其他值类型的时候,IL2PP是不会进行泛型共享的。因为这个时候类型的大小会很不一样。
      实际的情况是,对于新加入使用的SomeGenericType,如果T是引用类型,那么它对于最终的可执行代码的尺寸几乎是没有影响的。然而,如果新加入的T是直类型,那就会影响到尺寸。这个逻辑对于Mono和IL2CPP都适用。如果你想知道的更多,请继续往下读,到了说实现细节的时候了!
      项目搭建
      这里我会在Windows上使用Unity 5.0.2p1版本,并且将平台设置到WebGL上。在构建设置中将“Development Player”选项打开,并且将“Enable Exceptions”选项设置成“None”。在这篇文章的例子代码中,有一个驱动函数在一开始就把我们要分析的泛型类型的实例创建好。








      public void DemonstrateGenericSharing() { var usesAString = new GenericType(); var usesAClass = new GenericType(); var usesAValueType = new GenericType(); var interfaceConstrainedType = new InterfaceConstrainedGenericType();}

      接下来我们定义在这个函数中用到的泛型类:






























      class GenericType { public T UsesGenericParameter(T value) { return value; } public void DoesNotUseGenericParameter() {} public U UsesDifferentGenericParameter(U value) { return value; }} class AnyClass {} interface AnswerFinderInterface { int ComputeAnswer();} class ExperimentWithInterface : AnswerFinderInterface { public int ComputeAnswer() { return 42; }} class InterfaceConstrainedGenericType where T : AnswerFinderInterface { public int FindTheAnswer(T experiment) { return experiment.ComputeAnswer(); }}以上这些代码都放在一个叫做HelloWorld的类中,此类继承于MonoBehaviour。
      如果你查看il2cpp.exe的命令行,你会发现命令行中是不带本系列第一篇博文所说的--enable-generic-sharing参数的。虽然没有这个参数,但是泛型共享还是会发生,那是因为我们将其变成了默认打开的选项。
      引用类型的泛型共享
      让我们从最常发生的泛型共享情况开始吧:对于引用类型的泛型共享。由于所有的引用类型都是从System.Object继承过来的。因此对于C++代码而言,这些类型都是从Object_t类型继承而来。所有的引用类型在C++中都能以Object_t*作为替代。一会儿我们会讲到什么这点非常重要。
      让我们搜索一下DemonstrateGenericSharing函数的泛型版本。在我的项目中,它被命名为HelloWorld_DemonstrateGenericSharing_m4。通过CTags工具,我们可以跳到GenericType的构造函数:GenericType_1__ctor_m8。请注意,这个函数实际上是一个#define定义,这个#define又把我们引向另一个函数:GenericType_1__ctor_m10447_gshared。
      让我们往回跳两次(译注:使用CTags工具,代码关系往回回溯两次)。可以找到GenericType 类型的申明。如果我们对其构造函数GenericType_1__ctor_m9进行追溯,我们同样能够看到一个#define定义,而这个定义最终引向了同一个函数:GenericType_1__ctor_m10447_gshared。
      如果我们跳到GenericType_1__ctor_m10447_gshared的定义,我们能从代码上面的注释得出一个信息:这个C++函数对应的是C#中的HelloWorld::GenericType`1::.ctor()。这是GenericType类型的标准构造函数。这种类型称之为全共享类型,意味着对于GenericType而言,只要T是引用类型,所有的函数都使用同一份代码。
      在这个构造函数往下一点,你应该能够看到UsesGenericParameter函数的C++实现:








      extern "C" Object_t * GenericType_1_UsesGenericParameter_m10449_gshared (GenericType_1_t2159 * __this, Object_t * ___value, MethodInfo* method){ { Object_t * L_0 = ___value; return L_0; }}
      在两处使用泛型参数T的地方(分别在返回值和函数参数中),C++代码都使用了Object_t*。因为任何引用类型都能在C++代码中被Object_t*所表示,所以我们也就能够对于任何引用T,调用相同的UsesGenericParameter函数。
      在系列的第二篇中,我们有提到过在C++代码中,所有的函数都是非成员函数。il2cpp.exe不会因为在C#有重载函数而在C++中使用继承。在是在类型的处理上却有所不同:il2cpp.exe确实会在类型的处理上使用继承。如果我们查找代表C#中AnyClass类的C++类型AnyClass_t,会发现如下代码:




      struct AnyClass_t1 : public Object_t{};
      因为AnyClass_t1是从Object_t继承而来,我们就能合法的传递一个 AnyClass_t1的指针给GenericType_1_UsesGenericParameter_m10449_gshared函数。
      那函数的返回值又是个什么情况呢?如果函数需要返回一个继承类的指针,那我们就不能返回它的基类对吧。那就让我们看看GenericType::UsesGenericParameter的声明:


      #define GenericType_1_UsesGenericParameter_m10452(__this, ___value, method) (( AnyClass_t1 * (*) (GenericType_1_t6 *, AnyClass_t1 *, MethodInfo*))GenericType_1_UsesGenericParameter_m10449_gshared)(__this, ___value, method)
      C++代码其实是把返回值(Object_t*类型)强制转换成了AnyClass_t1*类型。因此在这里IL2CPP对C++编译器使了个障眼法。因为C#的编译器会保证UsesGenericParameter中的T是可兼容的类型,因此IL2CPP这里的强转是安全的。
      带泛型约束的共享
      假设如果我们想要让T能够调用一些特定的函数。因为System.Object只有最基本的一些函数而不存在你想要使用的任何其他函数,那么在C++中使用Object_t*就会造成障碍了,不是嘛?是的,你说的没错!但是我们有必要在此解释一下C#编译器中的泛型约束的概念。
      让我们再仔细看看InterfaceConstrainedGenericType的C#代码。这个泛型类型使用了一个‘where’关键字以确保T都是从一个特定的接口(Interface):AnswerFinderInterface继承过来的。这就使得调用ComputeAnswer 函数成为可能。大家还记得上一篇博文中我们讨论的吗:当调用一个接口函数的时候,我们需要在虚表(vtable structure)中进行查找。因为FindTheAnswer可以从约束类型T中被直接调用,所以C++代码依然能够使用全共享的实现机制,也就是说T由Object_t*所代表。
      如果我们由HelloWorld_DemonstrateGenericSharing_m4function的实现开始,跳到InterfaceConstrainedGenericType_1__ctor_m11函数的定义,会发现这个函数任然是一个#define定义,映射到了InterfaceConstrainedGenericType_1__ctor_m10456_gshared函数。在这个函数下面,是InterfaceConstrainedGenericType_1_FindTheAnswer_m10458_gshared函数的实现,发现它也是一个全共享函数,接受一个Object_t*参数,然后调用InterfaceFuncInvoker0::Invoke函数转而调用实际的ComputeAnswer代码。














      extern "C" int32_t InterfaceConstrainedGenericType_1_FindTheAnswer_m10458_gshared (InterfaceConstrainedGenericType_1_t2160 * __this, Object_t * ___experiment, MethodInfo* method){ static bool s_Il2CppMethodIntialized; if (!s_Il2CppMethodIntialized) { AnswerFinderInterface_t11_il2cpp_TypeInfo_var = il2cpp_codegen_class_from_type(&AnswerFinderInterface_t11_0_0_0); s_Il2CppMethodIntialized = true; } { int32_t L_0 = (int32_t)InterfaceFuncInvoker0::Invoke(0 /* System.Int32 HelloWorld/AnswerFinderInterface::ComputeAnswer() */, AnswerFinderInterface_t11_il2cpp_TypeInfo_var, (Object_t *)(*(&___experiment))); return L_0; }}
      因为IL2CPP把所有的C#中的接口(Interface)都当作System.Object一样处理,其所产生的C++代码也就能说得通了。这个规则在C++代码的其他情况中也同样适用。
      基类的约束
      除了对接口(Interface)进行约束,C#还允许对基类进行约束。IL2CPP并不是把所有的基类都当成System.Object处理。那么对于有基类约束的泛型共享又是怎样的呢?
      因为基类肯定都是引用类型,所以IL2CPP还是使用全共享版本的泛型函数来处理这些受约束的类型。任何有用到约束类型中特定成员变量或者成员函数的地方都会被C++代码进行强制类型转换。再次强调,在这里我们仰仗C#编译器强制检查这些约束类型都符合转换要求,我们就可以放心的蒙蔽C++编译器了。
      值类型的泛型共享
      让我们回到HelloWorld_DemonstrateGenericSharing_m4函数看下 GenericType的实现。DateTime是个值类型,因此GenericType不会被共享。我们可以看看这个类型的构造函数GenericType_1__ctor_m10。这个函数是GenericType所特有的,不会被其他类使用。
      系统的思考泛型共享
      泛型共享的实现是比较难以理解的,问题的本身在于它自己充满着各种不同的特殊情况(比如:奇特的递归模板模式)(译注:这是C++中的一个概念,简单的说就是诸如:class derived:public base这样的形式,使用派生类本身来作为模板参数的特化基类。目的是在编译期通过基类模板参数来得到派生类的行为,由于是编译期绑定而不是运行期绑定,可以增加执行效率)。
      从以下几点着手可以帮助我们很好的思考泛型共享:

      泛型类中的函数都是共享的有些泛型类只和他们自己共享代码(比如泛型参数是值的泛型类)泛型参数是引用的泛型类总是全共享-他们总是使用System.Object来适用于各种参数类型有两个或者更多泛型参数的泛型类能够被部分共享。前提是在泛型参数中至少有一个参数是引用类型il2cpp.exe总是先产生全共享代码。其他特别的代码在有用到时才会特别单独产生。
      泛型函数的共享
      泛型类可以被共享,泛型函数同样也可以。在我们原始的C#示例代码中,有一个UsesDifferentGenericParameter函数,这个函数用了另外一个泛型参数而不是GenericType。我们在GenericType类的C++代码中查找不到UsesDifferentGenericParameter的实现。事实上,它在GenericMethods0.cpp中:








      extern "C" Object_t * GenericType_1_UsesDifferentGenericParameter_TisObject_t_m15243_gshared (GenericType_1_t2159 * __this, Object_t * ___value, MethodInfo* method){ { Object_t * L_0 = ___value; return L_0; }}
      请注意这个是一个泛型函数的全共享版本,因为它接受Object_t*作为参数。虽然这是一个泛型函数,但是它的行为在非泛型的情况下是一样的。il2cpp.exe总是试图先产生一个使用泛型参数的实现。
      结论
      泛型共享是自IL2CPP发布以来一个最重要的改进。通过共享相同的代码实现,它使得C++代码尽可能的小。我们也会继续利用共享代码机制来进步一减少最终二进制文件的尺寸。
      在下一篇文章中,我们将探讨 p/invoke 封装代码是如何产生的。以及托管代码中的类型数据是如何转换到原生代码(C++代码)中的。我们将检视各种类型转换所需要的开销,并且尝试调试有问题的数据转换代码。


      原文连接



    • ayame9joe 1252 3

      类似《迷失之风》的物理效果实现?

      滑动手指控制主角移动。
      是在接触点上施加一个作用力?
      求一个实现思路。

    • 红茶君 1536 1

      昨天给莎木3投完钱,今天来看看E3上的独立游戏

      这几天E3的消息铺天盖地,我知道你们都被hololens版的Minecraft、FF7重制、莎木3等等各种重磅炸弹刷屏了。然而我们这个业界的繁荣,不光是因为巨头们费尽心思的准备大型武器,也依靠无数小团队的奇妙创意。
      所以,让我们来看看本次E3发布会上一闪而过的独立游戏们。
      首先是连续几年登上索尼发布会的太空沙盒游戏No Man’s Sky(无人深空),这个看起来规模无比庞大的宇宙探索游戏,却是由来自英国的小团队Hello Games制作的。从开发商公布的最新消息来看,这个通过算法生成宇宙的游戏,拥有着天文数字级别的星球数量,以及难以穷尽的广袤宇宙。
      以下是E3索尼发布会上最新的游戏演示。如果开发团队的设想能够成功实现,那么这可能会一个独立团队做过的最黑科技的事了。
      而微软则在发布会上专门设立了一个ID@Xbox的单元,公布了一系列将要登上Xbox的独立游戏作品,视频如下。视频里出现了好几个值得注意的新作品:Cuphead,上世纪30年代动画片风格的新作;Tacoma,由获奖无数的Gone Home开发团队开发的新作品,看起来对游戏叙事又有了新的探索;Ashen,一个风格和氛围都很棒的开放世界RPG游戏。除此之外,我们之前报道过的Gemini也在这个视频剪辑中出现了(查看对Gemini团队的采访可以关注IndieACE微信公众号,然后回复gemini取得)。

      剪辑中出现的所有游戏名单如下,一些游戏已经发售或者处于Early Access阶段。大部分游戏都将可以在Xbox One或者PC上玩到。
      Cuphead(Studio MDHR)Beyond Eyes(team17,Tiger & Squid)Rise & Shine(Adult Swim Games)Gemini(Echostone Games)Below(Capybara Games)The Flame in the Flood(The Molasses Flood)Ashen(Aurora44)The Solus Project(Grip Games)Westerado: Double Barreled (Adult Swim Games),已发售Happy Dungeons(Toylogic)Recruits(QUByte Interactive),Early Access on SteamCastle Crashers Remastered(The Behemoth)Tacoma(Fullbright)Full Mojo(Nicalis),已发售Zheros(Rimlight Studios)Sword Coast Legends(n-Space and Digital Extremes)Goat Simulator: Mmore Goatz Edition(Double Eleven)Game 4(The Behemoth)Phantasmal(Eyemobi),Early Access on SteamWarhammer(Fatshark)Outward(Nine Dots Studio)Sheltered(team17,Unicube)ARK: Survival Evolved(Studio Wildcard),Early Access on SteamFishing(Dovetail Games),Early Access on SteamSpace Dust Racers(Space Dust Studios)The Mean Greens(Virtual Basement)The Long Dark(Hinterland Games),Early Access on SteamSuperhot(Superhot)

      感谢这个好游戏多得玩不过来的时代。

    • Sobek 2688 3

      看了眼E3,有一个像素风格的游戏

      游戏名字是"Eitr",去年11月在steam青睐之光第一眼看就表示关注,近年上了E3 PC站台。像素风格,Diablo+Dark Souls的2D结合体
      最后今天才发现作者用的是U3D做的{:235_554:}
      EITR: 5 TOOLS BEHIND PIXEL-ART ACTION/RPG EITR
      这个是主页:http://eitrthegame.com/ 视频需要翻墙。




      刚开始做游戏,之前在用COCOS做了一些简单游戏的demo,感觉有些局限了,现在想转U3D看看能否更简单的做一些有趣的游戏,这种类型的第一眼就爱上它了



    • Bowie 1770

      IL2CPP 深入讲解:方法调用介绍

      IL2CPP深入讲解:方法调用介绍IL2CPP INTERNALS: METHOD CALLS


      这里是本系列的第四篇博文。在这篇文章里,我们将看到il2cpp.exe如何为托管代码中的各种函数调用生成C++代码。我们在这里会着重的分析6种不同类型的函数调用:
      类实例的成员函数调用和类的静态函数调用编译期生成的代理函数调用虚函数调用C#接口(Interface)函数调用运行期决定的代理函数调用通过反射机制的函数调用
      对于每种情况,我们主要探讨两点:相应的C++代码都做了些啥以及这么做的开销如何。和以往的文章一样,我们这里所讨论的代码,很可能在新的Unity版本中已经发生了变化。尽管如此,文章所阐述的基本概念是不会变的。而文章中关于代码的部分都是属于实现细节。

      项目设置这次我采用的Unity版本是5.0.1p4。运行环境为Windows,目标平台选择了WebGL。同样的,在构建设置中勾选了“Development Player”并且将“Enable Exceptions”选项设置成“Full”。我将使用一个在上一篇文章中的C#代码,做一点小的修改,放入不同类型的调用方法。代码以一个接口(Interface)定义和类的定义开始:[code]interface Interface {
      int MethodOnInterface(string question);
      }

      class Important : Interface {
      public int Method(string question) { return 42; }
      public int MethodOnInterface(string question) { return 42; }
      public static int StaticMethod(string question) { return 42; }
      }[/code]
      接下来是后面代码要用到的常数变量和代理类型:[code]private const string question = "What is the answer to the ultimate question of life, the universe, and everything?";

      private delegate int ImportantMethodDelegate(string question);[/code]


      最后是我们讨论的主题:6种不同的函数调用的代码(以及必须要有的启动函数,启动函数具体代码就不放上来了):[code]private void CallDirectly() {
      var important = ImportantFactory();
      important.Method(question);
      }

      private void CallStaticMethodDirectly() {
      Important.StaticMethod(question);
      }

      private void CallViaDelegate() {
      var important = ImportantFactory();
      ImportantMethodDelegate indirect = important.Method;
      indirect(question);
      }

      private void CallViaRuntimeDelegate() {
      var important = ImportantFactory();
      var runtimeDelegate = Delegate.CreateDelegate(typeof (ImportantMethodDelegate), important, "Method");
      runtimeDelegate.DynamicInvoke(question);
      }

      private void CallViaInterface() {
      Interface importantViaInterface = new Important();
      importantViaInterface.MethodOnInterface(question);
      }

      private void CallViaReflection() {
      var important = ImportantFactory();
      var methodInfo = typeof(Important).GetMethod("Method");
      methodInfo.Invoke(important, new object[] {question});
      }

      private static Important ImportantFactory() {
      var important = new Important();
      return important;
      }

      void Start () {}[/code]


      有了这些以后,我们就可以开始了。还记得所有生成的C++代码都会临时存放在Temp\StagingArea\Data\il2cppOutput目录下么?(只要Unity Editor保持打开)别忘了你也可以使用 Ctags 去标注这些代码,让阅读变得更容易。

      直接函数调用最简单(当然也是最快速)调用函数的方式,就是直接调用。下面是CallDirectly方法的C++实现:[code]Important_t1 * L_0 = HelloWorld_ImportantFactory_m15(NULL /*static, unused*/, /*hidden argument*/&HelloWorld_ImportantFactory_m15_MethodInfo);
      V_0 = L_0;
      Important_t1 * L_1 = V_0;
      NullCheck(L_1);
      Important_Method_m1(L_1, (String_t*) &_stringLiteral1, /*hidden argument*/&Important_Method_m1_MethodInfo);[/code]


      代码的最后一行是实际的函数调用。其实没有什么特别的地方,就是一个普通的C++全局函数调用而已。大家是否还记得“代码生成之旅”文章中提到的内容:il2cpp.exe产生的C++代码的函数全部是类C形式的全局函数,这些函数不是虚函数也不是属于任何类的成员函数。接下来,直接静态函数的调用和前面的处理很相似。下面是静态函数CallStaticMethodDirectly的C++代码:[code]Important_StaticMethod_m3(NULL /*static, unused*/, (String_t*) &_stringLiteral1, /*hidden argument*/&Important_StaticMethod_m3_MethodInfo);[/code]


      相比之前,我们可以说静态函数的代码处理要简单的多,因为我们不需要类的实例,所以我们也不需要创建实例,进行实例检查的那些个代码。静态函数的调用和一般函数调用的区别仅仅在于第一个参数:静态函数的第一个参数永远是NULL。由于这两类函数的区别是如此之小,因此在后面的文章中,我们只会拿一般函数调用来讨论。但是这些讨论的内容同样适用于静态函数。

      编译期代理函数调用像这种通过代理函数来进行非直接调用的稍微复杂点的情况会发生什么呢?CallViaDelegate函数调用的C++代码如下:[code]
      // Get the object instance used to call the method.
      Important_t1 * L_0 = HelloWorld_ImportantFactory_m15(NULL /*static, unused*/, /*hidden argument*/&HelloWorld_ImportantFactory_m15_MethodInfo);
      V_0 = L_0;
      Important_t1 * L_1 = V_0;

      // Create the delegate.
      IntPtr_t L_2 = { &Important_Method_m1_MethodInfo };
      ImportantMethodDelegate_t4 * L_3 = (ImportantMethodDelegate_t4 *)il2cpp_codegen_object_new (InitializedTypeInfo(&ImportantMethodDelegate_t4_il2cpp_TypeInfo));
      ImportantMethodDelegate__ctor_m4(L_3, L_1, L_2, /*hidden argument*/&ImportantMethodDelegate__ctor_m4_MethodInfo);
      V_1 = L_3;
      ImportantMethodDelegate_t4 * L_4 = V_1;

      // Call the method
      NullCheck(L_4);
      VirtFuncInvoker1::Invoke(&ImportantMethodDelegate_Invoke_m5_MethodInfo, L_4, (String_t*) &_stringLiteral1);[/code]


      我加入了一些注释以标明上面代码的不同部分。需要注意的是实际上在C++中调用的是VirtFuncInvoker1::Invoke这个函数。此函数位于GeneratedVirtualInvokers.h头文件中。它不是由我们写的IL代码生成的,相反的,il2cpp.exe是根据虚函数是否有返回值,和虚函数的参数个数来生成这个函数的。(译注:VirtFuncInvokerN是表示有N个参数有返回值的虚函数调用,而VirtActionInvokerN 则表示有N个参数但是没有返回值的虚函数调用,上面的例子中VirtFuncInvoker1::Invoke的第一个模板参数int32_t就是函数的返回值,而VirtFuncInvoker1中的1表示此函数还有一个参数,也就是模板参数中的第二个参数:String_t*。因此可以推断VirtFuncInvoker2应该是类似这样的形式:VirtFuncInvoker2::Invoke,其中R是返回值,S,T是两个参数)具体的Invoke函数看起来是下面这个样子的:[code]template
      struct VirtFuncInvoker1
      {
      typedef R (*Func)(void*, T1, MethodInfo*);

      static inline R Invoke (MethodInfo* method, void* obj, T1 p1)
      {
      VirtualInvokeData data = il2cpp::vm::Runtime::GetVirtualInvokeData (method, obj);
      return ((Func)data.methodInfo->method)(data.target, p1, data.methodInfo);
      }
      };[/code]


      libil2cpp中的GetVirtualInvokeData函数实际上是在一个虚函数表的结构中寻找对应的虚函数。而这个虚函数表是根据C#托管代码建立的。在找到了这个虚函数后,代码就直接调用它,传入需要的参数,从而完成了函数调用过程。你可能会问,为什么我们不用C++11标准中的可变参数模板 (译注:所谓可变参数模板是诸如template,这样的形式,后面的...和函数中的可变参数...作用是一样的)来实现这些个VirtFuncInvokerN函数?这恰恰是可变参数模板能解决的问题啊。然而,考虑到由il2cpp.exe生成的C++代码要在各个平台的C++编译器中进行编译,而不是所有的编译器都支持C++11标准。所以我们再三权衡,没有使用这项技术。那么虚函数调用又是怎么回事?我们调用的不是C#类里面的一个普通函数吗?大家回想下上面的代码:我们实际上是通过一个代理方法来调用类中的函数的。再来看看上面的C++代码,实际的函数调用是通过传递一个MethodInfo*结构(函数元信息结构):ImportantMethodDelegate_Invoke_m5_MethodInfo作为参数来完成的。再进一步看ImportantMethodDelegate_Invoke_m5_MethodInfo中的内容,会发现它实际上调用的是C#代码中ImportantMethodDelegate类型的Invoke函数(译注:也就是C#代理函数类型的Invoke函数)。而这个Invoke函数是个虚函数,所以最终我们也是以虚函数的方式调用的。Wow,这够我们消化一阵子的了。在C#中的一点小小的改变,在我们的C++代码中从简单的函数调用变成了一系列的复杂函数调用,这中间还牵扯到了查找虚函数表。显然通过代理的方法调用比直接函数调用更耗时。还有一点需要注意的是在代理方法调用处理时候使用的这个查找虚函数表的操作,也同样适用于虚函数调用。

      接口方法调用在C#中通过接口方法调用当然也是可以的。在C++代码实现中和虚函数的处理方式差不多:[code]Important_t1 * L_0 = (Important_t1 *)il2cpp_codegen_object_new (InitializedTypeInfo(&Important_t1_il2cpp_TypeInfo));
      Important__ctor_m0(L_0, /*hidden argument*/&Important__ctor_m0_MethodInfo);
      V_0 = L_0;
      Object_t * L_1 = V_0;
      NullCheck(L_1);
      InterfaceFuncInvoker1::Invoke(&Interface_MethodOnInterface_m22_MethodInfo, L_1, (String_t*) &_stringLiteral1);[/code]


      实际上的函数调用是通过InterfaceFuncInvoker1::Invoke来完成的。这个函数存在于GeneratedInterfaceInvokers.h头文件中。就像上面提到过的VirtFuncInvoker1类,InterfaceFuncInvoker1类也是通过il2cpp::vm::Runtime::GetInterfaceInvokeData查询虚函数表来确定实际调用的函数的。
      那为什么接口的方法调用和虚函数的调用在libil2cpp库中是不同的API呢?那是因为在接口方法调用中,除了方法本身的元信息,函数参数之外,我们还需要接口本身(在上面的例子中就是L_1)在虚函数表中接口的方法是被放在一个特定的偏移上的。因此il2cpp.exe需要接口的信息去计算出被调用的函数到底是哪一个。
      从代码的最后一行可以看出,调用接口的方法和调用虚函数的开销在IL2CPP中是一样的。

      运行期决定的代理方法调用使用代理的另一个方法是在运行时由Delegate.CreateDelegate动态的创建代理实例。这个过程实际上和编译期的代理很像,只是多了一些运行时的处理。为了代码的灵活性,我们总是要付出些代价的。下面是实际的代码:[code]// Get the object instance used to call the method.
      Important_t1 * L_0 = HelloWorld_ImportantFactory_m15(NULL /*static, unused*/, /*hidden argument*/&HelloWorld_ImportantFactory_m15_MethodInfo);
      V_0 = L_0;

      // Create the delegate.
      IL2CPP_RUNTIME_CLASS_INIT(InitializedTypeInfo(&Type_t_il2cpp_TypeInfo));
      Type_t * L_1 = Type_GetTypeFromHandle_m19(NULL /*static, unused*/, LoadTypeToken(&ImportantMethodDelegate_t4_0_0_0), /*hidden argument*/&Type_GetTypeFromHandle_m19_MethodInfo);
      Important_t1 * L_2 = V_0;
      Delegate_t12 * L_3 = Delegate_CreateDelegate_m20(NULL /*static, unused*/, L_1, L_2, (String_t*) &_stringLiteral2, /*hidden argument*/&Delegate_CreateDelegate_m20_MethodInfo);
      V_1 = L_3;
      Delegate_t12 * L_4 = V_1;

      // Call the method
      ObjectU5BU5D_t9* L_5 = ((ObjectU5BU5D_t9*)SZArrayNew(ObjectU5BU5D_t9_il2cpp_TypeInfo_var, 1));
      NullCheck(L_5);
      IL2CPP_ARRAY_BOUNDS_CHECK(L_5, 0);
      ArrayElementTypeCheck (L_5, (String_t*) &_stringLiteral1);
      *((Object_t **)(Object_t **)SZArrayLdElema(L_5, 0)) = (Object_t *)(String_t*) &_stringLiteral1;
      NullCheck(L_4);
      Delegate_DynamicInvoke_m21(L_4, L_5, /*hidden argument*/&Delegate_DynamicInvoke_m21_MethodInfo);
      [/code]

      首先我们使用了一些代码来创建代理这个实例,随后处理函数调用的代码也不少。在后面的过程中我们先创建了一个数组用来存放被调用函数的参数。然后调用代理实例中的DynamicInvoke方法。如果我们更深入的研究下DynamicInvoke方法,会发现它实际上在内部调用了VirtFuncInvoker1::Invoke函数,就如同编译期代理所做的那样。所以从代码执行量上来说,运行时代理方法比静态编译代理方法多了一个函数创建,比且还多了一次虚函数表的查找。

      通过反射机制进行方法调用毫无疑问的,通过反射来调用函数开销是最大的。下面我们来看看具体的CallViaReflection函数所生成的C++代码:[code]// Get the object instance used to call the method.
      Important_t1 * L_0 = HelloWorld_ImportantFactory_m15(NULL /*static, unused*/, /*hidden argument*/&HelloWorld_ImportantFactory_m15_MethodInfo);
      V_0 = L_0;

      // Get the method metadata from the type via reflection.
      IL2CPP_RUNTIME_CLASS_INIT(InitializedTypeInfo(&Type_t_il2cpp_TypeInfo));
      Type_t * L_1 = Type_GetTypeFromHandle_m19(NULL /*static, unused*/, LoadTypeToken(&Important_t1_0_0_0), /*hidden argument*/&Type_GetTypeFromHandle_m19_MethodInfo);
      NullCheck(L_1);
      MethodInfo_t * L_2 = (MethodInfo_t *)VirtFuncInvoker1::Invoke(&Type_GetMethod_m23_MethodInfo, L_1, (String_t*) &_stringLiteral2);
      V_1 = L_2;
      MethodInfo_t * L_3 = V_1;

      // Call the method.
      Important_t1 * L_4 = V_0;
      ObjectU5BU5D_t9* L_5 = ((ObjectU5BU5D_t9*)SZArrayNew(ObjectU5BU5D_t9_il2cpp_TypeInfo_var, 1));
      NullCheck(L_5);
      IL2CPP_ARRAY_BOUNDS_CHECK(L_5, 0);
      ArrayElementTypeCheck (L_5, (String_t*) &_stringLiteral1);
      *((Object_t **)(Object_t **)SZArrayLdElema(L_5, 0)) = (Object_t *)(String_t*) &_stringLiteral1;
      NullCheck(L_3);
      VirtFuncInvoker2::Invoke(&MethodBase_Invoke_m24_MethodInfo, L_3, L_4, L_5);[/code]


      就和运行时代理方法调用一样,我们需要用额外的代码创建函数参数数组。然后还需要调用一个MethodBase::Invoke (实际上是MethodBase_Invoke_m24函数)虚函数,由这个函数调用另外一个虚函数,在能最终得到实际的函数调用!

      总结虽然Unity没有针对C++函数调用的性能分析器,但是我们可以从C++的源码中看出不同类型方法调用的不同复杂程度的实现。如何可能,请尽量避免使用运行时代理方法和反射机制方法的调用。当然,想要提高运行效率还是要在项目的早期阶段就使用性能分析器进行诊断。
      我们也在一直想办法优化il2cpp.exe产生的代码。因此再次强调,这篇文章中所产生的C++代码或许会在以后的Unity版本中发生变化。
      下篇文章我们将更进一步的深入到函数中,看看我们是如何共享方法简化C++代码并减小最终可执行文件的尺寸的。
      原文连接


    • 红茶君 1567 1

      为信仰充值要花多少钱:独立游戏应该如何定价?

      导语:不久之前,Steam开始实行一个游戏退货制度:玩家在购买游戏的两周内,如果对游戏不满意,而游戏时间也未达到2小时,可以申请退款。这个政策在开发者中间引起不少争议。但从另一些角度看,也未必是一件坏事。有太多人体验过在Steam疯狂打折时非理性地买买买,然后在面对一堆自己不会去玩的游戏时后悔不已。希望Steam做出的改变可以让玩家更加谨慎地考虑一个游戏在他们心中究竟价值几何,而不是在打折季中沦陷。
      这篇文章出自Axiom Verge的开发者Dan Adelman,他早就开始反思各平台疯狂的折扣和大量的低价游戏对开发者的影响,并写出了一些很有意思的定价建议。他的观点和立场颇有一些古典经济学的风骨:游戏定价的关键,在于正确预估你的游戏对于玩家的价值。
      希望他对Axiom Verge的定价和宣传思路能给各位游戏开发者一些启发。[indent]文章:On Indie Game Pricing
      作者:Dan Adelman[/indent]
      本周早些时候,我们宣布了发布Axiom Verge的消息。我和Tom为这款作品工作了6个月,我非常激动,所以我更能想象为它独自工作了5年的Tom此时激动的心情。大部分玩家给出的反馈都不错,但有些人质疑它19.99美元的售价。我写这篇博客的原因不是为了证明这个售价的合理性,而是为了阐释游戏定价背后的逻辑,因为这几年有许多游戏开发者向我咨询过该如何对游戏定价。
      我们应该如何定价……理论上

      经济学101的定价方法是十分简单直接的。你有一群潜在的买家,每个人都会对你的游戏价值进行一个独立的评估,如果你能完美掌握每个人心中最大的价格限度这个信息,那么你就能挑一个合适的价格点,使收入最大化(价格x销售量,价格上升,销售量就会下降,反之亦然),然后你就可以盈利。由于电子游戏的发售渠道是数字分发,所以一旦游戏完成,增加收入和增加盈利就成了一回事,因为成本已经固定了。多一份拷贝并没有真正使成本增加。
      如果人们心中愿意支付的最大价格高于你设置的价格,那么就皆大欢喜。如果人们的支付意愿等于你设置的价格,那么对他们来说,买不买你的游戏就没有两样。一些开发者和发行商试图在这其中保持平衡。对于那些支付意愿非常高的人,你可以提供像季卡、DLC或是其他产生高利润的道具去获取额外的收入。但我个人认为这件事很难做得非常优雅,虽然育碧、EA和Zynga对这种做法并不避讳。
      注意,在这种理论模型中,定价不是基于开发成本的。一直有一种说法,说AAA游戏应该卖得比独立游戏贵,因为它们的开发成本高。只需要稍加思考,就会明白这种说法毫无道理。首先,如果一个游戏定价太高,购买者的数量就会下降——这和你的开发成本无关。许多人认为高定价意味着能赚更多钱,所以定价高的开发商就是贪婪。
      第二,为什么玩家要关心一款游戏是多少人做出来的呢?如果我可以用魔杖在顷刻之间毫不费力地做出与Skyrim或者GTA:V同等规模与质量的作品,游戏体验会因此减少分毫吗?如果我花2000万美金做出了个垃圾app,难道它就更值得花钱吗?不,绝不是这样的。
      理论世界的难题
      经济学可以让我们理解商业决策的广泛方式,因为它不会纠结于细节。然而,当将其运用于真实世界时,我们就需要考虑其他因素的影响。顺便说一句,这不仅限于经济学这一门知识。
      最大的问题之一就是,游戏是一种体验式的商品,这意味着在人们体验到它之前,它的价值对他们来说并不重要。电影和书籍也是一样。消费者试图通过专家的评论、朋友的推荐、试玩、用户评分等等方式来解决这个问题,但他们都是不完美的解决方案。
      开发商和发行商认为,人们的最大支付意愿是一个非理性的价格(意味着他们的期待值过高),所以他们希望能不过多透露游戏信息,以尽量长久地保持这种期待。这就是发行商们在游戏发布前、甚至有时在发布或者预售后,都不愿放出游戏评论的原因。而通常的做法是,在游戏通过认证后就尽早发布。我们正在与Sony一起努力,确保评论家们差不多能提前一个月拿到游戏。
      想象一下,你在看一场棒球赛。到了比赛的关键时刻,所以你站起来以便看得更清楚,这很合理,这最大化了你的个人利益。但是你身后的人就有了两个选择:坐着看不见、或是站着看得更清楚。于是,为了最大化个人利益,他们选择站立,以此类推。最后,每个人都站起来了,没有人比之前看得更清楚,每个人只是更不舒服。
      同样的问题也发生在促销活动中。当销售量下降时,合理的方法是降低售价。很多游戏用这个方法赚了很多钱——实际上是赚了大部分钱。2011年Gabe Newell把他们的游戏售价降低了75%,他们的收入增加了40倍!
      但是,如果每个人都这么做,这最终将是一个通往底部的竞赛。玩家被训练成不会以全价购买游戏,像每个人一样,我对此充满罪恶感。通过捆绑销售模式,我在Steam上买了超过200个游戏,许多游戏我都从未玩过。(实际上有很多我都不知道我居然拥有它。我记得我在PAX上看到一个很酷的游戏,回到家我打算买下它,但我发现我早已经拥有它了。)现在有了PS Plus,我在PS4和PS Vita上又有了一大堆我并不真的想玩的游戏。而在App Store上,人们则在一堆0.99美元的游戏中眼花缭乱。
      有人会说,一个游戏从我身上获得收入总好过什么都没有,这个说法看起来似乎公平。但问题在哪呢?如果我们把销售看出是一个如同天上出现蓝月亮一般的偶然事件,那么游戏开发能获得可持续收入的根基也就不存在了。
      顺带一说,玩家会为了短期的自我利益而去特意等待打折。他们可以搭上那些付了全款的人的顺风车(或者是那些不能自给自足的开发者们),付一小部分的价格拿到同样的商品。不幸的是,这对玩家群体来说不是好事。如果玩家们坚持在折扣很多的时候买游戏,那么最终游戏的质量会受影响。看看App Store就知道了。
      除了最大化短期个人利益的理由之外,玩家等待促销也有别的原因。因为游戏是一种体验商品,在玩到它之前没有人能够确定它的价值,所以尽早玩到是有意义的。我想我们都曾经有过这样的经历:原以为一个游戏超级棒,但是打开之后只玩了5分钟。除非我们能有一种体面的方式能让玩家在玩过游戏之后调整支付价格,否则对玩家来说,这个问题的唯一解决方案就是等。
      我曾经想过一些改善的方法。或许是在完成游戏后的虚拟消费的打赏机制?或许是提供更多的购买商品?也可能是换一个思路——付全价然后允许玩家退款,只要他的游戏时长没有超出一定限度。(基本上相当于一个预付费的demo)没有哪个解决方案是完美的,但是开发者、平台和玩家需要认真地考虑这些问题,如果我们不希望被垃圾的海洋所淹没的话。
      个体的利益最大化诉求和群体的利益存在着一些不连贯,如果我们可以共谋并达成协议,规定每个人应当如何为游戏付费,我们会过得更好。幸运(或者说是不幸?)的是,这是不可能的。相反,我只是恳请开发者们认真考虑自己游戏的价值并有所坚持,然后给游戏一个合理的定价。而玩家们需要考虑这些游戏是否真的值得。不是考虑现行的折扣,而是考虑它们到底值多少。
      经济学理论描述了两种价格设置的主要模型。第一种正如我上文说过的,当你的产品非常优秀,市面上不存在真正的替代品,那么如果人们想要得到它,他们就只能付出你所设定的价格。另一种则是商品价格的模型,种小麦的农民无法到市场上去说服每个人,他的小麦比别人的好。他无法为他的小麦设定价格,他只能在当天的市场上看到如今的价格是多少。
      所以当你在为你的游戏定价的时候,首先想想你的游戏属于哪一类。你是在卖一样别处没有的东西吗?还是你在贩卖一个与大量的其他游戏相似的作品?如果是后者,你没有其他选择,游戏价格只能由当前市场价格决定。如果你的游戏是前者,那么你得确定你的游戏在读者心中有多重要。如果人们认为Axiom Verge的定价过高,他们一定还是会去玩别的游戏。然而其他游戏也不是Axiom Verge。(我对盗版这个话题避而不谈,那可以写一整篇文章)
      每当我在新游戏发售的新闻下看评论的时候,总会看到有人在评论里说他会等几个月,等到这个游戏打5折的时候再买。同样的情况也出现在PlayStation上,如今人们总是说他们想等到游戏对PS Plus用户免费时再下载。付全价买游戏的人如今基本上成了冤大头。
      我已经说过好些关于我前雇主任天堂的事情(不太好的那些),但我认为这些年来他们做得非常对的一件事就是,他们给玩家一个很明确的信号,就是人们不应该等待游戏降价。如果你想要在Wii U上玩超级马里奥3D世界,你知道它就是59.99美元(重申一下,我在这里忽略了二手游戏市场),这个游戏已经发售一年多了和它的售价没有关系。任天堂是一家能够制作无可替代的作品的厂商,然后他们给出了坚定的信号,他们坚持自己的价值。
      那么,有何建议呢?
      真正解决问题的第一步,其实发生在远比思考定价早得多的时候。你要制作一个必玩的游戏,毫无疑问这是一个所有开发者都强烈希望的,但说起容易做起来难。但是,让我们来假设一下你做到了,第二步该怎么办呢?
      第二步是确保人们知道你的游戏,并且知道它有何独一无二之处。这件事非常不容易,如何做的问题可以写成一整本书。部分工作涉及到你如何向全世界阐述你游戏的愿景,并把这种愿景真的做到你的游戏当中;部分工作则涉及到怎样让更多的人玩到它、并且让他们向自己的朋友推荐这款游戏;而还有部分工作则涉及到在游戏中留给人们足够的想象空间,让人们不会觉得全然了解你的游戏…然而现在,让我们假设你已经做到了全部,接下来呢?
      最后一步分两个方面。首先,设置一个你觉得适当的价格。如果你的游戏(对于那些想买你游戏的玩家来说)比Titanfall, The Order: 1886或者Destiny更好——并且你能说服人们相信这一点——那么定价权就在你手上。不要受到其他独立开发者的影响。(虽然这个问题一直争论不休令人生厌,但我还是要说,如今“独立”这个词已经有了很多的含义。它的所指可以从刚开始学编程的爱好者,一直到涵盖到Double Fine这样的成熟团队。所以你又为什么要在如此多元的范围内给自己设限呢?)
      第二点则有些反直觉。让人们知道你的游戏会在何时打折。我不会建议说永远不要打折出售你的游戏,降价促销有助于重新提起人们对游戏的兴趣,让人们再一次谈论这个游戏。在第二步中,有些曾经被好评稍稍打动过的玩家,会被降价所激励而去购买这个游戏。但这个方法应该有节制地使用,不要让人们感觉到他们应该等到游戏打折再买。而如果你告诉人们你的下一次促销会是什么时候,则会提醒他们做一个决定:这次降价值得等待吗?
      Axiom Verge是怎么做的?
      第一步:质量/差异化:当然我个人一定是怀抱偏见的,但我相信Tom Happ能做出一些让Axiom Verge与众不同的东西,这是一种没有替代品的游戏。但这并非由我来评判,就像我在上面说到的,你必须使出浑身解数保证对游戏感兴趣的评论家们能在发售前拿到一份游戏。如果我们做的是一个PS4版本,那么我们会为他们编一个PC版。我们会让他们对评论暂时保密,直到游戏发售大约一周前再放出。不要隐藏游戏评论,但要保证评论家们有充裕的时间去玩游戏和写评论。(我并不天真,我相信一定有那种玩了5分钟游戏就凭第一印象写评论的人,我希望这些人是少数。)我们要看看他们对游戏质量的看法。
      第二步:将游戏推到众人面前:现在,我们已经竭尽所能,Tom接受了很多很多的媒体采访。我们逐月地对游戏做媒体曝光,这样人们就能慢慢在发售前看到一些游戏的样貌。我们在E3和IndieCade这样的展会上展示游戏,我们带着游戏奔赴各地的活动:GDC、PAX East, 和 SXSW——在这期间,Sony提供了很多帮助:帮我们在PlayStation的博客上建立了一个讨论专区、在零售店里演示游戏等等。如果有一笔大的广告预算,那么我们或许能做到人尽皆知的程度,但如今我们也已经倾尽全力了。
      第三步:我现在已经把Axiom Verge玩了5遍,我觉得19.99美元是一个很合理的价格。(重申一下,可能有偏见!)在降价促销方面,我们暂时还没有公布我们的计划,所以可能我们也可以在这里说一下。索尼刚刚宣布, Axiom Verge将是春季优惠产品中的一个,对PlayStation Plus用户有10%的折扣。我对此感到很高兴,因为这是对一直支持我们的玩家们的回馈。但是在春季优惠的这一周过去后,6个月内我们不会再打折,再之后的促销计划还没有决定。说得更明确一些的话,就是在2015年10月之前,Axiom Verge都不会再降价促销了。
      通过公布这一点,我希望表达以下两件事情:第一,我希望玩家不会觉得他们全价购买游戏是一个错误。第二,我希望那些觉得19.99美元的定价太贵了的人们能够重新考虑一下、能有一个更明智的判断。如果你希望等价格降到一个程度,比如14.99美元,那么你需要衡量一下6个月的等待是否值5美元。对于一些人来说,这是值得等的,而对于另外一些人则不然。我觉得这样很好,我希望玩家能在信息充分的情况下做决定,而不是事后懊悔。因为我们需要消费者有个好的购买体验,对于这一点,我们和玩家是站在一起的。

    • 红茶君 1536

      当一个独立游戏工作室被25亿美元收购以后

      导语:我想很多人都已经看过了今年E3上微软演示hololens版的Minecraft。现在我们也已经知道,去年微软到底是为了什么花25亿美元买下Mojang。
      做独立游戏最童话般的结局是什么?也许Mojang的经历算是一个典型。从一小群人的特立独行开始,到最后的名利双收,绝对是一个可以拍成励志电影的剧本。世界上有几家工作室能有这样的好运呢?
      但是身在其中的人们未必这样想。
      以下是美国《连线》杂志上个月发布的一篇文章,记者写下了去年这笔轰动业界的收购案的另一个侧面——Mojang的员工在收购中究竟经历了什么?对我们大部分人来说,谈论一个25亿美元的收购是奢侈的(毕竟我们没有坐在创业大街的咖啡店里聊天)。但下面这个故事不同于通常的科技媒体对明星团队的报道,它或许能让你感觉熟悉和切近。我们会发现,在很多共同的问题上,独立工作室和商业公司并没有太大的不同,常人的烦恼和欲望、商业化的冲突和矛盾…一样存在于他们的每一个日常。 [indent]The Unlikely Story of Microsoft’s Surprise Minecraft Buyout
      作者:Daniel Goldberg and Linus Larsson原文链接:http://www.wired.com/2015/06/minecraft-book-excerpt/[/indent]
      去年9月,微软花25亿美元收购了Minecraft的开发商Mojang,成为游戏历史上最大的一起收购之一,让无数游戏玩家大吃一惊。这对Mojang的员工来说也是一个巨大的惊喜,纵然这个惊喜并非全然快乐。Daniel Goldberg和Linus Larsson,the definitive history of the game的作者,更新了他们的书卷,写下了Mojang独立时代最后的日子,以下采访的摘录记录了Mojang的员工在收购中经历的事。
      对于Jens Bergensten来说,未来的生活有种令人愉快的熟悉感。虽然Markus相比起初识之时已经改变了许多,但Jens看起来并未因此感到十分担忧。他现在正在负责一个全世界最流行的游戏项目,每天都有成千上万的玩家沉浸在这个游戏世界中。当然,Mojang的盛名也多少波及到他的生活,他会经常受邀到世界各地的大会演讲;有时,人们在街上认出他、和他聊天或索要他的签名。但他日常的举止态度仍然一如往昔,他话不多、心思缜密、有着微妙的幽默感,常常需要人转转脑子才能明白他的笑点。
      2014年的夏天已经接近尾声,Jens感到十分欣慰,因为生活中的一切都在他的掌握之中。
      然而这种感觉很快就会消散殆尽。一天,Mojang的CEO Carl Manneh把他叫住,与他一同进到会议室,让他坐下,并告诉他:三位创始人经过几周的认真考虑,决定要把Mojang卖给微软。这个消息对Jens Bergensten来说,简直是世界上最重磅的炸弹,他起初觉得不真实,当时他能听到Carl同他说话,但他感到无法理解这语言的含义。在他心中,Mojang是独立游戏界中一颗耀眼的明星,公司的创始人曾一遍又一遍地强调,赚钱不是他们的重点。Mojang做游戏是因为做游戏是一件有趣的事,他们有自己独特的行事方式。当然,他们有大笔的收入,但这也是为了不去做那些无聊的工作而存在的,不是吗?为微软工作显然就属于Jens一直想极力避免的无聊之事。
      他与Carl一起坐在会议室里,他只能静静听着。他还记得自己为了极力抛开心中的纠结,尽量避免去想今后的大计划,而是去考虑一些具体的小事:微软会怎么看自己和公司对开源代码的依赖?要如何去和同行介绍自己略显诡异的编程风格?他甚至坚持与Markus私下聊天,他需要确认这次他的朋友是认真的,这不是一个老板为员工精心准备的玩笑。
      Jens还记得他与Markus之后的那次谈话,他们关着门,在一个办公室的玻璃隔间中,沉着而冷静。他们谈到在出售公司的消息公布后,Minecraft的玩家会有何反应:有人会愤怒,有人会觉得遭到了抛弃。Markus会被打上卖掉公司的标签,会成为别人眼中为巨额财富而放弃理想的家伙。他告诉Jens他想远离网络一段时间,或许他只是暂时性地彻底失联,为躲开那些一旦消息公开、一定会找上他的辱骂。
      即将到来的公司出售事件,意味着Jens的工作时间将会被许多突然降临的任务占据。Carl立即就布置给他几项在收购完成前必须做完的任务。他需要回答微软的一些技术问题,并交出自己的代码以便微软检查。后一项是一个软件公司被出售时的标准程序,就像是二手车在被新车主使用前必须经过机械检查。微软需要确保在千万行使Minecraft正常运行的代码中,没有藏着令人不愉快的意外,比如偷偷摸摸的小把戏、或是对未来发展不利的workarounds之类。这意味着微软要检查第三方的一切,以保证他们是可信的。在合同签署、收购款到账之前,Mojang在微软面前将不会保留任何秘密。
      Jens还被严厉地警告过要保守秘密。Carl, Markus,以及 Mojang的第三位联合创始人Jakob Porser必须确保这次的交易不会因为走漏消息而搞砸。对于Jens来说,最痛苦的一点莫过于,他要坐在这间坐满着同事和朋友的办公室里工作,其他人对于这个重磅消息一无所知,而自己却无法告诉他们。他取得了创始人的信任,因而知晓了一个不太愉快的秘密,他非常想把这个秘密与他的朋友们分享,即使他的老板们告诉他务必保密。然而,他还是没有开口说出这个重磅新闻。Jens认为Carl首先告知他这个消息,是因为他需要Jens马上开始代码审查的工作,不然的话,在新闻公布之前,他们很可能也不会告诉他。
      微软深知,自己十有八九是很难留住Mojang员工的信任与忠诚。确保人们保守秘密只是其一,更重要的是,微软和Mojang都需要保证此事不会影响员工们专注于工作、或是使他们在收购宣布时离职。解决办法就是用大笔的钱来摆平——每位在微软收购Mojang后留在公司、并至少工作六个月以上的员工,将得到两百万克朗的奖金,大约相当于30万美金(税后)。换句话说,小笔财富是献给收购案的平安祭。但对于一些人来说,这还是难以阻止他们的离去。
      钱这个东西,和世上的所有事一样,是相对的。Jens并不是Mojang公司中唯一对薪水不满意的员工。实际上,许多人都觉得自己没能从Minecraft的巨大成功中分享应得的好处。当然,Mojang员工的福利已经比大多数人好了。Mojang为大多数员工安排的旅行足以让大多数人嫉妒。比如,在2013年3月份,Minecraft在PC平台和移动平台的销量都超过了一千万,这是两座重要的里程碑。为了庆祝,Markus带着所有的员工坐私人飞机去了摩纳哥。他们在那里开跑车、乘坐直升机、品尝香槟、在豪华游艇上开Party…所有的费用都由公司承担。
      然而,还是有人觉得,他们辛勤工作取得的好处,主要还是由Markus, Jakob和Carl分享了。三位创始人甚至没有和任何其他人分享公司股份,即使是那些从一开始就在Mojang工作的员工。这意味着Minecraft取得的巨大收益还是直接进了他们的口袋,即使Markus已经有两年没有做任何与Minecraft相关的实际工作了。所有员工都领正常工资,再加上Markus在慷慨时发给他们的津贴或是奖金。
      在任何其他公司这都是再正常不过的事。然而Mojang是不同的——或者至少给人一种与众不同的印象。这家公司在人们眼中是由一群团结而随和的朋友组成的,他们很有凝聚力且十分有趣,公司文化真诚而开放,没有谁特别关心谁管理谁的问题。在最初的几年,这些都是真的。但随着公司的成长,公司的气氛也变了,Mojang理想中的美好印象与现实如今分歧不少。管理层和员工之间的距离变远了。许多人不再将Markus,Carl,和Jakob视为与自己平等的、团队中的一员,而是将他们看作是管理人员。Mojang正在渐渐变成一个纯粹的上班场所。
      “管理层很擅长压工资。然而,他们告诉我们Mojang是一个好公司,我们能够免费去参加GDC、所有人都能收到圣诞节奖金”,一名Mojang员工在2014年夏天时对我们说。
      即使如此,人们还是留了下来,几乎没有例外。
      公司出售的新闻改变了Mojang。有人觉得遭到了Markus的背叛,公司士气倍受打击。“感觉像是到了世界末日”,一个在Mojang工作了很久的员工在新闻公布后告诉我们。
      Daniel Rosenfeld,更广为人知的是他的艺名C418,他是为Minecraft制作音乐的作曲家,他是第一个分享对Mojang出售一事看法的Minecraft相关人员。“宣布公司要出售的那天,我觉得我被Markus背叛了”,他在2014年秋天卫报的采访中说,他还补充说他如今能够理解Markus这么做的原因:“Markus只是想一个人做一些没人关心的小游戏。这倒是令我很受用。”
      官方通告只是公布了大家已知的消息,然而有一个重要的细节需要我们注意:Markus, Jakob和Carl三人,在收购完成后全都离职了。没有任何人来告知任何关于Mojang的未来规划或者承诺公司未来将如何发展。
      像Mojang这样的大型收购案,通常的情况下,都会有一些保障性的措施。这可能意味着创始人在收购后的公司董事会里占有席位,他们同意继续担当“顾问”的角色,或是简单地在所有权过渡期继续管理公司。这是为了避免在此期间有太多突然的改变,管理层中熟悉的面孔可以避免短期内员工、用户、合作伙伴中产生过多变数,而导致业务突然崩塌,这保证公司得以走远。然而微软和Mojang之间就像是几乎没有此类协议一样,三位创始人的来去显得高度自由。按常理,微软不太可能对Markus的突然离去不置一词。虽然我们不知道他们之间究竟如何商量,但唯一合理的解释就是,Markus从一开始就强烈要求,自己要在收购完成时就切断与Mojang的所有联系。
      对Markus来说,将公司交予别人并不像是出售后的缺点,反而像是他的全部目的。
      即使把公司卖掉、甩手不管是Markus期盼已久的宣泄,可他淡出众人视线的速度也未免太令人惊讶了。当微软派出代表团来到斯德哥尔摩访问Mojang时,Markus就不在。虽然几乎没人知道确切情况,但仍有一些传言说他前几天才刚刚和Jakob一起从拉斯维加斯回来。无论如何,他要么是疲于见人,要么是没兴趣现于人前。在新主人面前代表Mojang的任务落到了Carl身上。
      上午九点刚过,微软游戏工作室的总经理Matt Booty来到了位于斯德哥尔摩的Mojang总部。他带来了七个代表团成员,他们自我介绍后,Matt就开始讲解他的计划。每个代表Mojang的员工都专注地听着,尽管这个计划中有许多事他们也是初次听闻。
      为什么微软要收购Mojang呢?很简单,因为创始人想把Mojang卖掉。Mojang旗下的卡牌对战游戏《卷轴》(Scrolls)命运将会如何?让我们拭目以待。如此模糊的回答在外人看来似乎争议不大。但实际上,Jakob制作的这款集换式卡牌游戏在此前已经被讨论了很久。它已经拥有一个由几千名玩家组成的粉丝团,这对于一个独立开发的视频游戏来说,是个不错的成绩,但比起出于同门的Minecraft,它交出的却依然是一张失败的成绩单。
      据出席会议的人说,Matt Booty在讨论Mojang的未来时曾几次失言。他数次用Minecraft来代表Mojang整个公司,但很快他就纠正了这个错误。然而对于会议室中的其他人来说,这是尴尬的。他们当中只有不到一半的人直接负责Minecraft的相关工作。每一次这位来自微软的人将公司名字与他们旗下著名游戏的名字弄混时,他都在无意中强调一个众人故意避而不谈、却又显而易见的事实:是的,微软收购了整个Mojang公司,但他们只对Minecraft有兴趣。
      即使如此,Mojang的每位员工还是得到了相当慷慨的对待。此外,微软还向他们保证,今后两年都会按时足量地发放月薪,即使微软今后决定关闭斯德哥尔摩的工作室、将Minecraft的开发业务搬到雷蒙德总部,这一点也不会改变。然而,至少有一位员工拒绝了这份邀请。
      Mojang所有权正式移交的准备手续花了几个星期才完成。当签完所有协议、审查完所有代码,正式移交的日期也就确定了。从2014年11月6日起,Mojang再也不是一个独立的公司。
      所有权移交的前一天,正是Markus在Mojang工作的最后一天。几个同事正在办公,他起身离开。他犹豫了一会儿,不知该如何说再见。于是,他决定不说再见。在他的员工在座位上工作时,他起身走过外面的办公桌、走过放着许多奖杯和荣誉的展示架。他左转出了门、走下一小段楼梯、走出了这栋大楼。大楼的门在他身后关上,十一月寒冷的空气刺痛了他的脸颊。

    • Bowie 2594

      IL2CPP 深入讲解:代码调试之诀窍

      IL2CPP深入讲解:代码调试之诀窍
      IL2CPP INTERNALS : DEBUGGING TIPS FOR GENERATED CODE

      这是IL2CPP深入讲解的第三篇。在这篇中,我们将探索使得调试由IL2CPP生成的C++代码更容易的一些技巧。我们将看到如何设置断点,查看字符串(string)和用户自定义结构中的内容,以及异常断点处理。

      鉴于我们要调试C++代码是由IL2CPP将.Net的IL字节码转换过来的,因此做起来可能不会是一场愉快的经历。然而如果使用本文中说到的这些技巧,我们还是能搞清楚Unity项目中的这些C++代码是如何在目标机器上执行的。(在文章的最后一小段我们还会稍微介绍下调试托管代码的情况)

      和前两篇中提醒大家的一样,如果你的Unity生成的代码和本文的有所不同,请不要奇怪。随着每一个新的Unity版本的发布,我们都在尝试新的方法让生成的C++代码更好,更快,更小。因此产生的代码有所不同也就可以理解了。


      建立项目

      在本篇文章中,我会采用Unity 5.0.1p3,运行环境是OSX。采用的示例项目和前篇博文的一致,只不过这次目标编译平台切换到了iOS并且使用IL2CPP设置。还有一点和前篇博文一样:我勾选了“Development Player”选项,如此一来il2cpp.exe会根据IL代码中的名字来命名C++代码中的类型和函数,使得代码更容易理解。


      在Unity生成了Xcode项目之后,我们将其打开(我用的Xcode版本是6.3.1,不过这个无需一致,只要是近期的版本都行),在Xcode中选择目标设备(我的是iPad Mini 3,但是任何可识别的iOS设备都行)然后构建整个工程。


      设置断点

      在开始运行项目之前,我将在HelloWorld这个类的Start函数中设置一个断点。如同我们在前篇文章中看到的那样,这个函数的名字是HelloWorld_Start_m3。我们能用Cmd+Shift+O组合快捷键,在弹出的菜单里输入函数的名字,然后设置断点。如下图:

      当然,我们也能采用在Xcode菜单中选择Debug > Breakpoints > Create Symbolic Breakpoint来设置断点。


      当我运行程序后,我能立刻看到程序被中断在函数一开始的地方。

      只要我们知道函数的名字,我们可以在任何函数里设置断点。我们也可以在C++文件的特定的一行上设置断点。事实上,所有由IL2CPP产生的文件都在Classes/Native目录中。


      检查字符串

      在Xcode中检查IL2CPP字符串有两种方式。我们可以直接检查字符串的内存,或者我们可以调用一个libil2cpp的字符串辅助函数将其转换成std::string,然后由Xcode显示出来。那就让我们来看看名字叫_stringLiteral1的字符串里面是什么内容吧(剧透慎入!!字符串里面的内容应该是“Hello, IL2CPP!”)

      如果用Ctags 或者在Xcode中使用Cmd+Ctrl+J,我们可以直接跳转到_stringLiteral1的定义所在,发现它是一个Il2CppString_14类型:

      struct Il2CppString_14
      {
      Il2CppDataSegmentString header;
      int32_t length;
      uint16_t chars[15];
      };


      事实上,在IL2CPP中的所有的字符串都有类似的定义。你可以在object-internals.h头文件中找到Il2CppString的定义。这些个字符串首先包含了一个所有托管类型都有的一个结构头:Il2CppObject(在这个特定的例子中,Il2CppObject通过typedef,变成了Il2CppDataSegmentString),接下来跟着一个四字节的长度变量,然后是一个双字节的数组。字符串是在编译期定义的,像_stringLiteral1这样的字符串在编译期就决定了数组的大小,而其他一些字符串是在运行时动态的分配数组的大小。这个数组用的都是UTF-16的编码方式。

      如果我们在Xcode中将_stringLiteral1加入watch window,我们就能够通过“_stringLiteral1”的查看内存选项来窥其一二。


      在内存窗口中,我们看到如下内容:


      字符串一开始是16个字节的头结构,跳过这些之后,我们看到的是四字节的0x000E (14)。在这个长度之后就是字符串的第一个字符了,它的值是0x0048 (‘H’)。由于一个字符是两个字节的宽度(UTF-16编码),而在这个例子中所有的字符都是一个字节表示,所以Xcode在显示的时候在每个字符间加入了额外的点隔开。尽管如此,字符串的内容还是显而易见的。这种查看字符串的方式对于简单的内容来说没有什么问题,但是对于复杂的内容来说,就显得力不从心了。

      我们也可以在Xcode的lldb命令行中查看字符串内容。utils/StringUtils.h头文件中有我们可以使用的libil2cpp的一些辅助函数。我们可以在lldb中使用Utf16ToUtf8函数:

      static std::string Utf16ToUtf8 (const uint16_t* utf16String);

      我们将string结构中的chars成员作为参数传给函数,其会返回一个UTF-8编码方式的std::string。在lldb的命令行中,当我们输入p命令,就能看见字符串的内容了:
      (lldb) p il2cpp::utils::StringUtils::Utf16ToUtf8(_stringLiteral1.chars)
      (std::__1::string) $1 = "Hello, IL2CPP!"


      检视用户自定义类型

      除了字符串,我们也能查看用户自定义类型的内容。在这个项目的代码中,我们创建了一个C#的类型,叫做Important,里面有个成员叫InstanceIdentifier。如果我在创建第二个Important实例的地方设置一个断点,我能如期的看到InstanceIdentifier被设置成了1。


      所以查看用户自定义结构的内容其实和平常在Xcode中查看C++代码的方式没什么两样。

      在代码的异常处设置断点

      调试生成的C++代码的目的多半是为了找出程序中的bug。在许多情况下这些bug可以通过托管的异常机制得以发现,在前篇文章中我们也提到过,IL2CPP使用很多C++的异常来实现托管代码的异常机制,因此在Xcode中我们有几种方式来实现异常的触发。

      最简单的方法是,我们可以在il2cpp_codegen_raise_exception函数中设置断点,当托管代码抛出异常后,il2cpp.exe就会使用这个函数在C++中抛出异常。


      此时如果我让程序继续运行,Xcode就会因为抛出了一个InvalidOperationException异常而停在断点上(译注:首先你得像上图那样设置一个和异常函数相关的断点)。这个时候后刚才讲到的查看字符串的调试方法就显得格外有用了。如果我们深入看下ex参数的内容,能发现其有一个___message_2成员,说明的是这个异常的具体原因。


      只要稍许的提取一下,我们就能将这个异常问题的内容打印出来:
      (lldb) p il2cpp::utils::StringUtils::Utf16ToUtf8(&ex->___message_2->___start_char_1)
      (std::__1::string) $88 = "Don't panic"


      需要注意的是,虽然这里的string结构和前面的一样,但是里面的成员名字有所改变。前面的chars成员现在变成了___start_char_1,而且类型不是uint16_t[]数组而是uint16_t(译注:原文中使用的是uint16_t,但实际上应该是uint16_t*,也就是其指针),其实它还是指向了字符数组的第一个字符,所以我们也还是可以把它传给Utf16ToUtf8函数得到可阅读的字符串。就这个例子而言,其显示的信息(Don't panic)还是令人感到安慰的。

      不是所有的托管异常都会显示的被C++代码抛出。libil2cpp在某些情况下还会抛出不调用il2cpp_codegen_raise_exception函数的异常。我们如何捕获这些异常呢?

      我们可以使用Xcode菜单中的Debug > Breakpoints > Create Exception Breakpoint,创建一个异常断点,然后将类型选择成C++并且设置成Il2CppExceptionWrapper丢出时触发中断。由于C++的这个异常接手所有托管代码异常,所以我们可以在这里发现所有的问题。

      让我们在Start函数中加入如下两行来进行一个验证:

      Important boom = null;
      Debug.Log(boom.InstanceIdentifier);

      代码的第二行会导致一个NullReferenceException异常抛出。当我们在Xcode中运行的时候,我们会看到代码确实停了下来。因为断点是在libil2cpp中,所以我们看到的都是汇编码。没有关系,我们还可以看看线程栈。在线程栈中向前走四个调用,我们会发现NullCheck方法,此方法是il2cpp.exe在代码生成的时候主动注入的。(译注:具体注入的细节可以参考前篇博文)


      由此再上一层,我们就能看到我们的Important实例的值确实是NULL。


      小结

      在讨论了一些调试生成代码的小技巧之后,我希望你在跟踪定位由IL2CPP产生的C++代码问题上有了一个更好的理解。我鼓励你去查看下其他的由IL2CPP产生的类型,熟悉下调试他们的方法。

      那托管代码呢?我们难道不能直接在设备上调试托管代码吗?实际上,这是可能的。我们有一个内部的处于开发阶段的托管代码调试器。这个调试器还没成熟到发布的阶段,但是它在我们的计划之中,如果你感兴趣,不防关注下。

      在下一篇文章中,我们将介绍对于托管代码中不同的函数调用, IL2CPP是如何区别对待实现的。对于每一种实现,我们会着重关注其运行时的开销如何。



      原文连接



    • 君子雷雷 1151

      【indienova】本次 E3 上 IndieCade 展出的部分独立游戏(第一部分)

      更多独立游戏资讯请关注indienova.comIndieCade 今年也高调参加了 E3,并且展出了一些最近比较受关注的独立游戏。今年明显展出移动设备上的游戏比较少,而 Windows、Mac、Linux 以及 PS 平台游戏占大多数,同时还有 VR 类的游戏参加展出。另外还有不少装置类和线下游戏。我们选了一部分值得关注的游戏列在这里,供大家对这次展出的大致情况进行一些了解。根据目前国内关注的情况,对 VR、装置类和线下游戏类做了些删减。IndieCade 展台的与众不同之处在于,开发者就在自己的游戏旁边,可以直接和玩家进行交流和互动,这种机会可是非独立游戏玩家很难得到的,所以现场也是非常的热闹。而且说实话,好多独立游戏不管从题材、立意和执行方面来讲,其实也有超越 3A 大作的方面。也难怪,这次 SONY PlayStation 就是主要的赞助商,他们早就看到独立游戏的潜力,而且知道独立游戏会成为他们的强有力的支柱之一。以下是一些现场的照片: 在《幸运枪手》中,你的运气会影响到你周围的世界,运气好的时候,敌人射向你的子弹会偏转,遇到陷阱会自动规避,同伴鸭子也会给你提供援助;运气不好的时候,桥梁会崩溃,岩石会落到你头上,你的枪会哑火。《幸运枪手》中的幸运是非常有趣的设定,收集金币会让你在各种危险面前安然无恙,还会影响到你装填子弹的质量,但你运气爆表的时候,你的手枪中每一发子弹都会命中敌人(会拐弯);运气不好的时候你需要谨慎前进,任何一个陷阱对你来说都是致命的,非常有意思。(介绍及视频)注:部分展会照片来自 IndieCade tumblr。

    • 红茶君 1796 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演讲中一些精彩的片段(文字版)。

    • 红茶君 1703 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 1048

      游戏圈业内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