A Matrix-themed social deduction game where players try to identify the hidden traitor among them. One player is secretly "De Rat" and must avoid detection while sabotaging the group.
- Setup: Host adds all players and secretly assigns one as "De Rat"
- Rounds: Each round, players answer questions on their phones
- Scoring: Correct answers earn points, wrong answers don't
- Voting: Everyone votes on who they think is De Rat
- Elimination: The lowest scorer (who isn't De Rat) gets eliminated
- Win Conditions:
- Players win: If everyone correctly identifies De Rat
- Rat wins: If only the Rat and one other player remain
# Clone or extract the game files
cd de-rat-game
# Find your local IP first:
# Linux/Mac: hostname -I | awk '{print $1}'
# Windows: ipconfig (look for IPv4 Address under your WiFi/Ethernet adapter)
# Start with your IP (replace with your actual IP!)
HOST_IP=192.168.1.100 docker-compose up -d
# Or on Windows PowerShell:
$env:HOST_IP="192.168.1.100"; docker-compose up -d
# View logs
docker-compose logs -f
# Stop the game
docker-compose down# Clone or extract the game files
cd de-rat-game
# Find your IP: hostname -I | awk '{print $1}'
# Start with podman-compose
HOST_IP=192.168.1.100 podman-compose up -d
# OR use podman directly:
podman build -t de-rat-game .
podman run -d --name de-rat -p 3000:3000 -e HOST_IP=192.168.1.100 -v de-rat-data:/app/data de-rat-game
# View logs
podman logs -f de-rat
# Stop
podman stop de-rat && podman rm de-ratJust open docs/standalone.html in any browser. Game state is saved locally in your browser.
Once running, open your browser to:
- Local: http://localhost:3000
- Network: http://YOUR_IP:3000 (for other devices on your network)
To find your IP address:
- Linux/Mac:
hostname -Iorip addr - Windows:
ipconfig
- Host opens http://localhost:3000 and enters Admin mode
- Host creates players and shares their personal links
- Each player opens their link on their phone
- Players answer questions, host manages the game
de-rat-game/
├── docker-compose.yml # Docker/Podman compose file
├── Dockerfile # Container build instructions
├── backend/
│ ├── server.js # Express + Socket.io server
│ └── package.json # Node.js dependencies
├── frontend/
│ └── index.html # Main game interface
└── docs/
└── standalone.html # Standalone version (no server)
| Variable | Default | Description |
|---|---|---|
| PORT | 3000 | Server port |
| NODE_ENV | production | Node environment |
# Docker Compose - edit docker-compose.yml or:
PORT=8080 docker-compose up -d
# Direct Docker/Podman:
docker run -d -p 8080:3000 de-rat-gameGame state is stored in a Docker volume (game-data). To backup:
# Docker
docker cp de-rat-game:/app/data/gamestate.json ./backup.json
# Podman
podman cp de-rat:/app/data/gamestate.json ./backup.jsonTo reset the game data:
docker-compose down -v # Removes the volume
docker-compose up -d # Fresh startcd backend
npm install
npm start# Docker
docker build -t de-rat-game .
# Podman
podman build -t de-rat-game .┌───────────────────────────────────────────────────────────────────────┐
│ YOUR COMPUTER │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ DOCKER/PODMAN CONTAINER │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ Node.js Server (Express) │ │ │
│ │ │ Port 3000 │ │ │
│ │ │ │ │ │
│ │ │ /api/state ←→ Game State (read/write) │ │ │
│ │ │ /api/hostip → Returns host IP │ │ │
│ │ │ /api/player/:id → Player-specific data │ │ │
│ │ │ Socket.io ←→ Real-time updates │ │ │
│ │ │ │ │ │
│ │ │ Serves: /public/index.html (the game UI) │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ │ reads/writes │ │
│ │ ▼ │ │
│ │ /app/data/gamestate.json │ │
│ │ │ │ │
│ └────────────────────────────│─────────────────────────────────────┘ │
│ │ │
│ │ MOUNTED VOLUME │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ DOCKER VOLUME: game-data │ │
│ │ │ │
│ │ Location: /var/lib/docker/volumes/de-rat-game_game-data/ │ │
│ │ (or similar for Podman) │ │
│ │ │ │
│ │ Contains: gamestate.json │ │
│ │ │ │
│ │ ⚠️ THIS PERSISTS even when container is rebuilt! │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────┘
│
│ Port 3000 exposed
▼
┌───────────────────────┐ ┌─────────────────────────┐
│ HOST BROWSER │ │ PLAYER PHONES │
│ (Admin) │ │ │
│ │ │ │
│ http://localhost:3000 │ │ http://192.168.x.x:3000 │
│ │ │ ?player=p12345 │
└───────────────────────┘ └─────────────────────────┘
- Matrix-themed UI with green terminal aesthetics
- Real-time sync across all connected devices
- Dramatic elimination with fingerprint scanning animation
- Win detection with game over screens
- Score tracking across multiple rounds
- Question templates for quick setup
- Import/Export game state for backup
- Undo elimination in case of mistakes
Works on all modern browsers:
- Chrome, Firefox, Safari, Edge
- Mobile browsers (iOS Safari, Chrome for Android)
# Check logs
docker-compose logs
# Rebuild
docker-compose build --no-cache
docker-compose up -d- Ensure firewall allows port 3000
- Use your local IP, not localhost
- Check devices are on the same network
# Run with user namespace
podman run --userns=keep-id -p 3000:3000 de-rat-gamedocker-compose down -v
docker volume rm de-rat-game_game-data
podman volume rm de-rat-game_game-data
┌──────────────┐ HTTP/WebSocket ┌──────────────┐ File I/O ┌─────────────────┐
│ Browser │ ◄──────────────────► │ Server │ ◄────────────► │ gamestate.json │
│ (UI) │ │ (Node.js) │ │ (Docker Volume) │
└──────────────┘ └──────────────┘ └─────────────────┘
- Browser sends action (add player, submit answer, etc.)
- Server updates in-memory state
- Server writes to gamestate.json
- Server broadcasts update via Socket.io
- All connected browsers receive update
The standalone HTML file (standalone.html) uses browser localStorage instead:
┌───────────────────────────────────────┐
│ BROWSER │
│ │
│ ┌──────────────────────────────┐ │
│ │ standalone.html │ │
│ │ │ │
│ │ JavaScript Game Logic │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ localStorage.setItem( │ │
│ │ 'deRatV8', │ │
│ │ JSON.stringify(state) │ │
│ │ ) │ │
│ └──────────────────────────────┘ │
│ │
│ Browser Storage (persists locally) │
└───────────────────────────────────────┘
- No server needed
- Data stays in YOUR browser only
- Other devices can't connect
- Clearing browser data = lose game
MIT License - Feel free to modify and share!
Have fun finding De Rat! 🐀
