Skip to content

Bringing a 2012 game back to life

Clash of Clans v1.70 shipped in 2012. It was built for the iPhones of that era: iOS only, compiled for 32-bit ARMv7. None of that survives in a usable form today — Apple dropped 32-bit support in iOS 11, the game long ago moved on to newer versions, and there's no source code. All that remains of v1.70 is a 4 MB binary.

The game itself is still online today — but the live servers only run the latest version and won't talk to a decade-old client, and there's no server source code to fall back on. So a 2012 client has nothing to connect to.

This project takes that binary and makes the game playable again — not in an emulator-of-an-emulator, but as a native app that runs on modern phones, desktops, and even in a web browser, talking to a brand-new server that speaks the original v1.70 protocol.

Play it now in your browser

Why this version? v1.70 is the very first public release of Clash of Clans — the game in its original 2012 form, before a decade of updates reshaped it. The goal was to bring back exactly this version, with its original features intact — global and local rankings, the full battle simulation, alliances, chat, and more — as a living snapshot you can hold up against today's game to see how far it evolved.

Getting there means making two things work, and the second depends on the first:

  • It has to run on modern platforms. The 32-bit iOS app won't launch on any current device, so the game first has to be recovered, translated off ARMv7, and given back the iOS environment it expects.
  • It needs a complete, safe server. The game is online, and nothing it can reach still speaks its protocol. But a faithful, authoritative server can't be guessed from network captures — it has to run the identical game logic as the client, or the two desync. So recovering that logic sits underneath everything.

Those needs became four layers of the stack:

  • You can't port what you can't read

    The only artifact is a stripped, optimized binary. We turn it back into readable, rebuildable assembly and C++ headers so the game logic can be studied — and re-built — one function at a time.

    → Reversing the binary

  • 32-bit ARM won't run on modern CPUs

    We built a static ARM recompiler that rewrites every ARM instruction as equivalent C++ ahead of time. The game becomes ordinary C++ that any modern compiler can target — arm64, x86, or WebAssembly.

    → The static recompiler

  • The binary expects an iPhone from 2012

    The game calls into iOS: UIKit, OpenGL ES, sockets, the filesystem, malloc. We re-implemented that whole environment as a portable runtime, with a thin platform backend for each host.

    → The iOS runtime

  • The live servers moved on

    A 1.70 client can't talk to today's servers, and the original code is gone. We rebuilt a compatible server in C#, reusing the reverse-engineered game logic through a C++→C# transpiler — and reproduced the game's deterministic lockstep sync.

    → The C# server

The whole stack at a glance

flowchart TB
    subgraph SRC["The only input we had"]
        BIN["Clash of Clans<br/>4&nbsp;MB ARMv7 iOS binary · 2012"]
    end

    subgraph RE["1 · Reverse engineering"]
        ASM[".S assembly + .h headers<br/><i>byte-identical, rebuildable</i>"]
    end

    subgraph CLIENT["The client"]
        LIFT["2 · armv7re<br/>static ARM → C++ recompiler"]
        CPP["Portable C++<br/><i>the whole game, as functions</i>"]
        RT["3 · runtime<br/>iOS environment emulator"]
        APP(["Native app<br/>arm64 · x86 · WebAssembly"])
    end

    subgraph BACKEND["The server"]
        CPP2CS["cpp2cs<br/>C++ → C# transpiler"]
        SRV["4 · C# game server<br/><i>safe, crash-resistant</i>"]
    end

    BIN -->|IDA + decomp pipeline| ASM
    ASM -->|lifted at build time| LIFT --> CPP
    CPP --> APP
    RT --> APP
    ASM -.->|game logic ported| CPP2CS --> SRV
    APP <-->|"original 1.70 protocol<br/>(RC4 over TCP)"| SRV

The left-to-right story: a single binary becomes readable assembly; that assembly is recompiled into portable C++ that runs natively on any CPU; a runtime supplies the iOS environment the game expects; and a from-scratch C# server — populated with game logic transpiled straight from the same reverse-engineered code — gives it something to talk to.

The revived village Clash of Clans v1.70, rebuilt — running natively today.

How to read these docs

The four layers are independent enough to read in any order, but they were built in the order below, and each one explains why it was necessary before how it works:

  1. Reversing the binary — from a 4 MB blob to rebuildable source.
  2. The static recompiler — ARM instructions → C++, ahead of time.
  3. The iOS runtime — re-implementing iOS so the game feels at home.
  4. The C# server — a safe, modern reimplementation of the backend.
  5. Running it everywhere — the same game on macOS, iOS, Android, and the web.

Why not just use an emulator?

A general-purpose emulator (like a dynamic recompiler / JIT) can run the binary, but it can't ship on the App Store (JITs are banned), can't run in a browser, and pays an interpretation tax forever. By translating the game to C++ once, at build time, we get a normal native binary on every platform with no runtime translation cost. That trade-off is the spine of the whole project — see the recompiler chapter.