铁锈为何是游戏开发的未来

2020-11-10 01:59:37

Rust与视频游戏(也称为Rust)无关,是一种很有前途的系统编程语言,具有新颖的功能,非常适合游戏开发。然而,游戏开发者社区内的曝光率和认知度仍然有限。在这篇文章中,我对铁锈做了一个温和的介绍,并试图证明它在你的雷达上的地位是正确的。

什么是铁锈?它是从哪里来的?在这个精彩的演讲中,詹姆斯·芒斯为我们讲述了一段详细的口述历史。早在2010年左右,Mozilla就对Firefox的开发现状感到沮丧,Firefox是一个主要用C++编写的大型软件项目。尽管有最佳实践和丰富的工程人才,但以这种复杂程度编写高性能、并行化和内存安全的代码仍然令人担忧且容易出错。

请记住,这早于C++11(也就是2011版)的问世,它预示着语言在某种程度上现代化的努力。即便如此,手动内存操作也很容易出错,多家供应商的研究表明,70%的安全漏洞都是由这类错误造成的。

在这个背景下,Mozilla员工格雷登·霍尔(Graydon Hoare)介绍了一种潜在的解决方案:铁锈,这是他自2006年以来一直在修修补补的业余爱好语言。2012年,Mozilla将正式宣布Servo,这是一个实验研究项目,旨在重新设想一个以内存安全和并发性为首要原则的浏览器引擎。与之并驾齐驱的是铁锈,这是使这一切成为可能的配套语言。

