用矩阵求解《异星工厂》的品质系统

查看原文 HN 讨论

文章摘要

作者 Simon Sapin(Servo、Rust 社区的老面孔)开篇一句自嘲:”我玩《异星工厂》(Factorio)的方式很正常:写矩阵运算代码来规划工厂。”这篇文章用线性代数给 Space Age 资料片引入的”品质”机制建了一个精确模型,最后做成了一个在线计算器 factoqual。

品质机制是什么。 Factorio 是工厂类游戏的开山之作:采集资源、合成物品,再用越来越多的机器和传送带把一切自动化。机器有模块槽,速度模块让机器更快但更耗电,产能模块用同样原料多产出,代价是速度和能耗。2024 年的 Space Age 资料片加入了品质系统:所有物品和配方都有五个等级,普通、优秀、稀有、史诗、传说,等级越高属性越好。高品质物品可以用同品质原料直接合成,但要提升品质,只能靠品质模块:它给每次合成一个概率 q 让产物升级,每多跳一级再乘 10%。四槽机器能达到的最高品质概率是 24.8%,一步从普通跳到传说的概率只有 0.0248%。有些玩家不喜欢在一个基本确定性的游戏里引入随机性,但作者说,”重复足够多次,概率就变成了比例”。这套概率的设计决定了想拿高品质物品,就不可避免地会造出大量不想要的低品质品,所以游戏又加入了回收机:把任何物品拆掉,通常返还 25% 的原料。玩家于是搭建”升级循环”:合成、回收、再合成,直到达到目标品质,代价是消耗多得多的原料。

为什么需要数学。 工厂游戏很适合拿电子表格做资源核算,也有少数玩家觉得表格不够用,花大量时间写专门的规划工具(比如 Factoriolab)。作者喜欢提前规划:每种机器要多少台、产量多少、瓶颈在哪。品质升级的循环结构让这件事既难凭直觉估计,也难用现有工具算准。

把品质跃迁写成矩阵。 他把一种物品在五个品质等级上的分布写成一个五维行向量,把一次带品质模块的合成写成一个 5×5 的上三角转移矩阵 T(q):对角线是 1−q(保持原级),右上方依次是 9q/10、9q/100、9q/1000、q/1000 等跳级概率,这和 wiki 上的概率表正好对应;q=0 时就是单位矩阵。这样多步加工就变成了连乘,比如用 7.5% 品质的矿机挖铁矿、5% 品质的熔炉炼铁板、10% 品质的组装机做管道,三个矩阵连乘就能得到最终管道的品质分布,约 79% 普通、17% 优秀、3% 稀有。按品质分拣也可以写成对角矩阵:保留矩阵和提取矩阵互补,相加就是单位矩阵;回收机返还 25% 就是乘以 1/4。

几种策略的计算。

通用方法与工具实现。 对于其他难以归类的策略(他点名了”LDS 洗牌”),方法都一样:把多种物品的流量写成向量,把合成、回收等线性变换写成矩阵乘法,把动态平衡写成矩阵方程,再求解。实现上他先用 Rust 和 nalgebra,但为了得到精确解而非浮点近似,他改用 num_rational 的有理数表示,i128 加溢出检查足以应付 15×15 矩阵(5×5 用 i64 就够)。为了让别人在网页上用,他最终用 TypeScript 重写了全部逻辑,借用 Factoriolab 开源的有理数库,界面用 VanJS 加 Vite,托管在 Grebedoc,成品就是 factoqual.grebedoc.dev,源码在 Codeberg。他在致谢中提到受到 Daniel Monteiro 关于品质数学的博客启发,也认为通过求解平衡方程得到精确解、而不是对无穷级数做迭代近似,是这篇文章新的地方。

HN 评论精华

帖子 282 分、100 多条评论。真正讨论数学的评论不算多,大量篇幅跑到了”新手怎么入坑”、”自动化与 AI 编程的类比”和”太空赌场被砍”这几个话题上。

数学上的补充。 crdrost 直接点出:L 本身不可逆,但 I − L 可逆,所以无穷级数 1 + L + L² + … 其实就等于 (I − L)⁻¹,这正是作者那套平衡方程的另一种写法。JaumeGar 说这和吸收马尔可夫链是同一个技巧:求不动点而不是对循环求和,在列昂惕夫投入产出模型和 PageRank 里也能看到。djkorchi 提出另一种表述:把传说态设为以概率 1 自转移的吸收态,系统 N 轮后的状态就是 Aᴺx₀,对 A 做对角化后各特征值按不同速率衰减,特征值 1 对应的分量就是稳态解,这套方法比作者的期望方程更通用。tobytylam 则提了一个排版建议:数学模式里的描述性文字可以用 \text 包起来,看起来会更好。

