A full-stack real-time multiplayer word-guessing game inspired by Codenames.
- Next.js 14 (App Router)
- React + TypeScript
- TailwindCSS
- Framer Motion
- Socket.IO Client
- Django 5
- Django REST Framework
- Django Channels (WebSockets)
- Redis (for channel layer)
- SQLite (development) / PostgreSQL (production)
codenames-game/
├── backend/ # Django backend
│ ├── backend/ # Django settings and config
│ ├── game/ # Core game logic, models, APIs
│ ├── users/ # User-related (minimal for now)
│ ├── websocket/ # WebSocket consumers and routing
│ ├── manage.py
│ └── requirements.txt
├── frontend/ # Next.js frontend
│ ├── app/ # App Router pages
│ ├── components/ # React components
│ ├── lib/ # Utilities (API, storage, types)
│ ├── public/ # Static assets
│ ├── package.json
│ └── tsconfig.json
└── README.md
- Python 3.10+
- Node.js 18+
- Redis (for WebSocket channel layer)
Install Redis:
- Windows: Download from https://github.com/microsoftarchive/redis/releases or use WSL
- macOS:
brew install redis - Linux:
sudo apt install redis-server
- Navigate to backend folder:
cd backend- Create a virtual environment:
python -m venv venv- Activate virtual environment:
- Windows:
venv\Scripts\activate - macOS/Linux:
source venv/bin/activate
- Install dependencies:
pip install -r requirements.txt- Create
.envfile (optional):
DEBUG=1
DJANGO_SECRET_KEY=your-secret-key
ALLOWED_HOSTS=*
CORS_ALLOWED_ORIGINS=http://localhost:3000
REDIS_URL=redis://127.0.0.1:6379/1
USE_IN_MEMORY_CHANNEL_LAYER=0For quick development without Redis, set USE_IN_MEMORY_CHANNEL_LAYER=1.
- Run migrations:
python manage.py migrate- Create superuser (optional):
python manage.py createsuperuser- Start Redis:
redis-server- Run the Django development server:
python manage.py runserver 0.0.0.0:8000Backend will be available at: http://localhost:8000
- Navigate to frontend folder:
cd frontend- Install dependencies:
npm install- Create
.env.localfile:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
NEXT_PUBLIC_WS_BASE_URL=ws://localhost:8000- Run the Next.js development server:
npm run devFrontend will be available at: http://localhost:3000
cd backend
python manage.py runservercd frontend
npm run devredis-server- Go to http://localhost:3000
- Click "CREATE ROOM" or "JOIN ROOM"
- Share the room code with your friends
- Players select teams (Red or Blue)
- Each team selects one Spymaster and one or more Operatives
- Host clicks "START GAME"
- Spymaster gives clues like "Ocean 2"
- Operatives guess words
- Match all your team's words to win!
- Grid: 5x5 board of 25 random words
- Teams: Red (9 agents) vs Blue (8 agents)
- Roles:
- Spymaster: Can see hidden colors, gives one-word + number clues
- Operative: Guesses words based on clues
- Turn Flow:
- Spymaster gives clue
- Operatives guess up to
<number> + 1words - If correct → continue guessing (same team)
- If neutral → turn ends
- If opponent's word → opponent scores, turn ends
- If assassin → instant loss
- Win Condition: First team to reveal all their agents wins
✅ Real-time multiplayer rooms
✅ Secure server-side validation
✅ WebSocket-based live updates
✅ Responsive design (mobile/tablet/desktop)
✅ Beautiful UI with Framer Motion animations
✅ Confetti win celebration
✅ In-game chat
✅ Sound effects
✅ Copy room code button
✅ Spymaster view with color overlays
✅ Turn indicator
✅ Remaining word counter
| Method | Endpoint | Description |
|---|---|---|
| POST | /create-room |
Create a new room |
| POST | /join-room |
Join an existing room |
| GET | /room-state |
Get current room state |
| POST | /set-team |
Set player team |
| POST | /set-role |
Set player role |
| POST | /start-game |
Start the game (host only) |
| POST | /submit-clue |
Submit a clue (spymaster) |
| POST | /guess-word |
Guess a word (operative) |
| POST | /end-turn |
End current turn |
| POST | /restart-game |
Restart game (host only) |
| POST | /chat |
Send chat message |
| POST | /react |
Send emoji reaction |
| Event | Trigger | Payload |
|---|---|---|
player_joined |
Player joins room | { player, players } |
player_left |
Player disconnects | { players } |
team_changed |
Player changes team | { players } |
role_changed |
Player changes role | { players } |
game_started |
Host starts game | { room, remaining } |
clue_given |
Spymaster submits clue | { clue, guesses_left } |
word_guessed |
Word is revealed | { card, remaining, turn } |
turn_changed |
Turn switches | { turn } |
game_over |
Game ends | { winner, remaining } |
chat_message |
Chat sent | { by, message } |
reaction |
Emoji reaction | { by, emoji } |
-
Set environment variables:
DEBUG=0DJANGO_SECRET_KEY=<strong-random-key>ALLOWED_HOSTS=yourdomain.comDATABASE_URL=postgres://...(if using PostgreSQL)REDIS_URL=redis://...
-
Collect static files:
python manage.py collectstatic- Use a production ASGI server like Daphne or Uvicorn:
pip install daphne
daphne -b 0.0.0.0 -p 8000 backend.asgi:application- Build for production:
npm run build- Start:
npm run startOr deploy to Vercel/Netlify.
- Ensure Redis is running
- Check
NEXT_PUBLIC_WS_BASE_URLmatches your backend - Verify Django Channels is properly configured
- Add frontend URL to
CORS_ALLOWED_ORIGINSin Django settings
- Check WebSocket connection in browser console
- Ensure all players are connected to the same room code
Built with ❤️ using Next.js, Django, Channels, and Socket.IO.
Inspired by the board game Codenames by Vlaada Chvátil.
MIT License - Feel free to modify and use for your own projects!