在生态链上,完成自己的角色。
上海木鸡网络科技有限公司联合创始人 杨轶如是说。
《移动 Web 上玩转原生游戏》的学习笔记。
了解当前移动端 Web 游戏开发的历程、技术瓶颈和作者产品的功能。
当今移动端浏览器为游戏开发准备了啥
- HTML5,CSS3,JS,WebGL
- Web API:Web Audio API, XHR/Fetch, WebSocket, WebRTC, Web Worker, Touch/Accelerometer
- 存储,IndexedDB
- PWA,Service Worker
- JS 引擎:V8,SquirrelFish Extreme,JaegerMonkey
Web 上游戏开发之现状
- 纯 Web 游戏引擎
- COCOS 2DX,Egret,LayaBox,Construct 2,three.js
- 原生游戏引擎 Web 版
- Unity,移动端游戏王者,50%占有率,可用资源多
- Unreal,大,占有率不高
- Emscripten
- Web 游戏渠道平台
- 小游戏框架,国内环境
- 标准 HTML5,WebView 渠道,海外渠道
移动 Web 上能玩原生游戏吗
- 移动 Web 环境,Unity
- WASM 模块:函数多,加载慢,编译慢,内存占用高
- Web 天生不支持阻塞调用,加载大资源是问题
- 使用 MultiThreading,BSD Socket 的游戏
- WEB-IR,Unity 引擎游戏通过 WEB-IR 处理,使其可以在移动 Web 环境运行,轻游戏2.0时代
- 代码动态 Profiling,Code Size 减至1/3,加载启动提速2X
- 编译器支持的阻塞机制,虚拟上下文切换,支持资源渐进式加载,支持 TCP/UDP select/poll
- 虚拟协程来模拟多线程
- 软件栈
- OS Layer
- WebView Client, Browser Client
- Game Engine Core / WebAPI 和设备打交道,平台 SDK
- Game Logic Native Part / Game Logic Web Part 游戏逻辑
- 内存使用是 Web 游戏的第一阻碍
案例分析
- 贪吃蛇游戏
- 代码动态 Profiling,Code Size 缩小到1/3,编译加载时间缩短
- 支持阻塞调用,资源文件可以同步读取,仅需要8M 内存来做 Cache,按需下载的数据很小,加载耗时明显缩短
- 对原始 WASM 代码进行重编译,插入控制指令,并 Patch Unity 的 IL2CPP 库以支持虚拟的多线程调用和 UDP 连接,解决了原生游戏所依赖的网络连接问题
- MMO 3D 游戏
- 3D 游戏,需要更大的计算量和更多的资源,同时也证实了 Unity 3D 游戏的表现力
- 由于原生游戏依赖了很多第三方库,Unity WebGL 版执行代码有超过60K 个函数
- Demo 版的资源有300M,意味着完整游戏会在 GB 级别,占用内存也就在 GB 级,在手机浏览器环境是完全不可接受的
- MMO 游戏,要用到 BSD Socket 和 Multi-Threading,不做调整的 Unity WebGL 版依旧无法运行
- 通过我们处理,有效函数控制在20K 个,为了满足 iOS 对编译 WASM 的限制采取了 WASM 和 JS 混搭的 Hybrid 模式,同时配以 IndexedDB 来满足资源持续储存并作为 Cache 加速再次加载的速度
- 3D 动作游戏
- 中量级,3D 单机游戏,内容丰富,移植速度快
- 解谜类游戏
- 适合 Web 化,操作要求不高
- 实践中的关键
- WASM 程序所要编译的函数
- 游戏首帧启动时间
- 游戏运行时内存占用
WEB-IR,这种方案所要解决的关键问题
- WEB-IR 解决问题的关键-重构 Unity WebGL
- 动态 Profiling
- 资源渐进加载
- 大块文件切割成若干个 Chunks
- Chunks 预加载
- Chunks 多种方式存储
- 解析出来的资源数据会被保存到内存 Cache 中提高访问速度
- Chunk 渐进加载以阻塞 I/O 为前提
- 云端跟踪前端资源的加载情况,为后面的加载做准备
- 渐进加载无需开发者修改代码
- 阻塞 I/O
- 阻塞 IO 是保存完整的调用栈,以做恢复使用
- 虚拟线程
- 协程方式代替线程
WEB-IR 工具链
- WEB-IR 以一种中间语言的代码格式支持整个技术框架,工具链所 Build 产出的任何代码都是基于 WEB-IR 中间语言之上
- WEB-IR 中间语言是和 WebAssembly 在相同级别的低级语言,基于的是 CFG 而不是 AST
- WEB-IR 中间语言以纯文本的形式保存,方便修改调试
- WEB-IR 中间语言可以通过源代码(C/C++)和 WebAssembly 二进制码生成
我们的感悟
- 用好前人的肩膀,尽量不要重复造轮子,在生态链上,完成自己的角色
- 拓展思维,尝试做一些不一样的事情
- 很少有火箭科技,更没有黑魔法,在实践中不断地改良
- 时刻不要忘记真实环境的适配能力