低代码到底是不是行业毒瘤?一线大厂怎么做的?戳此了解>>> 了解详情
写点什么

如何用 WebAssembly 将桌面游戏编辑器移植到浏览器上

2019 年 12 月 13 日

如何用WebAssembly将桌面游戏编辑器移植到浏览器上

本文要点

  • 尽管 WebAssemly 还在积极开发当中,并且仍然比较小众,但这项技术本身已经足够成熟,足以用来将诸如桌面平台游戏编辑器之类的复杂应用程序移植到 Web 上。

  • 将桌面平台软件移植到 WebAssembly 的好处包括:移植的软件可以跨平台交付,可能会吸引更多的目标受众等。

  • 与原生桌面应用程序相比,前端框架和工具可简化 UI 开发并缩短反馈周期。

  • Web 还带来了新的可能性,例如深层链接以及丰富的 UI 生态系统的帮助,这些可能会极大改善用户体验。

  • 开发人员必须特别注意内存管理、测试和键盘操作,以减少移植过程中出现的问题。


谷歌软件工程师和GDevelop游戏编辑器的创建者Florian Rival,最近在布拉格举办的ReactiveConf 2019 大会上发表了演讲。他在演讲中讨论了将一款原生桌面平台游戏编辑器通过WebAssembly移植到浏览器中的经验教训。


InfoQ 采访了 Rival,询问了他在这一过程中所遇到的技术挑战、从移植中获得的收益,以及开发人员在考虑使用 WebAssembly 移植桌面应用程序时可以参考的技巧。



InfoQ:首先介绍一下GDevelop吧。它的目标受众是哪些?GDevelop 对于自身受众的价值主张是什么?它为游戏创作者解决了哪些痛点?


Florian Rival:GDevelop 的理念是让初学者到经验丰富的游戏开发人员都可以创作游戏。GDevelop 允许你使用视觉事件(由条件和动作组成)来创建游戏逻辑。你还可以通过组合预定义和可自定义的行为来构建游戏对象。

这样以来就消除了学习编程语言语法和习语这一入门门槛。对于非开发人员来说,这是一种通过直观界面快速上手并开始创作的方法。很多人喜欢沙盒游戏。GDevelop 是一个沙盒——但是你用它可以做的事情是无限的。

对于经验丰富的游戏开发人员来说,你将获得一个集成的开发环境,可以使游戏的创建工作非常快速且高效(事件被转换为“真实”代码),并且可扩展。

最后,对于团队而言,这是一种使所有人(开发人员、艺术家、项目经理、游戏设计师……)围绕一个共同界面协作,并培养所有人创造力的一种方法。

当然,与游戏创作相关的培训和讲习班使用 GDevelop 与学生互动也是好处多多的。只需几秒钟时间,你就可以开始探索游戏底层,通过事件来教学编程概念,甚至可以进一步创建扩展。


InfoQ:是什么促使你将游戏编辑器移植到 WebAssembly 的?移植到 Web 会给你带来哪些在桌面平台无法或很难获得的好处?


Rival:这款编辑器以前是原生 C++桌面应用程序。它正常工作的时候还可以,不好不坏。但它在某些方面开始出了问题:对 macOS 和 Linux 的支持很难正确实现(UI 工具包中频繁出现崩溃),并且在 UI 上的工作进展相当缓慢(因为“做一项更改>编译>运行>重复”这套循环流程太费时间了),还只能使用过时的 UI 组件。这些也会给新的贡献者提高门槛。

在工作中使用 React 相当长一段时间(以及使用 React Native 等框架制作移动应用程序)之后,我知道了组件范式(和“UI 作为状态的函数”)是制作接口时的一种非常强大且可扩展的方法。

当时我很怀念这种开发速度及其在原生侧实现的出色架构!

总而言之,我开始思考 Web 技术是否能用来帮助开发出更好的应用程序。

