A real-time competitive Wordle game where players battle to guess the most 5-letter words within a timed session. Built with Phoenix LiveView for instant, multiplayer gameplay.
๐ Play Live
- ๐ฏ Real-time Multiplayer - Compete with friends in the same session
- โก Live Updates - See opponent progress in real-time via Phoenix PubSub
- ๐ Smart Scoring - Bonus points for speed and accuracy
- ๐พ Session Persistence - Rejoin games automatically after disconnection
- โฑ๏ธ Timed Rounds - Race against the clock to maximize your score
- ๐จ Color-Coded Feedback - Classic Wordle-style letter hints (green/yellow/gray)
- ๐ฑ Responsive Design - Play on any device
- ๐ Endless Rounds - Start new games with the same players
- Phoenix Framework 1.8 - Web framework
- Phoenix LiveView 1.1 - Real-time UI without JavaScript
- Elixir - Functional programming language
- GenServer - Stateful game session management
- Tailwind CSS - Styling
- Fly.io - Deployment platform
- Create or Join a Session - Share the session URL with friends
- Ready Up - Click ready when all players have joined
- Guess Words - Type 5-letter words and press Enter
- Use Color Hints:
- ๐ฉ Green - Letter is correct and in the right position
- ๐จ Yellow - Letter is in the word but wrong position
- โฌ Gray - Letter is not in the word
- Score Points - Each correct word scores points (bonus for fewer attempts!)
- Race the Clock - Maximize your score before time runs out
- Base: 1 point per correct word
- Bonuses:
- 1 attempt: +5 bonus โ 6 points total
- 2 attempts: +3 bonus โ 4 points total
- 3 attempts: +2 bonus โ 3 points total
- 4-6 attempts: +1 bonus โ 2 points total
- Failed word: 0 points
- Elixir 1.18.3 or later
- Erlang 27.1.2 or later
- Node.js (for asset compilation)
# Clone the repository git clone <your-repo-url> cd wordle_battle # Install dependencies and build assets mix setup # Start the Phoenix server mix phx.server # Or start in interactive mode iex -S mix phx.serverNow visit localhost:4000 from your browser.
# Run tests mix test # Run pre-commit checks (compile, format, test) mix precommit # Build assets mix assets.build # Run specific test file mix test test/path/to/test.exs # Run only failed tests mix test --failedThe game uses a GenServer-based architecture with Phoenix LiveView:
-
WordleServer (GenServer) - Each session runs as a supervised process
- Manages game state and phase transitions (
:lobbyโ:playingโ:game_over) - Handles word assignment, guess validation, and scoring
- Broadcasts state updates via PubSub
- Persists state across player disconnections
- Manages game state and phase transitions (
-
WordleLive (LiveView) - Real-time UI for players
- Subscribes to PubSub for session updates
- Renders game grid, virtual keyboard, and leaderboard
- Handles user interactions
-
Dynamic Supervision - Sessions registered via Registry
- Efficient process lookup
- Fault-tolerant session management
- 2,300+ answer words (common 5-letter words)
- 12,000+ valid guesses (extended dictionary)
- Per-session tracking prevents word repetition
- O(1) validation using MapSet
- UUID stored in browser localStorage
- Automatic reconnection on page refresh
- Graceful handling of disconnections
- Automated cleanup of inactive sessions
lib/ โโโ wordle_battle/ โ โโโ application.ex # App supervision tree โ โโโ dictionary.ex # Word loading and validation โ โโโ wordle_server.ex # Game state GenServer โโโ wordle_battle_web/ โ โโโ live/ โ โ โโโ wordle_live.ex # Main game LiveView โ โ โโโ lobby_live.ex # Session creation/joining โ โโโ components/ โ โ โโโ core_components.ex # Reusable UI components โ โโโ router.ex # Routes priv/ โโโ dictionary/ โโโ answer_words.txt # Curated answer list โโโ valid_guesses.txt # All valid words This app is deployed on Fly.io in the Amsterdam region.
# Install flyctl curl -L https://fly.io/install.sh | sh # Login to Fly.io flyctl auth login # Launch the app (configure as needed) flyctl launch # Set secrets flyctl secrets set SECRET_KEY_BASE=$(mix phx.gen.secret) # Deploy flyctl deployThe app uses auto-scaling with a single shared-cpu-1x instance that stops when idle to minimize costs.
See fly.toml for configuration details.
Tests use Phoenix.LiveViewTest for comprehensive LiveView testing:
# Example test test "player can submit a valid guess", %{conn: conn} do {:ok, view, _html} = live(conn, "/session/#{session_id}") view |> form("#guess-form", guess: %{word: "HELLO"}) |> render_submit() assert has_element?(view, "[data-guess='HELLO']") endRun tests with: mix test
Two-pass algorithm handles duplicate letters correctly:
- First pass: Mark exact matches (green)
- Second pass: Mark present letters (yellow) from remaining pool
- Remainder: Mark as wrong (gray)
:lobby โ :playing โ :game_over โ :lobby (new round) - Lobby: Players join and ready up
- Playing: Active gameplay with timer
- Game Over: Display winners and final scores
- Countdown broadcasts every second via PubSub
- Auto-transition to game over at 0
- Audio notification on expiration
Contributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.
- Dictionary words sourced from common Wordle word lists
- Inspired by the original Wordle by Josh Wardle
- Built with the amazing Phoenix Framework
Made with โค๏ธ using Elixir and Phoenix LiveView