Skip to content

Designing for the remote

A TV remote has four arrows, OK and Back. On a chessboard that is a long way from a mouse. With a cursor that moved one square per press, a turn of Dice Chess took 23 presses on average in simulated games. The board now takes about 9.

  • A turn is up to three actions, and each action is two choices: a piece, then a square.
  • The dice decide which pieces may move, so most of the board is never a choice at all.
  • A cursor that moves square by square spends its presses crossing squares that cannot be chosen.

npm run presses, the evaluator in scripts/cursor-presses.ts, replays 200 seeded random games through the app’s own core. For every action it counts the presses each candidate design needs. No design left a piece or a destination out of reach.

Remote presses per turn, hotseat, 200 simulated games (lower is better)

Square by square, as before23.0

Square by square, starting on the central piece

15.6
Jump between the pieces that can move14.0
…and wait on a piece that can move12.4
…and jump between destinations too (shipped)9.2
…the same, landing always in the centre8.9
Design Per action Per turn Median turn 90th percentile
Square by square, the cursor stays 8.91 23.04 24 32
Square by square, starting on the central piece 6.01 15.55 16 23
Jump between the pieces that can move, the cursor stays 5.40 13.97 15 19
Jump, and the cursor waits on a piece that can move 4.78 12.37 13 17
Jump between pieces, then between destinations 3.56 9.21 10 13
The same, but landing always on the central destination 3.45 8.92 9 12

Both sides of 200 hotseat games, 8,346 turns, seed 68. The shipped row uses the cone rule described below. The same design with a plain axis rule scores 9.16, so the rule was chosen on another ground: in 20,000 random sets of squares, the cone rule reached every square, while two simpler rules each left some square out of reach.

The last row shows what the landing rules below cost in these games. A random mover takes no more often than it makes any other move, so landing on a capture saves it nothing, and the shipped design spends 0.29 presses a turn more than landing in the centre. People are different: they take far more often than not, and a pawn on its starting square usually advances two. The landing follows people, so random games cannot credit it.

A hotseat game: Black’s knight is picked up, its destinations are dotted, the capture of White’s knight is ringed, and the cursor landed on that capture

  • What can move is marked. After every roll and every action, a green fill marks the pieces that can move. They are the starts of the engine’s legal actions, so they already follow the rule that a turn uses as many dice as it can.
  • Arrows jump. A press lands on the nearest choice within 45 degrees of the arrow. Failing that, it lands on the choice least far ahead, counting sideways distance twice. With nothing ahead the cursor stays. On the board turned for Black, the arrows follow the screen.
  • The cursor waits where it helps. It stays on its square while that piece can still move, and otherwise moves to the central piece, the one fewest presses from all the others.
  • OK lands on the likely destination. Picking a piece up puts the cursor where players usually go: on the most valuable piece it can take, the king above all, since taking it wins. A pawn that cannot take but can advance two squares lands on that push, the usual choice over the single step. Any other piece lands on its central destination, so a piece with a single destination plays with OK, then OK. The arrows do not reach every destination from every square, so a landing that would leave one out of reach gives way to the central destination. Back puts the piece down, with the cursor back on it.

The rules live in the app’s core (src/core/cursor.ts, src/core/boardInput.ts), are covered by its tests, and were played on the Vega Virtual Device. Nothing here has run on a Fire TV Stick yet.

A second mark was tried: amber brackets on the pieces that could move only after one more action. It was dropped for three reasons.

  1. The cursor could not land on those pieces, so the mark offered nothing to press.
  2. Green and amber are the pair that colour-blind viewers confuse most.
  3. It cost one legal-move generation per legal action, up to 43 ms per step on the Virtual Device.

The green fill comes from the legal list the screen already has, at no extra cost.

  • src/core/cursor.ts and src/core/boardInput.ts: the rules, tested in test/cursor.test.ts and test/boardInput.test.ts.
  • scripts/cursor-presses.ts: the evaluator. npm run presses prints the table above.