Salon
Board games on the TV, phones as controllers
- Context
- Personal project
- Role
- Design, steering the development with Claude Code, deployment
- Period
- September 2026
- Stack
- TypeScript, React, WebSocket, Effect, three.js, Docker, Kubernetes
- Live
- salon.obstinate.fr

The need
Our game nights with friends had two enemies: the game left at home, and the friend who owns it but didn’t come.
Salon puts the games on the TV, and every phone becomes a controller. You scan a QR code and you play. There is nothing to install.
What made it tricky
- Hidden information: the roles in Werewolf or Avalon, the spymaster’s grid in Codename, the cards in Texas Hold’em. Each phone must see exactly what it is allowed to see, and nothing more.
- Dropouts mid-game: a phone locks, loses the wifi, reloads the page.
- Fourteen games, with timers and simultaneous actions, like the night phase in Werewolf.
Decisions
From a peer-to-peer page to an authoritative server
The first version fitted in one HTML page: Codename only, peer to peer, with the game state kept on the computer plugged into the TV.
For reliability, and to add games, I moved everything to a server. It holds the game state and sends each device only the view that concerns it. Reading your phone’s network traffic reveals nothing.
- The TV
- The phonesone action per tap
- The roomhandles actions one at a time
- The game statecomplete, never sent as is
- TVthe public board
- Spymasterthe colour grid
- Operativethe words only
A decoy for those with nothing to do
At night, in Werewolf, players with no action still get a screen to fiddle with. Nobody can guess the roles by watching who touches their phone.
One room, one queue
Each room handles its actions one at a time, in order. Two players tapping at the same moment cannot corrupt the game. A tap that arrives too late for the current turn is refused, and a stale timer is ignored.
I wrote the server with Effect: it is a modern stack, composition keeps this kind of logic readable, and its types frame AI-assisted development well.
Getting your seat back
A phone that reconnects, even after being locked or reloaded, takes its place back in the game. The screen stays on while you play.
Dice rolled by the server
In Las Vegas, you shake your phone to roll. The server simulates the throw physically, from the strength of the gesture, and sends the trajectory, around ten kilobytes. The TV and the phones replay it in 3D, at the same moment.
Designed by me, written with Claude Code
I designed the architecture and steered the writing with Claude Code, over a weekend.
What made it possible to go fast without breaking things:
- games written as pure logic, tested game by game;
- a test that starts the real server and plays over WebSocket;
- interactive rules that run the real game logic.
Result
- playable games, from Codename to Avalon
- 14
- playable games, from Codename to Avalon
- from the first page to the current version
- 1 weekend
- from the first page to the current version
- Fourteen games playable online, including Codename, Werewolf, Avalon, Texas Hold’em and 6 nimmt!.
- Deployed on my cluster: Docker image, continuous integration, automatic updates through Flux.
- We really do play it on game nights, and Codename is the one that comes back most often.
- An accepted limit: games are kept in memory, on a single instance. A restart cuts the games in progress.