Building a browser typing game for Japanese learners sounds simple until you hit romaji variants.

Learners type the same mora many ways: shi vs si, chi vs ti, fu vs hu, long vowels with or without u, and ん before consonants. If the game only accepts one spelling, practice becomes frustration instead of muscle memory.

What we wanted

For 寿司打 (Sushida), a free browser sushi typing practice site, the goals were:

  1. Accept common Hepburn / kunrei-style variants learners actually use
  2. Keep scoring fair (no free points for wrong kana)
  3. Stay entirely client-side (no iframe embeds of third-party games)
  4. Work on a phone keyboard and a physical JIS/US layout

Acceptance table, not string equality

Instead of comparing raw input to a single canonical string, we normalize keystrokes through a small acceptance table:

  • Map each target mora to a set of allowed romaji spellings
  • Consume the longest matching spelling from the left (greedy but bounded)
  • Reject mid-mora garbage early so the falling sushi does not “stick”

This is closer to how IME romaji engines think than to input === answer.

Edge cases that surprised us

  • ん before な行: nna vs n'na — we accept both when the next mora starts with n
  • 長音: ou / oo / ASCII approximations for some learners
  • 促音: doubling the consonant (kitte) must not steal the next mora’s first letter incorrectly
  • Mixed scripts: if someone pastes kana mid-word, fail soft and show the expected romaji hint

Why not just use an IME?

IME composition is great for writing, terrible for a falling-object timing game. Composition windows steal focus and break frame timing. We keep the game on raw keydown and teach romaji explicitly — that is the skill people practice on 寿司打.

Takeaway

If you ship a Japanese typing practice game in the browser, invest in the acceptance table before the particle effects. Fair input parsing is the product.

Free to try: https://sushida.org/