Left, right, and both

Two Beat's menu opens with one line: 'Left, right. Two buttons are all you need.' On a keyboard each side has five keys — F, D, S, A and ← on the left, J, K, L, ; and → on the right. On a phone the left and right halves of the screen are the buttons, and each finger is tracked separately, so two thumbs can press at once. A standard gamepad works too: LB/L1, LT/L2, d-pad left and X/□ are left; RB/R1, RT/R2, d-pad right and A/× are right.

Pressing both sides at once is the third gesture. In the five non-janggu songs, the first beat of each main section is normally a two-handed note on Easy and Hard. In the janggu songs it carries a real meaning: the left lane is the drum's low gungpyeon head (kung), the right lane its high chaepyeon head (deok), and both together are deong. Because of that mapping, the daily song never mirrors a janggu song, although on some days it swaps the lanes of the others.

Songs written as code, not audio files

Two Beat contains no audio files. Each song is a score written in code — key, scale, chord progression and sections — and the browser synthesises it live with Web Audio. The same file, shared/beat.mjs, runs in the browser and on the server, so the server can rebuild the exact chart for any board without trusting the player's device.

There are seven songs: Dawn Bus (lo-fi, 96 BPM, 80 s), Neon Jump Rope (synth-pop, 124 BPM, 62 s), Cat Parade (chiptune, 138 BPM, 59 s), Shooting Star Swing (110 BPM, 70 s), Canon Variations (96 BPM, 80 s), and two jangdan pieces, Gutgeori Yard (102 s) and Jajinmori Market (97 s).

For the first four, a seed generates one melody motif per section — sixteen steps of rhythm and pitch — and every section with the same name reuses it, because repetition is what makes a sequence sound like a song. Drop sections get busier melodies and a kick on every beat, and the fourth bar of each group of four lifts the motif by one scale degree.

Canon Variations is the exception. It is a fixed arrangement of Pachelbel's theme and repeating bass, written out note by note so the seed can never turn the famous melody into something random; from 40 to 65 seconds it plays the fast theme in full. The janggu songs, added on 2026-10-04, run on a twelve-cell cycle, four beats each split in three. A buk drum, a jing gong and a kkwaenggwari carry the time, and a flute voice plays a five-note melody. The accompanying janggu always plays the Hard pattern, so on Easy you still hear the full rhythm you are simplifying.

Charts that follow the music

Charts come from the same score. Easy follows the drums on the beat: kicks on the left, snares on the right, and the downbeat kick of every other bar stretched into a short hold. Hard follows the melody's contour: when the tune rises the note goes right, when it falls the note goes left, and a repeated pitch stays in the same lane. Melody notes four steps or longer become holds, and a kick on the first beat of a bar adds a tap for the other hand.

Two spacing rules keep the generated charts playable. Notes in the same lane are at least an eighth note apart on Hard and a full beat apart on Easy, counted from the end of a hold, and nothing appears in a lane while you are holding it.

Normal is derived from Hard rather than written separately. It keeps roughly the average of the Easy and Hard note counts, thinning each hand's notes evenly, caps holds at four steps and leaves two steps to release before the same hand presses again; a janggu roll without that room becomes a tap. The 18-second practice is eight bars of Neon Jump Rope cut from the start of its first main section, with every hold turned into a tap.

Judging against the sound you hear

The windows are ±45 ms for Perfect, ±90 ms for Great and ±135 ms for Good. Judgements make up 90% of the 1,000,000 points (1,000, 700 and 300 per note) and maximum combo the other 10%. A hold counts twice, head and tail, and the tail is good if you keep holding until 120 ms before its end. Perfects within ±20 ms are also counted separately as ★ Critical; they score the same, but the count appears on the results screen and in the rankings.

The harder question is what 'now' means. Two Beat uses one clock, the audio device's. The browser's audio clock advances in jumps each time the device takes a block of sound — about 5.3 ms in Chrome on macOS, 10 ms on Windows, more than 20 ms in Firefox — and reading it directly made notes shake. So the game follows the upper envelope of the gap between the audio clock and performance.now(), then subtracts the base and output latency the browser reports. In headless Chrome that cut frame-to-frame jitter from a standard deviation of 2.65 ms to about 0.05 ms. If the reported latency jumps by more than 50 ms, as when Bluetooth headphones connect, the game takes the new value at once.

Key and touch presses are judged at event.timeStamp, the moment the event happened, not when the code got to it. Gamepads are read every 4 ms using their own timestamps. Each frame is drawn for the song position 1.5 frames ahead, plus the visual sync setting, because a frame reaches the screen one to two frames after it is drawn. I also took the compressor out of the audio output: its look-ahead delayed every sound by 6 ms, so a zero-latency soft clipper replaced it.

