# Wrdler Specifications **Version:** 0.2.12 **Last Updated:** 2025-12-21 **Status:** Production Ready - Leaderboards & Enhanced Settings Page Implemented ## Recent Changes (v0.2.12) - Layout changes for improved usability - Fixed static spinner graphic and favicon - Background enable/disable toggles improved - Sidebar disabled for streamlined UI ## Overview Wrdler is a Python/Streamlit vocabulary puzzle game based on BattleWords, but with key differences. The objective is to discover hidden words on a grid by making strategic guesses and using free letter reveals at the game start. **Current Status:** All 7 sprints complete, 100% tested, fully documented ## Key Differences from BattleWords - **Python project** (Streamlit, Python 3.12.8) - **8x6 grid** (instead of 12x12) - **One word per row** (instead of 6 words placed anywhere) - **Horizontal words only** (no vertical placement) - **No scope/radar visualization** - **2 free letter guesses at game start** (all instances of chosen letters are revealed) - **All leaderboard and challenge submissions use the latest st.session_state, including challenge overrides.** ## Game Board - 8 x 6 grid - Six hidden words: - One word per row (row 0-5) - **Word composition:** Exactly 2 four-letter words, 2 five-letter words, and 2 six-letter words - All placed horizontally (left-right) - No vertical placement - No diagonal placement - Words do not overlap - Entry point is `app.py` - **Supports Dockerfile-based deployment for Hugging Face Spaces and other container platforms** ## Gameplay (Core) - Players start by choosing 2 letters; all instances of those letters are revealed in the grid - Players click grid squares to reveal letters or empty spaces - Empty revealed squares are styled with CSS class `empty` - After any reveal, the app immediately reruns (`st.rerun`) to show the change - After revealing a letter, players may guess a word by entering it in a text box - Guess submission triggers an immediate rerun to reflect results - Only one guess per letter reveal; must uncover another letter before guessing again - In the default mode, a correct guess allows chaining an additional guess without another reveal - **The game ends when all six words are guessed or all word letters are revealed** ## Scoring - Each correct word guess awards points: - 1 point per letter in the word - Bonus points for each hidden letter at the time of guessing - Score tiers: - **Legendary:** 45+ points - **Fantastic:** 42-44 points - **Great:** 39-41 points - **Good:** 35-38 points - **Keep practicing:** <35 points - **Game over is triggered by either all words being guessed or all word letters being revealed** ## Core Rules (v0.0.2 - Implemented) - ✅ 8x6 grid with one word per row - ✅ Horizontal words only; no vertical placement - ✅ No overlaps: words do not overlap or share letters - ✅ No radar/scope visualization (removed in Sprint 3) - ✅ 2 free letter guesses at game start (implemented in Sprint 4) - ✅ Incorrect guess history with optional display - ✅ 10 incorrect guess limit per game - ✅ Two game modes: Classic (chain guesses) and Too Easy (single guess per reveal) ## Implemented Features (v0.2.9) ### Settings Management (v0.2.9) - Enhanced settings management: create, update, rename, and delete settings files - Split "Save Settings" into "Create Settings" and "Update Settings" actions - Improved settings loading and user feedback - Default sound effects enabled in settings - New default configuration: `classic-classic-full_sound_free_letters.json` - Deprecated configuration removed: `classic-classic-2.json` - Footer navigation updated to prevent reloading active pages ### Word List Management - **Filter Wordlist:** Remove words found in `assets/filter.txt` from the selected word list - **Sort Wordlist:** Sort words by length and alphabetically - **Feedback:** Dialog showing count and list of removed words ### AI Word Generation - **Topic-Based Generation:** Create custom word lists for any theme using AI - **Dual Generation Modes:** - HF Space API (primary): Uses Hugging Face Space when `USE_HF_WORDS=true` - Local transformers (fallback): Falls back to local models if HF unavailable - **Intelligent Word Management:** - Smart detection separates existing dictionary words from new AI-generated words - Only saves new words to prevent duplicates in word files - Automatic retry mechanism (up to 3 attempts) if insufficient words generated - 1000-word file size limit prevents dictionary bloat - Auto-sorted by length then alphabetically - **Guaranteed Distribution:** Ensures exactly 25 words each of lengths 4, 5, and 6 - **Graceful Fallback:** Uses dictionary words if AI generation fails - **Enhanced Logging:** Detailed pipeline visibility for debugging ### Challenge Mode - **Game ID Sharing:** Each puzzle generates a shareable link with `?game_id=` to challenge others with the same word list - **Remote Storage:** Game results and leaderboards stored in Hugging Face dataset repos - **Leaderboards:** Multi-user leaderboards sorted by score (descending) then time (ascending) - **Word List Difficulty:** Calculated and displayed for each challenge - **Top 5 Display:** Leaderboard banner shows top 5 players - **Optional Sharing:** "Show Challenge Share Links" toggle (default OFF) controls URL visibility ### Leaderboard System (v0.2.1) ✅ IMPLEMENTED Wrdler features a comprehensive daily and weekly leaderboard system: **Core Features:** - **Daily Leaderboards:** Top 25 scores for each day (resets UTC midnight) - **Weekly Leaderboards:** Top 25 scores for each ISO week (resets Monday UTC 00:00) - **Settings-Based Separation:** Each unique combination of game-affecting settings creates a separate leaderboard: - `game_mode` (classic, easy, too easy) - `wordlist_source` (classic.txt, fourth_grade.txt, etc.) - `show_incorrect_guesses` (boolean) - `enable_free_letters` (boolean) - `puzzle_options` (spacer, may_overlap) - **Sorting:** Scores sorted by: score (desc) → time (asc) → difficulty (desc) - **Qualification:** Only top 25 (configurable) scores displayed per leaderboard (more can be stored) **Storage Structure:** ``` HF_REPO_ID/games/ ├── leaderboards/ │ ├── daily/{YYYY-MM-DD}/{file_id}/settings.json │ └── weekly/{YYYY-Wwww}/{file_id}/settings.json └── {challenge_id}/settings.json ``` **File ID Format:** `{wordlist_source}-{game_mode}-{sequence}` - Example: `classic-classic-0`, `easy-too_easy-1` - Sanitized (no .txt, lowercase, underscores for spaces) **Leaderboard Page UI:** - **Today Tab:** Current daily and weekly leaderboards - Query params: `?gidd={file_id}` and `?gidw={file_id}` for filtering - Side-by-side display in two columns - **Daily Tab:** Last 7 days of daily leaderboards - Expandable groups per date - All settings combinations shown - **Weekly Tab:** Current ISO week leaderboard - All settings combinations displayed - **History Tab:** Historical leaderboard browser - Dropdown selectors for period and settings - Separate daily and weekly columns - **Navigation:** Access leaderboards via the footer navigation at the bottom of the page (not the sidebar) - **Routing:** Leaderboard page uses query parameters and custom navigation links for tab selection **Integration:** - Automatic submission after game completion (opt-in) - Game over dialog now integrates leaderboard submission and displays qualification results (rankings) - Challenge scores also contribute to daily/weekly leaderboards - Source tracking via `source_challenge_id` field - Unified JSON format with `entry_type` field (daily/weekly/challenge) - **All leaderboard and challenge submissions use the latest st.session_state, including challenge overrides.** **Access:** 'Leaderboard' link in the footer navigation at the bottom of the page ### PWA Support - **PWA Installation:** App is installable as a Progressive Web App on desktop and mobile - Added `service worker` and `manifest.json` - Basic offline caching of static assets - INSTALL_GUIDE.md added with platform-specific install steps - No gameplay logic changes ### Settings Page (v0.2.8+) - All game settings moved from sidebar to a dedicated settings page (`?page=settings`) - Accessible via the footer navigation (`⚙️ Settings` link) - Controls game mode, word list selection, grid options (spacer, grid ticks), and audio (music and sound effects) - Settings are persisted to JSON files in `wrdler/settings/` and the latest settings are loaded on app startup - Enhanced management: create, update, rename, delete settings files