<SK>
live2026

Cards-Against-Humanity-Style Browser Game with Live Rooms

Real-time multiplayer party game where players match meme cards to funny prompts — a browser-based, no-download take on the Cards Against Humanity formula, with live rooms, a rotating judge, and full multi-language support.

RoleFull-Stack Developer
Duration7 months, part-time (Jan-Aug 2026, ongoing)
TeamSolo engineer
01 /

Overview

Problem

Party games like this usually mean physical cards or a native app install — nothing lightweight that a group can jump into from a shared link, on any device, with state staying in sync for everyone in real time and surviving a dropped connection mid-round.

Approach

Split the game into two services: a Next.js client that renders a server-driven state machine (lobby → phrase_selection → picking → judging → result), and a standalone Socket.io/Express server that owns all game logic — room lifecycle, hand dealing, phase transitions, and validation of every action (is this player the judge? is it the right phase?). The client never trusts local state: a Zustand store is fully re-synced from the server's room_state broadcast after every change, with derived-state selectors (selectIsJudge, selectIsWinner) driving the UI. Reconnection is handled via a playerId + roomCode pair persisted in sessionStorage, so a dropped player can rejoin mid-game without losing their hand or score.

02 /

Stack

01React
02Next.js (App Router)
03TypeScript
04Tailwind CSS v4
05Zustand
06Socket.io
07Node.js
08Express
09next-intl
03 /

Outcomes

3
Languages shipped (EN / UK / PL)
10
Players per room
04 /

Build

01
Server-authoritative game engine
A GameRoomManager class on the Node/Socket.io server owns every room's state, validates each incoming event against the current phase and caller (host/judge/winner-only actions), deals and replenishes hands, and is the single source of truth the client always re-syncs to.
02
Stable judging under a shared shuffle
Submitted memes are shown to the judge in randomized order, but the order is locked once per round into shuffledSubmissionOrder rather than re-shuffled on every state broadcast — fixing a class of bug where the judge's pick could resolve to a different player than the one they saw on screen.
03
Reconnect-safe sessions
Players rejoin an in-progress game via a playerId + roomCode pair kept in sessionStorage; the server marks them disconnected but keeps their seat and hand during an active round, only freeing the slot after a grace period in the lobby.
04
Full multi-language support
next-intl drives the client UI while the server maintains locale-aware phrase pools and translated error codes for English, Ukrainian, and Polish — each player carries their own locale, phrase options are generated in the judge's language, and locale can change mid-game.