Skip to content

Strophox/tetro-tui

Repository files navigation

"Tetro TUI logo"

Tetro TUI - Terminal Game

Crates.io License

Tetro TUI is a terminal-based but modern tetromino-stacking game that is very customizable and runs cross-platform.

"tetro-tui live demo GIF"

6 more demo images available;

"tetro-tui coolretroterm-monochrome-classic-elektronika"

"tetro-tui alacritty-terafox-combo-advc"

"tetro-tui gnome-solarized-cheese-monochromeboardgrid"

"tetro-tui gnome-standard-replay-harddrop"

"tetro-tui kitty-okpalette-puzzle-ascii"

"tetro-tui wezterm-gruvbox-swift-default"

Ways to Run

Download & Run

  1. Download a release for your platform (Linux/MacOS/Windows/...) if available.
  2. Navigate to the application binary (tetro-tui/tetro-tui.exe/...) and run it in a terminal

Quick Install

Cargo (crates.io):

cargo install tetro-tui
#  tetro-tui

Arch Linux (aur.archlinux.org):

yay -S tetro-tui # Or paru, etc.
#  tetro-tui

Compile from source

Tetro TUI is written in Rust and can be compiled as usual:

git clone https://github.com/Strophox/tetro-tui
cd tetro-tui
cargo run

FAQ

How does the base game work?

Tetro TUI is about tetromino pieces falling from the sky and stacking inside a 2D playing field. When a horizontal line is full it automatically clears away and everything 'stacked' above shifts down.

A skilled player may keep playing indefinitely. Different game modes will change up the gameplay while still using the same base mechanics.

How good is it in terms of customization / features?

We provide a solid amount of configuration options and features:

  • Graphics: Unicode/ASCII/Electronika styles, old-terminal-compatible or very modern designs, 10 color palettes, hard drop/piece lock/line clear effects and much more.
  • Gameplay and handling: Various rotation systems, piece randomizers, adjustable preview, timings (DAS¹, ARR¹, SDF¹, LCD, ARE), IRS/IHS/IMS/ITS¹ (¹caveat).
  • Game keybinds: to your heart's desire.
  • Game mode miscellany: Swift ('40-Lines'), Classic ('Marathon'), Master, Puzzle, Cheese, Combo, Custom (select goal, initial gravity, toggle gravity progress, cmdline flags: start board, seed).
  • Highscores, replays, statistics, ... - can can be accessed as well as backed up with a simple savefile.

Visuals depend on / can be customized together with your underlying terminal settings. E.g. you can set a bigger font to scale the game, or use cool-retro-term for nostalgic look etc.

See also: Complete list of Tetro TUI v3.0 menus contents:

New game/

  • Swift: How fast can you clear 40 lines?
  • Classic: Clear 150 lines at increasing gravity.
  • (unlocked after Classic) Master: Clear 150 lines at instant gravity.
  • Puzzle: Clear 24 hand-crafted puzzles.
  • Cheese-20: Eat through lines like Swiss cheese. Limit∈[None, Some(10), Some(11), .., Some(20), ..]
  • Combo-30: Get consecutive line clears. Limit∈[None, Some(10), Some(11), .., Some(30), ..]
  • Ascent*: (experimental, requires 'Ocular'- + 180° rotation)
  • Custom: [Del]=reset
    • Initial fall delay = 1.0s (Gravity: 1.0 Hz)
    • Progressive gravity ∈ [on, off]
    • Limit ∈ [None, TimeElapsed(300s), .., PointsScored(200), .., PiecesLocked(100), .., LinesCleared(40), ..]
  • Game save: (Only shows up after using Ctrl+S)

