← Back to Blog

Dev Blog · May 28, 2026

Block Stacker: What I Learned Rebuilding a Classic

Block Stacker

I knew rebuilding a Tetris-inspired game would be familiar territory. I had a mental model of how it worked, I'd played it thousands of times, and I figured the implementation would go quickly. I was wrong about almost every assumption. Block Stacker took three times longer than expected and taught me that the games we know best are often the ones we understand the least.

The Rotation System Is a Rabbit Hole

Rotation seems simple: spin the piece 90 degrees around its center. In practice, naive center-rotation causes the piece to clip into walls or the floor and simply refuse to rotate, which feels terrible. The standard solution is wall kicks — when a rotation would result in collision, try a series of offset positions to find a valid landing spot. I implemented a basic kick table and it covered most cases. Then I found the S and Z pieces. Their rotational symmetry means they oscillate between two states, and my kick offsets caused them to creep horizontally across the board on repeated rotations. I spent an entire afternoon tracing a kick table I'd copied from a reference implementation before realizing I had the offset directions inverted. The lesson: don't copy data structures without understanding the coordinate system they were designed for. My grid grows downward; the reference grew upward. Every Y offset was flipped.

Line Clears and the Feel of Reward

Clearing a line is the core reward loop of the game, and I underinvested in it at first. My initial implementation: check for full rows, splice them from the array, shift everything down, update score. It worked instantly and felt like nothing. The rows just vanished. I added a 120ms flash animation where cleared rows turn white before disappearing — and the game suddenly had weight. The blocks above don't fall immediately; they pause for that same 120ms as if they're surprised too. The score ticker animates upward over 200ms. None of this changes the gameplay mechanics at all, but the difference in how satisfying a clear feels is enormous. Deferred gravity — the brief pause before blocks fall — is the single most impactful animation I added to the whole game.

Balancing Speed Across Score Levels

The fall speed curve is a design problem that looks mathematical but is really psychological. I plotted a clean exponential ramp from level 1 to level 15 and gave it to playtesters. Levels 1 through 5 felt too slow — people were bored before they built any spatial reasoning. Levels 12 and above felt physically impossible. The issue was that I optimized the curve for someone who was already good at the game. I rebuilt it with three distinct zones: a fast warm-up ramp through levels 1–4 that gets players engaged quickly, a gradual middle section from 5–10 where most play sessions live, and a steep final section from 11–15 that functions as a skill ceiling rather than a standard difficulty setting. Most players never see level 12. That's fine — it just needs to exist as a horizon to chase.

Browse All Games