tetro-tui 3.5.2

A terminal-based but modern tetromino-stacking game that is very customizable and cross-platform.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
!["Tetro TUI logo"](https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro_logo_glow.png?raw=true)


# Tetro TUI - Terminal Game

[![Crates.io](https://img.shields.io/crates/v/tetro-tui.svg)](https://crates.io/crates/tetro-tui)
[![License](https://img.shields.io/crates/l/tetro-tui)](https://github.com/Strophox/tetro-tui#license)
<!--[![Documentation](https://docs.rs/tetro-tui/badge.svg)](https://docs.rs/tetro-tui)-->

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

!["tetro-tui demo GIF"](https://github.com/Strophox/tetro-tui/blob/15d6f8a13d146d2655f80559e0aee0430527f1c9/demo_assets/tetro-tui-v3.5.0_demo.gif?raw=true)


> <details>
> <summary>
> 6 more demo images available;
> </summary>
>
> !["tetro-tui coolretroterm-monochrome-classic-elektronika"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro-tui-v3.0.0_coolretroterm-monochrome-classic-elektronika.png?raw=true
>
> !["tetro-tui alacritty-terafox-combo-advc"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro-tui-v3.0.0_alacritty-terafox-combo-advc.png?raw=true
>
> !["tetro-tui gnome-solarized-cheese-monochromeboardgrid"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro-tui-v3.0.0_gnome-solarized-cheese-monochromeboardgrid.png?raw=true
>
> !["tetro-tui gnome-standard-replay-harddrop"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro-tui-v3.0.0_gnome-standard-replay-harddrop.png?raw=true
>
> !["tetro-tui kitty-okpalette-puzzle-ascii"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro-tui-v3.0.0_kitty-okpalette-puzzle-ascii.png?raw=true
>
> !["tetro-tui wezterm-gruvbox-swift-default"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/tetro-tui-v3.0.0_wezterm-gruvbox-swift-default.png?raw=true
>
> </details>


## Ways to Run

### Download & Run

1. [Download a release]<https://github.com/Strophox/tetro-tui/releases> 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]<https://crates.io/crates/tetro-tui>):
```bash
cargo install tetro-tui
#  tetro-tui
```


#### Arch Linux ([aur.archlinux.org]<https://aur.archlinux.org/packages?K=tetro-tui>):

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


### Compile from source

Tetro TUI is written in [Rust 1.95.0](<https://doc.rust-lang.org/book/ch01-00-getting-started.html>) and can be compiled as usual:
```bash
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]<https://en.wikipedia.org/wiki/Tetromino> pieces falling from the sky and stacking inside a 2D playing field. When horizontal lines are filled they automatically clear away and everything 'stacked' above moves 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 configuration / features?

> We provide a solid amount of customization options / features for casual and (potentially) experienced players alike:
> - **Graphics:** Unicode/ASCII/Elektronika styles, old-terminal-compatible or very modern designs, 10 color palettes, hard drop/piece lock/line clear effects and much more.
> - **Game keybinds:** to your heart's desire. 
> - **Gameplay/handling:** Various rotation systems, piece randomizers, adjustable preview, timings (DAS¹, ARR¹, SDF¹, LCD, ARE), IRS/IHS/.. ([¹caveat]#why-do-some-gameplay-preferences-dasarrsdf-or-some-keybinds-ctrlshiftalt-not-work-for-me).
> - **Game mode miscellany:** Regular ('Marathon'), Swift ('40-Lines'), Classic & Master (unlocked after Regular), Puzzle, Cheese, Combo, Custom (select win condition, initial gravity, toggle gravity progress, *cmdline flags:* start board, seed).
> - **Highscores, replays, statistics, ...** - can be viewed as well as backed up with a simple **savefile**.
>
> Visuals can be customized together with your underlying terminal settings.
> E.g. one can set a bigger font to scale the game, or use <a href="https://github.com/Swordfish90/cool-retro-term">cool-retro-term</a> for a nostalgic look etc.
> 
> <details>
> <summary>
> See also: Big overview of actual Tetro TUI v3.5 menus:
> </summary>
> 
> **- Title screen -**
> - New Game
> - Settings
> - Scores and Replays
> - All-Time Stats
> - About
> - Quit
> *[←↓↑→/Enter/Esc/Del] or Vim, Press [?] to view keybinds anytime*
> 
> **+ Start New Game +**
> - Regular: Clear 160 lines as gravity increases.
> - Swift: How quickly can you clear 40 lines?
> - *(unlocked after Regular)* Classic (lvl 0+)(*): 'NES' Gameplay/Graphics settings recommended.
> - *(unlocked after Regular)* Master: Clear 320 lines at instant gravity.
> - Puzzle: Clear 24 hand-crafted puzzles (feat. the Ocular rotation system)
> - Cheese-40: Efficiently eat through some lines. Limit∈[None, Some(10), Some(11), .., Some(40), ..]
> - Combo-30: Get consecutive line clears. Limit∈[None, Some(10), Some(11), .., Some(30), ..]
> - Survival: Lines regenerate as you place more pieces.
> - Ascent: Experimental gamemode (requires 180° rot.)
> - Custom: [Del]=reset
>   * Initial fall delay = 1.000000000s (Gravity: 1.00 Hz)
>   * Progressive gravity ∈ [on, off]
>   * Limit ∈ [None, TimeElapsed(300s), .., PointsScored(200), .., PiecesLocked(100), .., LinesCleared(40), ..]
> - *(available after using `Ctrl+S`)* Game save
> 
> **# Graphics Settings #**
> * Slot ∈ [Default, Guideline, Terminal compatibility, Focus+, Minimal, I⠐⢷⠗ Braille, Elektronika 60, NES; Custom I/II/..]
> * Tile colors ∈ [Terminal default, Just white, ANSI, Tetro Pastel, Guideline, Gruvbox, Solarized, Terafox, Fahrenheit, Matrix, Sequoia, Just amber, NES levels]
> * UI colors ∈ [Terminal default, Just black/white, Tetro Dark, Gruvbox Dark, Solarized Light, Matrix, Sequoia, Just amber, NES, OneHalfDark]
> * UI style ∈ [ASCII, Frame UTF8, Rounded frame UTF8, No frame UTF8, No hold/next-frame, Braille, Elektronika 60]
> * Hard drop effect ∈ [None, Particle trail ASCII, Particle trail 2 ASCII, Particle beam ASCII, Colored beam UTF8, White beam UTF8, Braille helix]
> * Lock effect ∈ [None, Flash white, Transforming ASCII, Pulsing block UTF8, Spiraling Braille]
> * Line clear effect ∈ [None, Disappear halfway, Disappear instantly, Blink, Flash white, Clear left-to-right, Clear outward, White clear inward, Burn outward, Pop, Pop (more), Confetti (gratuitous), Stardust, Blast, Sparks, Sparks Braille, Sparks ASCII]
> * Tile/Tetromino symbols ∈ [ASCII, Blocks UTF8, Braille, NES simulacra, Elektronika 60]
> * Small tetromino symbols ∈ [Dots ASCII, Blocks UTF8, Braille]
> * Mini tetromino symbols ∈ [Letters, Braille]
> * Normalsized tetromino previews ∈ [unlimited, 1, 2 ..]
> * Frames rendered per second ∈ [5, 10, .., 60, ..]
> * Grid ∈ [on, off]
> * Piece shadow ∈ [on, off]
> * Upcoming spawn preview (if stack high) ∈ [on, off]
> * Uniform locked tiles ∈ [on, off]
> * Main HUD ∈ [on, off]
> * Include basic keybinds HUD ∈ [on, off]
> * Show active/held buttons ∈ [on, off]
> * Lock delay visualizer ∈ [on, off]
> * FPS counter ∈ [on, off]
> 
> **@ Game Keybinds @**
> * Slot (modifiable preset) ∈ [Default, Guideline, Control+, Terminal finesse, Vim; Custom I/II/..]
> * MoveLeft, MoveRight;
> * RotateLeft, RotateRight, Rotate180;
> * DropSoft, DropHard;
> * TeleDown, TeleLeft, TeleRight;
> * HoldPiece.
> 
> **Settings/Adjust-Gameplay/**
> * Slot ∈ [Default, Guideline, Finesse+, Elektronika 60, Gameboy, NES; Custom I/II/..]
> * Piece rotation ∈ [Ocular, ClassicL, ClassicR, Super]
> * Piece randomization ∈ [Uniformly random, Classic (Reroll 1x), Rerollx 2x, .., 7-Bag, 14-Bag, .., Balance out, Recency (^2.5), Recency (^2.6), ..]
> * Piece preview count ∈ [0, 1, .., 4, ..]
> * Delayed auto move (DAS) ∈ [0ms, 1ms, .., 167ms, ..]
> * Auto repeat rate (ARR) ∈ [0ms, 1ms, .., 33ms, ..]
> * Delayed soft drop ∈ [None, Some(5ms), Some(10ms), .., Some(100ms), ..]
> * Soft drop rate (SDF) ∈ [raise gravity to 30 Hz, ..; 0x gravity, 0.25x gravity, .., 15x, .., inf x gravity]
> * Line clear duration (LCD) ∈ [0ms, 5ms, .., 200ms, ..]
> * Spawn delay (ARE) ∈ [0ms, 5ms, .., 50ms, ..]
> * Allow spawn manipulation (hold-IRS/IHS/IMS/ITS) ∈ [on, off]
> * Convert double-tap to teleport ∈ [None, Some(5ms), Some(10ms), ..]
> 
> **§ Advanced Settings §**
> * Save ∈ ["--Nothing", "Only settings,stats --No scores,replays", "Only settings,stats,scores --No replays", "Everything (settings,stats,scores,replays)"]
> * Renderer used ∈ [Main, Halfblock, Braille]
> * Pause on focus lost ∈ [on, off]
> * 'Blindfold' game ∈ [on, off]
> * Assume enhanced-key-events available ∈ [on, off]
> 
> </details>


### Why do some gameplay preferences (DAS/ARR/SDF...) or some keybinds (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 <a href="https://sw.kovidgoyal.net/kitty/">Kitty</a> or <a href="https://alacritty.org/">Alacritty</a> (also <a href="https://docs.rs/crossterm/latest/crossterm/event/struct.PushKeyboardEnhancementFlags.html">others</a>) for flawless game handling.
> 
> <details>
> <summary>
> Explanation:
> </summary>
> 
> 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: Generally unable to actually 'hold' any buttons; DAS & ARR & SDF determined by terminal (& holding Soft Drop may 'accidentally' lock the piece), unable to hold Teleport, unable to hold 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' / 'kitty keyboard protocol']<https://sw.kovidgoyal.net/kitty/keyboard-protocol>.
>
> </details>


<!--NOTE: This list has not been updated since the addition of the in-app `?` (help) command in ~v3.X.
### 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.
> 
> <details>
> <summary>
> Menu controls:
> </summary>
> 
> 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` | Reload app from savefile (Caution: overwrites current data!) |
> | `Ctrl`+`Alt`+`S` | Perform savefile store (respects save preferences) |
> | `Ctrl`+`C` | Quit 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 (\*)']) |
>
> </details>
> 
>
> <details>
> <summary>
> (Default) Game controls:
> </summary>
> 
> | 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` | Reload app from savefile (Caution: overwrites current data!) |
> | `Ctrl`+`Alt`+`S` | Perform savefile store (respects save preferences) |
> | `Ctrl`+`C` | Quit program (respects save preferences) |
> 
> </details>
> 
>
> <details>
> <summary>
> Replay controls:
> </summary>
> 
> | 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` | Reload app from savefile (Caution: overwrites current data!) |
> | `Ctrl`+`Alt`+`S` | Perform savefile store (respects save preferences) |
> | `Ctrl`+`C` | Quit program (respects save preferences) |
> 
> </details>-->


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

> <details>
> <summary>
> The application will not store anything by default and 'Keep save file' needs to be opted in;
> </summary>
> 
> 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*).
>
> </details>


### *Experienced players:* How does it compare to (or deviate from) common stacker games?

> At the time of writing we implement all the most common mechanics found in the wild (and then some).
> Groups of (e.g. gameplay) settings are bundled in a 'slot'(= settings template/profile) which allows us to provide common presets as well as our suggested defaults. 
> 
> <details>
> <summary>
> See list of notable differences:
> </summary>
>
> **Keybinds:**
> - Default controls suggested to be **WASD + Arrow keys** (reasoning: We prefer to assign movement and rotation to separate hands instead of mixing; do not use Shift key due to common [terminal limitations]#why-do-some-gameplay-preferences-dasarrsdf-or-some-keybinds-ctrlshiftalt-not-work-for-me).
> - Dedicated buttons supplied for **Rotate 180°**, **Teleport Down** ('Sonic Drop') and Teleport Left/Right.
> 
> **Gameplay:**
> - Default rotation system suggested to be the [**Ocular Rotation** System]#experienced-players-what-is-this-ocular-rotation-system (reasoning: Ocular is designed to be symmetrical, intuitive and flexible (in different ways) compared to the quirky / sometimes asymmetrical 'Super' Rot.Sys.).
> - Default piece randomizer suggested to be a **Recency Randomizer** (reasoning: 'Recency' is biased toward 'fairly' choosing less recent pieces but still technically allowing arbitrary piece sequences, compared to the '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' without 'minis' (reasoning: we are not preoccupied with just 'T-spins').
>   - *Note:* Combos, without 'back-to-back' (reasoning: Back-to-back incentivizes playing special maneuvers, but those already yield disproportionate score bonus by themselves).
>   - Exact formula: `point_bonus = lineclears*lineclears * if is_spin{ 4 }else{ 1 } * if is_perfect{ 4 }else{ 1 } + (combo - 1)`
> - **Time-based lock reset limit** (reasoning: Providing a 'hard time limit before lock'(= `N`⋅current lock delay) seems more flexible/natural than 'hard move limit before lock'(=`N` 'moves').
> - Default speed/gravity/fall curve is slightly less aggressive but very close to standard (reason: We use a simpler formula).
>
> **Graphics:**
> - Default palette is more pastel (reasoning: Uniform perceptual brightness, 'looks pretty').
> 
> </details>
> 
> <details>
> <summary>
> See list of <a href="https://crates.io/crates/falling-tetromino-engine">core game engine</a> mechanics:
> </summary><!--NOTE: This list is quoted from the core game engine repository.-->
> 
> - 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 manipulation** (IRS/IHS/IMS/ITS; by keeping rotate/hold/move/teleport pressed during spawn),
> - **Rotation systems**: 'Ocular' (engine-specific, playtested), 'Classic', 'Super',
> - **Delayed auto-move** (DAS),
> - **Auto-move rate** (ARR),
> - **Soft drop rate** (SDF),
> - **Delayed soft drop** ('DAS but for Soft drop'),
> - **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).
> 
> </details>


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

> <details>
> <summary>
> An extensive attempt at better tetromino rotation with regards to symmetry and visual intuition;
> </summary>
>
> 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 the 'industry default' rotation system vs. Ocular rotation:
> 
> !["super rotation system heatmap"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/rotation-system-heatmap_srs.png?raw=true
> 
> !["ocular rotation system heatmap"]https://github.com/Strophox/tetro-tui/blob/b66590cb461d34c95e988ef41b6d8b7d7783f37b/demo_assets/rotation-system-heatmap_ocular.png?raw=true
> 
> </details>


### *Programmers / Terminal enthusiasts:* Can you provide some insight into the programming of this terminal game?

> <details>
> <summary>
> This project handles a handful of aspects to try and provide excellent user experience for a classic game. It also aims to maintain a decently high quality in code. The scope of this project consists of: 
> </summary>
> 
> - A **fully-featured [Tetromino game engine/backend]<https://github.com/Strophox/falling-tetromino-engine>** 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]<https://crates.io/crates/crossterm>. Currently there appears no need to change this situation, though a full TUI library like [Ratatui]<https://ratatui.rs/> might be reconsidered e.g. to handle UI translation (displaying other languages) etc.
> - A competent **input-update-render game loop**.
> - Implementing **game replays**.
> - **Savefile** storage:
>   * In particular **replay data serialization and compression**.
> - **Scoreboard** and **statistics**.
> - Game **graphics renderer** that handles all of the **effects** and dozens of graphics settings, efficiently.
>   * Custom **buffer diff'ing** so we can guarantee we only send the minimum number of required changes to the terminal (this minimizes flicker), see <https://github.com/Strophox/tetro-tui/blob/7f0ebacee7a1ed8d399057e270f9071aa13aaaa8/src/game_renderers/standard_buffered/dense_terminal_double_buffer.rs#L103>.
> - 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...
>   * Rust code quality.
> 
> </details>


### What is the motivation behind this project?

<!--NOTE: This text is the same as in the program 'About' menu. -->
> <details>
> <summary>
> Tetro TUI started as a passion project from someone who loves programming, minimalistic games and ASCII art;
> </summary>
> 
> Out of curiosity I snuck a peek to see how deep the mechanics of such a universal game can go:
> Basic versions are simple to code up, but it gets surprisingly complex when it comes to supporting all the modern/advanced features (especially while dealing with terminal limitations)!
> 
> To the best of my abilities I have implemented a most featureful & customizable version that still remains faithful to the essential
idea and also looks/runs nicely within a 'mere' terminal - Enjoy!
>[L.C.Werner]<https://github.com/Strophox>
> 
> </details>


## License

Licensed under MIT.


## Provenance

100% human-sourced spaghetti code

Color palettes featured: [Gruvbox](<https://github.com/morhetz/gruvbox>), [Solarized](<https://ethanschoonover.com/solarized/>), [Terafox](<https://wezterm.org/colorschemes/t/index.html#terafox>), [Fahrenheit](<https://wezterm.org/colorschemes/f/index.html#fahrenheit>), [matrix](<https://wezterm.org/colorschemes/m/index.html#matrix>), [Sequoia Monochrome](<https://wezterm.org/colorschemes/s/index.html#sequoia-monochrome>), [OneHalfDark](<https://wezterm.org/colorschemes/o/index.html#onehalfdark>).


## Acknowledgements

A big thank you to the [AUR package](#arch-linux-aurarchlinuxorg) maintainers!
- [wcasanova]<https://github.com/wcasanova>, [druxorey]<https://github.com/druxorey> and Dominiquini

Thank you to many sources of inspiration:
- Dunspixel – regarding ['O'-spins]<https://dunspixel.github.io/ospin-guide/chapter4.html#tetro-tui>
- Martín G / mg1399 – regarding particle-based line clear effects from his own PICO-8 game
- thehuglet – regarding the [potential of terminal graphics]<https://github.com/thehuglet/germterm>
- Akousoukos – regarding the [customizability of Apotris]<https://apotris.com/>
- DoktorOcelot – regarding the addition of [Survival Zen mode in Tetr.js Enhanced]<https://doktorocelot.com/tetr.js/>

Special Thanks
- GrBtAce, KonSola5 and bennxt – help during early dev/research
- madkiwi – help with 4-wide-6-residual combo layouts
- mathmaster13 and Kitaru – help with retro mechanics
- RayZN and ˗ˋˏthe One and Onlyˎˊ˗ – help with *Tetro* logo choice
- and Alexey Leonidovich Pajitnov – for discovering this universal genre of game