Calibration you can trust

Calibration has you tap along to a drum-and-shaker loop rather than a click, because people tap earlier to a bare click than to drums, and calibration should measure how you will actually play. The first four beats are discarded as warm-up, the next eight taps are kept, and their median, rounded to 5 ms, becomes the suggestion. If the taps are spread by more than 35 ms, the result is flagged as unstable. A separate visual check bounces a ball that lands on each drum hit, so you can line up picture and sound.

A review on 2026-10-05 pointed out that one offset shared by touch, keyboard and gamepad would feel wrong whenever you switch. Calibration is now per device: Default, Touch, Keyboard and Gamepad profiles, each with its own judgement and visual offsets and the date it was last measured. After a run with at least 20 hits whose median sits 12 ms or more to one side, the results screen offers a one-press 'Sync a → b ms' button for the profile in use.

Two extra modes

Rhythm Playground and Janggo Festival took their current shape in a 2026-10-03 rework that studied Rhythm Heaven, Taiko no Tatsujin and Patapon. Rhythm Playground is call and response: a robot plays a bar and you answer in the next. Instead of a metronome click, a shaker, off-beat chords and bass carry the pulse; a rising whoosh on the robot's last beat says it's your turn; a ball hops ahead to each spot you need to hit.

Janggo Festival puts you on janggu over kkwaenggwari, buk and jing. I first built it on a sixteenth-note grid, which made the rhythms stiff, and rebuilt it on a grid of three per beat (two for the fast hwimori). Its guide drum shrinks when you play well and grows again when you miss, so it neither sounds like a double hit nor becomes something to lean on. Every percussion sound used for judging reaches full level within 3 ms, and the slow-attack jing is triggered 20 ms early. In both modes a C (700,000) opens the next of five stages; those scores stay on your device and are not ranked.

Phones and accessibility

On a touch screen the labels under the judgement line change from F and J to ◀ and ▶. Hits in song mode trigger very short vibrations — 8 ms for a Perfect, 5 ms otherwise — and a broken combo of ten or more gives a 30 ms buzz, all through GameNow's shared vibration setting. Switching tabs or leaving the window pauses the song instead of ending it, and resuming counts down three seconds.

Lanes are told apart by shape as well as colour: blue ● on the left and pink ◆ on the right, in every mode. That was a fix; the 2026-10-04 review found the two extra modes used the opposite colours from the main game. With reduced motion on, the per-beat brightening stops, flashes are dimmer, judgement text keeps a fixed size and position, and there is no shake or sparks. Music and hit sounds have separate volume sliders on a squared curve, so each step down sounds even.

Scores the server can check

Until 2026-10-04 a replay was a list of judged notes with their timing errors. The server could only check ranges and spread, and a fabricated set of plausible errors earned S+. Rules version 2 sends the raw input instead — song time in milliseconds, lane, press or release — and the server reruns the same judging functions the game uses to find each note, error and hold length. The results screen recalculates the score the same way, so the number you see is the number that gets ranked.

One limit can't be removed: in a rhythm game the device reports the input times, so the server cannot prove a person played. It does reject runs of 30 or more hits whose timing errors have a standard deviation under 4 ms, because human hands wobble.

What changed after testing

Here is what changed, and when.

  • 2026-10-04: test runs had finished the 18-second practice at S and S+ with full combos, so the top of the rankings couldn't separate players. New Hard boards — the janggu songs, and daily songs from 2026-10-05 — narrowed Perfect to ±33 ms. Older boards kept their windows so existing records stay comparable.
  • 2026-10-04: raw-input replays replaced judged ones, and the two janggu songs arrived; at 97 and 102 seconds they are longer than the original five, which the 2026-10-04 review had called short.
  • By 2026-10-07 (release 1.0.46): separate music and hit-sound volume, matching lane colours with ●/◆ shapes, per-device calibration profiles, and bar practice. The results screen marks the three bars where you lost the most, and a bar can be practised from two beats before it at 0.75×, 0.9× or full speed; practice runs are never submitted.
  • 2026-10-08: a run below C now counts as a failure; before, a 0-point D could be reported as a success.
  • 2026-10-09: grade lamps for clear, full combo and all perfect, saved on the device even without an account; a recommended next board; points needed for the next grade; an early/late spread; a DROP banner when a song reaches its drop section; and a light tap sound on each hit in song mode.
  • 2026-10-10: the hold bar now fills on the judgement clock, so a visual sync offset no longer makes it look complete before the note ends.

Known trade-offs

The song-mode tap sound is on by default; if it clashes with the music on high-latency Bluetooth headphones, lower the hit-sound slider in ⚙ and the music stays as it is. Guest scores and lamps stay on that device and don't move to your account when you sign in.

Two Beat →