A real-time multiplayer anagram game built with Phoenix LiveView and WebSockets. Players race to form words from a communal pool of letter tiles, with the ability to "steal" words by extending them with new letters.
Cutthroat Anagrams (aka Pirate Anagrams or Anagram Thief or just Anagrams) is a fast-paced word game where players compete to claim words from a shared pool of letters. The twist? You can steal other players' words by making them into longer words!
-
Join a Game
- Enter your name
- Create a new game or join with a game code
- Set minimum word length (3, 4, or 5 letters)
-
Game Flow
- Letters are flipped from the tile bag into a communal pool
- When you see a word you can make, claim it quickly!
- Use either:
- Voice Recognition: Say the word aloud (mic must be enabled)
- Manual Input: Type the word in the quick claim box
-
Word Claiming
- Words must meet the minimum length requirement
- You have 5 seconds to confirm your claim
- Successfully claimed words are added to your collection
-
Stealing Words
- Take another player's word and add letter(s) from the communal pool
- The new word must be longer than the original
- The new word must change the root word
- Example: Steal "CAT" + "S" → "CAST" is valid but "CATS" is not
-
Scoring & Winning
- Words are color-coded by length:
- 🔵 Blue border: 3-4 letters (basic points)
- 🟡 Yellow border: 5-6 letters (medium points)
- 🟢 Green border: 7+ letters (high points)
- Score is based on total letters in your claimed words
- Game ends when all tiles are flipped and players vote to end or all tiles are claimed
- Words are color-coded by length:
- Voice Recognition: Enable your microphone for hands-free word claiming
- Tie Breaking: Simultaneous claims are resolved by coin flip
- Reconnection: Rejoin games if disconnected
- Auto-flip Timer: New tiles appear automatically every 10 seconds (resets when words are claimed) if someone does not flip manually first
- Elixir 1.15+
- Erlang/OTP 27+
- Node.js (for asset compilation)
Note: PostgreSQL is configured but not actually used - all game state is stored in memory via GenServers.
-
Clone the repository
git clone <repository-url> cd cutthroat_anagrams
-
Install dependencies
mix setup
This runs:
mix deps.get- Install Elixir dependenciesmix ecto.setup- Set up databasemix assets.setup- Install Tailwind CSS and esbuildmix assets.build- Build frontend assets
-
Start the server
mix phx.server
-
Visit the application Open http://localhost:4000 in your browser
Data Storage: All game state is stored in memory using Elixir GenServers - no database required! Games are temporary and don't persist between server restarts.
Asset Compilation:
- CSS: Uses Tailwind CSS with DaisyUI components
- JS: Compiled with esbuild
- Assets auto-rebuild in development mode
# Run all tests
mix test
# Run with coverage
mix test --cover
# Run specific test file
mix test test/cutthroat_anagrams_web/controllers/page_controller_test.exsThe test environment automatically:
- Creates a test database
- Runs migrations
- Provides isolated test cases for channels and controllers
Run the full precommit suite:
mix precommitThis runs:
- Compile with warnings as errors
- Remove unused dependencies
- Format code
- Run all tests
# Start the server
mix phx.server
# Start in interactive mode
iex -S mix phx.server
# Restart (games will be lost - stored in memory only)# Rebuild assets
mix assets.build
# Deploy assets (minified)
mix assets.deploy
# Install asset dependencies
mix assets.setup# Format code
mix format
# Check formatting
mix format --check-formatted
# Compile with warnings as errors
mix compile --warning-as-errors- Phoenix Framework: Web framework and WebSocket handling
- GenServer: Game state management (
CutthroatAnagrams.GameServer) - Phoenix Channels: Real-time multiplayer communication
- DynamicSupervisor: Manages multiple game instances
- Registry: Game discovery and player reconnection
- Vanilla JavaScript: Game client logic and speech recognition
- Phoenix Channels Client: Real-time server communication
- Tailwind CSS + DaisyUI: Responsive styling and components
- Gotham Font: Scrabble-style letter tiles
GameServer: Core game logic and state managementGameChannel: WebSocket message handlingGameSupervisor: Game instance lifecycle managementgame.js: Client-side game interface and speech recognition
- Real-time multiplayer with WebSockets
- Voice recognition for hands-free play
- Responsive design works on desktop and mobile
- Automatic reconnection if connection drops
- Scrabble-style tiles with authentic visual design
- Coin flip resolution for simultaneous claims
- Vote-to-end functionality when tiles are running low
- Auto-flip timer keeps the game moving
# Phoenix
SECRET_KEY_BASE=your-secret-key
PHX_HOST=localhost
PORT=4000Note: Database environment variables are not needed since the app doesn't use persistent storage.
Configure in config/config.exs:
- Default minimum word length
- Tile distribution
- Auto-flip timer duration
- Voice recognition settings
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
mix test) - Run precommit checks (
mix precommit) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Cutthroat Anagrams combines the strategic thinking of word games with the excitement of real-time competition. Whether you're playing with friends or strangers, every game is a race against time and wit!
Built with ❤️ using Elixir, Phoenix, and modern web technologies by JonMarkGo and Claude Code.