SET Game - TL;DR Presentation
Real-Time Multiplayer Card Game in 5 Minutes
šÆ What We Built
SET Game - A mobile-first, real-time multiplayer card game for 1-4 players.
- ā Zero friction: No passwords, just name + avatar
- ā Social: Share 6-digit code via WhatsApp/SMS
- ā Fast: 3-5 minute games
- ā Mobile-first: 95% of users on phones
The Game: Find 3 cards where each feature (color, symbol, number, shading) is either all same OR all different.
š ļø Tech Stack (The Simple Version)
Frontend
- React 18 + TypeScript + Tailwind CSS + Vite
- Zustand (state management)
- Socket.io (real-time)
- Framer Motion (animations)
Backend
- Node.js + Express + TypeScript
- Socket.io (WebSocket server)
- JWT (session auth)
- In-memory storage (Map<gameCode, GameRoom>)
Why These?
- Fast development
- Great mobile performance
- Real-time multiplayer out of the box
- Type safety everywhere
šļø Architecture (30 Second Version)
āāāāāāāāāāāāāāā
ā React ā ā User taps cards, sees scores
ā Frontend ā
āāāāāāāā¬āāāāāāā
ā
WebSocket (instant updates)
REST API (sessions)
ā
āāāāāāāā¼āāāāāāā
ā Node.js ā ā Validates SETs, manages rooms
ā Backend ā
āāāāāāāāāāāāāāā
Key Flow:
- Create game ā Get 6-digit code
- Friends join via code
- Host starts ā 81-card deck shuffled ā 12 cards dealt
- Players race to find SETs
- First to tap 3 valid cards wins the point
- Game ends when no more SETs possible
šØ Key Features (The Cool Stuff)
1. Instant Feedback
- Tap 3 cards ā Client validates immediately
- Invalid SET: Red shake + vibration (800ms)
- Valid SET: Wait for server ā Celebration overlay
- Why? 200-500ms server lag feels bad
2. Mobile-First Everything
- Touch targets: 44Ć44px minimum
- Haptic feedback (vibration patterns)
- Responsive card grid (12-21 cards)
- Auto-reconnect when tab switches
- Works on: iPhone SE (smallest common device)
3. Real-Time Sync
- Player joins ā Everyone sees instantly
- SET found ā Scores update for all
- Player leaves ā Game continues
- Powered by: Socket.io WebSocket
4. Smart Game Logic
- Guarantees valid SET in first 12 cards (tries 10 shuffles)
- Auto-adds cards if no SET exists
- "Hint" button: "Is there a SET?" (yes/no)
- "Add Card" button: Manually add 1 card (blocked if SET exists)
šÆ Top 3 Technical Challenges
1. Mobile Browsers Kill WebSocket
Problem: iOS Safari suspends tabs ā socket disconnects
Solution:
- Session in HTTP-only cookie (persists)
- On reconnect: Read cookie ā auto-rejoin room
-
visibilitychangeevent ā reconnect on tab focus
2. Race Conditions (2 Players Submit Same SET)
Problem: Player A and B tap same cards at same time
Solution:
- Server is authoritative (always)
- Client validation = UX only
- First submission wins, second gets "invalid"
3. Ensuring Valid SET Always Exists
Problem: After removing cards, might have no SETs left
Solution:
while (!hasValidSet(board) && deck.length > 0) {
// Add 3 more cards
board.push(...deck.splice(0, 3));
}
- Auto-adds up to 9 extra cards (max 21 total)
- If deck empty + no SET ā game ends
š§® Core Algorithm: Is This a Valid SET?
function isValidSet(card1, card2, card3): boolean {
for each feature in [color, symbol, number, shading]:
values = [card1[feature], card2[feature], card3[feature]]
unique_count = Set(values).size
if unique_count === 2: // 2 same + 1 different
return false // INVALID
return true // All same or all different = VALID
}
Time Complexity: O(1) - always checks 4 features
Finding all SETs: O(n³) where n = 12-21 cards
- 12 cards = 220 combinations
- 21 cards = 1330 combinations
- Fast enough for real-time gameplay
š Results
What Works
ā
Real-time sync is instant
ā
Mobile experience is smooth
ā
No lag on invalid SET feedback
ā
Auto-reconnect works perfectly
ā
High test coverage (Jest + Vitest)
What We'd Improve
ā In-memory storage (doesn't scale)
ā No persistent user profiles
ā Bundle size could be smaller
ā Missing some accessibility features
š Future Plans
Phase 2 (Post-MVP):
- PostgreSQL + Redis for scaling
- User profiles & stats
- Leaderboards
- Sound effects
- PWA (installable app)
Phase 3 (Dream Features):
- Replay mode
- Spectate mode
- Team battles
- Dark mode
š Key Takeaways
- Socket.io made multiplayer trivial - Auto-reconnect, rooms, broadcasting
- Zustand > Redux for simple apps - Less boilerplate, easier to test
- TypeScript caught tons of bugs - Strict mode pays off
- Mobile-first isn't optional - 95% of users on phones
- Client-side validation = better UX - Instant feedback feels magical
š± Demo Time!
Live Demo: [Insert URL here]
Try it yourself:
- Open on your phone
- Enter name + pick avatar
- Share game code via WhatsApp
- Start game
- Find 3 cards where each feature is all same or all different
- First to 10 SETs wins!
š Questions?
Code: [GitHub repo]
Docs: See /docs folder
Tech Stack Summary:
- Frontend: React 18 + Zustand + Socket.io + Tailwind
- Backend: Node.js + Express + Socket.io + JWT
- Testing: Vitest + Jest
- Deployment: Vercel (frontend) + Railway (backend) [planned]
Thank You! š
Built with ā¤ļø for kids (and adults who love pattern games)
SET Game - TL;DR Presentation
By Itay Shmool
SET Game - TL;DR Presentation
- 85