โ† All apps

CandyTetris

๐ŸŽฎ CandyTetris

Tetris on the SugarCraft stack

port of tetrigo game tetris srs deterministic

SugarCraft runtime, CandySprinkles for rounded borders + per-piece colours, deterministic 7-bag RNG, ghost piece, hard drop, hold, level-driven gravity ramp, NES-classic line-clear scoring. Full SRS wall-kicks via official Tetris Association tables, T-Spin detection via the 3-corner rule, Back-to-Back (1.5ร—) and combo bonuses, DAS/ARR keyboard timing (167/50 ms), and perfect-clear detection (+5000/level).

Install

composer require sugarcraft/candy-tetris

Quickstart

composer install
./bin/tetris

# Controls
# โ† / โ†’   Move left / right
# โ†‘ / x   Rotate clockwise
# z       Rotate counter-cw
# โ†“       Soft drop
# Space   Hard drop
# p       Pause / resume
# q       Quit

What's in the box

SRS rotationFull Super Rotation System โ€” official Tetris Association kick tables for J/L/S/T/Z and I piece. Tries up to 5 offsets per rotation transition; the first that fits the board is used.
7-bag RNGDeterministic shuffle of the seven pieces; injectable RNG closure for reproducible tests.
Ghost pieceTranslucent preview at the hard-drop landing position.
Hard drop / holdSpace-bar drop; level-driven gravity speed-up at every 10 lines.
NES scoring1 โ†’ 40, 2 โ†’ 100, 3 โ†’ 300, 4 โ†’ 1200 โ€” multiplied by (level + 1).
T-Spin (3-corner rule)Full T-Spin (400 ร— level+1) and T-Spin Mini (100 ร— level+1) via the official 3-corner detection: piece must have rotated and โ‰ฅ2 diagonal corner cells must be filled (wall = filled).
Back-to-Back (B2B)1.5ร— multiplier on Tetris or full T-Spin clears when preceded by another B2B-eligible clear. Resets on 1โ€“3 line clears or T-Spin Mini.
Combo counterConsecutive line clears add combo ร— 10 ร— (level+1) bonus points; resets to 0 on a zero-line lock.
Perfect clearClearing the full board awards +5000 ร— (level+1) bonus โ€” documented via Board::isPerfectClear().
DAS / ARR timing167 ms DAS delay (time before auto-repeat begins) + 50 ms ARR interval (repeat rate). Gives precise single-tap and smooth continuous movement; configurable via Input\Das.
Six pure-state classesTetromino, Piece, Board, Bag, Score, Game โ€” each individually testable without booting the runtime.

Source & demos

Try the quickstart โ†’

API

ClassMethodDescription
Tetrominonew(type)Create a tetromino piece
Piecerotate(direction)Rotate piece
PiecerotationsWithKicks(delta)All valid rotated positions (naive + SRS wall-kick offsets)
Piecemove(dx, dy)Move piece
Boardnew(width, height)Create game board
Boardlock(piece)Lock piece into board
BoardclearLines()Clear completed lines
BoardisPerfectClear()True iff every cell is null (empty board after a perfect clear)
Bagnext()Get next piece from bag
Scoreadd(lines, level)Add score for lines cleared
Gametick()Process game tick
Gamestate()Get current game state
SrsKickTablekicks(piece, from, to)Return kick offsets for a rotation transition
SrsKickTableallKicks(piece)Return all four transition tables for a piece
Scoring\TSpindetect(board, piece, wasRotated)Detect T-Spin state using the 3-corner rule; returns TSpin(active, mini)
Scoring\TSpinT_SPIN_POINTS / T_SPIN_MINI_POINTSBase score constants (400 / 100, scaled by level+1)
Input\Dascreate(dasMicroseconds, arrMicroseconds)Factory โ€” defaults 167_000 / 50_000 ยตs
Input\Dasadvance(us)Accumulate microseconds; returns fresh Das
Input\DasleftFiring() / rightFiring() / downFiring()Whether the direction should fire at current tick

Demos.

VHS-recorded GIFs of every example shipped with the app. Regenerated automatically on every push that touches the source.

Play

Play

Full game with ghost piece, hard drop, level-driven gravity.