秀技术,把Cocos C++和Lua游戏编译到浏览器上跑?!

Posted COCOS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秀技术,把Cocos C++和Lua游戏编译到浏览器上跑?!相关的知识,希望对你有一定的参考价值。

今年2月份WebAssembly的MVP(Minimum Viable Product)发布,这个核并没有包含WebAssembly组织所计划的所有特征,而是提供了可以使WebAssembly稳定运行的基础版本。随着苹果和腾讯入局,基本上WebAssembly在移动端的应用已初具外部条件。

 

Cocos早在2013年5月就在Zynga工程师的协助下支持了Emscripten,将游戏整个编译为ASM.js。随着Emscripten工具对WebAssembly的支持延伸,Cocos游戏也可以无缝支持WebAssembly。这无疑给众多Cocos原生游戏开发商打上一针兴奋剂,终于有机会可以弯道超车低成本到达Web平台。现在原生游戏白热化激烈竞争的态势下,无疑又是一波及时雨。


那么WebAssembly这个停留在实验室阶段不算短时间的产品,在html5游戏领域中形成霸主地位吗?今天来看,机会和前景不错,可能是一个HTML5游戏的下个拐点,但目前不少的现存问题导致大规模的使用仍为时尚早。商业作品的使用方面,目前建议是提前探索,谨慎使用。

 

WebAssembly在游戏领域的应用和痛点

 

Cocos游戏,今天在WebAssembly的应用上,大致有两种情况:

1. 整个游戏编译为WebAssembly,包括C++游戏或者Lua游戏;

2. 部分模块采用WebAssembly取代javascript

 

路线1:原生游戏直接编译为WebAssembly


目前Cocos的CPP游戏,Lua游戏可编译为WebAssembly,原生游戏开发商可能暗爽,不小心抄了个近道,欧耶。


社区里面已有开发商在配合Cocos引擎团队进行这个路线的探索,引擎提供了平台适配层的工具,简单合并之后,用Emscripten工具编译出WebAssembly版本,就可以到达支持Web。通过引擎自带的性能测试例进行比较,WebAssembly版本的性能提升会比纯JS版本快50%以上,内存使用上也更小更稳定。

秀技术,把Cocos C++和Lua游戏编译到浏览器上跑?!这个路线,由于游戏逻辑基本都集中在WebAssembly内部,可以很好的避开WebAssembly目前的两个痛点:

•   WebAssembly和JavaScript的交互性能低下

•   随着对JavaScript API暴露数量的增加,

WebAssembly代码体积会急剧增加

 

目前,当WebAssembly需要和JavaScript进行相互调用的时候,开销很大,就算数据交互同ArrayBuffer进行交互也没有太大效果,WebAssembly组织也意识到这个是大问题,但是未来什么时间点可以解决,目前还未知。


这种模式下运行速度还没普通的JavaScript运行得快,原因是现代的JavaScript引擎已经是高度优化的。因此如果游戏需要和JavaScript有大量协同工作,当前的WebAssembly还尚未具备可生产的阶段,当然如果只是一些非核心关键路径上的少量交互,那么这个速度还是可以容忍的。

 

在游戏包体方面,目前的游戏编译出来的体积还会偏大,正常情况下代码和数据加起来在2~3M左右,部分游戏可能会有超过10M的情况。


WebAssembly在加载速度上,也会占用大量的编译和优化时间,比起JavaScript的加载会更慢50%以上的时间。目前WebAssembly社区也意识到这样的问题,未来FireFox会采用两个编译器的模式,一个编译器先启动,只做少量优化,第二个编译器会在后台进行足够量级的优化,最终再替换。目前社区有重量级的游戏在配合我们做这个路线的探索,包括CPP游戏和Lua游戏两种类型。

 

路线2:部分计算量大,交互少的模块采用WASM进行加速


目前Cocos引擎团队已经在对物理库、骨骼动画库、数学库进行WebAssembly的替换和对比测试,未来计划中的还有更多的模块,包括渲染库、组件层等;


Box2d的测试例对比数据

 

上节,我们交代过了目前WebAssembly在局部使用方面目前只适合有大量计算的情况。以Box2D物理引擎为例,JavaScript API暴露少,数据交互不多的情况,性能提升在某些情况下可达100%以上。


但是只要超出了这个目前适合使用的情景,实际情况就是另外一个结果,从引擎的transform测试例中可以看到,JavaScript和WebAssembly数据交换也是一个非常“昂贵”的代价,大批量的矩阵数据交互和计算,WebAssembly性能反而是降低的,比纯JavaScript慢60%左右。

  

从各个专项测试的结果来看,今天WebAssembly还存在不少问题,整体技术还有巨大的优化空间,已有的游戏包体积偏大、加载时间太长、WebAseembly和JavaScript互相调用性能低下等问题还没有到达可以商用的状态。


WebAssembly的诞生和设计目标

 

HTML5游戏里使用的语言是JavaScript脚本,属于解释型语言,其特点就是慢。在JIT技术 (Just in time compiling,即时编译)出现之前,简直就是蜗牛的速度,各种网页的复杂度是高度受限的,想好好做游戏?你就别想了。 

 

2008年JIT技术算是从性能的深坑里将JavaScript拉出了半截身子,促成JavaScript在语言界的重要地位,进入更广的应用领域。JIT技术并不神奇,其原理就是在JavaScript执行的时候,监视代码的执行状态,对重复执行的代码进行优化编译。在后台偷偷干,产生出对应的执行性能高效很多倍字节代码或者机器语言,让JavaScript性能得到质的飞跃,这才让HTML5游戏开始崭露头角。 

 

然而,JIT的天花板并没有很高,因为JavaScript是动态的语言,很难事先准确获知对象类型或者完整的属性,会经常导致JIT在优化假设阶段的假设,实际执行的时候发现不正确,此时这种失手的情况,就会打断当前的执行模式,抛弃已优化的代码,将代码重新优化或者进入解析器。这种反优化的过程,容易产生不小的开销。所以,如何写出让JIT编译尽量少失手的代码,就是手写JavaScript性能提升的重要方法。 

 

那么问题来了,这个事情能不能少发生,或者不发生?随之而来的两种优化思路,一种是TypeScript、Dart、JSX,一种是ASM.js。第一种是变为强类型的,类型错了,滚;第二种就是在代码里通过各种手段来声明是啥类型,再匹配一个大家都认可的识别机制。 

 

然后Mozilla、Google、Microsoft和Apple都觉得,嗨,第二个路线很靠谱嘛,有了业界几个最牛逼公司的支持,那就搞得更标准更彻底。于是WebAssembly粉墨登场了,爷来拯救你们了。 

 

WebAssembly(WASM)就是基于编译器而设计,什么手写、代码可读性、编码模式,统统和我没关系。编译出的一堆二进制码,解码之后,直接编译和优化,类型也是确定的,向毛主席保证,绝对不出现上述的重新优化的过程,一路到底。这一切看上去似乎挺美好的……只要我解决了Code size问题,WASM和JavaScript数据交互问题,调试工具,加载时间,更多的高级功能……


以上是关于秀技术,把Cocos C++和Lua游戏编译到浏览器上跑?!的主要内容,如果未能解决你的问题,请参考以下文章

如何将外部库集成到Cocos Android项目中

cocos2dx-3.x 导出自定义类到 lua 过程

cocos2dx-lua 3.10 中怎样移除layer

Cocos2d-x lua游戏开发之安装Lua到mac系统

cocos2dx3.0 lua工程怎么打包apk

如何将外部库集成到 Cocos Android 项目中