淘系前端互动引擎Eva.js架构与生态实现
背景
漫画中的三个人物,左边的人在玩金币庄园,金币庄园中金币可抵扣现金,用户每天都会来收金币,中间的人在玩天猫农场,通过助力可以升级果树,种成可拿到真正的水果,右边的人通过扫码得到一定权益,促使消费。
结合平台业务属性,利用用户的目标感、成就感和社交欲打造互动游戏产品,从而达到拉新、留存、转化的效果。
我们需要基于一套互动引擎来打通阿里巴巴经济体互动研发工作流,未来会基于引擎实现编辑器、逻辑编排以及互动模板。另外,我们需要把控互动领域的核心技术,所以,我们需要开发一套互动引擎。
要解决的问题
集团目前有很多互动业务,很多BU也在陆续开始进行互动业务的探索,我们需要给各个BU提供一套上手快、开发效率高、能力完善的互动开发链路,因此互动引擎至少要完成以上漫画中的三个点,沉淀最佳实践、支持编辑器、支持常用资源。 互动引擎面临以下三大挑战,以及对应策略。
- 实现易于开发的引擎架构
- 提供高扩展性的架构
- 支持场景编辑器
- 支持渲染与动画能力
- 渲染能力完备
- 动画资源类型支持完善
- 友好的用户体验
- 提供性能优化方案
- 提供最佳实践
实现易于开发的引擎架构
从目前的项目中,我们发现,每个项目都有一些共同的能力,比如说动画、图片、物理碰撞、交互等能力,我们需要通过组合的方式,将这些能力拼接到游戏对象上面,然后将游戏对象放入场景中,这个过程中尽量减少重复代码编写。所以,我们的引擎架构需要以组合的方式进行,并且需要对编辑器友好。
引擎架构
通过调研,我们发现ECS模式是业界游戏引擎开发的最佳实践,因此EVA采用了ECS的设计模式作为底层架构。
ECS具有高扩展性和高性能的特点,接下来详细看一下引擎的架构设计,我们通过游戏对象,组件和系统三层架构来实现游戏,游戏对象代表游戏中的物体,组件给予物体一些属性值,通过系统,读取组件中的属性值来给物体设置能力。这样,我们通过组件随时添加/删除游戏能力;通过组件和系统扩展游戏的功能,实现引擎架构的高扩展性。
ECS设计中,组件是存放数据的,将组件数据存放到CPU缓存当中,实现了天然的高性能读写,游戏循环中去遍历CPU缓存中的数据非常的高效,但是由于JS无法直接控制CPU缓存,因此无法享受到ECS设计中的这种优势,但是,我通过JS的getter/setter能力,实现了属性变化收集方案,当属性变化时通知系统进行相应操作,无需对数组进行遍历,大大提升运行性能。未来,如果我们能够使用WebAssembly的能力,或者将组件数据存放到ArrayBuffer中,是否能够更好到利用CPU缓存能力呢?这非常值得我们去探索。
编辑器支持
ECS天然支持编辑器设计,在图中编辑器案例中,左侧是游戏对象管理器,右侧是组件管理器,游戏对象和组件组合后,通过系统能力将其渲染到画布上。
对于编辑器而言,需要获取到对应的组件和系统的参数以及属性,提供给开发者进行可视化编辑,我在ECS之上做了一层装饰器,将属性、事件、类型、参数暴露给编辑器进行使用。
通过ECS架构和装饰器,我们实现了高扩展性、高性能、编辑器友好的引擎架构。
支持渲染与动画能力
我们知道,计算机游戏都要在屏幕上显示游戏内容来与用户进行交互,通过炫酷的效果能够提升游戏体验。 这些效果是如何实现的呢?
首先我们通过资源生产工具导出资源文件,然后使用渲染能力将其呈现在画布上。因此,我们需要支持常用的资源文件,并且实现完备的渲染能力。
为了快速的支持业务,我动画与渲染的实现过程分成了三步。
第一步:使用业界渲染引擎,业界渲染引擎一般将常用的动画能力和渲染能力放在一起。通过这种方案,快速的实现了引擎的渲染动画能力,并且落地到业务中使用。但是我们发现,动画能力是内置到渲染引擎中的,不符合我们引擎的架构模式,我们支持新的动画也不应该内置到渲染引擎当中。
第二步,抽离动画能力,将骨骼动画,帧动画,抽离成单独的系统,通过修改渲染组件上的属性进行动画实现,保障了引擎的统一性,扩展新的动画更方便。在渲染引擎上层,实现渲染适配器,通过统一的API进行绘制,更换渲染引擎只需要实现对应的API即可,为自研渲染引擎做准备。
我们发现,抽离了动画能力后,业界渲染引擎中有很多能力是冗余的,我们需要更轻量级的渲染引擎,另外,随着业务的发展,业界的渲染引擎能力已经没办法支持当下的业务场景了,业务中会用到更复杂的渲染效果,比如漫画的渲染效果、在2D场景里面实现更加立体的效果,接下来我们需要会对渲染引擎做简化、改造或自研渲染引擎。
友好的用户体验
对于互动引擎来讲,用户分为两部分,一部分是客户端用户,一部分是开发者用户。
客户端用户中,移动设备有好有坏,用户所处的环境、国家都对用户体验有非常大的影响,例如一些低端机上,如何优化动画卡顿问题,对于国际化、无障碍、夜间模式如何支持,因此,对于客户端用户来说我们需要做到端上更稳定,效果更丰富。
对于开发者用户,希望能够拿到一个可以快速开发互动游戏的引擎,关注引擎的学习门槛,系统健壮性,调试工具是否齐全。因此,我们需要做开发更高效,能力更完善。
接下来我会给大家分享三个解决方案,客户端用户的端稳定性、无障碍化、开发者的编码实践。我们来看一下具体问题和解决方案。
性能/稳定性问题
首先,我们来看最棘手的端稳定性问题,在互动业务开发中,最常见的问题就是首屏渲染时长和Crash问题。
首屏渲染时长主要是因为互动资源非常多,资源在使用之前需要实例化,骨骼动画、帧动画的实例化时间相对较长。 目前的加载流程,一般游戏都是先加载资源,再创建对象再实例化资源,最后再渲染,以这种线性的模式进行的。 我在引擎中做了三个事情。 第一,创建游戏对象和资源加载可以并行,我们的架构中,加载和对象的创建是完全分开的,天然做到了这一点。 第二,某个资源加载成功立即实例化,我在资源管理器中实现了实例创建器,各种资源注册实例化方法进去,每当一个资源加载回来,立即进入实例创建器,这时也不影响其他资源加载。 第三,实例化后立即渲染。因为游戏对象已经被创建了,所以当实例化后会瞬间被使用。
通过优化,我们实现了CPU线程和加载线程同时工作,可降低首屏30%-50%的加载时长。
对于Crash的问题,骨骼动画、帧动画都运用一些合并的图片,尺寸偏大,内存占用比较高,低端机承受不住内存压力,带来了很多crash,因此,我开发了分级体验组件,通过客户端等级判断,获取当前客户端是高端机还是低端机,针对高端机低端机选择图片还是骨骼动画,通过分级体验组件,我们可以在低端机中将骨骼动画替换成图片,从而降低内存占用,在数据中看到,使用这种方法内存占用降低30-60%。但是这种方法对视觉效果是有损害的,未来,我们会探索更多对业务和视觉无伤的能力去降低内存占用。
我们使用了引擎提供的资源管理能力和分级体验组件解决客户端用户的体验问题,接下来我们看一下如何解决开发者体验问题。
无障碍化
我们在游戏区域之上创建了A11y层,在该层上设计符合AOM(Accessbility Object Model)标准的接口,提供给开发者用户进行无障碍信息设置,从而达到标准化。无障碍插件将会自动识别手机是否开启了系统旁白,实现自动设置无障碍能力。无障碍的应用设计并非一个全自动化的过程,而是需要投入产品设计、开发人力的,我们需要针对具体场景进行无障碍设计,在开发中我们需要针对产品的无障碍设计去写无障碍化所需的代码。
我们知道 Canvas 上目前是没有办法实现无障碍操作的,目前,最有效的方案是在DOM中创建对应的可操作、可阅读的DOM元素,并且设置对应的无障碍化属性。
利用在架构中设计的组件监听器,监听A11y/Transform/Event组件的变化/添加/删除。只用被添加A11y组件的游戏对象才会被A11y系统接管,这样不会造成不必要的DOM生产和无意义的屏幕阅读,另外需要读取A11y组件上面的无障碍属性设置给DOM。监听Transform组件信息,判断游戏对象是否在游戏区域,并且读取Transform组件上面的信息设置DOM的定位以及宽高,直接读取Transform上面存储的Matrix信息设置给CSS的transform属性。最后监听Event组件的添加删除来给DOM添加事件。
目前无障碍化插件有几个特点:
- 在手淘/支付宝可自动识别是否开启无障碍能力
- 自动识别无障碍对象上的交互事件
- debug模式将无障碍对象展示出来
目前,无障碍化插件提供出了符合标准的接口设计以及自动识别的能力,能够实现互动游戏的无障碍化能力。
开发者体验问题
对于开发者,最紧迫的事情就是如何快速开始写代码,在开发者体验中,优先做了最佳实践。 我们知道,上手一个互动游戏类引擎是有一定门槛的,对于前端开发者而言,我们更希望通过前端的思路和解决方案处理问题。
在基于H5的互动开发中,我们通常在Canvas区域实现炫酷的动画效果、游戏逻辑,使用DOM实现一些布局类操作界面。 根据这个最佳实践,我们提供了基于Rax的互动开发解决方案,根据Rax的组件规范,将互动引擎的组件进行封装,提供给开发者使用,通过统一的Rax的开发规范来开发游戏区域和DOM区域的内容。
RaxEVA提供背景、操作界面、游戏区域三个区域,我们通过Rax提供的Driver对不同对区域中的组件进行不同形式的渲染,在背景和操作界面中使用的组件将会被渲染成DOM,在游戏区域使用的组件将会被渲染到Canvas上。
通过这种方式,可以降低前端开发的理解成本,使用JSX+Hooks的方案进行互动游戏的开发,另外,我们可以使用完善的Rax生态进行开发,更加便利。
总结
我们实现了一个易扩展的引擎架构,让游戏能力解偶,并且提供了编辑器的底层支持。 官方沉淀20+常用组件,包含动画、渲染、性能、数据状态以及常用的脚本组件。降低开发成本,提高开发效率。 针对首屏加载和内存问题,提供针对性的优化方案,提升C端用户体验。针对业务开发,提供解决方案和最佳实践,提升开发者体验。 目前EVAJS还未开源,可以参考下方内容进行实践。
扫描二维码查看DEMO
文档二维码
https://eva.js.org 欢迎志同道合的同学加入,一起共建阿里巴巴互动生态体系,这里有我们的团队介绍
如果希望进一步与作者沟通交流,可以联系作者微信: 微信:maydayfantast
版权声明
本博客文章均为 范明非 原创或翻译,采用知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
原文地址: https://fanmingfei.com/posts/Eva_js_Structure.html