Alt-F4 #53 - 自动化偷懒  2021-11-26

作者 Therenas, 编辑 stringweasel, Nanogamer7, Conor_, Firerazer, MyNameIsTrez,
翻译 Ph.X

目录

在地处黄金地段的第 53 期 Alt-F4 中,Therenas 大师又回来恩赐予我们一篇新文章。承接他之前着重于谈论自己 Mod 的杰作,这次是全新的复刻内容大放送。本期探讨了异星工厂中自动截图的话题。虽然实际内容只有 20% 的技术细节,此外加上 40% 的哲学和 50% 的冷笑话。你没看错,合计高达 110 点!

自动化偷懒 Therenas

我经常苦恼于为我的 Mod 拍摄适当的截图。要把一个场景设置得很吸引人 并且 以视觉方式解释 Mod 的核心概念,需要做很多工作。在我看来,很多 Mod 缺乏优秀截图,并非由于 Mod 作者不关心,而是因为制作好的截图真的很困难。虽说 一图胜千言,但截图需要他们用相当有限的“语言”做大量的工作。

尽管这一切听起来像在发牢骚(也确实如此),但实际问题不在于截图本身。在你花了几十个或几百个小时来做出这个 Mod 之后,再花几个小时为这个 Mod 截图是完全可以接受的。实际的问题是保持它们更新。你对 Mod 所做的每一个改动,最好都能在更新的截图内反映出来;如果截图过时了,对我来说就是一种缺乏关注的信号。当然也可能是我太过偏执。

当然更新的频率取决于每个 Mod 自己。如果是瓶颈这种不常改变的,那你的截图就不会过时。如果你是一个相当复杂的 GUI Mod,几乎每个版本都会在这里或那里改变你的界面的一些像素。理想情况下,一个耗时 5 分钟的 UI 修复应同时伴随更新截图,但这将让你花更多的时间在截图而非实际的开发工作上。没有人愿意这样做,因此截图总会随着时间的推移而过时。

人类心理学使这种影响更加复杂,并造成了一种恶性循环。如果你知道你的截图每隔一个版本就需要更新,你就会决定跳过更新它们,只跳这一次。下一版本无论如何都会有另一个变化,那么为什么还要现在去更新它们,这不是在浪费时间嘛。当下一个版本到来时,同样的心理会导致你再一次拖延。就这一次。永无止境地重复下去。

也许只有我是难以置信的懒惰,正常人不会有这样的问题。他们可能只会定期更新截图,因此大部分时间都会是最新的。但我不是。在实践中,它导致我大约每六个月更新一次截图。我为他们没有及时更新而烦恼,但“下次再做就好了”的心态在面对一周后就白干了的事实面前显得格外强烈。

不过,我还是想要一个解决方案。我需要一个解决方案,哪怕只是为了免除我对过期截图的自我愧疚。当然,这并不难做到。工作是不可能工作的,下周再做。自动化看来是应许之地,有时如此,有时确实如此。

我以前自动化过一些与 Mod 开发有关的流程,最知名的是构建一个新版本的流程和所有与此相关的细节管理。在这个特例中,这甚至不是因为我不想为我所有的版本做同样繁琐的步骤(至少 169 个版本的工厂规划师),更多的是为了防止我在这个过程中犯错,以免用户得到错误的版本等等,这可不妙。

快来截图吧!

好了好了,让我们进入有趣的部分。我的想法很简单。写一个 Python 脚本来启动异星工厂进入一个自定义场景,然后接管实际的截图部分(感谢异星工厂有一个截图专用的 API 方法),之后脚本会把截图放到正确的文件夹中,也许会对它们进行一些裁剪。第一部分相当容易,我只需要弄清楚我需要哪些命令行参数,把它们串起来,然后场景就可以运行了。到目前为止,如此简单。

不过实际情况要复杂一些。为了能够截出有意义的图,我需要在不同的状态下设置各种 GUI,以显示我想要突出的功能。对地图上的实体做这种事情比较容易,因为你可以使用你通常使用的与游戏世界互动的所有 API。不过,对于 GUI 来说,它们有点自成一体,你必须构想出你自己的系统。

