Avalanche
Puzzle · Unity · C#
- My role Programming and mechanics design
- Team 3 people
- Context Academic project
- Engine Unity
- Code GitHub
Play now
Click the game to give it the keyboard. Arrows to move and rotate, Space to hard drop, C to hold a piece, Esc to pause. The fullscreen button is in the corner of the game.
Not loading? Open it directly on itch.io.
The game
Avalanche is Tetris rebuilt from scratch and then broken on purpose. On top of the normal rules run three systems that compete with the player for the board.
Steel blocks appear in the middle of your pieces and cannot be cleared: a line won't complete while there is steel in it. They clog up columns and climb.
Rune blocks are the answer. When they land, they fire a beam up the whole column and convert every piece of steel they find. The more steel trapped on the board, the higher the chance a rune shows up — the difficulty and the relief grow together.
And the avalanche, which gives the game its name: every so often, an entire row drops onto the board. A counter on screen tells you when it's coming, but never what's coming with it — if the board is clogged enough, the whole avalanche arrives made of runes.
The C key holds the current piece for later. Holding a rune and choosing when to spend it turned out to be the most interesting decision in the game, and it wasn't planned: it appeared on its own when two independent mechanics met.
What was mine
Everything but the art. Programming, the animation state machines, the scoring system, the loading screen and the mechanics design.
The team did the block art, the background and the animations.
Rebuilding Tetris without looking up the answer
I could have looked up how Tetris is implemented. I chose to play a lot of it and work the rules out from what I saw on screen.
That cost me in places, and piece rotation was the most expensive of all: up against a wall, rotating simply didn't work. I later found out the problem has a name and a known solution — the official system uses wall kicks, testing a few offsets when a rotation would hit a wall, and accepting the first one that fits.
The game has wall kicks now. Doing it from scratch was slower, but it forced me to understand why each rule exists instead of copying a behaviour and not knowing what it solves.
The mechanic that did the opposite of what it should
The steel block was born to get in the way: indestructible until a rune converted it back.
But the function deciding whether a line was complete checked one thing only — whether all ten cells were occupied. It never asked what was occupying each cell. So a line with steel in it completed normally, vanished, and the steel block stayed right there. In practice, that column now needed one piece fewer. The obstacle had become a gift.
The fix is one line: the check returns "not full" as soon as it finds steel.
And then the second bug showed up, the more interesting one. When a rune converts the steel, the component marking the block as metallic is removed — but in Unity, removing a component doesn't happen immediately: it is scheduled for the end of the frame. In the very frame where the rune cleared the column, the line still considered itself blocked by steel that, for all practical purposes, no longer existed.
The solution was to disable the component before asking for it to be removed, and to make the check ask whether it is enabled rather than whether it exists. Disabling is immediate; removing is scheduled. It's a distinction I wasn't making before that bug, and one I started seeing everywhere after it.