Back to folio
Plate 02 — colour guessing game

Hue Knew?

A colour guessing game for two. One player picks a secret square on a board of 480 colours and gives short clues; the other has three guesses to land on it.

Role
Solo. Game design, visual design, frontend, networking, sound.
Timeline
October 2026, built in a day and refined over two more
Built with
Vanilla JS · WebRTC · PeerJS · Web Audio · OKLCH
The Hue Knew? game table: a 30 by 16 board of colours in a dark wood frame, hue running across and lightness down, with four numbered card positions marked. On the right, the clue-giver's panel offers four colour cards, D28, D4, A21 and I19, with a New cards button. A score track to 15 runs under the board.
The clue-giver's view at the start of a round. The four cards on offer are marked on the board.

The brief I gave myself

Hues and Cues is a board game I like playing with people who are not in the same room. I wanted a version that works across a table or across countries, costs nothing to run, needs no accounts, and is finished in a day.

The harder constraint was the feel. A party game lives or dies on whether pressing a button is satisfying, so the clicks, the pawn landing and the reveal mattered as much as the rules.

It must not look generated

Before writing code I wrote down what the game was not allowed to look like.

No purple gradients, no glass panels, no hero section with three feature cards, no Inter, no sparkles, no exclamation marks, no emojis anywhere — including the commit messages. Each of those is a default that makes a site read as nobody's in particular.

What it does instead comes from the materials of a real board game: a wooden table, a cardboard box lid for the start screen, clue cards printed like playing cards and tilted a degree or two, a stamped round tag, and printed row and column labels round the board. The chrome stays in wood browns and warm card stock, with cherry and navy for the two players, so the only bright colour on screen is the board itself. Headings are condensed Archivo in capitals like box type; coordinates and scores are IBM Plex Mono.

The copy follows the same rule. It reads like rules printed in a game box: "Pick your secret colour." "Clue 2 — up to two words." "Lock in H14."

A board where every clue has somewhere to land

The board is 30 columns by 16 rows. Hue runs across, one full trip round the colour wheel; lightness runs down, from pale to deep. It is computed in code when the page loads, not stored.

It took three versions. The first used HSL, whose hue steps are not even to the eye — the greens and cyans blurred into one band and the bottom rows went near-black. The second arranged hue round the edges with a pale centre, which looked good and played badly: 44% of squares had a look-alike four or more rings away, so a perfectly good clue could point to two places.

The third steps hue in equal OKLCH increments and stops lightness at 0.44 instead of black. Far look-alikes dropped to 7%. It also has real pastels and deep shades, so clues like "mint", "navy" or "maroon" have a place to go.

Those numbers are checked, not eyeballed. A test page asserts that all 480 colours are distinct, every column darkens row by row, the hue wraps cleanly, and the count of near-identical neighbours and far look-alikes stays under a fixed ceiling.

Rules that hold up between two people

The physical game is built for up to ten players. With two, some of its rules break, and the fixes are design decisions rather than code.

  • Distance is counted in square rings, so diagonals count as one. The guesser scores 5, 3, 2 or 1 for their best guess only.
  • The clue-giver scores when the guess does, and more for getting there sooner: +3 after the first clue, +2 after the second, +1 after the third. Revealing early is a bet.
  • Clues grow from one word to two to three, and basic colour names are blocked, so the clue has to be a fruit, a place or a mood.
  • The four cards on offer are always at least five columns apart round the wheel and away from last round's colour, so a deal never offers four shades of the same thing twice running.
  • Once someone reaches the target score, play continues until both players have given clues the same number of times. Otherwise player 1 gets an extra turn as clue-giver.
  • Ties are common with two players — about one game in ten in a simulation of evenly matched players, because a good round pays both of you. The board game's tiebreak would always hand it to player 2, so a level game here plays one more round each until someone leads.

Three ways to sit at the table

  • Laptop is the board. The laptop shows the shared table and is not a player; both people join from their phones, which become private hands. The clue-giver's phone holds the secret and the clue box. The guesser's says "Make your guess on the big screen."
  • Each on your own device. Two screens, one four-letter room code. This is the long-distance mode.
  • One device. Pass it back and forth; an opaque "Pass to Arjun. No peeking." card covers the screen whenever the acting player changes.

All three run the same game. Rendering is a function of the state and who is looking at the screen, so the modes differ only in who that viewer is.

One device owns the truth

Only the host runs the rules. Everyone else sends requests.

Players send actions — pick, clue, guess, reveal. The host passes each one through a pure reducer that checks the phase, whose turn it is and the word limits, then sends every connection the new state. An invalid action changes nothing, and the sender gets the current state back.

Before the state goes out, the secret is removed for anyone who should not see it. Hiding the target in the interface is not enough when the target is sitting in the data a curious player can open in dev tools.

Because the reducer is pure, the rules are tested without a network: distance and points, best-guess-only, the earliest-tie rule, bonuses per clue, auto-reveal on a perfect hit, word limits, blocked colour words, and repeated guesses.

Networking without a server

Rooms run peer to peer over WebRTC, with PeerJS's free signalling server for the introduction and a TURN relay for networks that block direct connections. There is no backend to pay for.

  • Room codes skip letters that are easy to misread, such as I and O. A join link pre-fills the code.
  • A phone or host that refreshes mid-game goes back to the same room and seat, with the scores intact.
  • A dropped guest retries in the background behind a "Reconnecting…" banner, and the host is told who left and how they can rejoin.
  • A third phone trying to join a two-player table is told the room is full.
  • Errors are written for people: "Couldn't find that room. Check the code?" rather than a PeerJS error name.

Sound made in code

There are no audio files. Every sound is synthesized with the Web Audio API from oscillators and filtered noise, which means no licensing and nothing to download. The brief was wooden and bell-like, not arcade.

  • A pawn landing is a short rising tone plus a filtered noise tap, like a piece knocked on a board.
  • A new clue is a two-note bell.
  • The reveal is a drumroll of band-passed noise hits that speed up over 1.3 seconds before the target lights up.
  • Points play a rising arpeggio, one note per tier, and the score counts up a tick at a time.

Effects are triggered by comparing the previous state with the next, so a guest's phone plays the same sounds as the host without being told to. Confetti is small rectangles of paper in board colours, and most motion switches off under reduced-motion settings.

Outcome

Built in a day in October 2026, then tuned over the next two days from playing it — the board went through three colour layouts and the scoring and end-of-game rules were rewritten after real games exposed the loopholes. It is live and free to play.

What I would do differently

The rules are cleanly separated; the networking is not yet. Room codes live in their own module, but the PeerJS rooms still sit inside the main game file alongside rendering and sound. I would split them out first, because reconnect logic is the part most likely to need changing.

Beyond that, the game is designed for two. Teams or more players would change the scoring more than the code, and that is the next design problem worth solving.