至此,我开始转向 WebAssembly(使用Emscripten),这是将现有的大型 C++代码库移植到浏览器(以及像 Node.js 这样的 JS 引擎)的便捷方法。

我的想法是将 WebAssembly 用作核心,将 JavaScript + React(或另一个前端框架)用作接口,之后我就会拥有一个可移植到几乎所有现有平台上的应用程序,可在各种设备上一致地工作。我还可以解锁一些做梦都想不到的新东西,比如说你可以在几秒钟内启动应用并开始尝试它,或者在手机和平​​板电脑上运行一模一样的应用。


InfoQ:在谈到移植这个话题时,你在演讲中提到了以下架构:



对于一款游戏编辑器来说,我知道有两个关键模块,一个是丰富的交互式 UI,用于处理编辑这部分工作;另一个是与规则引擎和游戏代码生成相关的,更具事务性的算法部分。移植到 WebAssembly 时这些模块如何转换为新的架构?


Rival:移植到 WebAssembly 的过程中,首先是在原始 C++代码库中明确区分应用程序的核心(“业务逻辑”,在我的情况下指的是描述游戏结构的各种类,以及操作这些结构的各种类,还有游戏代码生成部分)与 UI 部分。编译到 WebAssembly 的就是这一“核心”部分——除了围绕文件系统的一些抽象外,编译后的内容几乎没有任何变化。

这一代码库能够跑在浏览器中之后,下一步是编写绑定来将部分代码暴露给 JavaScript。(所使用的工具取决于你的语言。我这里针对的是 C++和 Emscripten,选择用WebIDL来编写绑定)。

然后我终于可以用 React 编写一个新接口来使用这些代码了——就像写了一个新库一样。


InfoQ:你遇到的主要挑战有哪些?对于寻求通过 WebAssembly,将现有桌面软件用类似的方式移植到 Web 上的开发人员,你有什么建议?


Rival:熟悉现有代码库当然是一个巨大的优势。最好看看现有的原生代码是怎样工作的,如果要移植的是库,那就看看它是怎样被使用的。

内存管理是一项很大的挑战。虽然 JavaScript 对象是可以垃圾回收的,但你在“ WebAssembly 世界”中创建的对象却并非如此。因此如果你调用一个函数来创建存储在 WebAssembly 内存中的对象,然后在 JavaScript 中删除对该对象的引用,则只会导致内存泄漏。一定要删除你创建的内容——直到 Emscripten/wasm 有了一些垃圾回收器为止。

另一项挑战是正确使用 WebAssembly 编译库。如果你传递了错误类型的参数,或尝试从 JavaScript 调用一个对象的方法,可是这个对象已经在 C++代码里从内存中删除了,那么你就会身处未定义行为的未知领域(在 C++中),并且很可能在 wasm 模块内遇到“崩溃”。而且你不太可能从中恢复过来(不过 JavaScript 可能会更宽容一些,并且如果应用程序的非关键部分未捕获到异常,你也有机会让应用继续工作下去)。

JavaScript 中的类型(使用 Flow 和 Typescript)可能会有所帮助——不幸的是,我还没找到一种将 C++类型自动转换为 Flow 或 Typescript 类型的方法。

调试也可能会更困难。我建议为你的 wasm 库准备一个全面的测试集,仔细检查一切是否正常运行。如果你要将实现转移到另一种语言上,这会很有用途,并且也会是一份有关如何正确使用库的实用文档。


InfoQ:你最后是如何打包/分发 Web 应用程序的,为什么这样做?


Rival:因为这款应用的一项重要特性就是可以访问文件系统,并且人们希望能够脱机处理游戏,因此我将整个应用程序打包为可以在 Windows/macOS/Linux 上运行的 Electron 应用。它在所有平台上都运行得很好。尽管 Electron 的打包尺寸可能有点偏大,但我觉得还可以接受,因为用户下载的是一款完整的游戏编辑器。

