openblocks is a Tetris reimplementation. Ten-wide playfield, seven pieces, no wall kicks, no hold, no ghost piece. Rotation cycles four fixed states in place. The piece bag is the NES rule: draw at random, reroll once if it repeats the last piece. Auto-shift is 16 frames to the first repeat, then 6. Line-clear scoring is 50 / 150 / 400 / 1000 times level plus one, and a level arrives every ten lines. Colors follow the NES scheme: two block colors plus white per level, cycling every ten levels. The gravity table and the point values are tuned by feel rather than copied frame-for-frame, so this plays like the original without claiming to be a clone of it.

I built it for myself, mostly on weekends. Rebuilding a classic from nothing is the best way I know to understand why it felt good in the first place.

openblocks gameplay

How it is built

The game logic is one platform-independent C file, shared unchanged everywhere and covered by unit tests that need no window. Drawing, input, and audio go through raylib 6.0 on every platform except iOS, which has its own backend written in Metal and UIKit with no raylib at all. Sound effects are synthesized at startup. There are no asset files.

Desktop builds can record the session to an H.264 MP4, one video frame per rendered frame, with no external tools. Toggle Record from the menu or pass --record on the command line. The mobile and web builds compile it out.

Layouts

There are two renderers, and the build picks one.

  • Landscape, on desktop: a fixed 640x480 canvas, letterbox-scaled to the window. Piece statistics on the left, playfield in the middle, lines / score / level / next on the right.
  • Portrait, on iOS and Android: adaptive to the live screen. Title bar on top, a score / lines / level / next band under it, and the playfield filling the rest at the largest square cell that fits. No on-screen buttons. Everything is a gesture.

The web build compiles both and picks at load from the primary pointer type. Coarse pointer gets portrait and touch, everything else gets landscape and the keyboard. There is no manual override.

Controls

Keyboard, on desktop and desktop browsers:

KeyAction
Left / Right, A / DMove
Down, SSoft drop
Space, Up, W, X, ZRotate
EnterPause / resume
EscapeBack to the menu, game stays resumable
Alt+EnterToggle fullscreen
Up / Down, Enter / SpaceMenu navigation

Touch, on iOS, Android, and mobile browsers. All gestures, no buttons:

GestureAction
Drag sidewaysMove. The piece tracks your finger, one column per cell
Drag downSoft drop
Flick downHard drop
TapRotate
Two-finger tapBack to the menu, game stays resumable
Swipe up / down, tapMenu navigation and select

In the browser

The same C compiles to WebAssembly with Emscripten, so the browser version is the game and not a separate port. Same rules, same feel, same code. Play it here. Nothing to install.

Download

Every push to main cuts a release with per-platform builds: Linux, macOS, and Windows archives, an Android APK, an iOS .ipa, and the WebAssembly bundle. Source is on GitHub under MIT; the README has the build instructions.

On iOS, use the App Store. It is free, iPhone and iPad, iOS 15 or later, no ads and no tracking. The .ipa attached to the release is the App Store build and will not sideload. Android is not on Google Play, so install the APK directly. Everything else runs as-is.

Download openblocks on the App Store