同道中人。 scottmsul 说自己也在这个兔子洞里钻得很深,写过 Python 脚本和一个 JS 应用来求解升级循环的线性规划。他学到的最反直觉的一点是:稍微加一点速度模块往往大有好处,尤其在低品质阶段。如果唯一目标是”每个普通原料能换多少传说产出”,速度模块永远是坏的;但升级循环本身要用传说级的机器和模块才高效,真正的限制往往是那些极其昂贵的机器,而不是原料产线,加一点速度能让同样数量的传说机器吞吐量大增,浪费的原料多铺几台矿机就能补上。jvanderbot 说他博客草稿里也有几乎一样的文章,结果”被 Factorio 分了心”一直没写完。willis936 说这正是他完成 Space Age 通关所需要的,他在每个星球建品质工厂时反复迭代设计,反馈循环很慢,”简直是敲石头”,普通表格算不了这种机制。DanielHB 分享了他做的一个蓝图:单台组装机靠切换配方,就能从基础原料一路做出传说品质的大部分物品,只是切换配方会丢掉产能加成进度,实用性有限。DannyBee 说他做过把 Factoriolab 链接自动转成可用蓝图的工具,支持 Factorio、戴森球计划和 Satisfactory,用 CP-SAT 做布局、再单独做走线。hangrybear666 则是反面例子:他靠手动控制的回收循环、浪费了上百万铁和铜才硬刷出传说级机甲护甲。

太空赌场要没了。 fabian2k 说”清洗”和”升级”的差距巨大,与他的体感一致,能看到量化很好;他也指出更好的品质模块效果非线性,容易被低估。但他和 unglaublich 都提到,文中的”太空赌场”在 Factorio 2.1(目前是实验版)里已经不能用了,因为小行星再处理不再接受品质物品,开发者在 FFF-442 中解释说这样拿传说物品”太容易了”。kabakabakaba 对此很高兴,认为它太有效、毁了乐趣。butlike 和 unglaublich 则用”不喜欢就别用”反驳,someonebaggy 回敬说”那你怎么不去玩地图编辑器”;infogulch 认为开发者要为普通玩家塑造体验,去掉一个显而易见的全局最优解,反而会冒出许多有意思的局部最优设计,想要旧玩法可以装 mod「bring-back-space-casino」。oefrha 提到靠火山星 Vulcanus 的无限岩浆,刷品质依然容易;jfindley 指出纯流体配方不支持品质,weberer 给出一条路线:只需开采传说煤和方解石,经塑料、低密度结构、混凝土等回收,就能得到传说铜、钢和铁矿。

入坑门槛。 排第一的评论来自 shellwizard:他多次想玩 Factorio 都被陡峭的学习曲线劝退,觉得它不像游戏,更像在管理复杂的软件架构。CodesInChaos 建议关掉虫子(或至少关掉扩张),用主干道(main bus)布局起步;fxwin 干脆推荐和平模式,说虫子像一个跑来打断你的同事,不聊天,而是关掉你一半标签页、清空浏览器登录、还偷走你的咖啡杯。gHA5 则坚决反对向新手推荐任何布局模式,说他最快乐的经历就是摸黑打到火箭、跟自己的意大利面工厂搏斗。Joker_vD 指出真的有一个把 Factorio 接入 Grafana 的 mod,fragmede 的回复是一段三连:”去你的”、”装好了”、”怎么已经凌晨四点了”。

自动化与 AI 编程。 lordnacho 的长评引出了一条主线:他和孩子玩了很久,但有了建设机器人和蓝图库、再装上自动放置 mod 之后,他发现自己更在乎维护组件库,而不是亲手接线,”不知怎么就把乐趣毁了”。他把这和 AI 编程相比:很多人抱怨的是”不再真正写代码了”,微操没了,工作的性质变了。9dev 说 Factorio 是软件工程”好得过分的隐喻”,但游戏里没有复杂度熵增的惩罚,而现实中抽象层叠得越高,故障率越高。setr 认为乐趣从来不在放置物体这个动作,而在于应对混乱和修正它;Pifanjr 说他一到需要复制粘贴扩产的阶段就失去兴趣,bigstrat2003 补充了 Portal 2 设计师的经验:让难点永远在想出解法,而不在执行解法。wren6991、Pannoniae 等人分享了”蓝图不跨存档”的规则,认为用别人的蓝图是杀死乐趣最快的方式;ssl-3 则相反,恨不得尽快拿到机器人,好把精力放在跨星球物流这类他真正喜欢的问题上。DharmaPolice 说游戏最终的 boss 是 UPS(每秒更新数),”工厂必须扩张”到最后反而让问题更糟。

现实与游戏。 jordiburgos 说要选做这种分析的人当总统;onion2k 提醒现实中有人在不断利用和改变系统,而游戏里的系统不会在你脚下变化;jcranmer 举了胡佛当例子,说技术官僚能力未必造就好总统。bob1029 好奇如果把投在这个游戏上的精力拿一小部分去优化真实的农业和工业会怎样,Liftyee 列出游戏与现实的差别:没有官僚和审批、建造瞬间完成可逆、机器没有半年交期、维护靠魔法。sdenton4 说现实自动化的真正瓶颈是维护,delichon 回了一句:”Factorio 把随机故障建模成了外星生物的袭击,出奇地贴切。”lowbloodsugar 吐槽品质机制让游戏变成了”垃圾管理游戏”:就像福特为了得到一辆林肯,造 2800 辆 Explorer 再拆回零件重来。另有几位”被书呆子狙击”的读者纠正文章开头”Factorio 开创了工厂游戏类型”的说法:michael-online 指出它深受 IndustrialCraft 2 等 Minecraft 模组影响,weegee101 提到 1996 年的 Free Enterpri$e,Pet_Ant 提到 Zachtronics 的 SpaceChem。