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.

PLAY TETERI ALL ARTICLES