Settings/Adjust-Graphics/

  • Slot ∈ [Default, Focus+, Guideline, Terminal compatibility, Elektronika 60, Blank slate, Custom I/II/..]
  • Color Palette (modifiable presets) ∈ [Monochrome, ANSI, Standard, Okpalette, Gruvbox, Solarized, Terafox, Fahrenheit, The Matrix, Sequoia]
  • TUI style ∈ [ASCII, Unicode, Elektronika 60]
  • Mino textures ∈ [ASCII, Unicode, Elektronika 60]
  • Hard drop effect ∈ [None, Particles ASCII, Streak ASCII, Beam ASCII, Beam]
  • Lock effect ∈ [None, Transform ASCII, Pulse Unicode, White]
  • Line clear effect ∈ [None, Instant, Left to right, Inward, Outward, Flash white, Blink, Pop out, Pop out (more), Sparks ASCII, Blast]
  • Mini tetromino style ∈ [ASCII, Braille]
  • Small tetromino style ∈ [ASCII, Blocks, Braille]
  • Normalsize previews ∈ [unlimited, 1, 2 ..]
  • Frames per second ∈ [5, 10, .., 60, ..]
  • Show grid ∈ [on, off]
  • Show piece shadow ∈ [on, off]
  • Preview spawn when stack high ∈ [on, off]
  • Color board tiles ∈ [on, off]
  • Show left HUD ∈ [on, off]
  • Show keybinds legend ∈ [on, off]
  • Show active buttons ∈ [on, off]
  • Show FPS counter ∈ [on, off]

Settings/Adjust-Keybinds/

  • Slot (modifiable preset) ∈ [Default, Control+, Guideline, Vim, Custom I/II/..]
  • MoveLeft, MoveRight
  • RotateLeft, RotateRight, Rotate180
  • DropSoft, DropHard
  • TeleDown, TeleLeft, TeleRight
  • HoldPiece

Settings/Adjust-Gameplay/

  • Slot ∈ [Default, Finesse+, Guideline, NES, Gameboy, Custom I/II/..]
  • Piece rotation system ∈ [Ocular, ClassicL, ClassicR, Super]
  • Piece randomization ∈ [Completely random, 7-Bag, 14-Bag, .., Recency (^2.5), Recency (^2.6), .., Balance out]
  • Piece preview count ∈ [0, 1, .., 4, ..]
  • Delayed auto move (DAS) ∈ [0ms, 1ms, .., 167ms, ..]
  • Auto move rate (ARR) ∈ [0ms, 1ms, .., 33ms, ..]
  • Soft drop speedup (SDF) ∈ [0x, 0.25x, .., 15x, ..]
  • Line clear duration (LCD) ∈ [0ms, 5ms, .., 200ms, ..]
  • Spawn delay (ARE) ∈ [0ms, 5ms, .., 50ms, ..]
  • Allow initial rotation/hold (IRS/IHS/IMS/ITS) ∈ [on, off]
  • Convert double-tap to teleport ∈ [None, Some(5ms), Some(10ms), ..]

Settings/Advanced-Settings/

  • Save contents ∈ ["--Nothing", "Only settings --No scores,replays", "Only settings,scores --No replays", "Everything (settings,scores,replays)"]
  • Assume enhanced-key-events available ∈ [on, off]
  • Blindfold gameplay ∈ [on, off]
  • Pause on focus lost ∈ [on, off]
  • Renderer selected ∈ [Standard, Legacy, Prototype, Twoxel, Braille]

Why do some gameplay (DAS/ARR/SDF...) settings (or some keybinds like Ctrl/Shift/Alt/...) not work for me?

It is likely that your current terminal provides too little input information to enable custom timings¹ or those special keys. (¹Instead, DAS/ARR/SDF will be determined by how quickly your terminal sends key-repeat events.) If possible use an enhanced terminal like Kitty or Alacritty (also others) for flawless game handling.

Explanation:

The fundamental problem lies in how terminals usually send input signals.

  • Due to historical reasons, most will only send "key pressed" but not "key released again". This makes it impossible to implement mechanics such as: "If [←] is pressed, move left with a certain speed until key is released again."
    • Affected mechanics: Fixed DAS, Fixed ARR, Fixed SDF (& holding Soft Drop will lock the piece), Unable to hold Teleport, Unable to hold buttons for IRS/IHS/IMS/ITS.
    • Note that some terminals e.g. on Windows do send key-release signals, without this being auto-detected: Use the 'Override' in Advanced Settings for such cases.
  • Also due to history, modifier keys can only modify 'actual' text signals and are never sent by themselves.
    • Affected mechanics: Cannot register modifier Ctrl/Alt/Shift/Win//... as individual key presses.

