The trainer is built local-first: your board plays perfectly with zero internet, forever. The network exists for exactly one reason โ the shared detection model that every board helps train and every board gets back. This page shows everything that is stored, where, and why. Numbers are live as of 2026-07-18.
stats.dbSQLite on the Pi ยท the local-first source of truth ยท works offline forever
games (every run: mode, config, players, final metric),
throws (every dart), derived (computed stats).ramdisk (/dev/shm) ยท ephemeral ยท never wears the SD card
on the board, not in the browser
highscores.json): the board-scope leaderboard is
complete offline โ every game mode's best runs, per combo.players.json): everyone who played on this board โ the same
quick-pick list from any device that opens the page.groups.json): only a hash of the group passphrase is
stored โ the passphrase itself never exists on disk, anywhere.the seeing part
tipnet.onnx: the dart-tip detection model, shipped with the app and
updated over the air; the previous version is kept for instant rollback.One small service holds the shared brain: the training data both boards contribute, the model registry they update from, and the cross-board leaderboards. The darts themselves are tiny โ the whole database is 12 MB; it is the camera frames that weigh 13 GB.
| Table | Rows | What it holds |
|---|---|---|
game_throw | 6,464 | every uploaded throw: label, model proposal, correction flag, game context, capture timestamp |
capture / capture_image | 6,464 / 19,392 | the capture sets โ 3 camera frames per throw, lossless WebP, content-addressed (SHA-256), stored in the 13 GB blob volume |
highscore + highscore_tag | 91 + 9 | leaderboard rows with extensible tags (board:, group:, variant:โฆ) โ new scopes need no schema change |
elo_rating | 5 | the ranked-match ladder (K=32, saved players only) |
player / player_identity | 9 / 1 | display names ยท opt-in 12-word key bindings (only the public key is stored โ never the words) |
rig / rig_token | 3 / 5 | enrolled boards and their per-board access tokens (each board holds only its own key; any one can be revoked alone) |
rig_health / rig_event | 471 / 14,313 | heartbeats + the shipped decision log โ a friend's board can be debugged without SSH |
rig_calibration | 28 | calibration snapshots โ per-throw provenance for training |
model | 16 | the published model registry: every trained model with its provenance and metrics โ boards pull updates from here |
feedback | 11 | in-app bug reports, arriving with screenshot + rig context as evidence |
eval_run / eval_result | 0 / 0 | reserved: detector-vs-truth evaluation slices |
stats.db
and
frames + label queue in the outboxโ
central capture store
The loop's honest rule: models are judged by field acceptance โ how often real players accept proposals untouched at a real board โ not by lab metrics alone. A model that aces the test set and annoys players does not ship.
install ยท game modes ยท
statistics
dart-room.com โ open dart detection, local-first