Junsang Yoo About ↗
← All Projects
Websites · Games · 2026 · Solo

OneShot

One room code, six party games, zero installs.

OneShot
Role
Design · Full-stack
Team
Solo
Year
2026
Stack
React · TypeScript · Colyseus · Node.js · Vite · Docker

OneShot began as an attempt to rebuild The Great Dalmuti, the card game that owned my friend group’s drinking nights. Two walls went up fast: the systems I loved are someone else’s IP and couldn’t be lifted as-is, and a solo developer with no designer can’t polish one game until it deserves to stand alone. So I turned the project sideways — instead of one deep game, a hub of fast, simple drinking games, where the product isn’t any single game but how quickly a table gets from “let’s play something” to actually playing.

Problem

A bar table is the most hostile UX environment I’ve designed for. Nobody installs an app for one round; phones are a mix of everything; nobody makes an account. The games have to be explainable in one sentence, because the rules get shouted, not read. And the app has to survive how parties actually go — someone’s phone dies, someone disappears for ten minutes, someone rage-quits — without ever stalling the table.

One more constraint I cared about: taste. A single look divides a party — some people want loud and techy, others find it exhausting. I didn’t want anyone to open it and go “ugh.”

Approach

A room that outlives its games. One tap creates a room with a 5-character code drawn from an ambiguity-free alphabet (no 0/O/1/I to misread at 1am). Friends join by typing the code, tapping the invite link, or scanning the QR on the host’s screen — nickname only, guests included. The room is the container for the whole night: pick a game from the library, play, see the podium, pick the next one. Even the Enter key follows intent on the home screen — with a code typed it joins, otherwise it creates.

OneShot lobby in the cyber theme: sector access code, invite link, QR entry, module grid, and a three-player operators manifest
The lobby — code, link, and QR entry on the left, game modules in the middle, live seats on the right. Cozy-themed friends show up with their cozy avatars inside a cyber lobby.

Two full identities, not a dark-mode toggle. Cyber is a neon terminal HUD — scanlines, corner brackets, deadpan flavor text like A SYSTEM OF CONTROLLED CHAOS. Cozy is cream paper, handwritten type, and soft 3D buttons. One data-theme attribute swaps an entire CSS token block (226 override rules), all 16 avatars exist as separate art in both skins, and the theme is per-player — everyone sits at the same table wearing the look they chose. UI copy ships fully bilingual (KR/EN, 382 mirrored keys), and so does the game content itself.

The same home screen in Cozy and Cyber — different fonts, chrome, layout density, and mood, driven by one attribute on the root element.

The server is the only referee. Every room is a Colyseus WebSocket room keyed by its code; clients render state and send input, nothing more. Rules, validation, and RNG live in server-side game modules, and secrets travel only to their owner: the Liar’s word, the King’s pending mission, another player’s hand all stay on the server — public state carries card counts, not cards.

Liar, dealt to two phones in the same round — one player taps their card and sees the secret word, the other learns they're the liar. 450 bilingual words across 9 categories.

Engineered for how parties fail. A signed reconnect token restores your seat and private state for 24 hours, so a dead battery isn’t a lost seat. There are deliberately no turn timers and no auto-kick — humans resolve the game, the app just keeps the secrets. Votes count their quorum against connected players only, phase-critical pairings are snapshotted so a mid-game kick can’t orphan a card exchange, and the dice game quietly rolls for anyone who dropped so a round never hangs.

Outcome

OneShot is live at oneshot.jsyoo.dev, running as a single Docker container on an Oracle Cloud VM behind Caddy. Every game module has bot-playthrough tests that simulate full matches — including the ugly cases like kicks mid-vote and reconnects mid-round — plus Playwright journeys that drive several browsers through a real room.

6
party games
2×2
themes × languages
0
installs or accounts
24h
reconnect window

What I actually took away is a respect for boring reliability. The flashy parts — neon HUD, themed avatars — were fun, but the feature that makes it work at a real table is that nothing ever waits on a missing person. Fast in, fast between games, impossible to strand.

Scan the code, pick a game, play. Built for the table, 2026.