Johan Alphonso Braga
Typing test⌘J
AboutProjectsReadingStackCraftDesignStatusResume

Utilities

Ask anything Typing test

Elsewhere

GitHub

All projects

Games / 2026 / Live in the browser

Antiphon

A one-button call-and-response rhythm game. The song plays a phrase, you tap it back a bar later, and every tap plays the next note of the melody. Three seeded tracks, judged against the moment each sound reached your ears.

Antiphon

01

The problem

One-button rhythm games usually scroll notes toward a line, so the player reads instead of listening. I wanted the music itself to be the chart: hear a phrase once, then play it back. That needs songs where every answer is exactly the call shifted by a bar, difficulty that comes from rhythm and memory rather than speed alone, and timing judged against what the player actually heard rather than when the key handler ran.

02

How I approached it

A DOM-free UMD engine composes each song from a seed. Rhythms are drawn from a 16-step grid with weights for downbeats, off-beat eighths and sixteenths that ramp up over the song under a minimum note gap, and the melody is a weighted random walk on the track's scale that favours the current chord. The same pass writes drums, bass, pads and count-in as one event list, which a 25 ms timer books 150 ms ahead on the Web Audio clock. Taps are mapped from the event timeStamp onto the audio clock with getOutputTimestamp, which includes output latency, and a calibration screen measures the rest as a median offset. A tap takes the nearest open note within 130 ms, and a tap that hits nothing inside an answer bar is a stray that counts against accuracy. Lantern keeps the call on the dial while you answer, Tidewire fades it after a beat and Glasswork hides it.

03

The outcome

Three tracks at 84, 108 and 132 bpm, remixable to any seed, with early, late and perfect feedback on every tap, a live hit-error meter and a results screen with a 10 ms offset histogram and a per-phrase breakdown. 13 tests with no dependencies cover the one-bar echo for every note, grid and gap rules over 30 seeds per track, judgement windows, nearest-note matching, strays, scoring and calibration. A bot player scores S with 12 ms of timing error and F when it mashes every sixteenth.

antiphon.johanthegoat.xyz Open in a new tab ↗
Next projectRiposte →