_GASTER☜_ 纪念账号00001
关注数: 18 粉丝数: 118 发帖数: 4,131 关注贴吧数: 21
教学:GMS2的另一种编译模式——YYC编译 转自B站,已取得作者本人同意 原地址:http://tieba.baidu.com/mo/q/checkurl?url=https%3A%2F%2Fwww.bilibili.com%2Fread%2Fcv16211736&urlrefer=3ea36f496fb06f23e50054fda598a89e 一、什么是YYC编译? YYC(YoYo Compiler)编译是GMS2的两种编译模式之一。 GMS2其实提供了两种编译模式,一种叫做VM(虚拟机)模式,另一种是YYC模式。许多人甚至可能都没有注意到YYC模式的存在,这是很合理的——VM模式是GMS的默认编译模式,而YYC模式的启用则要求你在GMS界面的角落里点上它。 此处我们不多谈其编译本质。那不是我们的中心内容。我就简单介绍一些YYC模式的好处: YYC模式下,程序的执行效率会高得多。 YYC编译时做了数不胜数的优化工作。YOYOGAMES没有公开技术细节,但是执行效率的提升是确凿无疑的——VM模式下的GML执行效率只能说可堪入眼,而使用了YYC模式之后的GML执行效率甚至能与C系的执行效率碰碰——若是各位有兴趣,可以利用GML中的delta_time这一内置变量做点测试,看看执行效率的变化。 YYC编译从根本上就杜绝了反编译的可行性。 请不要相信任何告诉你YYC模式的程序可反编译的言论。它真的不能反编译。 在本质上来讲,VM模式输出了字节码,而YYC则直接输出机器码。计算机语言由底层至高层分为四级,依次是机器语言,汇编语言,高级语言还有脚本语言。YYC直接输出到了机器语言这一层,所以当我们谈及“拆”YYC程序时,我们谈的应该是反汇编。 不过,即使你走到了反汇编这一层,花了大量的时间去学习反汇编技术,你实际上也拆不出任何有意义的内容。现行理论不认为这是可能的。 说到这里,YYC模式似乎百密无一疏,只有好处,没有坏处,这种想法当然也是错误的——如果YYC模式真的只有好处,为什么YOYOGAMES会将VM模式作为默认编译模式? YOYOGAMES在手册中是这样写的: YYC: The YYC (YoYo Compiler) takes the normal GameMaker output and compiles it into native code for the target platform, "stripping out" unneeded functions and performing a host of other optimisation techniques to create a smaller and performance enhanced executable package. This can increase your games performance by at least two or three times, especially on logic-heavy games, and is ideal for those larger or CPU intensive projects. Compile times may take longer and you should always clear the compiler cache before building any final complete asset package for a target platform. Note that the YYC target may require extra tools to be installed for the platform selected, otherwise it will not work. YYC:YYC模式接受常规的GM代码,再将之编译为目标平台的机器码。它“剥离”掉游戏中不需要的函数功能,并执行许许多多的其余优化项目,从而创建一个更小又更高效的程序包。这可以使你的游戏执行效率提升至少两到三倍,对那些逻辑型代码和大量消耗CPU性能的代码尤为有效。编译的时间可能会更长,而且在这么编译以前,你永远应当先清空你的编译器的缓存。请注意,YYC模式可能会需求额外的工具来为你所选的目标平台输出,否则它就不会起效。 (专栏作者译,信息可能失真) 这么说你应该就明白了。YYC编译的编译时长要比起VM编译长很多(这意思就是说,虽然将程序打包给其他人以后,游玩时的执行效率会很高,但是打包这一过程会很漫长),所以YYC并不该作为平日里在开发程序时使用的编译模式,除非你希望每次在编译时都要等上好几分钟乃至几十分钟。 此外,上述我提及了YYC模式输出的是机器码,不存在把它们变成具有良好可读性的代码的可能性,所以在YYC模式下你自己也没法方便地进行bug处理工作。 实际上,YOYOGAMES的设计初衷就是将VM作为开发程序时的调试模式,而在最终发布你的作品的时候使用YYC模式来发行它。 二、我该如何使用YYC模式? 在一个不是非常起眼的角落里。勾选完成后,右上角原先为VM的字样会变为YYC。 不过不要高兴地太早。如果你兴冲冲地在勾选完以后立即去编译了个程序想看看效果,那么你大概率只会得到报错警告,连程序界面都不会弹出来。 这段报错信息一般是这样的(实际上会视你的平台目标不同而有所变化,此处以Windows目标平台举例): 为什么会这样报错呢?这和YYC编译的本质有关系——对于Windows目标平台而言,YYC编译的本质是把GML代码转换为C++代码。但是光是转换成C++代码是不够的:C++代码也是高级语言,还是得经过编译。而在此处,GMS只是做了一个把GML代码转化为C++代码的工作,GMS本身并没有内置C++代码的编译器,所以你需要为它提供Visual Studio来作为C++代码的编译器。 安装Visual Studio的过程不是本篇教程的负责范围。实际上,如果你真的没有安装Visual Studio的能力的话,不解决智商问题。 安装完毕以后,请进入GMS2的“偏好设置”选项,为GMS2给出它需要的文件的所在位置。非Windows平台请类比此方法 在这一切配置完成以后,GMS2就有能力进行YYC编译了。 不过——极为不幸的是,尽管你的程序可以运行,但是往往会在一些奇怪的地方出问题:比如某一处的instance_create_depth()函数生成了一些骇人听闻的,你根本没有填写进去的object的实例。 这就是YYC编译真正的障碍。其实上述的问题都不算什么。 三、YYC编译真正的障碍? YYC编译真正的障碍在于:它可能会生成一些你根本没有写过的代码。是真正意义上的没写过的代码:你可能要求生成obj_a的实例,但是结果是生成了obj_1的实例。这都是很常见的。 这倒也不能太责怪YOYOGAMES。跨语言转化代码本来就是个不太靠谱的事情,更何况这还是机器批量转化,并没有谁坐在这条流水线上监工。 值得庆幸的是,我们有能力减少这种错误的发生。如果做得足够好,我们甚至有能力把这样的错误减为0. 人人都有代码风格。有的人喜欢用四个空格代替tab,有的人喜欢大驼峰命名,有的人喜欢花括号单列一行。不同的代码风格为我们带来不同的阅读体验,在此处,同样地,YYC编译器也会因为你的代码风格而无法理解它。 YYC编译器需求的代码风格大都是较为良好的代码风格:比如要求你在行末添加分号,要求你使用双等于号作判断而不是用单等于,等等。但是除却这些风格外,YYC编译器还会需求另一些代码风格。 四、YYC编译的“特定代码风格”? 其实这一栏才是重头戏。 免责声明:笔者四处寻找过YOYOGAMES有关YYC编译器的说明,得到的信息却相当之少。也许YOYOGAMES的确发布过完整而具体的代码风格要求,但是笔者并没有找到。接下来所陈述的代码风格要求,只不过是笔者本人和几位共事者的开发经验外加咨询了一些界内人士所得的。 1.在行末添加分号。2.在进行逻辑判断时,使用双等于而不是单等于。3.如果你的表达式较复杂,那么就使用括号来说明你的运算顺序。 YYC不一定能够清晰地理解你想要的运算顺序,这就可能导致你的运算得到一个错误的结果。请使用括号来明确地告诉YYC你想要什么顺序。4.把你的参数“显式地”传入进函数。 此处的“显式”不是指计算机术语上的那个显式,而是指“明确地”,“清晰地”。这也是YYC编译要求的码风中最为奇怪的一点。 我们在编写GML程序时,很常见的一种写法是这样的: instance_create_depth(random(640),random(480),depth,obj_example); 这段代码会创建一个坐标随机的实例,但是这种语法对于YYC而言可能就有点困惑了。我们在此处将random()函数的返回值作为了instance_create_depth()函数的参数,进行了一次函数嵌套——而YYC可能无法完美理解嵌套。 为了避免这种嵌套,一个自然而然的思路是: var x_random = random(640); var y_random = random(480); instance_create_depth(x_random, y_random, depth, obj_example); 很有趣。 5.即使你的表达式并不是很复杂,也建议把它们加上括号。 我们经常写出这样的代码: a = b + c; 在99.999%的情况下YYC也确实能够正常理解它。只是为了这最后的0.001%的可能性,你还是得多花一步,写作: a = (b + c); 6.使用其他的官方手册中所倡议的语法。 官方手册中其实有很多不为人注意的细节。很多人清楚"?"是ds_map的访问器,也知道"|"是ds_list的访问器,但是很多人都不清楚数组也有其访问器"@",用于避免数组拷贝。 这种细节实在是太多太难以罗列了,请原谅笔者在此无法详细举出。 五、后记 事实上,即使你完全遵照上述要求,错误依然是可能出现的——YYC编译目前仍然处于非成熟体的阶段。遇见这种情况,如果你认为你的代码都已经遵循了上述要求的却依然报错的话,尝试清空编译器缓存,或者重启GMS2,或者重启电脑。有时这就会让一切解决。也有的时候你可能只是在某个脚本中写入了gml_pragma("forceinline")让它转为内联编译它就解决了,这都是说不准的事情。 你可以考虑用邮件联系YOYOGAMES的官方。他们其实是会处理客户问题的。 即使YYC编译的毛病颇多,YYC编译为我们带来的巨大执行效率飞跃以及100%不可被反编译性依旧值得我们尝试。 如果你遇到了难以解决的问题(注意:不解决智商问题),或者你对YYC编译有进一步的研究,笔者极其欢迎你在评论区说出它们,或是私信本B站账号。 本文遵循CC BY-SA 4.0协议。 感谢阅读。
[通知]MAS0.11.3版本于2020.07.04早晨发布了! [什么?你觉得标题格式很眼熟?哦,我说过我会包了以后的更新通知/翻译的] [另外其实还有个0.11.2版本,这两个版本之间发送间隔很短,所以我就忽略那个了] [再另外,我不会翻译所有的内容,有的小东西我估计你们也不太在乎就不翻了] [依然是二楼放原文] 1.增加了日出/日落效果,是个持续三十分钟的渐变效果。估计会很酷炫,还没实测。 2.如果你选了静态的背景和天气,现在不会因为重启而改变了。 3.如果你添加过背景,背景版选择器(详见0.11.2)现在会被自动解锁。 4.添加了........“歌曲分析模块”,这意味着你现在可以和Monika讨论某个曲子了(实际用法不明,难道智械危机真要到来) 5.选择“随机歌曲”时会优先选择你没听过的。 6.那些会被消耗的物品现在有了最大值(就是以前你可以一次送114514个coffee以让她永远用不完现在别想了) 7.各种输入文本的地方(比如取名之类的)直接有个Nevermind(就当我啥都没说)按钮,而不是需要你输入Nevermind. 8.以前可以通过在第一次取名时直接输入那些“不太好的名字”来成功取名(之后会被Monika婉拒),现在别想了 9.加了一组话题,关于“pool of pool”(实在不懂怎么翻译),这有助于让新玩家有交互感。 10.“pool”每次增加的量变成了五点。 11.选择性别时可以选择.......“跨性别”。字面意思。 12.加了一些新话题。自行前往二楼找那些monika_XXX了解。 13.马上回来选项中多了以下几个选项: 1):我要去做作业 2):干点事 3:)打盹 4:)锻炼/运动 5:)编码(说实在的,我不太觉得会有多少人选这个吧) 14.加了六个新的fun fact(有趣知识),6首新歌,1个新问候语。 15.如果你告诉过Monika你吸烟,后来又戒了烟,那么会有些新对话(不会吧不会吧这个青少年占主体受众的游戏真的有人吸烟吗)
【大新闻】YOYOGAMES决定发布GMS5! 今天,YOYOGAMES在GKD大会上宣布了<GameMaker:Studio 5>即将发售的消息。YOYOGAMES首席执行官Toby Box在大会上称,“去年,随着GMS4的发布,Unity4D在我们的产品面前也显得苍白无力,现如今GMS4已经成为了银河系中最强大的游戏引擎,甚至在近日的4.62003版本更新中足以令使用者在几分钟内构建一个大型4D游戏,但是这依然不是我们的极限!我们已经在暗中研发好了GMS5,并即将发售!” 据了解,GMS5在曾经用口语编程的基础上又进一步降低了门槛,现在甚至支持使用者使用语音编程,使用者仅需口述出自己所想要的代码效果,即可自动生成对应的GML代码。实际上,这并不仅限于代码!你甚至可以向新版本的精灵图像编辑器描述你想要的精灵图像,在那之后,它甚至可以直接生成你想要的精灵图像!在曾经的GMS4,这还只是一项试验性的,不稳定的技术,现在通过大数据采集,出错率已经降低到了每千万亿次出错一次的概率! 另外,YOYOGAMES称,籍由YYC编译的改革,现在他们已正式推出了由他们自己所生产的新型计算机,GMS5的使用者可以用YYC编译生成仅可在这种计算机上游玩的程序,但这种程序的执行效率是以前的GML的2077倍不止! 由于巨大的算法优势,目前GML已经成为了一切计算机程序的编制通用语言,想到这一点,我们难免不提到曾经的C语言,在当时,那是一种被认为是“万物之母”的语言,然而现在GML的独立已经证明了一切非GML语言的脆弱不堪。 Gamemaker之父Mark Overmars在YoyoTwitter上表示,GMS4已经让YOYOGAMES的足迹遍布每一个银河系的角落,这一次,GMS5的出现必将让YOYOGAMES扩展到跨宇宙企业。
关于GMS2 YYC编译的研究 GMS2在输出游戏时提供两种编译模式,一种是VM,也即默认编译模式,一种是YYC。 VM就是字节码,这样的输出虽然快,但是有被破解的风险。 YYC则是将GML转化为cpp进行输出,尽管编译时间相比VM来讲长的多,但是造出来的程序是几乎不可能被破解的,此外,YYC游戏的处理效率远高于VM编译。 因此,有时候使用YYC编译就显得很必要了。 这里给不知道的同学们提一下,切换地点就在GMS2的右上角,那个像是个瞄准器的图标,点下去,在Output窗口中切换为YYC即可。 但是,YYC有很多毛病——这也是我今天要讲的问题。 有时候,你在VM中编译起来毫无问题的游戏,转入YYC后,你会发现bug奇多——而且这些bug不是你能想象的。例如,instance_create_depth与instance_create_layer,往常,哪怕你的代码再混乱,最起码创建的实例也是正确的。 但是,在YYC中,可能它创建的实例根本就不是你想要的。你填的是obj_123,它有可能给你创建obj_456。实际上,这还不是最糟的,它最后的运行结果可能会比这还要可怕的多......包括但不限于出现死循环,出现你根本没调用的函数——从某种意义上,它的创造力比Shader的创造力还强。 这就是我们今天探讨的问题:到底该怎么减少这种错误编译? 仅据个人研究,如果你的码风(代码风格)符合“某种规范”,可以大大减少这种错误率。 首先,你必须尽一切可能地减少那些不符合大众所认可的码风,包括但不限于:语句中不能省略括号,逻辑判断必须使用双等于,每一行结束后添加分号以示结束...... 但是这并不是我们所需要的全部。即使你完全遵循这些公认码风,YYC的编译依然会出错。 以下是某个示例:这是可以在YYC中运行的代码(注意图中仍然有些问题,如等于号前后的空格问题)。 这些代码有个很奇怪的现象,第六行,第七行的临时变量似乎是完全不必要的,你完全可以在下文中的instance_create_depth中将它们替换掉,不是吗? 按照常规理解确实如此,但是,事实证明,如果我不这么干,在执行这里时,创建的实例是一个叫做“obj_system_heart”的实例。 事实上,各种平日里可以在函数里直接写入的表达式,似乎都必须使用一个变量储存表达式的值,然后在函数内写入变量......反正很莫名其妙。 现在,我想请教的问题是,还有什么码风是能降低YYC编译错误概率的?又或者不是码风,总之,什么能规避YYC的出错? (是的,这其实不是个科普贴,是个请教问题的贴子)
1 下一页