Classic multiplayer games reimagined with modern real-time technology
Live Demo β’ Report Bug β’ Request Feature
PlayClassix is a modern web platform bringing classic games to life with real-time multiplayer capabilities. Built with Next.js 16 and powered by serverless Redis, it offers seamless gameplay experiences with instant state synchronization across players.
Perfect for casual gaming sessions with friends, PlayClassix eliminates the need for downloads or installationsβjust share a link and start playing instantly in your browser.
Current Status: Memory Match is fully playable with 2-player real-time multiplayer. More games coming soon!
- No Login Required β Start playing instantly with auto-generated session IDs stored in browser cookies. No personal data collected, all session data cleared when browser closes
- Real-Time Multiplayer β Play with friends instantly using Pusher WebSocket connections for sub-100ms state synchronization
- Optimistic UI Updates β Cards flip immediately on click with automatic rollback on network failures for butter-smooth UX
- Session Statistics β Track wins, losses, and draws with your opponents using serverless Redis persistence
- Smart Turn Management β Race condition-free gameplay with processing locks preventing double-moves
- Dark Mode Support β Fully responsive design with light/dark theme support and custom CSS variables
- Serverless Architecture β Zero-latency deployment on Vercel with Upstash Redis for global performance
- Accessibility First β Semantic HTML, ARIA labels, and keyboard navigation throughout
| Category | Technologies |
|---|---|
| Framework | Next.js 16 with App Router & React Server Components |
| Language | TypeScript 5 with strict mode |
| Styling | Tailwind CSS 4 with custom design system |
| State Management | Zustand for client state |
| Database | Upstash Redis for game state & session stats |
| Real-Time | Pusher for WebSocket-based multiplayer sync |
| Icons | React Icons (Feather set) |
| Fonts | Geist Sans & Geist Mono |
| Deployment | Vercel with Edge Runtime |
| Dev Tools | ESLint 9, Sharp (image optimization) |
A classic memory card game reimagined for real-time multiplayer:
- 16-card grid with fruit-themed illustrations
- 2-player competitive gameplay
- Real-time score tracking and turn indicators
- Session-based statistics (W/L/D records)
- Game complete modal with individual stats
- Optimistic card flips with error recovery
- Wordle Clone β Daily word puzzle with multiplayer duels
- Tic Tac Toe β Strategic multiplayer grid game
- Snake β Classic arcade action
- Chess β Timeless strategy game with real-time play
PlayClassix follows a modern Next.js App Router architecture with clear separation of concerns:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client Layer β
β - React Components (Server + Client Components) β
β - Zustand Stores (Local State) β
β - Custom Hooks (Business Logic) β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββ
β API Routes Layer β
β - Server Actions (Next.js 16) β
β - RESTful API endpoints β
β - Cookie management (authentication) β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββ
β Services Layer β
β - Game Store (game-store.ts) β
β - Pusher Server (real-time events) β
β - Redis Client (state persistence) β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββ
β External Services β
β - Upstash Redis (Serverless DB) β
β - Pusher Channels (WebSocket) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Optimistic Updates β Client updates UI immediately, rolls back on API failure
- WebSocket Sync β Pusher broadcasts game state changes to all connected players
- Redis as SSoT β All game state persists to Redis with 2-hour TTL
- Custom Hooks β Game logic encapsulated in reusable hooks (useCardClickHandler, useSetUpPusherClient)
- Type Safety β End-to-end TypeScript with strict compiler options
- Node.js 20.x or higher
- npm or pnpm
- Upstash Redis account (create free)
- Pusher account (create free)
-
Clone the repository
git clone https://github.com/abeshahsan/playclassix.git cd playclassix -
Install dependencies
npm install # or pnpm install -
Configure environment variables
Create a
.env.localfile in the root directory. see.env.examplefor required variables. -
Run development server
npm run dev
Open http://localhost:3000 in your browser.
-
Build for production
npm run build npm start
playclassix/
βββ public/
β βββ assets/
β β βββ cards/ # Game card images
β β βββ icons/ # App icons (favicon, apple-touch)
β β βββ logos/ # Brand logos
β β βββ ui/ # UI assets (medals, backgrounds)
β β βββ social/ # OG images for social sharing
β βββ manifest.json # PWA manifest
β
βββ scripts/
β βββ generate-assets.mjs # Asset generation utilities
β
βββ src/
β βββ app/
β β βββ api/ # API routes
β β β βββ games/ # Game-specific APIs
β β β β βββ memory-match/
β β β β βββ new-game/
β β β β βββ join-game/
β β β β βββ move/
β β β β βββ player-stats/
β β β βββ me/ # User authentication
β β β βββ message/ # System messages
β β βββ games/ # Game pages
β β β βββ memory-match/
β β β βββ [gameId]/
β β β βββ new-game/
β β βββ set-username/ # Onboarding
β β βββ layout.tsx # Root layout
β β βββ page.tsx # Home page
β β
β βββ components/
β β βββ games/ # Game-specific components
β β β βββ memory-match/
β β β βββ card.tsx
β β β βββ game-complete-modal.tsx
β β β βββ score-board.tsx
β β β βββ ...
β β βββ global/ # Shared components
β β βββ app-shell.tsx
β β βββ sidebar.tsx
β β βββ site-header.tsx
β β βββ theme-provider.tsx
β β
β βββ core/
β β βββ game.registry.ts # Game metadata registry
β β
β βββ hooks/
β β βββ games/
β β βββ memory-match/
β β βββ useCardClickHandler.ts
β β βββ useJoinOrFetchGame.ts
β β βββ useSetUpPusherClient.ts
β β
β βββ lib/
β β βββ game-store.ts # Redis-backed game state
β β βββ pusher.ts # Pusher server config
β β βββ redis.ts # Redis client (Upstash/ioredis)
β β
β βββ store/
β β βββ gamer.ts # User state (Zustand)
β β βββ games/
β β βββ memory-match.ts # Game-specific state
β β
β βββ types/
β βββ index.ts # Global types
β βββ games/
β βββ memory-match/
β βββ types.ts
β
βββ .env.local # Environment variables (not in git)
βββ next.config.ts # Next.js configuration
βββ tailwind.config.ts # Tailwind CSS config
βββ tsconfig.json # TypeScript config
βββ package.json # Dependencies
Games are stored with a 2-hour TTL:
// Key pattern: game:memory-match:{gameId}
await redis.set(`game:memory-match:${gameId}`, JSON.stringify(gameState), "EX", 7200);Player stats use sorted pair keys:
// Key pattern: player-stats:{player1Id}:{player2Id}
// IDs are sorted to ensure consistency
const key = [player1Id, player2Id].sort().join(":");- Client flips card immediately
- Send move to server
- On success: Pusher broadcasts to all players
- On failure: Rollback local state + show error
const previousState = { ...gameRoom };
optimisticFlipCard(cardId); // Immediate UI update
const success = await sendMove(cardId, gameId, userId);
if (!success) {
rollbackOptimisticFlip(previousState); // Revert on error
}Processing lock prevents double-clicks:
if (isProcessing) return; // Block new moves
setIsProcessing(true); // Lock for 500ms minimumCritical: Never commit sensitive keys to git!
Required environment variables:
UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKENPUSHER_APP_ID/PUSHER_SECRET/NEXT_PUBLIC_PUSHER_KEY/NEXT_PUBLIC_PUSHER_CLUSTER
Use .env.local for local development (already in .gitignore).
For production deployment on Vercel:
- Project Settings β Environment Variables
- Add all required keys
- Redeploy
Contributions are welcome! Standard flow:
- Fork the project
- Create your feature branch
git checkout -b feature/amazing-feature
- Commit your changes
git commit -m 'Add some amazing feature' - Push to the branch
git push origin feature/amazing-feature
- Open a Pull Request
- Follow existing code style (TypeScript strict mode)
- Add types for all new functions/components
- Test multiplayer features with 2+ browser tabs
- Update README if adding new features
Distributed under the MIT License. See LICENSE for more information.
K. M. Abesh Ahsan
GitHub: @abeshahsan
Website: playclassix.com
Give a star β if you like this project!
Built with β€οΈ by K. M. Abesh Ahsan