2026-08-11 10:52:35 +02:00
|
|
|
|
# Backgammon Clock
|
|
|
|
|
|
|
|
|
|
|
|
A two-player match clock with **simple delay you can actually see**. Reserve time
|
|
|
|
|
|
plus a fixed number of free seconds each turn that never carry over — the
|
2026-08-11 17:00:50 +02:00
|
|
|
|
Backgammon Galaxy control. Defaults to 3:00 + 12s.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
|
|
|
|
|
|
Plain HTML, CSS and JavaScript. No frameworks, no fonts, no images, no network.
|
|
|
|
|
|
|
2026-08-11 21:44:27 +02:00
|
|
|
|
There's an Android package too, in `android/` — a WebView around the same
|
|
|
|
|
|
`public_html/`, so the two can't drift. It declares no permissions at all. See
|
|
|
|
|
|
[RELEASING.md](RELEASING.md) for how to cut a new version for F-Droid.
|
|
|
|
|
|
|
2026-08-11 10:52:35 +02:00
|
|
|
|
## Getting it onto your phone
|
|
|
|
|
|
|
|
|
|
|
|
Chrome will only offer a real install over HTTPS, so the file needs a host.
|
|
|
|
|
|
GitHub Pages is free and takes about two minutes:
|
|
|
|
|
|
|
|
|
|
|
|
1. Create a new public repository, e.g. `bgclock`.
|
2026-08-11 17:47:50 +02:00
|
|
|
|
2. Upload all six files from `public_html/` to the root: `index.html`,
|
|
|
|
|
|
`manifest.webmanifest`, `sw.js`, `icon-192.png`, `icon-512.png`,
|
|
|
|
|
|
`icon-maskable-512.png`.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
3. **Settings → Pages → Source: Deploy from a branch → `main` / `(root)` → Save.**
|
2026-08-11 11:53:56 +02:00
|
|
|
|
4. Wait a minute, then open `https://<you>.github.io/bgclock/` on your phone.
|
|
|
|
|
|
5. **Android, Chrome:** menu (⋮) → **Add to Home screen** → **Install**.
|
|
|
|
|
|
**iOS, Safari:** Share (□↑) → **Add to Home Screen** → **Add**. It has to be
|
|
|
|
|
|
Safari — Chrome and Firefox on iOS can't install a web app.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
|
|
|
|
|
|
Open it from the home-screen icon and it runs fullscreen with no browser
|
|
|
|
|
|
chrome, offline, with the screen kept awake while a game is on.
|
|
|
|
|
|
|
2026-08-11 11:53:56 +02:00
|
|
|
|
On iOS a few things behave differently, none of them fatal:
|
|
|
|
|
|
|
|
|
|
|
|
- **Install from Safari, and play from the home-screen icon.** In a Safari tab
|
|
|
|
|
|
you lose a strip of the screen to the toolbar, and iOS clears the saved
|
|
|
|
|
|
settings of a site you haven't visited for a week. The installed app keeps
|
|
|
|
|
|
its own storage and doesn't get pruned that way.
|
|
|
|
|
|
- **The ringer switch doesn't mute the clock.** The page claims a playback
|
|
|
|
|
|
audio session so you can hear the delay tick with the phone silenced, which
|
|
|
|
|
|
in exchange pauses any music you had going. If you'd rather keep the music,
|
|
|
|
|
|
delete the `navigator.audioSession` line in `index.html`.
|
|
|
|
|
|
- **Screen wake needs iOS 16.4 or newer.** Below that the screen dims on its
|
|
|
|
|
|
usual schedule mid-game.
|
|
|
|
|
|
|
2026-08-11 10:52:35 +02:00
|
|
|
|
If you're using a different path than `/bgclock/`, edit the `"id"` field in
|
|
|
|
|
|
`manifest.webmanifest` to match, or just delete that line.
|
|
|
|
|
|
|
2026-08-11 17:47:50 +02:00
|
|
|
|
To try it before hosting, open `public_html/index.html` in any browser —
|
|
|
|
|
|
everything works except installation and the service worker.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
|
|
|
|
|
|
## Using it
|
|
|
|
|
|
|
|
|
|
|
|
- **Tap your own half** to end your turn and start your opponent's clock.
|
|
|
|
|
|
At the start, whoever taps first sets the *other* player going.
|
|
|
|
|
|
- The waiting player's taps are ignored, so a stray hand won't stop the clock.
|
2026-08-11 17:26:56 +02:00
|
|
|
|
- A tap counts when you **lift** your finger, and only if it didn't move. A swipe
|
|
|
|
|
|
does nothing, so Android's swipe-up-from-the-bottom and the status-bar pull-down
|
|
|
|
|
|
work over either half without costing anyone their turn — and a hand dragged
|
2026-08-11 17:47:50 +02:00
|
|
|
|
across the panel won't change it either.
|
|
|
|
|
|
- Your clock runs until you lift. Holding a finger on the panel costs you the
|
|
|
|
|
|
time you can see counting off, and holding it past zero flags you, exactly as
|
|
|
|
|
|
if you hadn't touched it at all.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
- The bar under the big time is the delay draining. When it empties you get a
|
|
|
|
|
|
soft tick and your reserve starts moving. That's the moment worth hearing.
|
2026-08-11 20:05:24 +02:00
|
|
|
|
- **Run out and your half turns red and reads "Out of time"**, in letters sized
|
|
|
|
|
|
to whatever room that half has left, so it's readable from across the board.
|
|
|
|
|
|
The other half keeps showing its own remaining time.
|
2026-08-11 14:39:32 +02:00
|
|
|
|
- **Reset** starts a whole new match: clocks back to full *and* the score back to
|
|
|
|
|
|
0–0. It takes two taps: the first arms the button — it lights up and a ring
|
|
|
|
|
|
unwinds around it — and a second tap within those two seconds does it. One
|
2026-08-11 17:47:50 +02:00
|
|
|
|
stray thumb can't wipe a live match. It's absent on a fresh match, where there
|
|
|
|
|
|
is nothing yet to wipe.
|
2026-08-11 11:18:02 +02:00
|
|
|
|
- **Pause** freezes mid-turn and resumes exactly where it stopped, delay
|
2026-08-11 15:11:31 +02:00
|
|
|
|
included. Opening either sheet pauses automatically. The settings sheet leaves
|
|
|
|
|
|
it paused — everything in there resets the clocks anyway — while the score
|
|
|
|
|
|
sheet picks the turn back up when you close it, so glancing at the score
|
2026-08-11 20:20:30 +02:00
|
|
|
|
doesn't cost you a tap on play. It's absent whenever there's no clock running
|
|
|
|
|
|
to freeze: before each game's first tap, and once someone has run out of time.
|
2026-08-11 17:47:50 +02:00
|
|
|
|
|
|
|
|
|
|
Both buttons keep their space in the bar while they're away, so nothing shifts
|
|
|
|
|
|
under your thumb — the same as the gear.
|
2026-08-11 15:57:37 +02:00
|
|
|
|
- **Settings are only reachable before a match starts.** Every control in that
|
|
|
|
|
|
sheet resets both clocks, so the gear disappears the moment the first tap
|
|
|
|
|
|
starts the clock and comes back after a reset. Its space in the bar is kept
|
|
|
|
|
|
empty, so nothing else shifts. That means a mistake in the time or delay can
|
|
|
|
|
|
only be fixed by resetting and starting the match again — deliberately, since
|
|
|
|
|
|
the alternative is wiping two live clocks by accident. Correcting a clock
|
|
|
|
|
|
mid-match is what the score sheet is for.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
|
|
|
|
|
|
Backgammon clocks pause between games, and after a cocked die the delay is
|
|
|
|
|
|
normally restarted — use pause and reset for those.
|
|
|
|
|
|
|
2026-08-11 14:39:32 +02:00
|
|
|
|
## Matches
|
|
|
|
|
|
|
|
|
|
|
|
Set **Match** in the settings to the number of points you're playing to — 1, 3,
|
|
|
|
|
|
5 and up to 29. The time you set is *per point*, so a 5-point match at 2:00 a
|
|
|
|
|
|
point puts 10:00 on each clock, and the settings sheet shows you that sum.
|
|
|
|
|
|
|
2026-08-11 15:11:31 +02:00
|
|
|
|
Each half reads the state from that player's own side of the board:
|
2026-08-11 14:48:44 +02:00
|
|
|
|
|
2026-08-11 15:11:31 +02:00
|
|
|
|
```
|
|
|
|
|
|
You: 1 out of 5
|
|
|
|
|
|
Them: 3
|
|
|
|
|
|
Moves: 7
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
So "You" always means whoever is sitting at that end — both players read their
|
|
|
|
|
|
own score on the top line, and the two halves show mirrored numbers.
|
|
|
|
|
|
|
|
|
|
|
|
At **1 point** there's no match to keep score of, so the score lines and the
|
|
|
|
|
|
score-sheet icon all disappear and you get the plain single-game clock with just
|
|
|
|
|
|
its move count. Set the match to 3 or more and they come back.
|
|
|
|
|
|
|
|
|
|
|
|
The score sheet is the middle icon in the bar. It's filled in from the phone
|
|
|
|
|
|
holder's side: **You** is the bottom half, **Them** the far end.
|
2026-08-11 14:39:32 +02:00
|
|
|
|
|
|
|
|
|
|
Nothing in that sheet takes effect until you press **Done**:
|
|
|
|
|
|
|
|
|
|
|
|
- **Done with nothing changed** leaves everything exactly as it was — same turn,
|
2026-08-11 15:11:31 +02:00
|
|
|
|
same delay part-spent, same move counts — and the clock picks up where it left
|
|
|
|
|
|
off. Tapping outside the sheet is the same as changing nothing, so a stray tap
|
|
|
|
|
|
can't restart a game. A pause you set yourself before opening the sheet
|
|
|
|
|
|
survives; only the sheet's own pause is undone.
|
2026-08-11 14:39:32 +02:00
|
|
|
|
- **Change a score** and the game restarts when you press Done: move counters
|
|
|
|
|
|
back to zero and the turn back to the first tap, waiting on whoever rolls the
|
|
|
|
|
|
lower die. The clocks keep whatever they were showing.
|
|
|
|
|
|
- **Change only a clock** — the sheet also lets you correct either player's time
|
2026-08-11 15:11:31 +02:00
|
|
|
|
to the second — and the game carries on undisturbed and running: same turn,
|
|
|
|
|
|
same delay position, same moves.
|
2026-08-11 14:39:32 +02:00
|
|
|
|
|
|
|
|
|
|
Shortening the match to fewer points than someone has already won pulls their
|
|
|
|
|
|
score down to fit.
|
|
|
|
|
|
|
2026-08-11 10:52:35 +02:00
|
|
|
|
## Settings
|
|
|
|
|
|
|
2026-08-11 18:11:04 +02:00
|
|
|
|
Under **Delay** are three presets — **2m / 12s**, **3m / 12s** and **3m / 15s**.
|
|
|
|
|
|
Tapping one jumps both timers there and lights it up. Change the time or delay by
|
|
|
|
|
|
hand and the highlight goes out; land back on a preset's numbers and it comes
|
|
|
|
|
|
back on.
|
2026-08-11 11:18:02 +02:00
|
|
|
|
|
2026-08-11 10:52:35 +02:00
|
|
|
|
| Setting | Range | Default |
|
|
|
|
|
|
| --- | --- | --- |
|
2026-08-11 14:39:32 +02:00
|
|
|
|
| Match | 1 – 29 points, odd | 1 |
|
|
|
|
|
|
| Time | 0:15 – 99:00 per point | 3:00 |
|
2026-08-11 17:00:50 +02:00
|
|
|
|
| Delay | 0 – 60 s | 12 s |
|
2026-08-11 10:52:35 +02:00
|
|
|
|
| Colour | Sage, Brass, Slate, Teal, Plum | Sage |
|
|
|
|
|
|
| Sound | on / off | on |
|
|
|
|
|
|
|
|
|
|
|
|
Brass is the colour in the chess.com app, if you want the exact original look.
|
2026-08-11 14:39:32 +02:00
|
|
|
|
Changing match, time or delay resets the clocks — the score is left alone, so you
|
|
|
|
|
|
can fix the delay mid-match without losing where you are.
|
|
|
|
|
|
|
|
|
|
|
|
Settings **and the match in progress** are kept in `localStorage`, so they
|
|
|
|
|
|
survive closing the tab, force-quitting the installed app and rebooting the
|
2026-08-11 11:18:02 +02:00
|
|
|
|
phone — the app also asks for persistent storage so they aren't evicted when the
|
2026-08-11 14:39:32 +02:00
|
|
|
|
device runs low on space (Chrome honours that request; Safari ignores it).
|
|
|
|
|
|
Reopening restores the score, both clocks, the move counts, whose turn it is and
|
|
|
|
|
|
how much delay was left. The one thing it can't restore is time passing while
|
|
|
|
|
|
the app was closed, so it comes back paused rather than charging anyone for the
|
|
|
|
|
|
gap: a crash shouldn't decide a game.
|
2026-08-11 10:52:35 +02:00
|
|
|
|
|
|
|
|
|
|
## Sounds
|
|
|
|
|
|
|
|
|
|
|
|
All three are generated with the Web Audio API, so there are no audio files to
|
|
|
|
|
|
download and nothing to attribute.
|
|
|
|
|
|
|
|
|
|
|
|
- **Turn change** — a soft rising fifth with an octave partial, marimba-like.
|
|
|
|
|
|
- **Delay expiry** — a single quiet 300 Hz tick, deliberately easy to miss unless
|
|
|
|
|
|
you're listening for it.
|
|
|
|
|
|
- **Time out** — a falling triad, loud and unambiguous.
|
|
|
|
|
|
|
|
|
|
|
|
## Licence
|
|
|
|
|
|
|
2026-08-11 19:28:05 +02:00
|
|
|
|
MIT — see [LICENSE](LICENSE). Do whatever you like with it, in other words, but
|
|
|
|
|
|
now in a form F-Droid and everyone else can read.
|