A real-time multiplayer Uno Web Game engineered with an authoritative game engine, intelligent AI bot fallback, Elo rating leaderboards, and animated card physics powered by Framer Motion and Next.js 16.
flowchart TB
subgraph Clients["Browser Clients (Players & Spectators)"]
PlayerA["Player 1\n(React 19 + Framer Motion)"]
PlayerB["Player 2 / Mobile\n(Touch-friendly UI)"]
Audio["Web Audio Sound Manager\n(Synthesized FX)"]
end
subgraph Server["Authoritative Game Server (server.js)"]
SocketServer["Socket.io Gateway\n(Room Subscriptions)"]
subgraph Engine["Game Engine Core (lib/UnoEngine.js)"]
StateMachine["State Machine\n(Turn Order, Direction, Current Color)"]
RuleValidator["Action & Stacking Rule Validator\n(+2 / +4 Stacking Chaining)"]
BotRunner["AI Bot Simulation\n(1.2s Human Delay & Heuristics)"]
RoomManager["Room Lifecycle Manager\n(Auto-Destroy Inactivity Timers)"]
end
end
subgraph Persistence["Persistence & Ranking"]
Prisma["Prisma ORM\n(@prisma/client)"]
Database[("SQLite Database\n(Elo Ratings, Match History, Replays)")]
end
PlayerA <-->|"WebSocket Events (join_room, card:play)"| SocketServer
PlayerB <-->|"WebSocket Events (card:draw, call_uno)"| SocketServer
SocketServer <--> StateMachine
StateMachine --> RuleValidator
StateMachine --> BotRunner
StateMachine --> RoomManager
SocketServer -->|"update_game_state (Private hand + Public state)"| PlayerA
SocketServer -->|"update_game_state"| PlayerB
StateMachine -.->|"play audio cue"| Audio
SocketServer -->|"Match Finished (handleGameOver)"| Prisma
Prisma <--> Database
- 🎮 Authoritative Game Engine (
lib/UnoEngine.js): All card validity, turn rotation, card drawing, and penalty resolutions occur on the server, eliminating desync and client-side tampering. - ⚡ Real-Time Room Synchronization: Instant turn notifications, card flip animations, and public discard pile synchronization using Socket.io.
- 🤖 Intelligent AI Bots: Fill empty seats with autonomous AI players. Bots evaluate color matching, action card utility, and respond with a natural human-like 1.2s thinking delay.
- 🔥 Competitive Stacking Rules: Support for chain penalties — players can stack
+2on top of+2, or+4on top of+2/+4to pass accumulated card draw penalties to the next player. - 🏆 Elo Rating & Leaderboards: Integrated competitive rating system (+25 Elo on win, -10 Elo on loss) with player match records saved in SQLite via Prisma ORM.
- 📢 UNO Shout & Catch Penalty: Real-time "UNO!" button with penalty mechanics if an opponent calls out a player with one card who forgot to call UNO.
- 🔊 Synthesized Web Audio FX: Card shuffle, flip, color change, draw, reverse, and victory fanfare sound effects.
- 📱 Fully Responsive: Fluid animations across mobile phones, tablets, and wide desktop screens.
| Event Name | Direction | Payload | Description |
|---|---|---|---|
get_rooms |
Client → Server | — | Fetch list of active public rooms in the lobby |
create_room |
Client → Server | { roomCode, username, maxPlayers, config } |
Initialize a new multiplayer room |
join_room |
Client → Server | { roomCode, username } |
Connect player to room and assign seat |
start_game |
Client → Server | { roomCode } |
Host triggers game start; deck is dealt |
card:play |
Client → Server | { roomCode, cardId, chosenColor } |
Submit a card move to the engine |
card:draw |
Client → Server | { roomCode } |
Draw card(s) from deck or accept stacked penalty |
call_uno |
Client → Server | { roomCode } |
Call UNO or challenge opponent's single-card status |
add_bot |
Client → Server | { roomCode } |
Spawn an AI bot player into an empty room seat |
update_game_state |
Server → Client | GameState (sanitized per player) |
Broadcasts updated table, turn index, and player's private hand |
game_over |
Server → Client | { winner } |
Displays winner screen and updates Elo ratings in DB |
- Node.js
20.xor22.x - npm
9.xor newer
git clone https://github.com/stenlysayd/uno-online.git
cd uno-online
npm installcp .env.example .envGenerate Prisma client artifacts and create local SQLite schema tables:
npm run db:generate
npm run db:pushnpm run devOpen http://localhost:3000 in your browser.
Tip
Testing Multiplayer Locally:
Open two separate browser windows (or an incognito window) at http://localhost:3000. Enter a player name in each window and join the same room code!
Because Uno Online utilizes custom WebSocket handling via server.js, it runs as a dedicated Node process:
# Build Next.js client and SSR bundles
npm run build
# Launch the production HTTP + WebSocket server
npm startDeployable to any container or VPS platform (Docker, Railway, Render, Fly.io, DigitalOcean, or AWS EC2).
Contributions are welcome! Please review CONTRIBUTING.md for contribution guidelines and architectural overview.
For responsible disclosure guidelines, please see SECURITY.md.
This project is licensed under the MIT License © 2026 Stenly Sayd.