A newer version of the Streamlit SDK is available:
1.52.1
Wrdler Game Specifications (specs.md)
Version: 0.2.4 Status: Production Ready - Leaderboards Implemented Last Updated: 2025-12-08
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.4)
Word List Management (v0.2.4)
- β
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 (v0.1.0+)
- β 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 20 scores for each day (resets UTC midnight)
- Weekly Leaderboards: Top 20 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-Www}/{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 (Planned/Upcoming)
- Move all game settings from sidebar to a dedicated settings page (
?page=settings) requiring a logged in user (OAuth)
Storage
Current (v0.2.1)
- β Challenge Mode uses remote storage via Hugging Face datasets
- β Game ID is generated from the word list for replay/sharing
Planned (Future)
- Local persistent storage for game results and high scores (JSON files)
- Local storage location:
~/.wrdler/data/ - Privacy-first offline access
UI Elements (v0.2.1 - Implemented)
- β 8x6 grid (48 cells total)
- β Free letter guess buttons (2 at game start) - circular green gradient design
- β Text box for word guesses
- β Score display (shows word, base points, bonus points, total score)
- β Guess status indicator (Correct/Try Again)
- β Incorrect guess history display (toggleable)
- β Game ID display and share button in game over dialog
- β Challenge Mode banner with leaderboard (top 5)
- β High score expander in sidebar
- β Player name input in sidebar
- β
Checkbox: "Show Challenge Share Links" (default OFF)
- When OFF:
- Challenge Mode header hides the Share Challenge link
- Game Over dialog still supports submitting/creating challenges, but does not display the generated share URL
- Persisted in session state and preserved across "New Game"
- When OFF:
Word List
- External list at
wrdler/words/wordlist.txt - Loaded by
wrdler.word_loader.load_word_list()with caching - Filtered to uppercase A-Z, lengths in {4,5,6}; falls back if < 25 per length
Generator
- Centralized word loader
- No duplicate word texts are selected
- Horizontal-only word placement
- One word per row in 8x6 grid
- Word length distribution: Each puzzle must contain exactly 2 four-letter words, 2 five-letter words, and 2 six-letter words
- No word spacing configuration (fixed one word per row)
Entry Point
- The Streamlit entry point is
app.py - A
Dockerfilecan be used for containerized deployment (recommended for Hugging Face Spaces)
Deployment Requirements
Basic Deployment (Offline Mode)
No special configuration needed. The app will run with all core gameplay features.
Optional: Install as PWA from the browser menu (Add to Home Screen/Install app).
Challenge Mode Deployment (Remote Storage)
Requires HuggingFace Hub integration for challenge sharing and leaderboards.
Required Environment Variables:
HF_API_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxx # or HF_TOKEN (write access required)
HF_REPO_ID=YourUsername/YourRepo # Target HF dataset repository
SPACE_NAME=YourUsername/Wrdler # Your HF Space name for URL generation
Optional Environment Variables:
CRYPTO_PK= # Reserved for future challenge signing
Setup Steps:
- Create a HuggingFace account at https://huggingface.co
- Create a dataset repository (e.g.,
YourUsername/WrdlerStorage) - Generate an access token with
writepermissions:- Go to https://huggingface.co/settings/tokens
- Click "New token"
- Select "Write" access
- Copy the token (starts with
hf_)
- Create a
.envfile in project root with the variables above - For Hugging Face Spaces deployment, add these as Space secrets
Repository Structure (automatically created):
HF_REPO_ID/
βββ shortener.json # Short URL mappings (sid -> full URL)
βββ games/
βββ leaderboards/
β βββ daily/
β β βββ {YYYY-MM-DD}/ # Daily period folders
β β βββ {file_id}/ # Settings-specific leaderboard
β β βββ settings.json # entry_type: "daily"
β βββ weekly/
β βββ {YYYY-Www}/ # Weekly period folders (ISO week)
β βββ {file_id}/ # Settings-specific leaderboard
β βββ settings.json # entry_type: "weekly"
βββ {challenge_id}/
βββ settings.json # Challenge data (entry_type: "challenge")
Data Privacy:
- Challenge Mode stores: word lists, scores, times, game modes, player names
- No PII beyond optional player name (defaults to "Anonymous")
- Players control URL visibility via "Show Challenge Share Links" setting
- App functions fully offline when HF credentials not configured
Deployment Platforms:
- Local development: Run with
streamlit run app.py - Docker: Use provided
Dockerfile - Hugging Face Spaces: Dockerfile deployment (recommended)
- Any Python 3.10+ hosting with Streamlit support
Development Status
Current Version: 0.2.4 (Production Ready - Leaderboards Implemented)
Completed β
v0.2.4: Word List Filtering
- Added "Filter Wordlist" button to sidebar
- Implemented blocklist filtering via
assets/filter.txt - Added results dialog showing removed words
v0.2.1: Daily and Weekly Leaderboards
- Settings-based leaderboard separation
- Folder-based discovery (no index.json)
- Top 20 displayed entries per leaderboard
- Four-tab leaderboard page (Today, Daily, Weekly, History)
- Automatic score qualification and submission
- Integration with challenge mode
- Query parameter filtering for direct links
- Settings page planned (move from sidebar, OAuth login required)
v0.1.1: Enhanced AI word generation
- Intelligent word saving with duplicate prevention
- Automatic retry mechanism (up to 3 attempts)
- 1000-word file size limit
- Improved HF Space API integration
- Enhanced logging and error handling
v0.1.0: AI word generation foundation
- Topic-based word list creation
- Dual generation modes (HF Space + local)
- Utility modules integration
v0.0.2: All 7 sprints complete
- β 100% test coverage (25/25 tests)
- π Development time: ~12.75 hours (sprints 1-7)
- π Complete documentation
Future Roadmap
- Local persistent storage, high score tracking, player statistics, leaderboard caching (future)
- Enhanced UI animations, retry logic, rate limiting, archival script (future)
- AI difficulty tuning, multi-language word generation, i18n (future)
Copyright
Wrdler is based on BattleWords. BattlewordsTM. All Rights Reserved. All content, trademarks and logos are copyrighted by the owner.
Test File Location
All test files must be placed in the /tests folder. This ensures a clean project structure and makes it easy to discover and run all tests.