Precisely these issues are fixed with 'enhanced keyboard events' / 'progressive enhancement' / 'kitty protocol'.

Can you give me a table of all controls / shortcuts / keybinds?

You can press ? in every single menu to access a keybinds overview for it.

Otherwise please refer to the tables below.

Menu controls:

Universal:

Keys ≈ Meaning
Enter, e Select
Esc, q, Back, Go back
Del, d Delete/Reset
/, j/k Navigate down/up
/, h/l Adjust value
? Open Keybinds Overview
Ctrl+Alt+L Re-load from savefile (Caution: overwrites current data!)
Ctrl+Alt+S Do savefile storage (respects save preferences)
Ctrl+C Exit program (respects save preferences)

Specific to 'Scores and Replays':

Keys Meaning
Alt+Del, Alt+d Delete replay (in 'Scores and Replays')
Home/End Navigate to top/bottom

Specific to 'Start New Game':

Keys Meaning
Alt+/, Alt+h/l Adjust value differently (under ⇝['Combo','Custom','Game save'])
Home/End Set fall delay to infinite/zero (under ⇝'Custom'), jump to beginning/end of inpus (under ⇝'Game save')
Alt+Enter View replay instead of starting game save (under ⇝'Game save')
Ctrl+U (For experienced/impatient players) unlock all game modes

Specific to 'Gameplay settings':

Keys Meaning
Alt+/, Alt+h/l Adjust value differently (under ⇝'Piece randomization'⇝['*-Bag', 'Recency (*)'])
(Default) Game controls:
Default Key (customizable) Action
Move left
Move right
A Rotate left (CCW)
- Rotate around (180°)
D Rotate right (CW)
Soft drop
Hard drop
- Teleport down
- Teleport left
- Teleport right
Space Hold piece
Key Action
Esc Pause game
? Open Keybinds Overview
Key Special action
Ctrl+D Forfeit game
Ctrl+R Restart game mode (Caution: discards current game)
Ctrl+Z Undo last input (Caution: overwrites current game)
Ctrl+L Load game save (Caution: overwrites current game)
Ctrl+S Store game save (accessible in 'Start New Game'⇝'Game save' or (live)'Game'⇝Ctrl+L)
Ctrl+E Store seed (accessible in 'Start New Game'⇝'Custom')
Ctrl(+Alt)+G Cycle through graphics settings slots
Ctrl+Alt+B Toggle on/off visibility of tiles ('Blindfolded')
Ctrl+Alt+L Re-load from savefile (Caution: overwrites current data!)
Ctrl+Alt+S Do savefile storage (respects save preferences)
Ctrl+C Exit program (respects save preferences)
Replay controls:
Key Action
Enter, e Start Game from current replay state ('take over')
Esc, q, Back Exit replay
Space Pause replay
/ , j/k Speed up / slow down replay by ±0.25x
- Reset replay speed to =1.0x
/ , h/l Skip forward / backward 1s in time
. Skip forward one player input & pause
1/2/3... Jump to 10%/20%/30%/...
Home/End Jump to beginning/end
? Open Keybinds Overview
Key Special action
Alt+/, Alt+j/k Speed up / slow down replay by ±0.05x
Alt+. Skip forward one game state change & pause (might not work properly for modded games)
Ctrl+L Toggle replay looping
Ctrl+S Store game save (accessible in 'Start New Game'⇝'Game save' or (live)'Game'⇝Ctrl+L)
Ctrl+E Store seed (accessible in 'Start New Game'⇝'Custom')
Alt+I (Experimental) Toggle instantaneous interactive input intervention mode
Ctrl(+Alt)+G Cycle through Graphics Settings slots
Ctrl+Alt+L Re-load from savefile (Caution: overwrites current data!)
Ctrl+Alt+S Do savefile storage (respects save preferences)
Ctrl+C Exit program (respects save preferences)

