
Tetro TUI - Cross-platform Terminal Game
A cross-platform terminal game where tetrominos fall and stack.

Ways to Run
Download + run
- Download a release for your platform (Linux, MacOS, Windows, ..) if available.
- Navigate to and run the application (
tetro-tui)
Compile from source
- Ensure Rust is installed.
git clone https://github.com/Strophox/tetro-tuior otherwise download this repository.- Navigate inside
tetro-tui/and docargo run.
Install via cargo
Tetro TUI is available on crates.io. It can be installed via cargo like so:
cargo install tetro-tui
Then you can run the game with tetro-tui.
FAQ
How does the game work?
Tetro is about tetromino pieces falling from the sky and stacking on a rectangular playing field.
Whenever a line is filled up horizontally, it clears away, and the rest of what you 'stacked' moves down. This way a skilled player can keep playing without Blocking Out the entire board.
How good is customization?
For what started as a small project, solid:
- Graphics: Unicode/ASCII/Electronika, a handful of default color palettes, FPS, toggle effects...
- Game Keybinds: to your heart's desire.
- Gameplay/Handling: Rotation system, tetromino generator, preview count; DAS, ARR, SDF, LDC, ARE (timings), IRS/IHS
- Gamemode selection: Swift (40 lines), Classic ('marathon'), Master, Puzzle, Cheese-X, Combo-X; Custom (choose start gravity, toggle gravity progress, select goal, advanced flags: start board or seed).
Terminal customizations can carry over to game graphics, e.g. using cool-retro-term:
What was the motivation behind this project?
This is a passion project. The addition of the many features stem from personal motivation to make them available and make things enjoyable.
The result is (hopefully!) solid customizability; Editable json savefiles, compressed game replays, nontrivial gamemodes, a compile-time modding system, and almost as many modern stacker game mechanics as one could fit.
Maintaining high Rust code quality, especially in the game logic, was also important.
Where's the config file? Will it bloat or clutter my system?
The application will not store anything UNLESS 'Keep save file' is opted in.
The exact location of the config file is visible in the Advanced settings TUI menu:
- Location based on
dirs::config_dir()(e.g.C:/User/username/AppData/Roaming/.tetro-tui_1.0_savefile.jsonor/home/username/.config/.tetro-tui_1.0_savefile.json),- Otherwise directory of execution.
Savefile size may grow primarily due to saved replays (though good care has been taken to compress those well). The Scores and Replays menu can be used to delete past games or only their replay (
[Del]or[Alt+Del]respectively).
Experienced Stackers: Why do timing-settings (DAS/ARR/SDF etc.) not apply for me?
TL;DR use a terminal like kitty or Alacritty (or ->other) for 'true'/smoother handling in the terminal. Otherwise timings might solely depend on how quickly your terminal sends key-repetition events.
The real problem lies in how terminals normally send "key pressed" signals, but no "key released again" signals. This makes it impossible to implement mechanics like: "If
[←]is pressed, move left repeatedly until key is released again". Precisely this issue is fixed with 'kitty protocol' / 'progressive enhancement' / 'enhanced keyboard events'.Some Windows terminals support it but are not auto-detected, if so try the Override toggle in the Advanced Settings menu.
Note that a similar technicality affects the recognition of
[Shift],[Alt],... key presses as separate keys. On unenhanced terminals, those keys do not cause signals by themselves, but only in combination with a nonspecial-key presses (e.g.[Ctrl+C]).
Experienced Stackers: How 'polished' are the mechanics?
Quote from the Falling Tetromino Engine powering the actual game logic:
The engine aims to compete on the order of modern tetromino stackers; It incorporates many features found in such games. Experienced players may be familiar with most of the following mechanics:
- Variable gravity/fall delay (frame-agnostic); '20G' (= 0s fall delay),
- Simple but flexible programming of custom fall and lock delay progressions (
DelayParameters),- (Arbitrary) piece preview,
- Pre-spawn actions toggle ('Initial Hold/Rotation System'),
- Rotation systems: 'Ocular' (engine-specific, playtested), 'ClassicL', 'ClassicR', 'Super',
- Tetromino generators: 'Uniform', 'Stock' (generalized Bag), 'Recency' (history), 'Balancerelative',
- Spawn delay (ARE),
- Delayed auto-shift (DAS),
- Auto-repeat rate (ARR),
- Soft drop factor (SDF),
- Lenient lock delay reset toggle (reset lock delay even if rotate/move fails),
- Ensure move delay less than lock delay toggle (DAS/ARR automatically shortened when lock delay is very low),
- Lock-reset-cap factor (~maximum time before lock delay cannot be reset),
- Line clear duration (LCD),
- Custom win/loss conditions based on stats: time, pieces, lines, score,
- Hold piece,
- Higher score for larger lineclears and spins ('allspin')
- Game reproducibility (PRNG),
- Available player actions: MoveLeft, MoveRight; RotateLeft, RotateRight, Rotate180; DropSoft, DropHard, TeleDown ('Sonic drop'), TeleLeft, TeleRight, HoldPiece.
Experienced Stackers: In which ways is it unlike familiar stacker games?
The project took its liberties to adapt/experiment with certain aspects of game mechanics (to try and improve it):
- Use of the intuitive/symmetrical Ocular Rotation System, instead of the 'odd' industry standard.
- Default controls set to WASD + Arrow.
- Recency/History generator instead of 'overdeterministic' 7-bag.
- Scoring system is different, more simplified.
- 'Allspin' (no 'minis') instead of preoccupation with 'T-spins'.
- Combos, but no back-to-back.
- Exact formula is:
score_bonus = if is_perfect_clear{ 4 }else{ 1 } * if is_spin{ 2 }else{ 1 } * lineclears * 2 - 1 + (combo - 1)- Additional controls for Teleport Down (a.k.a. 'Sonic Drop') / Left / Right.
- Different lock reset implementation ('max 15 moves' instead of 'max 10⋅current lock delay')
- Speed/Gravity/Fall curve slightly adapted.
Experienced Stackers: What's the "Ocular Rotation System"?
A 'better' implementation of tetromino rotation, based off visual intuition and symmetry:
The Ocular Rotation System affords:
- Rotation based on 'where it looks like the piece should be able to go'.
- Symmetric (mirrored) situations should lead to symmetric (mirrored) outcomes.
- Tetrominos should not teleport up/down too much.
Visual heatmap comparison of rotation systems:
CLI Enthusiasts: How was the Terminal User Interface (TUI) programmed?
This basic but hopefully decent TUI was programmed directly using the amazing Crossterm. Crossterm handles all the placement of (colored) characters and reading inputs from the terminal. We implement custom diff'ing so I/O does not bottleneck smooth rendering.
How do I navigate the TUI? Can I see a table of all the controls?
Keys ≈Meaning ↓/↑,j/kNavigate up/down ←/→,h/lChange value Enter,eSelect Esc,q,Back,Go back Del,dDelete/reset 1/2/3...Quickselect option (⇝'New game') Alt+?Different value change' (⇝'New game'⇝['Combo','Savepoint','Custom'], ⇝'Gameplay settings'⇝'Tetromino generation') Alt+Del,Alt+dDelete replay (⇝'Scores and replays') Ctrl+CExit application (respects save preferences)
Key Action EscPause game ←Move left →Move right ARotate left (CCW) - Rotate around (180°) DRotate right (CW) ↓Soft drop ↑Hard drop - Teleport down - Teleport left - Teleport right SpaceHold piece Ctrl+DForfeit game Ctrl+EStore seed (accessible in ⇝'New game'⇝'Custom') Ctrl+SStore savepoint (accessible in ⇝'New game'⇝'Savepoint', ⇝(live) 'Game'⇝ Ctrl+L)Ctrl+LLoad savepoint (Caution: overwrites live game) Ctrl+Alt+BToggle on/off visibility of tiles ('Blindfolded') Ctrl+CExit application (respects save preferences)
Key Action Esc,q,BackExit replay SpacePause replay ↓/↑,j/kSpeed up / Slow down replay by ±0.25x Alt+↓/↑,Alt+j/kSpeed up / Slow down replay by ±0.05x -Reset replay speed to =1.0x ←/→,h/lSkip forward/backward 1s in time 1/2/3...Jump to 10%/20%/30%/... .Skip forward one player input and pause Alt+.Skip forward one game state change* and pause (experimental, might not work properly for modded games) Enter,eStart (live) Game from current replay state Ctrl+EStore seed (accessible in ⇝'New game'⇝'Custom') Ctrl+SStore savepoint (accessible in ⇝'New game'⇝'Savepoint', ⇝(live) 'Game'⇝ Ctrl+L)Ctrl+IToggle Instant Interactive Input Intervention mode (experimental) Ctrl+CExit application (respects save preferences)
License
Licensed under MIT.
Provenance
100% human-sourced spaghetti code
Color palettes used:
Acknowledgements
Special Thanks to:
- GrBtAce, KonSola5 and bennxt – for support early in development
- Dunspixel – for inspiration regarding 'O'-spins
- madkiwi – for advice regarding 4wide-6residual combo layouts
- (Apostolos Kousoukos for making Apotris!)
- and RayZN and ˗ˋˏthe One and Onlyˎˊ˗ – for advice regarding the Tetro logo


