deniz.in

Markets

Weather

Loading weather

· via Hacker News – Front Page (native)

How the original SimCity simulated a whole city on a 16 MHz CPU

A larstofus.com deep dive that reached Hacker News' front page traces the original SimCity's 16 MHz trick: rotate simulation work across frames so most systems simply don't run most of the time.

How the original SimCity simulated a whole city on a 16 MHz CPU

A blog post dissecting how the original SimCity simulated an entire city on a 16 MHz processor was upvoted to the front page of Hacker News, and its central finding is disarmingly simple: the game skipped most of its simulation on most frames.

The post, published on November 16 at larstofus.com, digs into the source code of Maxis's 1989 city builder and argues that early entries in the genre are a more startling technical achievement than the era's graphical landmarks. Games like Doom and Quake usually get the credit, the author writes, but modelling whole economies with a sliver of modern processing power is harder to comprehend — especially when contemporary builder games struggle on today's hardware.

A 386SX and a hard budget

The original SimCity listed Intel's 386SX among its system requirements. That chip ran at 16 MHz when it launched, according to the post, which corrects an earlier version of the text that cited 12.5 MHz — the clock rate of the base processor rather than the SX variant.

So how did Maxis fit a full simulation into that budget? Many of the reasons are external, the author notes, pointing to the operating system ecosystem of the time. But the game code contains a deliberate optimization worth studying, and it has been publicly readable since 2008, when the source was released under the GPL as Micropolis. Only the code was open-sourced, not the trademark, which is why the project carries a different name.

One function, rotated in sixteenths

When analyzing performance, roughly 90 percent of the codebase can be ignored, the post explains. The interesting part is a single function, Simulate() in s_sim.c, which runs every frame and dispatches work to the game's subsystems — routines such as CrimeScan(), FireAnalysis() and CollectTax() that model traffic, fire, power and crime.

Calling all of those every frame would have overwhelmed the 1989 hardware. Instead, Simulate() receives a parameter the author flags as unusual: where a modern game loop would pass a delta time, SimCity passes a counter cycling from 0 to 15, and that value decides which slice of the simulation executes in the current frame. Most subsystems simply sit out most frames.

The gameplay cost, per the author: a given aspect of the simulation takes eight frames on average to react to a player's action, and up to 15 in the worst case. That would be ruinous input lag in a shooter, but for a city the author argues the delay may even feel more natural than an instant response.

A pattern that never went away

The technique generalizes beyond one genre, the post continues. The racing game Assetto Corsa (2014) renders its car reflections with periodically refreshed cubemaps; rather than updating all six faces of a cubemap every frame, it refreshes only a few, governed by a FACES_PER_FRAME setting visible in its configuration file and tied to the reflection quality option.

A more dynamic variant decides the size and contents of each portion at runtime, based on factors such as screen size or the time since the last update. The author credits this approach with why Unreal's Lumen can look as good as it does without recomputing all lighting every frame — and notes the familiar side effect, since reflections occasionally display visibly incomplete updates.

Why it matters

Spreading expensive work across many frames instead of doing it all at once is one of the oldest ideas in game programming, and Micropolis remains a rare case where a complete, shipped implementation can be read line by line. The idea scales up rather than dating: Lumen is the same trick in modern dress, and its artifacts show that even current hardware cannot afford to do everything every frame. The post ends with a question the author suggests gameplay programmers ask themselves: whether all of that code truly needs to run every frame.

  • #simcity
  • #retro-computing
  • #game-development
  • #performance
  • #optimization

Related posts