话虽如此,但制作一款可独立运行的 Web 应用也是很必要的,这样以来应用就可以在线试用和使用了。相比我正在逐渐放弃的桌面版应用,Web 平台提供了一些等效的 API,或者需要重新寻找一些替代方案,也存在一些局限。


InfoQ:要做出一个最小可行的移植版编辑器(在 UI 和性能方面)要花多长时间?这个过程的难度如何?


Rival:这样做的时候肯定会有起伏。在完成可以在浏览器内部运行的核心版本后,我和几个朋友就开始为这款应用程序开发新的基于 Web 的 UI。我们只花了几周的时间就完成了工作。后来我们又从头重新开始整个过程——但是我们的原型证明了浏览器可以支持这款应用,并能正确运行它。

我确实得在某些时候重新设计绑定,并且升级到 Emscripten 的较新版本并不总是那么容易。现在我还没更新到最新版本上:)(但这部分工作需要的只是一些时间)。

当然这并不容易,但是这项工作一开始粗糙的样子正在逐渐改观(以前 Emscripten 的编译时间非常久,现在就不再是问题了)。


InfoQ:我注意到你提到了移植到 Web 的应用程序比原来的原生应用表现更好,这让我很感兴趣。能否详细介绍一下 Web 应用程序带来的改进细节?


Rival:有趣的是,移植版的启动时间有所缩短,我认为还有提升的空间。

我最满意的是建立这种链接的可能性。

点一下那里,然后在几秒钟内(具体取决于你的联网速度和设备性能),你就有了一款正常工作的游戏编辑器;你可以用它修改游戏、运行预览并开始探究底层细节。在过去想要做到这一点根本就是不可思议的。

从开发体验来看,应用的 C++部分处理起来和之前几乎没区别,但是 UI 的开发确实更快。诸如Storybook之类的工具可以用来独立地开发应用程序的各个组件——开发时甚至无需运行应用程序本身。开发 UI 时,我们的反馈循环从几分钟缩短到了几秒钟。Storybook 还可以可视化应用程序组件的异常状态(例如错误状态),并在更改后使你能确信一切正常。我认为它们是非自动化的,但仍然是非常有用的测试用例。

不同 Web 浏览器的各种怪癖是不可避免的,但是与我在 C++中尝试过的较老的跨平台 UI 工具包相比,总体而言在 Web 端实现多平台支持要容易得多。

虽然应用界面不是由原生小部件组成的,但我们仍然可以使用其中一些部件(特别是如果你使用的是 Electron,它可以让你利用原生上下文菜单和原生菜单栏等功能)。

使用 React 带来的干净的、面向组件的架构在模块化和保持代码库整洁方面有着巨大的优势——这进一步提升了开发效率。最后这将转化为更好的界面——因为你的整洁架构将转化为精心设计的,具备一致性的组件。例如,组件的响应更容易保持一致。很难想象使用旧界面该如何创建响应式 UI。


InfoQ:就编辑器的未来功能而言,你有哪些展望?


Rival:内容数都数不过来!社区总是在提议新的事物:)界面总是在不断改进,以在直观性和完整性之间取得适当的平衡。我想围绕软件创建一个更完整的生态系统和社区——我又想出了很多主意,可以让几乎任何人都能更轻松,更迅速地制作游戏。可以在 WebAssembly 中重做一些影响性能的关键组件,或者开发一些带来新功能的扩展,从而改进游戏引擎!

GDevelop 是一款开源的,跨平台的游戏引擎,可通过其GitHub存储库获取。


ReactiveConf 是面向开发人员的大会,每年举办一次,其主题涉及软件开发的最新技术和趋势。ReactiveConf 2019 大会于 10 月 30 日至 11 月 1 日举办,是 ReactiveConf 的第五届会议。


受访者介绍


