Chessynth
A chess game, scored. Every musical decision is caused by something on the board — and the app will name the move that caused it. These are the notes for a jury: what the machinery is, and how to check that the claim is true rather than decorative.
01The claim
Plenty of things turn data into sound. The bar Chessynth sets itself is higher and much easier to fail: a listener who does not play chess should be able to hear what happened, and a listener who does should be able to point at the move that did it.
So the mapping is not a sonification of coordinates. It is an arrangement decision per chess fact, chosen because that is what the fact means. A knight is a horn; when the knight is captured the horn stops for the rest of the game. Nothing re-instantiates it, because the piece is not coming back. That single rule does more work than any pitch mapping: the orchestra thins as the board thins, and an endgame is audibly a smaller ensemble.
The two-minute test. Open the app, choose Classical, and let the Botez game run. Around the middle you will hear parts stop appearing. Those are the captures. Nobody told you that in words — and the move list on the right will confirm it move for move.
02How a move becomes music
A game arrives as PGN, ideally with clock comments. It is then processed once, ahead of playback, and once per ply during it.
PGN → timeline legal moves, captures, checks, castling,
promotions, a per-ply piece census, and the
real think time between moves
→ analysis Stockfish 18 (WASM, shipped locally) scores
each position: evaluation, forced mates,
blunders and their severity
→ arrangement the whole game is planned before a note
sounds — recognised opening, intro length,
section arc, where the climax belongs
→ per ply six signals update, the bar is composed,
and the ply's chess events fire their voices
The number of musical bars a ply occupies is derived from how long the player actually thought, relative to their own median for that game. A long think is a long bar. This is why replaying a real blitz game feels hurried and a classical game breathes: the tempo of the music is the tempo of the thinking, not a setting.
03The six signals
Everything continuous about the music is driven by six numbers, each owned by exactly one place in the code. They are the only channel between the chess and the arrangement.
| Signal | What the chess is | What it controls |
|---|---|---|
| pace | how fast they are moving, relative to their own median think | note density and diminution |
| tension | the geometry of the position — not what recently happened to it | filter opening and dynamic |
| scramble | clock pressure: below a fifth of the starting clock | surface agitation, tremolo |
| danger | a low clock and an unresolved position at once | detune and bite |
| pressW / pressB | each player's own clock, separately | that side's phrases compress |
| adv | the engine's evaluation, smoothed | which side leads the texture |
They are deliberately not independent of the chess and deliberately
independent of each other. tension reads the position, so it stays
high while a loaded position sits still; an event accumulator would have
decayed. scramble reads only the clock, so a game with no clock
record reports zero and is unaffected rather than guessing.
04Pieces as instruments
In the orchestral family each piece type owns a part. The assignment is by register and behaviour, not by material value.
| Piece | Instrument | Why |
|---|---|---|
| Pawns | pizzicato strings (bowed swells in Symphonic) | many, short, and the texture underneath everything |
| Knights | horn | brass speaks with an attack; a knight arrives rather than slides |
| Bishops | clarinet and oboe — one per colour complex | two bishops that never share a square never share a timbre |
| Rooks | low brass | weight along a line |
| Queen | solo violin (piano in Chamber) | the one voice that can go anywhere |
| Kings | organ pedal | always present, rarely moves, holds the bottom |
A capture is scored by what was taken, in four brackets — a pawn gets a triangle and a short note with nothing underneath; a minor piece a damped stroke with a bassoon on the chord; a rook low brass; the queen the full stroke. The losing side's instrument then goes silent permanently.
Chess the music actually reacts to
- Recognised openings set how long the introduction holds — a King's Indian coils for a quarter of the game, a King's Gambit is alight by move three.
- Castling on opposite wings changes the character: both kings are targets and the arrangement stops being symmetrical.
- Tactics each have a figure — fork, absolute and relative pin, skewer, discovered check, double check, battery. A fork holds rather than restating itself; a double check strikes in two voices at once.
- A forced mate floors the tension and starts a clock figure whose rate accelerates as the distance closes.
- Blunders are graded by the engine's severity, not flagged as a binary.
05The eighteen modes
Three families. They are not presets over one engine: the orchestral and film-score families run a different scheduler from the club family.
Classical — four modes
| Mode | BPM | What separates it |
|---|---|---|
| Orchestral | 108–122 | the mapping at its most legible — one piece, one instrument, one-shot per event |
| Symphonic | 88–104 | the orchestra playing a piece rather than a groove: pawns bow long overlapping swells, so the pulse becomes a bed |
| Symphony-Astra | 72–92 | plans a bar at a time, ties notes across bar lines, schedules real rests, no percussion at all |
| Chamber | 96–112 | the smaller room — piano for the queen, no timpani |
Soundtrack — two modes
| Mode | BPM | What separates it |
|---|---|---|
| Underscore | 60–84 | natural minor with one chord held two bars — the mechanism, not a reverb setting. Brass carries the bed with strings on top, the reverse of every other mode |
| Main Title | 88–104 | dorian, and it moves. The theme is on the trumpet; a title cue is not an underscore |
Club — twelve modes
Detroit, Bleep, Dub Techno, Minimal, Melodic, Hardgroove, Acid, Industrial, Hard Techno, Schranz, Dark Techno and Peak Time, 120–165 BPM. Each names its own hats, reverb send, delay and drive — the hats alone distinguish most techno subgenres before anything else happens. Here the pieces are stems: the kick, the bassline, the acid riff, the pad. Losing a piece removes its stem from the arrangement, so the mix thins toward the endgame.
The phrase composer. In the composed modes the music is written in eight-bar sentences — state, move, move, lean open; state, move, move, close. The mover owns the phrase, so the two players' lines are drawn differently: one rounded, one angular, disjoint by construction. When a position repeats, the opening motto returns. When a piece is lost, the part that carried it is remembered once — the fallen instrument's colour and register appear in the next phrase and are then spent.
06Synthesis
Every sound is generated at runtime through the Web Audio API. There are no samples anywhere in the application: 72 voice functions build their own oscillators, noise buffers, filters and envelopes. A triangle is three inharmonic sine partials through a bandpass; a kick is one oscillator swept in frequency with the attack coming from saturation downstream rather than a separate click layer.
The instruments are level-matched by measurement, not by ear. An offline render of each voice is A-weighted through a biquad cascade and compared, because A-weighting is where the ear actually is — a bright voice at the same nominal gain is not the same loudness. The same bench measures decay time, which is how a triangle that read as quiet but rang for 1.8 seconds was found and shortened.
Determinism, and why it matters twice
Given the same game and the same seed, Chessynth produces the same audio, sample for sample, on any machine. That buys two things at once: the offline WAV render calls the same scheduler as live playback, so the exported file is the track rather than a re-performance of it — and two players in a live match stay in sync without streaming any audio, because each end renders the same thing from the same moves.
07The ledger
The failure mode for a system like this is not a bad sound. It is two chess facts quietly driving the same musical parameter, so neither is legible and the arrangement turns to mush. Chessynth carries an allocation ledger: 74 rows, one per musical sub-parameter, each naming the single signal that owns it and the function that writes it.
It is enforced rather than aspirational. A checker parses the source, matches it against the ledger, and fails if a shared audio node has two owners or if a documented row has drifted from the code. Twenty-six test suites sit behind that, and the assertions are mutation-tested — an assertion that still passes when the behaviour it guards is reverted is deleted and rewritten.
08The music log
The explainability claim is testable, which is the point of making it. Menu → Copy music log exports one entry per ply: the move in algebraic notation, the mover's clock, the chess evidence, what was captured and which instrument that cost, the recognised opening and the tactics, and every signal that moved by more than a threshold — with what that signal controls written next to it.
9. Qxb5 white 0:42 [capture]
queen takes bishop — black loses Bass · light-sq bishop, for good
minor piece (330) → a damped stroke, bassoon on the chord
FORK — the fork figure, which HOLDS rather than restating itself
tension 0.12→0.71 ↑ filter and dynamic · pace 0.36→0.54 ↑ note density
> section ROLL → BUILD (4-bar window; motto opens the next period)
A judge can therefore check the central claim directly rather than taking it on trust: play a passage, notice something, and read what the board did.
09Ways to play
| Mode | What it is |
|---|---|
| Replay | curated famous games with real clock data, or paste any PGN |
| vs Bot | Stockfish at a chosen clock, scored live as you play, with premoves and resign |
| 2-Player | a live match; only the move travels — 27 bytes a ply — because both ends render identically |
| Party | phones join by room code as silent controllers; one screen renders all the audio and streams it over WebRTC, so five phones cannot flam against each other |
| Deck | a DJ rack over the top: stems, filter, rolls, risers, recorded slots |
| Export | offline WAV render of the whole game, and PGN out |
10Stack & footprint
- One HTML file, ~1.1 MB. No framework, no build step, no bundler, no dependencies at runtime.
- Web Audio API for all synthesis;
OfflineAudioContextfor rendering and for the measurement benches. - Stockfish 18 lite (7.3 MB WASM) shipped locally, not called out to a service. GPL text travels with it.
- WebSocket relay for room signalling, WebRTC for party audio.
- No account, no telemetry, no third-party requests in normal play.
- Desktop and mobile; the interface folds its entry points into one control once a game is running so the deck is not pushed off a phone screen.
11What it does not do
Stated plainly, because a jury will find these anyway.
- The film-score family is the newest and is still being tuned. It is included because it is the strongest demonstration of the phrase composer, not because it is finished.
- 2-player is same-machine today. The wire protocol is written and measured — 326-byte handshake, 27-byte move — and party mode already runs over a real relay, but the internet transport is not yet wired to the 2-player button.
- Party mode fails on symmetric NAT. A relay is a different feature with a different bill, and it is not pretended otherwise.
- It is not a chess trainer. The engine is there to hear the game, not to coach it.