#string #output #text #ringhopper #version #original #invader

已删除 ringhopper-strings

Ringhopper文本输出中使用的字符串

使用旧的Rust 2015

0.1.0 2022年10月29日

#125#original

GPL-3.0-only

9KB

invader

这是Invader的Rust重写。

原始的C++项目可在https://github.com/SnowyMouse/invader找到

Invader采用GNU通用公共许可证版本3授权。有关更多信息,请参阅LICENSE.txt。

结构

所有源代码位于 src 文件夹中。

  • src/invader - 命令行前端
  • src/ringhopper - 用于修改《Halo: Combat Evolved》的Rust库。

为什么Invader需要重写?

Invader对我而言变得非常难以维护,而原始版本也是在技能水平和知识量都截然不同的时期开始的。

原始的Invader也因功能堆叠而存在许多问题,因为Invader的原始实现没有真正的目标,除了编译多人Halo Custom Edition缓存文件。

没有预料到它将成为一个用于从头制作资源的完整工具包,因为在Invader开始时,并没有完全意识到这一需求的重要性。

Invader解决的问题

当时,人们普遍认为我们已有的东西已经满足需求

  • 我们在HEK的Guerilla和MEK的Mozzarilla中有一个标签编辑器
  • 我们在MEK的Refinery中有一个标签提取器
  • 我们可以使用tool.exe构建缓存文件并制作位图、声音、模型等
  • 我们有一个实现整个游戏的场景编辑器,使用Sapien

最初,拥有更好的缓存文件构建功能的想法只是一个有趣的小项目 - 一个与MEK一起使用的开源应用程序,帮助制作一个不错的开源工具包。

然而,事实证明,Halo Custom Edition和Halo CEA的编辑套件存在许多问题,这些问题只能通过一个完整的开源重实现来解决。

  • 错误检查不足:原始的HEKs有一些错误检查,但它们通常引用的是不公开的源文件,并且打印出的任何消息都非常模糊。通常只是断言,或者最糟糕的是,缺乏任何有用信息的异常错误。在大多数情况下,它甚至不会在真正的有问题标签数据上出错,而把找到可能导致游戏崩溃的东西的责任留给您,即修改者。

    当涉及到制作游戏时,这可能还好。Bungie可能没有预料到这个编辑工具包会被用于在工作室内部制作《光环》(或者那次《僵尸斯图布斯》)。那里的错误检查足够制作游戏。然而,修改者需要更多东西来制作自定义内容,因为整个引擎基本上是一个黑盒,因为它是闭源的。

    高质量的准确错误是必要的,这正是Invader在原始C++版本中做得非常好的事情(尽管重写可能会做得更好!)

  • 信息不足:工具是闭源的,几乎没有官方文档,这意味着理解标签系统和其他编辑《光环》内容方面可能很困难。

    Invader完全免费,并且自从它首次公开发布以来一直如此。通过拥有一个完整的开源修改工具包实现,我们可以更好地理解《光环》的整个引擎,因为所有关于如何使这个引擎工作的验证和实验都已经完成,并且通过Invader的源代码进行了记录。拥有公共信息和更多内容可以使社区具有可持续性。

    多亏了Invader是一个免费的工具包,我们现在对缓存文件中存储的每个字节都进行了计数 - 游戏引擎中加载的最后一个比特。每个隐藏字段都是已知的,并且预先处理的内容都有记录。由于像Invader这样的免费工具,现在在修改游戏时不再有任何“陷阱”。

  • 性能问题:使用Halo编辑工具包构建缓存文件或打开大型标签需要非常多的时间。在2016年(距离《光环》原始Xbox发布超过15年后)的PC上打开具有复杂几何形状的BSP标签可能需要超过20秒。这可能看起来并不长,但当您不断打开和关闭标签时,20秒就会积累成很多时间。当前的Invader在相同的机器上打开这些相同的标签只需要不到一秒,甚至可以比Guerilla打开该地图的BSP更快地编译地图。

    原始工具是为Windows的32位x86编译的,尽管《光环:战斗进化纪念版》的当前版本原生支持现代的64位x86 Windows。

    据称,游戏中进行的许多检查和断言进一步减慢了游戏速度。当前的C++实现显示,我们可以在实现更强大的错误检查和更多功能的同时,达到比原始《光环》编辑工具包更高的性能。我们甚至可以针对现代PC和Linux,这是Invader直接支持的,通过一个Arch Linux AUR软件包

当前的C++ Invader有什么问题?

如前所述,Invader存在一个问题,就是当时为了实现一个需要的特性而匆匆添加了一些功能。

例如,Python代码是一团糟,生成大量C++代码以便运行Invader更快。这导致编译时间过长,并且很难对解析器进行增量工作。

还有一个hek模块,最初是为了存放从《光环》编辑工具包中逆向工程或提取的定义而存在的。这已经成为一个不一致、令人困惑的混乱,导致我在源代码树中寻找东西时也花了很长时间。

我也认为很多代码可以写得更好。大部分现有的代码使用起来是没问题的,但很多都是用一些不太正规的方式编写的,为了“完成事情”而针对多个引擎。例如,定义没有任何标志来区分不同的游戏引擎。这些本应在项目开始时就添加进去的东西,但我再次没有预料到《入侵者》会变得如此庞大。

为什么选择 Rust?

Rust 是一种优秀的语言,它强调安全而不牺牲速度。这对于这样一个由极少数开发者参与的大型项目来说非常有利。无意中破坏了已经存在多年的代码或触发了难以调试的段错误是非常令人沮丧的。

Rust 的生态系统也通过 cargo 程序提供了内置的功能,用于单元测试和外部模块。这意味着代码在发布前可以测试是否损坏。

使用 Rust 进行静态链接也要容易得多,因为这是默认操作。动态链接是一种反模式,会导致分发大量 DLL 文件和寿命不长的可执行文件。动态链接只有在系统库(如 kernel.dll 或 Linux 内核)等稳定的且在目标机器上保证存在的 API 上才有意义。如果目标机器上没有预期的动态链接库,则会导致依赖性问题。对于 Linux,包管理器试图解决这个问题,但 API 破坏仍然会发生。对于 Windows,使用工具包分发的 DLL 文件超过 100 MB 会导致使用体验不佳,有时 DLL 文件可能会冲突或需要单独更新。

总的来说,Rust 和 Cargo 提供了完成这项工作的正确工具。我仍然认为 C++ 是一种非常棒的语言,但 Rust 本身就是为了解决我在开发《入侵者》时遇到的一些问题而设计的。

C++ 项目会发生什么?

目前,C++ 项目将继续维护,直到 Rust 重写达到功能一致性。对《光环:战斗进化纪念版》的模组功能未来版本的更新和支持将继续进行,并将继续修复主要错误。

然而,一旦重写包含了 C++ 版本的《入侵者》的所有功能并证明是一个可行的替代品,C++ 版本将被完全弃用。此外,重写版本的版本号将继续从完成时的 C++ 版本号延续(例如,如果《入侵者》的版本是 0.60.3,则重写将是 0.61.0)。在此之前,Rust 重写的版本号将保持在 0.1.0 作为占位符。

依赖关系

~1.5–2MB
~48K SLoC