Florian Rival 是谷歌的软件工程师。他是 GDevelop(基于 WebAssembly 和 JavaScript 的开源游戏制作软件)的作者。他还制作了 Lil BUB 的《Hello Earth》(一款由网红猫为主角的 8 位游戏),支持台式机和移动设备,并 100%使用 GDevelop 制作。总的来说,他喜欢用创新方法来突破我们在应用程序、移动应用和游戏中可做事情的极限。


原文链接


Porting a Desktop Game Editor to the Browser With WebAssembly


2019 年 12 月 13 日 18:402287

评论

发布
暂无评论
发现更多内容

游戏夜读 | 关卡设计新手必看

game1night

架构0期Week4作业1

Nan Jiang

Java面试常用知识(附赠最新面试题)

架构大数据双料架构师

被“假”老干妈耍惨了?憨憨腾讯花1624万卖萌,引全网吃瓜!

程序员生活志

腾讯 互联网 大厂

最详细的 Spring Cloud OAuth2 单点登录使用教程送给大家

小闫

后端 JVM Java 面试 SpringCloud

面试腾讯被问JVM性能调优,勉强入职后,发现工资差了这么多

互联网架构师小马

Java 程序员 面试 性能优化 JVM

让你秒懂Spring中Mybatis的花样配置

小谈

Java spring Spring Cloud mybatis Java 面试

到底什么是HashMap?

小闫

Java spring 后端 JVM hashmap

当国产iVX遇上新晋产品PowerPlatform,能否披荆斩棘、稳住阵脚?

代码制造者

程序员 编辑器 低代码 快速开发 开发工具

腾讯的辣酱不香了 支付宝的区块链真能解决“萝卜章”问题?

CECBC区块链专委会

双链通 萝卜章 区块链方案

攻克SpringBoot底层源码后,才发现开发原来这么香

无予且行

Java spring Spring Boot 开发 Java 面试

终于有大佬把TCP/IP协议讲清楚了!面试再也不怂面试官提问了

小闫

jdk JVM Netty buffer TCP/IP

信创舆情一线--英特尔暂停向浪潮供货

统小信uos

服务器 舆情 芯片

Linux 操作系统!开篇!!!

cxuan

Linux

极客大学架构师训练营 系统架构 第8课 听课总结

John(易筋)

极客时间 系统架构 极客大学 极客大学架构师训练营 系统架构演化

使用 Flutter 快速实现请假与写周报应用

LeanCloud

flutter 数据 教程 后端开发

架构0期Week4作业2

Nan Jiang

拥抱开源开放,易观技术开发者的星海征途

易观大数据

海豚调度 调度引擎

如何快速将 Linux 系统制作成 ISO 镜像文件?

JackTian

Linux 运维 操作系统 镜像文件 ISO

javascript 部分数据类型的用法

Isuodut

七月份最新“美团+字节+腾讯”面试题,测试一下你能走到哪一面?

犬来八荒

Java 面试 java面试 大厂面试 线程’

「NIO系列」——之Reactor模型

小谈

Spring Boot reactor 后端 nio SpringCloud

如果是你,年薪80万和阿里P7月薪36K,会怎么选?

犬来八荒

Java 腾讯 面试 阿里 java面试

去面试Spring Cloud 被问的35个问题

小谈

Java 面试 springboot SpringCloud buffer JVM原理

面试官:十亿级数据ES搜索怎么优化?我直接傻了

犬来八荒

Java 面试 大厂

Google官方MVP+Dagger2架构详解

小吴选手

架构 架构师 架构是训练营

基于 Flagger 和 Nginx-Ingress 实现金丝雀发布

郭旭东

Kubernetes CI/CD

再有人问你分布式事务,把这篇扔给他

码哥小胖

分布式 Java 分布式

如何写好一封邮件?

石云升

职场 职场成长 邮件

【自学成才系列一】multipass安装篇

小朱

multipass

谈谈容器和K8s

Gabriel

2021 ThoughtWorks 技术雷达峰会

2021 ThoughtWorks 技术雷达峰会

如何用WebAssembly将桌面游戏编辑器移植到浏览器上-InfoQ