All case studies
2048 — making a merge you can actually follow
One of the most cloned games on the internet, rebuilt so the tiles move instead of teleporting.
- Client
- In-house title
- Platform
- WebGL / browser
- Engine
- Unity
- Genre
- Puzzle
Unity WebGLC#Brotli compressionApache
The challenge
2048 is one of the most cloned games on the internet. There are thousands of versions, most of them a weekend of work, and almost all of them feel wrong in the same way: the tiles teleport. A merge happens, the numbers change, and the player is left reconstructing what moved from a board that simply looks different than it did a moment ago.That reconstruction is the whole cost. In a chain merge — four tiles collapsing into two, then into one — a player who cannot follow the movement cannot plan the next swipe, and a game about planning becomes a game about guessing.
The second problem is that 2048 has two genuinely different control schemes. On a phone it is swipes; on a desktop it is arrow keys. Most browser versions pick one and bolt the other on badly, so half the audience plays a worse game than the other half.
There is also a correctness trap that separates a real 2048 from an approximation, and almost every quick clone falls into it. In a single swipe, a tile that has just merged must not merge again. Get this wrong and a row of four identical tiles collapses into one instead of two, which silently doubles the player's score and breaks the entire difficulty curve. It is invisible in casual testing and obvious to anyone who has played the original.
Our approach
Every tile animates its own movement rather than being redrawn in a new position. When a row collapses, the player watches each tile slide the exact distance it travelled and sees the two that fused. In a four-tile chain that is the difference between reading the board and re-learning it.Merges are resolved before anything is drawn, so a row never double-merges in one swipe — the rule that separates a correct 2048 from an approximate one. A tile that has already fused is locked for the rest of that move.
Swipe and keyboard are both first-class inputs, not one wrapped around the other. Touch reads direction and distance with a threshold that ignores an accidental drag; arrow keys respond immediately with no repeat lag. Each feels native on the device it belongs to.
The board is square, so the build was given the same 1:1 handling as our other WebGL title — the game resolves its size against the stage it sits in, which keeps it whole on a phone and uncropped on a wide monitor.
On the hosting side the build ships Brotli-compressed with its own server rule declaring that encoding, so the browser decompresses it natively rather than falling back to the slower JavaScript path.
The merge rule was implemented explicitly rather than emerging from the animation: a tile that has fused is locked for the remainder of that move, so four identical tiles in a row always produce two tiles and never one. The scoring that sits on top of that rule is only meaningful because the rule is right.
Best score is persisted locally, which matters more than it looks for a browser game. Without it, every visit starts from zero and there is no reason to improve; with it, the second session has a target carried over from the first.
The result
A 2048 that is readable at speed: chain merges can be followed as they happen, so the game rewards planning instead of punishing attention.It runs in the browser on desktop and mobile with no download and no account, plays correctly with either swipe or arrow keys, and keeps its full square board at any window size.
Playable on this site right now — like everything else here, it is a demonstration rather than a screenshot.
The double-merge rule is implemented correctly, so scores and the difficulty curve behave the way players who know 2048 expect — a detail that is invisible when right and immediately obvious when wrong.
Best score persists between visits, so a returning player has something to beat rather than starting over.
The build ships Brotli-compressed with its own server configuration, decompressed natively by the browser rather than through the slower JavaScript fallback.
