微信小游戏适配原理 & FAQ

感谢关注。我昨天写的那篇,因为考虑到媒体和非技术人员的传播,所以技术内容写得很少。今天咱们就放开了谈论技术。(篇末有微信团队给的彩蛋,自己找)

这篇技术文章比较长,我先列一下纲要:

  • HTML5游戏架构
  • 微信小游戏runtime
  • FAQ
    • 昨天发了16款小游戏,而不是15款?
    • Cocos2d-JS游戏如何适配小游戏?
    • Cocos2d-x Lua, Quick, C++游戏如何适配?
    • 运行时提示 wx.createImage is not a function 是怎么回事?
    • 未找到 app.json 文件,如何解决?

首先呢,需要科普一下,媒体上说的 H5 游戏,其实含义混淆蛮大的。当然很多程度也是「归功」于几家引擎商在宣传上有误导。

HTML5

我们看一下 HTML5 在 Wikipedia 上的定义:HTML5 is a markup language used for structuring and presenting content on World Wide Web. It is the fifth and current major version of the HTML standard.

所以很直接的定义是,HTML5 是 web 内容,跑在浏览器里面的。我们现在看到的哪些是 HTML5 游戏呢?比如微信里各种公众号渠道,爱微游、疯狂游乐场等,还有 Facebook Instant Games,这些地方跑的游戏,都是纯 HTML5 游戏。

在 HTML5 方案架构里面,Cocos 引擎最后是落在 WebGL、WebAudio 等浏览器 API 上面的,往上提供出 JavaScript API 给游戏开发者使用。

但微信小游戏不是这种定义下的 HTML5,或者说,不是纯 HTML5。


微信小游戏 Runtime

微信小游戏的技术架构,我称之为「runtime 方案」。

看图:

你可以把 runtime 大致理解为一个「阉割版」的浏览器内核,但是里面没有什么 HTML 标签的解析、没有 CSS 和 DOM 的解析。runtime 做的最主要事情,就是从操作系统的 Objective-C, Java, C++ API 上开始写起,里面实现自己的逻辑,然后架上安卓 v8、苹果 JavaScriptCore 等 JavaScript 虚拟机(JSVM),进而把这些操作系统 API 都绑定到 JavaScript 上。接着 Cocos 引擎就适配到小游戏的这层 JavaScript API 上面,往上提供出 JavaScript 的 Cocos API 给开发者。

正确地说:runtime 方案和 HTML5 标准是两码事,有一部分交集。比如小游戏封装出的 OpenGL JavaScript API,和 WebGL 是一模一样的,这就让引擎的移植工作量大幅降低。只是引擎覆盖掉了这些差异性,让开发者「感觉」自己就是用 Cocos Creator 在开发一款 HTML5 游戏,确实也能在 Chrome 里面做调试。但如果你一旦使用了既超出引擎 API、又超出 runtime API,但是符合 HTML5 标准的代码,比如来个 CSS,来个 DOM,那么就无法运行在小游戏里面啦!

Runtime 技术的黑历史,最早可以扒到 2011 年左右的 Impact.js,这货是始作俑者。我们也是受到这个启发,才折腾出所谓的 JSB - JavaScript Bindings,让开发者可以用 JavaScript 在引擎上写游戏逻辑,然后在不违反苹果审核机制的前提下,发布到 iOS, 以及发布到 Android 和 HTML5环境里。

JSB 的架构原理和 runtime 类似,其实我要从今天开始把 JSB 改名叫 runtime 也是没什么问题的,不混淆不误导。唯一区别是小游戏 runtime 的封装层面更低,允许在上面跑不同的游戏引擎。在 2012~2017 的 5 年期间, Cocos 一直是用 Mozilla FireFox 家的 SpiderMonkey 作为 JSVM,直到 Cocos Creator 1.7 才改为安卓用 v8、苹果用 JavaScriptCore 作为 JSVM,使得用 JavaScript 开发的原生游戏可以大幅提高了性能、缩小包体积。

这个世界上的 runtime 又分两大流派。

  • 大咖的 runtime,是集成在自有流量平台上的。比如微信小游戏、QQ厘米秀,都是这种类型。
  • 屌丝 runtime,没有自有流量平台,开发者就需要在每个原生游戏包里带一份 runtime,全球游戏引擎商的 runtime 都是这类。

所以,虽然开发者确实也能在 Chrome 里做调试,但引擎底下的技术是不一样的:

  • 落到 iOS 和 Android 用的是 Cocos 自家的JSB,或者成为自家引擎 runtime;
  • 落到 Chrome、Facebook Instant Games、QQ空间和 H5 公众号是纯HTML5;
  • 落到 微信小游戏,是引擎的 JavaScript 层适配了小游戏的 runtime。

既然用引擎开发出 H5 游戏之后,在纯 H5 和小游戏 runtime 环境都可以跑,所以行业里的非技术人员,也就懒得区分了,统称为 H5 游戏。但我相信今天解释清楚这一层关系和区别之后,对大家做更深度的游戏开发、引擎修改会有很大帮助。
(昨天不少媒体提到「国内 H5 引擎」,拜托我们不是 H5 引擎,而是 iOS、Android、 H5 跨平台引擎。看图看图)

