Replaying a village raid
Crown & Clan is a village-building and raiding game in the mould of Clash of Clans, written in TypeScript and Phaser with no server behind it. Because it is an independent fan project (“Clash of Clans assets and trademarks belong to Supercell,” its README notes), the figures here draw plain geometric shapes instead of sprites. Every battle in them was simulated by the game’s own engine in Node across the twelve campaign villages the project designed itself.
A simulation with no screen
One architectural rule governs the entire 66,000-line codebase: GameModel may never import Phaser, a scene class, or a single byte of rendering data. Fifty-three files in the repository touch Phaser, and none of them is reachable from the simulation. During a live battle, the Phaser scene steps GameModel twenty times a second (step(0.05)) and interpolates unit positions between ticks so movement looks smooth at any display refresh rate without the model knowing frames exist. Because the simulation is pure TypeScript, the exact same class runs live raids in the browser, verifies deterministic replays in CI, and generated every figure on this page from a Node script.
Where you attack from
Once deployed outside the shaded exclusion zone, every unit follows a greedy target rule: Barbarians and Archers march toward the nearest building of any kind, while Giants ignore resource huts and head straight for the nearest defense. That makes your landing point decisive, because it determines which defenses your Giants engage first and how long your damage dealers survive behind them.
Deploy the exact same 42-troop army (6 Giants, 4 Wall Breakers, 16 Barbarians, 16 Archers) from twelve points around Ember Keep and the outcomes split completely. From the northeast, the army strings out into the village’s defenses one at a time and dies at 37% destruction with zero stars. From lower down the same side, four of the six Giants survive into the core and the raid clears the village for all three stars in 42 seconds:
b.stars = Number(b.destruction >= 50)
+ Number(townHallDead)
+ Number(b.destruction === 100);
Routes through walls
findPath. Red: walls a route breaks through.Every ground unit finds its way across the 48×48 tile grid with four-directional A*. Buildings are solid obstacles, while walls are passable at a price: stepping onto open grass costs 1, and stepping through a wall tile costs 7. A troop will detour up to six extra tiles around a wall before deciding to stop and batter through it, recomputing its path whenever a building or wall segment falls.
Because Giants only target defenses—and Ember Keep’s defenses sit inside stone compartments—20 of the 64 perimeter starting points send them straight through a wall. Barbarians settle for the closest building of any kind, which from the perimeter is always an outside building, so their initial paths never break a wall at all.
One army, twelve villages
Because GameModel runs without a screen, balancing the twelve-stage single-player campaign means sweeping test armies across every village in Node. Deployed from the west, the small starter army fades after the fourth village, while the medium ground force holds three stars through village eight. Air (Balloons and Dragons) flies over every wall to clear the first eight villages just as easily as the ground army, then falls off sharply on the Expert stages as soon as villages gain a second Air Defense.
Every step, recorded
Crown & Clan does not record a battle as video or as a stream of unit positions. A replay saves only the initial setup and your timestamped taps, then simulates the battle again from scratch—45 actions and 317 step sizes for the 16-second raid above, under 10 KB in all.
That only works if simulating the raid a second time produces the exact same battle to the bit. Combat uses no ambient random number generator, hashing a fixed battle seed with a counter whenever a rule needs chance. Distances are computed with explicit arithmetic because browser implementations of Math.hypot can disagree by a few least-significant bits—enough for a projectile in Safari to arrive one tick later than in Chrome and fork the rest of the raid. And because a different tick rate produces a different battle—as the two boards above show halfway through the raid—the recording logs every step size alongside every tap.