现代城市建设游戏通常需要多核 CPU 和每秒数 GHz 的处理能力来模拟复杂的经济、交通和基础设施。然而,原始的 SimCity 能够在 Intel 386SX 处理器上运行这些模拟,而该处理器的运行频率仅为 16 MHz。这一工程壮举并非依靠原始的硬件性能,而是通过巧妙的软件优化,将计算权重分布到不同的时间段中实现的。

原始 SimCity 游戏中的一个复古城市建设模拟场景。
原始的 SimCity 通过巧妙的软件优化,在 16 MHz 硬件上实现了复杂的城市模拟。larstofus.com

这张图片展示了原始的 SimCity 游戏,文章将其作为受限硬件上高效软件工程的典型案例进行讨论。

对该游戏的开源代码(2008 年作为 Micropolis 发布)的分析揭示了 `s_sim.c` 文件中 `Simulate()` 函数的一个特定机制。游戏并非在每一个帧中都执行所有的模拟子系统——例如犯罪扫描、火灾分析和税收征收——而是使用了一个 `mod16` 参数。该参数作为一个帧计数器,在 0 到 15 之间循环,决定在任何给定的帧中更新模拟的哪一部分。通过在大多数帧中跳过大部分模拟逻辑,游戏将每帧的 CPU 负载降低到了 1980 年代硬件可以处理的水平。

虽然这种技术会在游戏对玩家输入的反应上引入轻微的延迟,但在城市建设类游戏中,这种权衡通常是可以忽略不计的。平均而言,一个模拟方面可能需要 8 个帧才能做出反应,最坏情况是 15 个帧。这种将工作分布到不同帧的原则并不局限于复古游戏;它仍被用于现代游戏,例如在 Assetto Corsa 中用于反射渲染,以及在 Unreal Engine 的 Lumen 系统中用于管理光照计算。SimCity 的例子提供了一个基础性的证明:许多沉重的计算任务可以通过思考它们是否真的需要在单个帧内完成来进行优化。