Move: arrow keys or A / D (hold to autorepeat) Rotate: X or UP clockwise, Z anticlockwise Soft drop: DOWN or S (1 point per cell) Hard drop: SPACE (2 points per cell) Hold: C, once per piece Restart: R Scoring is the guideline table - 100 / 300 / 500 / 800 by lines cleared, multiplied by level. Level goes up every ten lines and takes gravity with it.
Guideline Tetris, properly: full SRS rotation with the published wall-kick table, 7-bag randomiser, hold, three-deep preview, ghost piece, DAS/ARR, lock delay with a reset budget. WALL KICKS ARE WHY THIS FEELS LIKE TETRIS. When a rotation would collide, SRS does not just refuse - it tries a specific ordered list of offsets and takes the first that fits. That table is what lets you spin a piece into a gap flush against the wall, and it is what T-spins are built on. It is 160 numbers, and getting one wrong makes the game feel subtly wrong in a way that is very hard to debug by playing. So it is not hand-typed into blocks. tools/mkdata.py derives the rotation states and emits the kick table into assets/kicks.txt, loaded into a list at compile time. All 28 rotation states were printed as ASCII and checked against the standard shapes. LOCK DELAY WITH A 15-RESET BUDGET is the other feel-critical detail: a piece that lands does not freeze instantly, and moving or rotating resets the timer - but only fifteen times, so you cannot stall forever. VERIFIED, not assumed: the board logic was mirrored in Python and a placement AI ran thousands of pieces across six seeds. Line clears, compaction, levelling and scoring all behave. Best automated run: 91 lines, level 10, 64,000 points. All original - code, art and sound. See Inside is open.