最大的问题来自于无法模拟一个实际的用户点击你的界面。游戏中没有任何此类 API 方法,因为任何实际的 Mod 都用不着。但这意味着你需要以某种方式来模拟点击。这有点尴尬,因为除非你的 Mod 从一开始就为此设置,或者结构非常好,否则你将需要重写你的事件处理程序或者整点黑科技。你也许能猜到我走的是哪条路。

在把黑科技整理好后,这玩意儿就能启动游戏,把界面设置成一个有趣的场景,并对用户界面的各个部分进行截图。我必须指出,所有这些都是勉强能跑,而且很有可能在 Mod 代码更改后出错。但在这一特殊情况下,没有真正的替代方案,所以我不得不忍受它。不管怎么说,建立一堆屎山代码要比一次又一次地手动拍摄相同的屏幕截图有趣得多,所以无论如何都是一种胜利。

到目前为止我对我所做的工作相当满意,但最大自动化尚未实现。你看,还有一个问题就是要把截图裁剪得更小。在工厂规划师中的许多对话框都比较小,而背景中的游戏世界会让人分心。我可以手动进行裁剪,但我不想这样做。。我的脑海中有一个潜在的解决方案,但它需要一些脏活。

基本想法是,在场景拍摄屏幕截图的同时,也记录下正在拍摄的对话框的尺寸。然后,这个元数据也被写入一个文件,Python 脚本可以用该文件来裁剪屏幕截图到合适的尺寸。听起来理论上是个好主意,但在现实中却遇到了一个小问题。游戏不允许你读取 GUI 窗口的尺寸,只允许写入尺寸。

禁止这么做还算合理的,因为这些尺寸实际上并不是在所有情况下都是确定的,例如,不同的游戏语言可能会改变某些元素的尺寸。在多人游戏中读取和使用这些不确定的值会导致不同步,使 Mod 与多人游戏不兼容,也会破坏重放。这似乎是一个死胡同。我是否注定要永远手动裁剪屏幕截图?事实证明,这并非我的命运。

现在,我无法解决读取对话框尺寸导致解同步的问题,这是游戏底层的运行方式。然而,我并没有在多人游戏中运行游戏来拍摄这些截图,事实证明,你已经可以在一个名为仪表模式的特殊模式下启动游戏,该模式禁用多人游戏并启用一些不安全功能。这似乎是一个完美的地方,可以塞进一个超级秘密的隐藏方法,使我能够获得关于对话框尺寸的禁忌知识。所以我就这么干了。事实证明,给 Wube 打工确实有好处。

经过几天的黑科技开发,这头野兽终于咆哮着活了过来,为我实现了屏幕截图过程的完全自动化。但还不是 完全 自动化流程。事实证明,它仍然没有完全自动化。它当然不是。我怎么会得到 完全 的满足呢。有两个步骤,我仍然需要自己做。

首先是在截图后退出游戏,以便 Python 脚本能继续执行。事实证明,Mod 不能让异星工厂退出到桌面。为了防止滥用,这是完全合理的,尽管对于仪表模式而言将是一个很好的选项。无论如何,在适当的时候按下 Alt-F4()我想是能做到的。我有一个侵入性的想法,就是想办法让游戏崩溃以达到我的目的。我警告过你,这都是一堆黑科技。这个计划的问题是,游戏中很少有这样的 Bug,一旦被发现,你可以肯定 Bug 粉碎机会立即粉碎它们。

第二是将这些刚出锅的新截图上传到 Mod 门户。目前还没有合适的 API 来操作 Mod 门户网站的列表,所以我在这方面很不走运。现在,我不得不手动打开浏览器,逐一删除我的截图,然后逐一上传新的截图。真是悲剧!。也许将来会有此类 API 的希望,让我们拭目以待。

除了这两件事,我对这个结果很满意。我想这是值得的,因为我可以无限期地收获这个脚本的好处。自动化的乐趣。无限的收益。至少在它第一次坏掉之前是这样,而这可能很快就会发生。哦,好吧。

征稿

一如既往的,我们正在召集任何想要为 Alt-F4 做出贡献的人,无论是提交文章还是帮助翻译都可以。如果您有些有趣的想法,并乐于与社区分享,这里就是一个好地方。如果您没有太大把握,我们会很乐意帮助您讨论内容创意和结构问题。如果您有意参与,从加入 Discord 开始吧!