TETERI
How TETERI is built
Telling a Flick From a Drag
Two gestures that differ only in speed, and why measuring velocity at release is the only reliable answer.
Flick down to slam. Drag down to soft drop. These are the same motion in different amounts, and separating them reliably is harder than it looks.
What does not work
Distance. A slow deliberate drag and a quick flick can cover the same number of pixels. There is no threshold that separates them.
Total duration. A flick preceded by a moment of hesitation while the player decides reads as a slow gesture, even though the actual movement was fast.
Number of move events. Depends entirely on the device's sampling rate and how busy the main thread is.
What works
The velocity at the moment the finger lifted. A genuine flick is travelling well over a thousand pixels a second at release; a deliberate drag is at a few hundred, and a drag that has already stopped is near zero.
The implementation keeps a smoothed velocity across recent pointer moves, and the release handler classifies from that, the total displacement, and how far the finger wandered.
Making it testable
The classifier is a pure function: it takes displacement, velocity, duration, distance travelled and the current cell size, and returns one of hard-drop, hold, rotate-clockwise, rotate-anticlockwise, or nothing.
No DOM, no timers, no state. So it can be tested from Node against realistic numbers — 190 pixels in 110 milliseconds is a flick; 190 pixels in 700 milliseconds is not.
That mattered, because the browser harness could not dispatch synthetic events fast enough to simulate a real flick at all. Every early attempt to test it in a browser was measuring the test harness rather than the game.
The scaling detail
Thresholds scale with cell size. A fourteen-pixel movement is a decisive gesture on a phone with ten-pixel cells and an accidental twitch on a desktop with forty-pixel ones. Testing surfaced a case where such a twitch fell between "tap" and "flick" and did nothing at all.
Read next
- Rendering: Sprite Caches and Layer BakingDrawing four hundred glowing blocks per frame is slow. Drawing four hundred cached bitmaps is not.
- Every Sound Is Generated, Not RecordedOscillators, filtered noise and a reverb impulse built from decaying random numbers. No audio files anywhere.
- The Soundtrack Is a Sequencer, Not a FileA four-bar progression with drums, bass, arpeggio and a lead, whose tempo and arrangement climb with your level.
- Online Play With No Server At AllWebRTC connects the two browsers directly; a public relay handles only the introduction.
- Cancelling: Why Attacking Is How You DefendYour outgoing attack eats incoming garbage before any of it lands. There is no defensive option.
- Every Control in TETERIThe complete list for keyboard, touch and gamepad, including the ones that are not obvious.