圆胖肿付费游戏作品《萌版特攻》浅析(一):分发二进制

圆胖肿付费游戏作品《萌版特攻》浅析(一):分发二进制

前言

笔者今日开始对圆胖肿的商业作品、Steam上架游戏《萌版特攻》的正式版本进行一些没什么技术含量的粗浅分析。本系列文章不包含对圆胖肿个人的评价或攻击,分析也尽量以此游戏为原作者首部商业化游戏作品的角度考虑,绝不刻意为难原作者。笔者个人在游戏客户端领域主要以快速迭代、适配、分发大小优化与热更新流量优化为深入方向,观点可能较为片面。笔者希望能与作者及广大群众一起和平探讨,互通有无,共同成长。

作者在游戏发售前后写了很多文章介绍心得,知乎上就至少有如下两篇,外加Live等。其它游戏论坛和技术论坛也有一些,有兴趣的可自行搜索。看得出来作者对作品还是很上心的。

圆胖肿:用Java制作一款Steam上的游戏zhuanlan.zhihu.com图标圆胖肿:用Java制作一款Steam上的游戏(二)zhuanlan.zhihu.com图标

购买、下载与概览

该游戏在Steam上的名字是Xtrike,游戏内可见中文名《萌版特攻》。截至2020年1月21日的最新版本为0.7。售价15元人民币,刚好是巫师1+巫师2的节日价格。笔者思考再三,还是忍痛下单,该作品因此正式成为笔者在Steam上第510个游戏。

120.3MB的下载大小与350MB的安装后大小让笔者一惊。《部落冲突》的2012年版本在包含三套资源的情况下,即非Retina iPhone(480x320)、Retina iPhone和iPad前两代(960x640、1024x768)、Retina iPad(2048x1536),包体只有50多兆。特别值得注意的是,在Retina iPad上的资源是真正的全高清资源,而非当前(2020年)国内手游厂商普遍采用的720p、750p级别的UI资源,某大厂著名IP作甚至采用540p级别的资源。那么这120M究竟包含了哪些内容?

我们就从游戏根目录开始。

  • 从截图可以看到,作者在打包时没有剔除macOS生成的.DS_Store文件,Idea的本地工程目录.idea也没有删除,.vertx是空的,问题不大。
  • 为什么有个audio又有个sounds?这个稍后具体分析。
  • com显然是class所在目录,libs显然是jar所在目录。
  • config实为本地化文本目录。
  • fonts自然是字体目录。
  • scriptslinuxrtmacrtwinrt就是Java运行时二进制目录及启动脚本。

接下来再对各个目录进行详细分析。

音频

刚才笔者就对疑惑同时存在的audio和sounds产生了疑惑,进入一看,果不其然,audio中所有的文件在sounds中都有一份完全一样的拷贝。那么我们就认为游戏实际最多只需要4个音频文件,我们就对这四个文件进行分析。

四个文件包含了两种音频格式,单声道与双声道共存,VBR、CBR共存,采样率不统一。其中的battlefield.wav的元数据还未删除,可以搜到该音频来自网上。无论是wav,还是双声道,还是CBR,对于如此体量的游戏都是没有必要甚至是画蛇添足的。我们统一进行一下优化:裁去收尾空白部分,44100Hz采样率、单声道、导出为约48kbps~56kbps的VBR mp3。

操作完毕,效果还是很明显的。

class与jar

一般对于Java项目,这块不必花太多精力,但是追求极限的话,可以进行如下操作:

使用脚本将jar全部解包,剔除无用文件,批量压缩媒体文件(在手游SDK中常见),重新封装为单个fat jar。此操作也并非总是可行,根据所用jar不同,有可能出现冲突,这块本文不作展开。

另外部分库对于本游戏不是必需的,强烈建议作者精简一下。

本地化文本

启动界面的这么几条文本这么处理还勉强可行。

但恕我直言,其它文本这么做就很糟糕了。

本地化的过程中,肯定是无法保证手工拼装的顺序一定符合当地的语法。就以等级为例,如果英文是 Level n,中文是 第n级 呢?如果文本中有多个变量,且不同语言中的顺序都不同呢?

国际化与本地化的文本部分,我只推荐小胡须进行格式化。

{{ mustache }}mustache.github.io

