Skip to content
abhinavbhatia
Sheet 02 / 05 — Blogs← Archive

Rally Point: badminton rules you can see, and a scorer an umpire can trust

A badminton web app with animated lessons on every rule, an umpire's scorer with live links for spectators, and a rally game. How the scoring rules work from the basics, and how one tested engine, a court drawn in real metres and Firestore on the free plan put it together.

Badminton’s rules are short to read and surprisingly hard to picture. Which service court do you serve from? Who serves after the receiving side wins a rally? When do the players change ends? A written rule answers each question, but you only really understand it when you watch it happen on a court.

So I built Rally Point, a web app in three parts:

  • Learn: twelve animated lessons on the rules, each with the court drawn to scale and the players moving as the rule describes.
  • Umpire: score a real singles or doubles match from a phone. Tap the side that won the rally; the app works out everything else.
  • Play: a small side-on rally game against the computer, using the same rules.

It is a personal project, built with AI-assisted development in plain JavaScript, HTML and CSS, and it runs on Firebase’s free plan. The code is open source on GitHub.

The rules, from the basics

Every rally scores a point, whoever served. That is rally scoring, and it is the first thing the app teaches.

From 4 January 2027 badminton moves to a new standard, the 3 × 15 system:

  • A match is the best of three games.
  • A game is won by the first side to 15 points, but you must lead by two. At 14-all play goes on until one side is two ahead.
  • There is a cap: at 20-all, the next point wins, so no game goes past 21.
  • When the leading score reaches 8, the players get a 60-second interval. In the third game they also change ends at 8.

The classic 3 × 21 system (first to 21, capped at 30, interval at 11) stays available as an option, and there is a short 1 × 7 game for warm-ups.

Two rules decide where everyone stands, and they confuse most club players:

  • Singles: the server stands in the right service court when their score is even, and in the left when it is odd. The receiver stands diagonally opposite.
  • Doubles: the serving side’s score decides the court in the same way, but partners only swap courts when their side wins a point on its own serve. When the receiving side wins a rally, it becomes the serving side and nobody moves.

After a game, the winner serves first in the next one, and the players change ends.

What the umpire screen does

An umpire taps the side that won the rally. From that one input the app shows:

  • the umpire’s call, with the server’s score always first, the way an umpire says it out loud: “Love all, play”, “Service over, five-seven”, “Fourteen all”, “game point”;
  • who serves next and who receives, and where all players stand, on a live drawing of the court;
  • when the 60-second interval is due, with a countdown, the two-minute interval between games, and when the players change ends;
  • a rally log, undo for a mis-tap, and a history of finished matches.

A live link lets anyone follow the score on their own phone, from the side of the court or from home.

How it is built

One scoring engine, used everywhere

All the rules live in one file, engine.js, as pure functions: every call takes a match state and returns a new one, without changing the old one. That choice pays for itself three times:

  1. Undo is free. The umpire screen keeps a stack of past states; undo just steps back one.
  2. The rules are testable. Unit tests cover both scoring systems, the cap at 20-all, the interval and the change of ends in game three, service courts in singles and doubles, match point, and the umpire’s call.
  3. Every part of the app agrees. The lessons, the umpire screen and the game all call the same functions. A scoring system is one entry in a table (points to win, the cap and the interval score), so adding or changing one does not touch the rest of the app.

A court in real metres

court.js draws the court in SVG at its real size: 13.4 metres long and 6.1 metres wide for doubles, with the short service line 1.98 metres from the net and the doubles long service line 0.76 metres inside the back line. Because the drawing uses real measurements, the service courts for singles and doubles come out right without any special cases. A second file, scene.js, turns a match state into player positions, so the same court can show a lesson, a live match or a quiz.

A live link is a document in Cloud Firestore. The umpire’s phone signs in anonymously, creates the match document and writes to it after every rally. Spectators read it with a live listener.

The security rules are short and strict:

  • anyone with the link can read one match, but nobody can list matches;
  • only the anonymous user who created a match can update it;
  • each document may only contain the expected fields.

Match IDs are ten random characters from an alphabet without look-alikes such as 0, o, 1, i and l, so a link read out loud still works. Firebase is loaded only when someone opens a live link, so the rest of the app stays small and fast, and the config comes from Firebase Hosting’s reserved /__/firebase/init.json address, so there are no keys in the code.

Works offline

A service worker caches the whole app the first time it loads, and the app installs on a phone like a native app. Lessons, the umpire screen and the game all work without a signal, which matters in a sports hall. Only live links need the network.

What it costs to run

Nothing. It runs on Firebase’s free Spark plan: Hosting for the site, Firestore and anonymous Authentication for live links. The whole app is well under 1 MB. A live match writes once per rally, roughly 60 to 120 writes, against a free allowance of 20,000 writes a day. On the Spark plan a limit pauses a service until the next day instead of sending a bill.

Try it

It is one of the apps on my apps page, alongside a CV builder, a learning app for young children and a meal tracker.