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:

  1. Create game → Get 6-digit code
  2. Friends join via code
  3. Host starts → 81-card deck shuffled → 12 cards dealt
  4. Players race to find SETs
  5. First to tap 3 valid cards wins the point
  6. 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
  • visibilitychange event → 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

  1. Socket.io made multiplayer trivial - Auto-reconnect, rooms, broadcasting
  2. Zustand > Redux for simple apps - Less boilerplate, easier to test
  3. TypeScript caught tons of bugs - Strict mode pays off
  4. Mobile-first isn't optional - 95% of users on phones
  5. Client-side validation = better UX - Instant feedback feels magical

šŸ“± Demo Time!

Live Demo: [Insert URL here]

Try it yourself:

  1. Open on your phone
  2. Enter name + pick avatar
  3. Share game code via WhatsApp
  4. Start game
  5. Find 3 cards where each feature is all same or all different
  6. 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