常见编程语言都有小胡须的库。本文就不对其用法进行介绍了,各位可自行查看。

字体

作者集成了 站酷庆科追梦体站酷高端黑 ,在商业化产品中使用这两个字体应该是侵权的。此外通过分析刚才的本地化文本可得知,游戏只出现了屈指可数的几个中文字符,因此如果只是喜欢特定字体的英文数字字形,可自行裁剪。或使用bmfont。中文也可按相同方式处理,只保留对应字形;或是干脆出成图片资源。无论是什么做法,最终生成的资源只有几十KB大小,比起目前的大几兆来说真的是九牛一毛了。

图片

  • 作者没有使用Sprite Sheet,当然作者不知道是很正常的事情,这里不作指责。完全不使用Sprire Sheet会带来诸多不良影响,相信游戏客户端与Web前端的同学们都知道。除此之外,有的不足还是要提出来的:
  • 部分特效、单位、UI的资源混在一起。不仅不利于将来打成Sprite Sheet,也不利于对资源的文件管理,比如作者显然没注意到battle/landscape中的UI资源在battle里已经存在了。
  • 特效用序列帧来实现,这点也不能说是错或者怪作者,但是特效的尺寸应考虑到实际播放的大小,帧数也应考虑到实际播放的时长。有的效果可以考虑使用粒子。
  • 作者也知道单位的动作不需要为整个单位创建序列帧,但是实际操作时还是偷了懒。

请看unit/helicopter/apache,就这三帧,值得出三张直升机本体吗?明明只需要替换前后螺旋桨就可以了。而在同级的unit/helicopter/chinook,就要好很多。

  • UI图片不可定位锚点

以此按钮为例,为了按钮的阴影,按钮的本体是偏图片的左上方的,造成视觉上的中心并不在图片本身的中心。实际项目中通常在左边和上边也会留出合适的空白区域保证按钮本体是水平居中与垂直居中的,至于空白区域的浪费?打成Sprite Sheet就没这问题了。

  • 图片有极大的压缩空间。作者既未对图片进行文件大小优化,也未进行纹理压缩。考虑到游戏目前面向桌面端,我们尝试进行文件大小优化,画质的损失通常难以察觉。
  • 如有可能,上骨骼动画还能进一步较少美术资源的大小,同时拥有更佳的表现。这点也不能强求作者在首部作品中实践。

运行时

在Windows平台并不需要linux及mac的运行时,这里直接能砍掉2/3的运行时大小。有意思的是,作者保留了运行时的legal,希望作者对待字体或者其它资源也能一视同仁吧。

最终成果

如上所述,目前只对资源进行了浅度的优化调整,但是最终对比还是相当明显的:

安装后大小减少到28%,下载大小(LZMA固实,要比Steam的小)减少到25%。如果不算Java运行时以及非必需库,实际的内容至多只需几兆。真正实现了圆胖肿到细竹竿。

总结

今天对圆胖肿的游戏作品的分发二进制进行了粗浅的表面分析,发现无论是资源还是实现方式上可能都有很大的优化空间。在今后的后续分析文章里将对游戏其它方面进行分析,敬请期待。

发文一日后更新

游戏作者已修改分发与版权等等问题,并于昨晚连夜更新了Steam版本,并在本文下方留言,在此表示感谢。由于留言过于分散,笔者在此统一回复游戏作者。笔者不是盯着几兆十几兆的几个资源不放,是以此游戏为例探讨分发过程中的优化可能性。市面上体积庞大的手游、桌面端游戏不在少数,而实际上笔者认为大部分都可大幅瘦身。作者的游戏如果更新下去,资源达到当前的几倍大时,瘦身就显得很重要了。最主要的是,下载大小对于用户的心里预期有着不小的影响,较小的下载大小能降低一些用户的心理预期,使得评价不至于太难看。

此外关于内存占用,文中也提到,游戏往往大量采用压缩纹理,这种情况下文件的压缩比通常不会这么夸张,但是动点心思还是有优化空间的,比如启动时将位图数据重新编码转换等等。压缩纹理及转换等相关文章很多,本文不讨论。

第二篇更新

超人张宝胜:圆胖肿付费游戏作品《萌版特攻》浅析(二):Title Screenzhuanlan.zhihu.com图标

编辑于 2020-01-31