铁锈的早期被描述为寒武纪思想的爆发和狂野的实验。概念从其他语言(从C++到OCaml、Haskell、Erlang、ML、C#、Ruby等等)被大量窃取,反映了当时从事该语言工作的工程师的多样性。尽管如此,大多数业内人士在钦佩如此雄心勃勃的登月行动的乐观情绪的同时,仍对成功的前景持悲观态度。

2015年,随着Rust v1.0的发布,这是一个重要的里程碑。也许与功能清单同样重要的是,在剪辑室地板上留下的失败实验的数量,团队不怕把语言削减到它的精髓元素。这也是第一次提供稳定保证,这是出了名的缺乏这种品质。

不久之后,在2016年,火狐发布了它的第一个生产铁锈代码。业界和社区开始注意到,Rust开始了其令人印象深刻的、至今仍未中断的四个五年的连续五年,成为Stack Overflow最受欢迎的语言。[感谢詹姆斯·芒斯指出,现在实际上已经是五年了]。

从一开始,拉斯特就明确将重点放在建设一个包容的社区上。反过来,他们为拉斯特令人印象深刻的技术天赋做出了贡献,但也培养了一种在其他语言中不常见的崇敬和喜爱之情。他们是疯狂的狂热者还是在做什么?

这是铁锈第一次引起我的注意。C++由来已久,部分原因是它能够表达零成本抽象。正如C++的创建者Bjarne Stroustrup所解释的那样:

你不用的东西,你不用付钱。更进一步:你用的是什么,你的手写代码再好不过了。

很容易发现它与游戏的相关性。在模拟整个世界的同时实现帧速率是一个令人望而生畏的性能挑战。事实上,C++支撑了大部分游戏引擎。在大量编写程序的同时,根本没有其他工业语言可以提供相同的速度和低级控制。

然而,C++受到其遗留问题的影响。40多年的特点积累造就了一种复杂而错综复杂的语言。在过去的十年里,标准的现代化很好地将它从C语言的根源提升了出来,但经验丰富的程序员必须建立一个神秘的知识,其中的功能是有福的,而哪些机器是危险的。正如斯特罗斯特鲁普再次描述的那样:

这使得初学者很难掌握这门语言。在这篇博客文章中,Rust撰稿人Without Boats定义了一个关于抽象的重要品质:

与所有抽象一样,零成本抽象实际上必须提供比备选方案更好的体验。

所以,是的,C++提供了比你自己手工编写的汇编更好的时间。然而,这说明了一个微妙的问题:它正在与另一股次要力量竞争:一种更昂贵的抽象设计,它更舒适、更方便,从而证明了它的成本是合理的。

我们在流行游戏引擎的崛起中看到了这一点,这些引擎避开了C++的复杂性,最引人注目的是Unity。最终用户用C#编写代码,C#是一种更具容错性和符合人体工程学的语言,从而提高了开发人员的工作效率,减少了迭代时间。

不过,在接近性能极限的大型代码库中,这种权衡开始发挥作用。垃圾回收器通过将内存管理责任从最终用户身上移除,从而消除了整个类别的错误。然而,随着其工作量的增加,周期性的性能峰值也会增加,而不是流畅的游戏玩法。

有经验的开发人员仍然可以创建性能体验,然而,这需要填补抽象中的漏洞。他们必须建立幕后机器的心理模型,这是一种神秘智慧的集合,禁止了许多原始的便利,以免它们打扰垃圾收集器。

因此,开发团队面临着一个选择。资源更充足的AAA工作室通常选择基于C++的虚幻或内部引擎技术,能够吸收开销以获得长期收益。资源较少的工作室会优化上市时间,选择Unity或许多其他可用的游戏制作工具(Godot、Haxe、Game Maker等)之一。他们通常将业绩担忧推迟到确保业务资格之后。

然而,铁锈第一次承诺了第三条道路。在这个世界里,你可以在不牺牲高阶优雅的情况下,写出零成本的抽象概念。

为了理解铁锈的独特之处,我们不得不谈谈所有权以及它是如何处理内存的。这只是一个简单的草图,但对于好奇的人来说,有深入的资源可供参考。

编写优化的代码通常是采用我们作为人类自然想到的想法或算法的方式,而不是用有利于计算机的语言来表达它。这种行为通常会损害程序的易读性和理解性,这使得我们人类更难对其正确性进行推理。

在像C这样的手动管理语言中,倒霉的程序员要为机器的阴谋负责。他们必须非常小心地确保数据在操作前被适当地加载到内存中,然后在操作之后负责任地处理。一种困难的舞蹈,其中的失误要么会导致戏剧性的崩溃,要么就是微妙而难以察觉的漏洞。但这些工具正是允许细心用户调优性能的工具。

另一方面,垃圾收集向程序员承诺,它将代表程序员自动处理问题。他们现在可以自由地自然地表达代码,但这样做会把他们的双手绑在背后。他们不再拥有实现最高绩效所需的杠杆,至少不是没有间接的杠杆。

生锈是从一个不同的前提开始的。它没有隐藏这种复杂性,而是承认计算机对人类来说是困难的,相反,它试图将我们从危险中拯救出来。用户仍然可以调整机器,但脖子上缠绕的绳子更少了。

与静态类型存在的方式相同,非常聪明的人已经想出了如何让编译器消除整个类别的内存和并发错误。为了实现这一点,Rust与开发商进行了讨价还价:

我将为您记录程序中每一块内存的生命周期。这样,我可以检测到您不再使用它的时刻,并代表您安全地释放它。但作为回报,我需要你严格遵守有关内存所有权的规定。如果你试图在拥有它的范围之外使用它,我这位没有幽默感的朋友,借阅检查员,会确保你不会伤到自己。

然而,就像静态打字一样,这顿午餐也不是免费的。众所周知,生锈有一个陡峭的学习曲线,与借阅检查员抗争成为一种通行权。学习这种新模式需要时间。所有权使一些熟悉的模式变得困难或不可能,并要求在它们的位置上学习新的模式。也许我们应该把我们之前的说法修改为:C++的性能和C#&34的便捷安全性;

早期采用者有一个自私的理由来赞扬他们选择的技术的优点,因为广泛采用提高了他们高风险投资的回报。在这方面,虽然人们的兴趣很高,但接触现实世界的机会有限,但拉斯特有没有可能正在掀起一波不劳而获的炒作浪潮?例如,并不是每个对该语言感兴趣的Javascript或Python开发人员都有值得增加复杂性的用例。

对于一个站在2010年海岸线上的开发者来说,Git这个学习曲线陡峭的新版本控制系统似乎是一项高风险的投资。但是,在接下来的Github世界里,即使一些工作量(即大型游戏)仍然需要替代方案,也很难辩称这些努力是徒劳的。

同样,我们如何才能将铁锈的受欢迎程度定义为一个有意义的信号呢?最终,我们只能通过我们在战壕中挖出的泥土的数量来知道,诚然,现在为游戏收集这些数据还为时过早。

然而,在其他行业,有关铁锈的早期报道是热情洋溢的。微软、Facebook、亚马逊、Dropbox、Cloudflare都部署了Rust。Linux内核和Chrome团队至少已经调查了整合Rust的途径。这些公司并不打算扔掉数百万行代码库,重写所有代码,但他们选择了Rust作为独立的新项目,这样做是有意义的。在系统编程层面(操作系统和Web浏览器),Rust看起来确实是称职和可取的。

从裸机微控制器到通过网络组装部署的网络应用,它还在整个堆栈上下引起了人们的兴趣。铁锈已经做得非常好,使它的生态系统舒适和欢迎。编译工具、文档、错误消息、跨平台支持、模块、依赖项管理和包都是一流的。

对于任何启动商业游戏引擎的人来说,这可能并不是什么新鲜事。尽管如此,对于四面楚歌的操作系统内核开发人员来说,要想有机会拥有美好的东西,这种感觉怎么说都不为过。

然而,还有另一个我们应该对铁锈感兴趣的轴。作为一名系统开发人员,布莱恩·坎特里尔(Bryan Cantrill)在他非常有趣的演讲中解释道,只要有足够的经验和细心,就有可能写出行为良好的C代码。但“锈”让他兴奋,因为除了记忆安全,它还解锁了新的抽象概念。

当然,更好的抽象性是C++的理由,也是为什么它一开始就被固定在C上的原因。但是,即使与C++或C#相比,这里也有真正的创新。主流编程可能已经拒绝了像Haskell这样的核心函数式编程语言,但它并没有阻止最好的想法渗透到其他语言的地下水中。

通常,这表现为固定的语言扩展,C#中的LINQ就是一个例子。LINQ为开发人员提供了一种简洁的声明性语言来查询和操作数据。令人信服的是,除了作为垃圾收集压力的来源,游戏开发人员很快就学会了避开。然而,从第一天起,铁锈就是基于这些灵感而形成的。Rust迭代器,相当于LINQ,可以作为零成本抽象使用,缩小了人类思维方式和机器期望之间的差距。

函数式编程的核心是创建契约以避免意想不到的后果。这种DNA在“锈”中随处可见,其正确性的品质远远超出了记忆模型的范畴。如果你正在做一个复杂的项目或和一个大团队一起工作,这应该是一个很好的卖点。默认情况下,不可变性处于启用状态。对可变数据的严格读写规则允许Rust承诺无畏的并发性。虽然类型系统不同于C++和C#,但是没有基于继承的类,例如,它拓宽了可以验证的范围。通常,如果它编译了,它就会运行。

斯威夫特(Swift)和科特林(Kotlin)这两种现代且广受好评的语言,或许标志着这些想法的时代已经到来。虽然它们都有不同的内存模型(Swift类似于C++,而Kotlin是垃圾收集的),但它们代表了各自平台(iOS和Android)上的最新技术。虽然程度不同,但和铁锈一样,两者都有一种混合的半功能性味道。

铁锈仍然是一种不成熟的语言。时至今日,C++中仍有一些有用的特性是Rust无法比拟的。然而,这不是一个静态的目标。随着它周围的风起云涌和活力,以及每六周发布一次新语言,这一差距正在迅速缩小。

或许更令人担忧的是,更广泛的生态系统还不够成熟。例如,今天构建桌面应用程序的任何人都会因为缺乏事实上的图形用户界面(GUI)工具而感到沮丧。构建新的图形用户界面系统是一项精心设计的多年努力,但在这里,包生态系统和社区的活力大放异彩。程序包注册表中已经列出了数万个板条箱(即库)。尽管过多的选择最终可能会成为它自己的负担,但已经有足够的积木可以开始回答这些问题。事实上,几个早期的图形用户界面库都在争先恐后地这么做。

这说明了采用的最大障碍。现代游戏引擎是不同技术的巨大编排,其中编程语言的选择只是蛋糕的一小块。从零开始打造一台成熟的发动机可能需要十年的努力。我们可以很容易地对多个子技术说同样的话,例如,渲染、网络、物理和音频中间件。

最好重新利用我们能利用的东西。Ruust在这方面有一些优势,从高级语言(如C#)调用本机C代码的成本可能很高。Ruust的行为更像C++,尽管开销可以忽略不计。然而,大多数中间件都是用C++编写的,而不是C,而且没有从Rust调用C++代码的简单桥梁。这并不是说互操作是不可能的,C可以作为将两者粘合在一起的最低公分母,这是一种需要强大胃口的操作。

然而,与任何共同点一样,这种权衡是否会消除我们最初寻求的安全?归根结底,本地解决方案会更可取。在这一点上,生态系统已经在工作,以提供许多构建块。我最初以为图形编程将是最后的顽固者之一,在那里VFX是用基本的类似C的着色器语言构建的。但即使在这里,我们也看到了前景看好的铁锈替代能源。具有讽刺意味的是,这一创新可能是铁锈进入现有发动机的一条途径。

颠覆性技术往往不会仅仅因为它们的技术优势而成功。就Git而言,Github是杀手级应用,它让它在竞争中击败了竞争对手分布式版本控制系统,并最终颠覆了整个行业。

就游戏而言,杀手级应用几乎肯定是游戏引擎。Unity有许多引人注目的特点:易用性和价格点是游戏开发民主化的一场革命。但它在时间上也是独一无二的,成为访问爆炸式增长的iOS应用商店的最佳方式。建立在这种成功和思想共享基础上的团结最终将在移动领域以外的领域展开竞争和颠覆。

思想分享很重要;围绕一项技术建立护城河的良性循环。多年的机构知识让团队不断投入。它保持了他们对广泛人才库的访问权,并最大限度地增加了新平台或中间件供应商更喜欢他们选择的引擎的机会。

对于引擎开发来说,Ruust显示出了作为一种引人注目的语言的前景,对于大型或复杂游戏中系统的业务端的程序员来说,这没有理由有什么不同。然而,并不是每个开发团队成员都达到这个级别,甚至根本不是。对于制作脚本游戏内容的设计师来说,与Rust建立互动性可能是压倒性的。

其他引擎通过提供更简单的接口来解决这种不和谐。要么是像Lua这样的简化脚本语言,要么是像虚幻中的蓝图那样的可视化编程。然而,对于艺术家来说,他们更关心的是艺术管道的效率。

这并不是说铁锈口味的游戏引擎不能解决这些问题,但构建强大的用户体验超出了编程语言的范畴。IT看似铁锈将产生足够的程序员善意来推动采用,毕竟我们是一群固执己见的人。然而,无论是新的工作流程还是新的市场,新的游戏引擎似乎更有可能通过前所未有的民主化来确保其未来的安全。

预测细节将是一种算命行为。然而,我可以提供一些有根据的猜测:

在经历了漫长的磨难之后,开源的Blender开始颠覆3D内容创作软件。我们有理由期待游戏引擎也会紧随其后;然而,戈多已经拥有了显著的先发优势。早期的努力将是与戈多直接竞争,而不是与现任者竞争。

尽管出现了无障碍游戏引擎,但制作内容所需的专业技能仍然是劳动密集型的,因此成本高昂。程序性内容和人工智能辅助艺术工具具有巨大的潜力,可以在这里带来革命,正如早期研究所看到的那样。然而,这一创新也广泛应用于商用发动机,我们已经看到了第一批成熟的成果。

越来越多的排行榜冠军游戏有望提供大型多人共享世界。联网已经很困难,但大规模分布式计算在地狱模式下是困难的。我们已经在这个领域看到了大量风投支持的游戏,希望能为现有引擎上的开发人员提供一种简单的入门方式,到目前为止,结果好坏参半。

在这最后一点上,铁锈或许能够在技术上脱颖而出。无所畏惧的并发性和函数式编程非常适合分布式计算。采用Rust的网络平台只会进一步推动这一事业。一个更好地驾驭这个分布式世界的游戏引擎将具有显著的优势。不过,任何最终的获胜者都有可能实现以上所有目标,甚至更多。

不成熟可以通过时间和努力来修复,但逃离默默无闻的废墟要难得多。没有人想被困在一个下沉的小岛上。虽然不可能说出铁锈的尾巴会有多长,但对于经过验证的技术来说,情况并非如此。即使每个人都在一夜之间停止编写C++,用这种语言编写的代码也会在未来几十年里继续存在。

今年,由于财务状况不稳定,Mozilla解雇了数十名开发人员--包括整个Servo团队(试验性浏览器引擎与Rust配对)。曾经有一段时间,这可能是丧钟。然而,似乎有足够的韧性让这门语言生存和繁荣。随着来自行业的投资,一些团队找到了新家,以及宣布成立一个独立的基金会,我们似乎确实看到了曙光,而不是曙光。

在增量增长的同时。

.