Running SimCity 3000 in 4K: What Old Games Teach Modern Devs

A 26-year-old city-builder running at 3840×2160 should be impossible — or at least, deeply unreasonable. SimCity 3000 shipped in 1999 when 800×600 was considered a generous resolution. Yet someone got it running cleanly in 4K in 2025, and the technical journey to get there is one of the more instructive software archaeology projects you will read about this year.

The lessons buried in that project have nothing to do with nostalgia. They are directly relevant to anyone maintaining a legacy codebase, building software that needs to survive a decade of hardware drift, or shipping SaaS products today that will be someone else's migration headache in 2035.


Why Old Software Breaks on New Displays

Resolution independence is something modern frameworks advertise loudly — SwiftUI, Jetpack Compose, Flutter, and React Native all claim to handle it gracefully. But the problem is almost never the framework. It is the assumptions baked into application logic.

Classic games like SimCity 3000 hardcoded pixel dimensions everywhere:

  • Sprite positions calculated as fixed integer offsets
  • UI panels sized to exact pixel counts
  • Mouse hit-testing tied to screen-space coordinates
  • Asset textures rasterised at one resolution and never meant to scale

When you multiply those numbers by four to reach 4K, every assumption compounds. A button that sat neatly at pixel 640 now sits at a fractional logical position. Sprite sheets blur or tile incorrectly. The engine may cap frame buffers at dimensions it never anticipated.

Getting around this requires intercepting the rendering pipeline — typically by wrapping DirectDraw or OpenGL calls — and injecting a scaling layer that the original binary never knew existed.


The Compatibility Layer as a Design Pattern

The tool of choice for projects like this is usually a combination of a DLL shim (replacing the original graphics API implementation) and a patching layer that rewrites specific memory addresses at runtime. Projects such as dgVoodoo2 and community-built wrappers follow this exact model.

This is not a hack. It is a legitimate architectural pattern: the adapter pattern applied at the binary level.

[SimCity 3000 binary]
        |
        v
[Custom ddraw.dll shim]   <-- intercepts all draw calls
        |
        v
[Modern Direct3D / OpenGL renderer]
        |
        v
[4K framebuffer on your GPU]

The application believes it is drawing to a 1024×768 surface. The shim captures those draw calls, upscales geometry and textures using modern filtering, and composites the result onto your actual 4K display. The binary is untouched. The experience is transformed.

Software teams deal with analogous problems regularly: wrapping a brittle third-party SDK so the rest of your codebase does not have to care about its quirks, or building a translation layer between a legacy REST API and a new GraphQL surface. The pattern is the same. The stakes are just lower than city-building nostalgia.


Hardcoded Assumptions Are Technical Debt With Interest

The deeper lesson here is about the cost of hardcoded values that seem reasonable at the time.

In 1999, no engineer at Maxis was negligent for assuming screens would not be four times larger in 26 years. But the same mistake made today — hardcoding a pixel density, a viewport ratio, a font size in absolute pixels, or a network timeout in a way that cannot be configured — is genuinely negligent. We know better now.

Consider how many SaaS applications today:

  • Store layout constants as magic numbers scattered across stylesheets
  • Hardcode API rate limits that only work at current traffic volumes
  • Assume a specific database row count will never exceed an integer type
  • Build file upload logic that caps at sizes that made sense in 2020

Every one of those is a SimCity 3000 moment waiting to happen. Not in 26 years — probably in three.


What Good Longevity Engineering Looks Like

Software that ages well tends to share a few characteristics:

Separation of concerns at the data layer. SimCity 3000's city data format turned out to be remarkably stable — it is the rendering layer that crumbled. When your business logic and your presentation logic are tightly coupled, both break together.

Externalised configuration. Any value that describes the environment the software runs in — screen dimensions, memory limits, API endpoints, hardware capability flags — belongs in configuration, not source code.

Thin platform-specific layers. The thinner your OS or hardware-specific code, the easier it is to swap in a compatibility shim later. This is why cross-platform frameworks exist, but it applies equally to how you structure internal modules.

Documented invariants. The original SimCity codebase presumably had assumptions that were never written down. Future maintainers had to rediscover them by reading assembly. Write down what your code assumes. It costs ten minutes now and saves days later.


Reverse Engineering as a Skill Worth Respecting

There is a class of engineer who can read a disassembly, identify what a function is doing from its memory access patterns, and write a shim that intercepts it without source code. That skill is criminally undervalued in mainstream software hiring.

For African tech teams building on top of third-party platforms — payment gateways, telco APIs, legacy ERP systems — the ability to debug at the binary or protocol level is practically a survival skill. Not every vendor will hand you source code or respond to your support ticket. Sometimes you have to read the traffic, instrument the call stack, and figure it out.

The SimCity 4K project is a reminder that deep technical curiosity, applied patiently, can resurrect anything.


Why This Matters for Your Project

If you are building software today — a SaaS product, a mobile app, a custom enterprise system — the question is not whether your assumptions will become liabilities. They will. The question is whether you have built the seams that make them replaceable. Invest in clean interfaces between layers, externalise your environment assumptions, and document what your code takes for granted. The engineer who inherits your project in 2035 may not have source code either. Make their life easier than the SimCity 3000 modders had it.


Source: "SimCity 3k in 4k (2025)" — https://www.thran.uk/writ/hdid/2025/12/simcity-3k-in-4k.html, via Hacker News