what if every possible tetris move could be mapped to a button on the keyboard?
that's the idea behind a thing i threw together called keytris (i might change the name at some point, idk). it's very much a prototype rn. i wanna do more with it at some point, but i haven't had the motivation, so i'm writing this blog post instead.
my vision here is that, with enough time and practice, it should be possible to become proficient playing such a version of tetris. if it's possible to become as proficient here as with normal controls, then it could allow for some insanely fast tetris play.
like, if every possible move is just 1 keypress (or, as i'll explain later, sometimes 2, but usually just 1), and you have, like, 5 pieces of lookahead, then (theoretically) a skilled player could pretty much instantly drop all 5 pieces. and that idea is really exciting to me.
when i first started playing (normal) tetris, i had to think every time i rotated a piece about which rotation button to use. now, it's so second nature that i literally don't think about it. i decide what i want to do with the piece, and then i just... do it.
in NES tetris, this also applies for moving pieces across the board. i'm gonna oversimplify here a little bit, but: when playing with DAS, in order to play at high speeds, you pretty much need to be holding the directional button as soon as the piece appears, and let go of the button as soon as it's in the correct column. if you time it incorrectly, you have to adjust, and that causes you to lose DAS. but after playing so much NES tetris, the timings are so second nature to me that i pretty much never think about them. when i see a piece in the "next" box, i know exactly where i want it to go, and so my muscle memory kicks in and i'm able to optimally move it there without thinking about it.
now imagine if that kind of muscle memory was just for hitting a single key to instantly drop the piece exactly where i want it to go. hypothetically, it would be possible to play tetris at near the speed of thought! that's too cool of an idea to not at least try.
so here's the basic idea: each column of keys (think of an ortholinear keyboard) corresponds to one column on the playfield. the piece is placed in that column, relative to its center. the row on the keyboard corresponds to the piece's rotation: home row (asdf) is the default rotation, above that (qwer) is counter-clockwise, the numbers are 180 degrees (flat), and the bottom row (zxcv) is clockwise.
for example: on a qwerty keyboard, q rotates the piece counter-clockwise, and places it in the leftmost column. 6 lays the piece flat in roughly the middle of the board.
for some pieces, this results in duplicate keys. for example, since i'm using NES rotation mechanics, S and Z pieces only have 2 rotation states. so 2 of the keyboard rows are redundant. for O pieces, every row is the same.
additionally, for all pieces, there's some keys which are effectively dead keys, such as a, since none of the pieces in their default orientation can have their center in column 1.
i could maybe find a contrived way to solve those "issues", but doing so would make the system much less intuitive, and probably harder to implement, so i'm ok with them.
but this system still doesn't support spins or tucks. so how do those work?
it's a little more complicated. unfortunately, it's not possible to consistently map every single move onto a single key for every possible board state. and even if i could, i still want a system which is intuitive and, like, Possible to learn.
my first idea was this: only lock the piece after the key is released (rather than pressed). that way, while a key is held, another key can be pressed to perform a rotation or tuck.
besides making the game feel sluggish, this has two major drawbacks: the first is that, if the player performs multiple moves in quick succession, they may accidentally have two keys held at once. a bigger issue though is that there's sometimes multiple possible tucks. like, you could set up 2 I-piece tucks on top of each other, for example. making that work with this system would be complicated.
so instead, i decided on a different system, where the controls are sorta reversed. so, rather than first moving the piece and then performing the tuck/spin after (like you would normally), the tuck/spin is specified first, followed by the column to drop the piece. furthermore, rather than having the player specify the way the piece would move into the position, they only need to specify the final position of the piece. that means that tucks and spins become pretty much the same thing. the implementation only needs to prove that it would be possible normally to move the piece into the position.
more specifically: before dropping the piece, certain keys are reserved to specify that the piece should go beneath the position it would normally drop in. so like, the ' key says that, when locking the next piece, first drop it to where it would normally drop, then, like, phase it through to wherever it next fits below. if there's multiple places below that it could fit, it picks the first one. the enter key is the same, but it picks the second one.
the theoretical maximum is 10 possible positions (though in practice this would pretty much never happen), but luckily there's 9 extra keys to accomodate for that! i went with ', enter, [, ], \, -, =, backspace, and backtick, in that order. one way to think of them is as "modifier" keys, which affect the row the piece is placed. the next keypress always instantly locks the piece to the board.
so this means that every possible tuck and spin can be accomplished with 2 key presses. every other move always takes only 1 key press.
my prototype still doesn't check that tucks/spins are possible before letting you execute them, but other than that the controls and basic mechanics are all implemented.
i also added two extra features:
- practice mode shows a shadow of where the piece would go before dropping it, and requires you to press the movement key twice to commit to the placement. this is currently on by default.
- draw mode allows you to use your mouse to draw (or erase) on the board, so you can create set-ups to practice and stuff. it also lets you change the currently active piece by clicking on it. this was mostly implemented as a debug feature, but it's still kinda useful.
i've been messing around with the prototype, but i still haven't felt like i've been getting significantly better. i've learned a little bit, but i still make very frequent mistakes. like, just off-by-one mistakes and stuff. the biggest pain-points are:
- sometimes it's not intuitive where the "center" of a piece is, so you kinda just have to memorize it. i do still think it's possible to memorize, i mean, hell, i've pretty much subconsciously memorized it in NES tetris (timing DAS movement and spins, especially line spins), but it feels much more difficult here, probably at least partially because there's no visual indicator to help out. when combining that with the need to translate the column number into a key to press, it's all very error-prone.
- i'm using a staggered keyboard, so whenever i use the bottom row of keys, i always end up putting the piece farther to the left than i want. it doesn't help that there's fewer letters on the bottom, so m is only the 7th column when i sometimes try to use it like it's, like, the 9th or something.
- i pretty much need to relearn piece rotation, because now instead of pressing rotation buttons i need to remember that counter-clockwise is up and clockwise is down. especially for L and J pieces, i still often mess this up. T pieces have been easier for me to learn, for some reason. this is definitely learnable either way though.
i feel like there's gotta be a better way to have a practice mode which properly facilitates learning, rather than just making mistakes more forgiving (which might be having the opposite effect of making it harder to learn?). i'm not sure.
anyways, yeah, check out keytris! i might polish it up into something more than just a demo eventually, but for now uh yeah