Wrdler Specifications
Version: 0.2.9
Status: Production Ready - Leaderboards & Enhanced Settings Page Implemented Last Updated: 2025-12-09
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)
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.txtfrom 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
- HF Space API (primary): Uses Hugging Face Space when
- 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=<sid>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
- Query params:
- 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
Integration:
- Automatic submission after game completion (opt-in)
- Challenge scores also contribute to daily/weekly leaderboards
- Source tracking via
source_challenge_idfield - Unified JSON format with
entry_typefield (daily/weekly/challenge)
Discovery: Folder-based (no index.json)
- Scans period folders for date/week IDs
- Filters by file_id prefix for matching settings
- Loads and verifies full settings match
Date Display Updates:
- All leaderboard files use UTC for period boundaries.
- When displaying daily leaderboards, show the UTC period as a PST date range.
- Example: For UTC file date 2025-12-08, display:
2025-12-08 00:00:00 UTC to 2025-12-08 23:59:59 UTC
and
2025-12-07 16:00:00 PST to 2025-12-08 15:59:59 PST
The leaderboard expander label should show:
Mon, Dec 08, 2025 4:00 PM PST β Tue, Dec 09, 2025 3:59:59 PM PST [settings badge]
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 workerandmanifest.json - Basic offline caching of static assets
- INSTALL_GUIDE.md added with platform-specific install steps
- No gameplay logic changes
- Added
Settings Page (v0.2.8+)
- All game settings moved from sidebar to a dedicated settings page (
?page=settings) - Accessible via the footer navigation (
βοΈ Settingslink) - 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