Where's the config file? Will it clutter my system?

The application will not store anything by default and 'Keep save file' needs to be opted in;

The exact location of the config file is shown in the Advanced Settings menu and is based on dirs::config_dir():

  • Usually /home/yourname/.config/.tetro-tui_v1.0_savefile.json
  • or C:/User/yourname/AppData/Roaming/.tetro-tui_v1.0_savefile.json

Savefile grows primarly due to number/length of saved replays. As a rule of thumb, 1min of gameplay with fast inputs adds ≲ 1 kB. If you end up with a lot of play time but can't/don't want to spare the kB / MB, you can:

  • Delete some entries (// just their replay data) in Scores and Replays using [Del] (// [Alt+Del]).
  • Configure which categories of data get stored in the first place on program exit (see Advanced Settings).

Experienced players: How does it compare to / deviate from common stacker games?

We put to practical use our customizability and provide many *settings slots* (profiles/templates), e.g. to simulate guideline gameplay¹/keybinds¹/graphics (¹Handling limitations may apply to your terminal);

Note that the 'Default' settings slots – though they should remain very familiar – do take liberties in 'shifting mechanics closer to the platonic ideal' of a tetromino stacker game. This is obviously not an objective statement, in practice it just means:

Keybinds:

  • Default controls set to WASD + Arrow keys (also preferred due to common terminal limitations).
  • Dedicated keys possible for Rotate 180°, Teleport Down ('Sonic Drop'), even Teleport Left/Right.

Gameplay:

  • Default use of the flexible/intuitive/symmetrical Ocular Rotation System (instead of: the quirky / sometimes asymmetrical industry default).
  • Default Recency Randomizer which is random but biases toward choosing less recent pieces (instead of: 'overdeterministic' 7-Bag).
  • Points (score) bonus system is currently kept custom and simple.
    • '1pt for simple line clear, with increasing bonus for larger lineclears, combos, spins and perfect clears.'
    • Note: 'Allspin' (instead of: preoccupation with 'T-spins'), currently no 'minis'.
    • Note: Combos (but no additional points for 'back to back' other than existing incentives for special maneuvers).
    • Exact formula: point_bonus = if is_perfect_clear{ 4 }else{ 1 } * if is_spin{ 2 }else{ 1 } * (lineclears * 2 - 1) + (combo - 1)
  • Different lock reset limit: 'max time = 10⋅current lock delay' (instead of: 'max 15 moves with current lock delay').
  • Speed/gravity/fall curve slightly less fast but very close to 'standard'.

Graphics:

  • Chosen default palette is more pastel with uniform perceptual brightness.

Experienced players: And how extensive are the stacker mechanics exactly?

See this list quoted from the Falling Tetromino Engine that powers the core game logic:

In terms of advanced game mechanics the engine aims to compare with other modern tetromino stackers. It should already incorporate many features desired by familiar/experienced players, such as:

  • Available player actions:
    • Move left/right,
    • Rotate left/right/180°
    • Drop soft/hard
    • Teleport down(='Sonic drop') and left/right
    • Hold piece,
  • Tetromino randomizers: 'Uniform', 'Stock' (generalized Bag), 'Recency' (history), 'Balance-out',
  • Piece preview (arbitrary size),
  • Spawn delay (ARE),
  • Spawn actions (IRS/IHS/IMS/ITS; by keeping rotate/hold pressed during spawn),
  • Rotation systems: 'Ocular' (engine-specific, playtested), 'Classic', 'Super',
  • Delayed auto-move (DAS),
  • Auto-move rate (ARR),
  • Soft drop factor (SDF),
  • Customizable gravity/fall and lock delay curves (exponential and/or linear; also, '20G' (fall rate of ≥1200 Hz) just becomes ≤00083s fall delay),
  • Ensure move delay less than lock delay toggle (i.e. DAS/ARR are automatically shortened when lock delay is very low),
  • Allow lenient lock-reset toggle (i.e. reset lock delay even if rotate/move fails),
  • Lock-reset cap factor (i.e. maximum time before lock delay cannot be reset),
  • Line clear duration (LCD),
  • Customizable win/loss conditions based on the time, pieces, lines, points,
  • Score more points for larger lineclears, spins ('allspin'), perfect clear, combo,
  • Game reproducibility (PRNG/determinism).

Experienced players: What is the 'Ocular Rotation System'?

An extensive attempt at better tetromino rotation with regards to symmetry and visual intuition;

The Ocular rotation system affords:

  • Symmetric/mirrored situations should lead to symmetric/mirrored outcomes (e.g. no distinct but visually identical states).
  • Rotation generally based on 'proximity where it looks like the piece should (be able to) go'.
  • Pieces should prefer downwards placement, not 'teleport up' in general.

See this visual/'heatmap' comparison of industry default vs. Ocular rotation:

"super rotation system heatmap"

"ocular rotation system heatmap"

Programmers / Terminal enthusiasts: Can you tell me more about the programming behind this terminal game?

This project handles quite a few aspects to provide an excellent user experience for a classic game. Among the many things that have accumulated inside the scope of this project are:
  • A fully-featured Tetromino game engine/backend featuring:
    • Several dozens of configurable, advanced and important options.
    • Provided pre-implementations of extremely common standard mechanics.
    • Decoupled core game loop ('interpreter') with ergonomic API (hopefully).
    • Basic but functional modding functionality with ergonomic API (hopefully).
  • Different and interesting game modes, including special game modes that rely on engine modding.
  • Extensive TUI menus to allow modifying all relevant configuration options without being forced to edit the save file manually: * Graphics options, Configurable keybinds, Gameplay settings.
    • Providing many curated configuration templates for everything, inspired by existing standards and games.
    • Sidenote: Ever since its inception as a proof-of-concept the terminal user interface (TUI) has directly and only relied on Crossterm. Currently there appears no need to change this situation, though a full TUI library like Ratatui might be reconsidered e.g. to handle UI translation (displaying other languages) etc.
  • A good input-update-render game loop.
  • Implementing game replay.
  • Savefile storage:
    • Especially replay data serialization and compression.
  • Scoreboard and statistics.
  • Game graphics renderer that handles all of the effects and dozens of graphics settings, efficiently.
  • Miscellaneous:
    • Commandline arguments.
    • Terminal limitations, all the time.
    • Doing all of the above as simply, ergonomically and as correctly as possible while providing feedback to the user when something doesn't work as expected.
    • Code quality.

What is the motivation behind this project?

Tetro TUI started as a passion project from someone who loves programming, minimalistic games and ASCII art;

Out of curiosity I looked into the depths of this common type of Tetromino game: Basic versions are simple to code up, but it gets surprisingly nontrivial when it comes to comprehensively supporting of modern/advanced features and slews of QOL mechanics while dealing with terminal limitations!

I've given it my best effort to implement a most featureful and customizable version that not only remains totally faithful to the basic idea of the game, but also runs and looks nice within the confines of a mere terminal - Enjoy! ☻ L. Werner

License

Licensed under MIT.

Provenance

100% human-sourced spaghetti code

Color palettes featured: Gruvbox, Solarized, Terafox, Fahrenheit, matrix, Sequoia Monochrome.

Acknowledgements

A big thank you to the AUR package maintainers:

Thank you to the people who provided inspiration:

  • Dunspixel – regarding 'O'-spins
  • Martín G – regarding new line clear effect from his own PICO-8 game
  • thehuglet – for showing the potential of terminal graphics
  • Akousoukos – for making Apotris

Special Thanks

  • GrBtAce, KonSola5 and bennxt – support during early dev and research
  • madkiwi – for advice regarding 4-wide-6-residual combo layouts
  • and RayZN and ˗ˋˏthe One and Onlyˎˊ˗ – for advice regarding the Tetro logo