KNOCK ROLL DIE View source

Knock Roll Die

Tarot, a magic 8 ball and dice for the BUSY Bar, on its 72×16 pixel display. Ask a question out loud, spin the wheel, press Start.

Start screen The wheel A tarot card
Its prediction Magic 8 ball A die

How it plays

  1. Start screen – the deck's own phrase ("Ask aloud, press Start"). Start continues.
  2. The wheel – face-down cards sliding past a framed one in the middle. Turn the dial to launch the wheel, or press Start for a launch of random strength; more turns of the dial while it spins send it faster still. One spin lasts at least 12 seconds and shows every card of the deck at least once (tarot: about 15 seconds): it slows down step by step and settles on a card. Press Start while it spins to brake sooner. The cards move at 60 frames a second, played by the bar itself.
  3. The result – the card grows to fill the screen and shows what the deck says: art, text, a die face or a number. A result can have several steps (a tarot card, then its prediction); Start moves through them.
  4. After the last result of a reading the app returns to the start screen.

Auto play (Settings → Auto play) is Off, One game or Random game. Both have no start screen: the app spins the wheel by itself, shows each screen of a result for three seconds, and after the last result of a game shows "next game in 5" and starts over - for ever. One game plays the chosen deck again and again; Random game takes another deck for every game (the countdown names it; the lotto and bingo, which are a whole game by themselves, are left out). Start skips a wait or brakes the wheel; Back quits. Settings → Sound turns every sound off, the wheel's clicks included.

The wheel clicks for every card that passes the frame, so you hear its speed: dense clicks while it flies, ever further apart as it slows, and quickening again when you give it another turn of the dial. The wheel starting, settling, the result opening and moving to its next step have sounds too. Settings → Sound turns them off; the bar's own volume setting still applies.

Your own sounds

The sounds are five plain files in the app's sounds/ folder on the bar - click.snd, spin.snd, stop.snd, show.snd, next.snd - so to change them upload your own under the same names (or replace the ones in src/sounds/ and pnpm push). A .snd file is raw signed 16-bit little-endian mono PCM at 44100 Hz; make one from any audio with

ffmpeg -i in.wav -ac 1 -ar 44100 -f s16le -acodec pcm_s16le spin.snd

That is 88 KB per second, so keep effects short.

Button Start screen Wheel waiting Spinning Result
Start continue spin brake next step / next result
Dial – spin add momentum –
Back quit start screen start screen start screen

Decks

Two decks are in Russian: Fairy tales and Lotto. The others are in English.

Deck What you get Results per reading
Tarot 78 cards: the art, then a short prediction 3
Neon the same 78 cards in neon colours 3
Cosmic the same 78 cards as a space story: engines, capsules, beams, planets 3
Fairy tales the same 78 cards from Russian fairy tales, with Russian text 3
Tarot count for a physical tarot deck: a number, then "count N cards from the top" 3
Runes the 24 runes of the Elder Futhark: the sign, then its name and meaning 3
I Ching the 64 hexagrams, drawn line by line, with their names 1
Cards the 52 playing cards, a hand of five; the dial favours the higher ranks 5
Dominoes the 28 bones of a double-six set, a hand of seven; the dial favours the bigger sums 7
Lotto Russian lotto, with Russian text: the 90 barrels without repeats, each with its folk name (a number, then Start for the name) 90
Bingo the 75 balls: a letter, then the number 75
Roulette European wheel: the 37 pockets, each as a field in its colour with a big number; Start for colour, parity and half 1
Coin heads or tails 1
RPS rock, paper, scissors 1
Directions the eight directions of the compass, with an arrow 1
What to eat a dish for the day 1
8 ball one of 20 classic answers; the dial favours the positive ones 1
2d6 two dice, the 36 throws: their sum comes up as it does with real dice 1
d4 ... d100 a die face (d6) or a big number; the dial favours the higher 1

Cards in a reading never repeat; dice and the ball can. Settings → Results overrides how many results a reading shows (1–5); the default, Auto, uses the deck's own number. Settings → Card back picks the picture on the wheel's cards (Diamond, Lattice, Sparkle, Plain); Auto uses the deck's own back, and tarot, neon and the 8 ball each have one.

Your own deck

A deck is one text file. Drop deck-<name>.txt into the app's resources folder on the bar and it appears in Settings → Deck after the next run of the app. A broken file does not crash anything: the screen names the file and says what is wrong with it. The format is described in docs/DECKS.md.

A deck error

Install

Each release carries the packaged app. To build and install from source, upload it to the bar over its HTTP API:

pnpm install
pnpm push 192.168.1.20 <api token>     # builds, then uploads dist/ to the bar over its HTTP API (no address: tools/bar.sh finds the bar)

On the bar open Apps → Knock Roll Die.

Development

Needs Node below 26 (see CONTRIBUTING.md) and pnpm (corepack enable). Python 3 with Pillow is needed only to re-render the wheel's animations (tools/make_anim.py).

pnpm install
pnpm check        # typecheck, lint and tests
pnpm test         # tests only
pnpm format       # fix formatting and import order
pnpm build        # dist/<app id>/ (it builds the deck files from assets/ first)
pnpm decks        # only the deck files and the deck list: from assets/, plain Node, no extra setup
make push         # build and upload to the bar: tools/bar.sh finds it on the network or opens a tunnel through the jump host
make              # build and pack: builds/<app id>-<version>-<commit>-<time>.tgz (`make list` shows them)

The code is layered; each layer only uses the ones above it in this list:

src/
├── config.ts, util.ts        constants and small helpers
├── settings.ts               the user's settings
├── deck/
│   ├── format.ts             deck file format and parser (pure)
│   ├── store.ts              reading decks from the device's storage
│   └── discovery.ts          keeps the settings screen's deck list in step with the files
├── state.ts                  the whole mutable state
├── game.ts                   rules: what each button and tick does (no drawing, no I/O)
├── wheel.ts, clips.ts        the spin: an automaton that chains pre-rendered animation clips
├── view/                     what each phase looks like (elements.ts builders, screens.ts)
├── display.ts                one-at-a-time drawing queue
└── main.ts                   the controller: input, clock, loading

Identity, version and heap size live in src/appmeta/manifest.json; the settings screen in src/appmeta/settings.json.

Fairness

The card is drawn once, when the wheel is launched, uniformly from what can still come up; the spin is only a show. How, and how to test it with Monte Carlo: docs/RANDOMNESS.md.

Work with us

Knock Roll Die is free and open source, and it is also a small platform for branded experiences on the BUSY Bar. If you would like to put your company on the bar, we can build:

Terms are open to discussion: tell us what you have in mind and we will work out the scope and conditions together. Reach the author through the profile of the repository owner on GitHub, or open an issue titled "Partnership".

License

MIT © Sergey Trofimov. This covers the code and the bundled decks, including their artwork, which was generated by the author.