这张图很清晰地描述了 Cocos 引擎,尤其是 Cocos Creator 上开发出 H5、微信小游戏、原生(iOS+Android)的技术架构。我们也是够懒的,这样的架构图在引擎文档里居然没有现成的,还得我现画。一会儿我让同事更新文档去。

读到这里你被绕晕了没有?还没有,看来您是「真·程序员无双」,握爪握爪。

然后我们进入下一个环节,针对昨天各种问题的 QA。

FAQ

1、昨天明明是发布了 16 款小游戏,为啥 Cocos 只说了 15 款?

呃,我昨天下午写文章的时候的确是 15 款,到了我文章发出去才出现第 16 款《拳皇命运KO不服》。听说是昨天下午刚开的时候服务器不稳定,所以暂时从列表里消失了几个小时。这款小游戏也是腾讯内部开发的,作为给后续要上微信的《拳皇命运》原生游戏衍生品。据我所知,该游戏不是用的任何一家国内游戏引擎。

2、我用 Cocos2d-JS 开发的游戏,可以适配到小游戏上面吗?

当然可以,第一波上线的游戏里面,既有用 Cocos Creator,也有老游戏用 Cocos2d-JS。但是相对于 Cocos Creator 的一键导出和深度优化,Cocos2d-JS 需要用户手动去合并已经支持的小游戏引擎版本。

今天我们内部讨论了一下,计划在元旦后的一周内,也就是 1 月 5 日下班前,在官方论坛上提供经过测试验证的 Cocos2d-JS 适配小游戏的版本。 为什么是元旦后而不是今天呢?因为我们赶 Creator 1.8 的测试发布已经通宵了,兄弟们得睡觉嘛。再说了我不先测一周弄稳定了,匆忙发出来你敢用?

再次提醒,Cocos Creator 不论工具链和引擎框架的优化,都比 Cocos2d-JS 要好非常多,不仅性能提高不少,而且开发效率也大幅提升了。资源充裕的情况下,还是建议升级到 Cocos Creator 方案上。

3、我用 Cocos2d-x Lua, Quick,C++ 开发的游戏,可以适配到小游戏上面吗?

如果你理解了我上面写的 runtime 架构,就能明白原理上 runtime 技术是可以支持任何脚本语言的,包括 Lua, Python 等等,只要绑定出来即可。但是微信小游戏 runtime 并没有支持 Lua,而且我们自己也尝试了把 Lua 虚拟机架到 HTML5 环境里面运行,结果性能和开发调试体验都非常差所以放弃了。因此 Lua 游戏无法快速适配到微信小游戏上面,只能手工翻译为 JavaScript 了。

用 Cocos2d-x C++ 开发的游戏也是类似情况,需要手工翻译。虽然有 WebAssembly 技术,但我们评估后觉得这东西还很不成熟,无法大规模用在商用游戏上。

对于代码翻译工作,从我们之前的项目经验来看,有经验的程序员翻译速度大概在 800 行每人 / 天左右。你游戏的代码总行数 / 800 * 2,差不多就是移植游戏需要的人天数。乘以 2 是因为除了翻译代码,还有调试、资源优化、加载优化、内存优化等活得做完。

对于想把原生游戏翻译成小游戏的大厂,可以来联系我。在 Cocos 生态圈里有很多企业可以接这样的技术活。本身我们在全国各地的众创空间里就有一大堆企业,从雅基软件和触控科技离职出去的员工也开了很多游戏公司,可以接下这些工作。

4、我运行时提示 gameTirdScriptError, wx.createImage is not a function 是怎么回事?

恩,还有 wx.getSystemInfoSync 等方法找不到,也是同类的错误。

注意不要引用 HTML5 环境中的 jssdk,也不要在 Creator 中导入微信 jssdk 作为插件。认真理解一下我前面说的 HTML5 vs Runtime 架构。因为在小游戏环境中,这些接口都是直接在 runtime 层面支持的,如果你又引入 HTML5 的 jssdk,很可能会覆盖小游戏原有的接口。

5、我用 Creator 1.8 适配微信小游戏,调试的时候报错「未找到入口 app.json」是怎么回事?

很多人都遇到这个错误吧?昨天在论坛和微信里被问到爆。

抱歉之前 Creator 官方文档没说清楚这个问题,这是由于微信平台的权限问题导致。微信公众平台那边必须设置成小游戏服务类目。也就是说,你的小程序 appid 类别应该是游戏。

遗憾的是,个人开发者无法改为这个类别。公司认证账号呢?暂时也不可以,哈哈。我是认真的。

关于无法设置游戏类目,微信团队的回复是:“目前不开放注册以及设置游戏类目(预计元旦后开放),下载开发者工具,选择体验小游戏,可以开发预览”

所以,彩蛋呢?在这里:微信团队得知 Cocos 社区爆发 app.json 错误之后,今天中午给大家提供了一发重要的子弹:如果开发者没有appid 又需要体验,可以填写 wx6ac3f5090a6b99c5 这个作为 appid 进入调试!

感谢你耐心看完这么冗长的技术文章,祝各位 Cocos 开发者在小游戏的浪潮里面好运!

6赞

干货点赞

点赞, 浪里个浪

干活点赞

点赞!

mark