File size: 11,491 Bytes
a16932a 78d662e a16932a 4f625d4 a6975b2 4f625d4 a6975b2 4f625d4 78d662e 4f625d4 78d662e a6975b2 78d662e 6ca84dc 78d662e a6975b2 4f625d4 a6975b2 4f625d4 f449a3a a6975b2 4f625d4 d786c85 4f625d4 09427c9 f0df64e 09427c9 f0df64e 1a984ea f449a3a 1a984ea a6975b2 b7b95df f449a3a b7b95df a6975b2 082223e a6975b2 f449a3a 583f150 b7b95df a6975b2 f449a3a a6975b2 f0df64e 09427c9 a6975b2 09427c9 f449a3a 09427c9 4f625d4 09427c9 c1c3381 850b1df 4f625d4 c1c3381 4f625d4 f449a3a 4f625d4 a6975b2 09427c9 d786c85 4f625d4 d786c85 4f625d4 09427c9 4f625d4 09427c9 4f625d4 09427c9 4f625d4 a6975b2 6829252 09427c9 4f625d4 a6975b2 09427c9 a6975b2 4f625d4 a6975b2 4f625d4 a6975b2 4f625d4 a6975b2 09427c9 a6975b2 082223e a6975b2 4f625d4 f449a3a 4f625d4 a6975b2 f449a3a d786c85 a6975b2 d786c85 a6975b2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# CLAUDE
Wrdler v0.2.12
# Wrdler - Project Context
## Project Overview
Wrdler is a simplified vocabulary puzzle game based on BattleWords:
- **Python project** (Streamlit, Python 3.12.8)
- **8x6 grid** (8 columns Γ 6 rows, one word per row, horizontal only)
- **No scope/radar visualization**
- **2 free letter guesses at game start** (all instances revealed)
- **Word composition:** 2 four-letter, 2 five-letter, 2 six-letter words per puzzle
**Current Version:** 0.2.12
**Last Updated:** 2025-12-21
**Repository:** https://github.com/Oncorporation/Wrdler.git
**Branch:** main
## 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
- Minor grid layout tightening
- Added a couple words to classic.txt
- HF server fix
- Documentation updates
## Current Features (v0.2.12)
### Core Gameplay
- 8x6 grid with 6 hidden words (one per row, horizontal only)
- Players choose 2 free letters at start; all instances are revealed
- Click cells to reveal letters or empty spaces
- Guess words for points (word length + bonus for unrevealed letters)
- Game ends when all words guessed or all word letters are revealed
- Incorrect guess history display (toggleable, default enabled)
- 10 incorrect guess limit per game
- **All leaderboard and challenge submissions use the latest st.session_state, including challenge overrides.**
### Game Modes
1. **Classic Mode:** Allows consecutive guessing after correct answers
2. **Too Easy Mode:** Single guess per reveal
### Scoring Tiers
- **Legendary:** 45+ points
- **Fantastic:** 42-44 points
- **Great:** 39-41 points
- **Good:** 35-38 points
- **Keep practicing:** < 35 points
### Settings Page & Management
- All game settings moved from sidebar to a dedicated Settings page (`?page=settings`)
- Accessible via footer navigation (`βοΈ Settings` link)
- Local JSON-based settings persistence in `wrdler/settings/`
- Latest settings auto-loaded on startup
- 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`
### Word List Management
- Sort and filter word lists (filter using `assets/filter.txt` blocklist)
- Dialog display of removed words after filtering
### Challenge Mode & Remote Storage
- Short URL-based challenge sharing via `?game_id=<sid>`
- Each player gets different random words from same wordlist
- Multi-user challenge leaderboards (top 5 display)
- Remote storage via HuggingFace datasets
- Word list difficulty calculation
- "Show Challenge Share Links" toggle (default OFF)
- **Integration:**
- Automatic submission after game completion (opt-in via game over popup)
- 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)
- **Challenge settings override defaults on load, and all submissions use the current session state.**
**Access:** 'Leaderboard' link in the footer navigation at the bottom of the page
### Daily & Weekly Leaderboards
- **Settings-Based Separation:** Each unique settings combo creates separate leaderboard
- Settings: `game_mode`, `wordlist_source`, `show_incorrect_guesses`, `enable_free_letters`, `puzzle_options` (spacer, may_overlap)
- **Auto Score Submission:** Checks qualification for top 25 after game completion
- **Storage:** Folder-based discovery at `games/leaderboards/{daily|weekly}/{period}/{file_id}/settings.json`
- **File ID Format:** `{wordlist_source}-{game_mode}-{sequence}` (e.g., `classic-classic-0`)
- **Leaderboard Page:** Four tabs (Today, Daily, Weekly, History) accessible via `?page=today|daily|weekly|history` using query parameter routing and custom navigation links (not Streamlit native tabs)
- Leaderboard files use UTC for all 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]`
### Game Over Dialog & Leaderboard Integration
- Game over dialog now integrates leaderboard submission and displays qualification results (rankings)
- After submitting your score, the dialog will show if you qualified for the daily or weekly leaderboard and your rank
### AI Word Generation
- Topic-based word list generation via HuggingFace Spaces or local transformers
- Automatic word saving (max 1000 words per file)
- Retry mechanism (up to 3 attempts) for insufficient word counts
- Fallback to dictionary words if AI unavailable
### Audio & Visuals
- Ocean-themed gradient background with wave animations
- Toggleable background music with volume control (configured via Settings page, played globally)
- Sound effects (hit/miss/correct/incorrect) with volume control (configured via Settings page, enabled by default)
### PWA Support
- Installable as Progressive Web App on desktop and mobile
- Service worker for offline caching of static assets
- Works offline for basic functionality
### Footer Navigation
- Navigation links to Leaderboard, Play, and Settings pages are in the footer (not the sidebar)
- Footer navigation prevents reloading active pages
## Technical Architecture
### Technology Stack
- **Framework:** Streamlit 1.52.1
- **Language:** Python 3.12.8 (requires >=3.12, <3.13)
- **Remote Storage:** huggingface_hub (>=0.20.0)
- **AI Generation:** transformers, gradio_client
- **Testing:** Pytest
- **Package Manager:** UV or pip
### Project Structure
```
wrdler/
βββ app.py # Streamlit entry point
βββ wrdler/ # Main package
β βββ __init__.py # Version: 0.2.10
β βββ models.py # Data models (Coord, Word, Puzzle, GameState)
β βββ generator.py # Puzzle generation with deterministic seeding
β βββ logic.py # Game mechanics (reveal, guess, scoring)
β βββ ui.py # Streamlit UI with query param routing
β βββ oauth.py # HuggingFace OAuth utilities
β βββ settings_page.py # Settings page UI (enhanced)
β βββ leaderboard.py # Leaderboard system (daily/weekly)
β βββ leaderboard_page.py # Leaderboard UI page
β βββ word_loader.py # Word list management
β βββ word_loader_ai.py # AI word generation
β βββ game_storage.py # HF game storage wrapper
β βββ version_info.py # Version display
β βββ modules/ # Shared utility modules
β β βββ __init__.py # Module exports
β β βββ storage.py # HuggingFace storage & URL shortener
β β βββ storage.md # Storage module documentation
β β βββ constants.py # Storage-related constants
β β βββ file_utils.py # File utility functions
β βββ words/ # Word list files
β βββ classic.txt # Default word list
β βββ fourth_grade.txt # Elementary word list
βββ tests/ # Unit tests
βββ specs/ # Documentation
βββ static/ # PWA assets (manifest.json, service-worker.js)
βββ .env # Environment variables (HF credentials)
βββ pyproject.toml # Project metadata
βββ requirements.txt # Dependencies
βββ uv.lock # UV lock file
βββ Dockerfile # Container deployment
βββ README.md # User-facing documentation
βββ CLAUDE.md # This file - project context for Claude
βββ GAMEPLAY_GUIDE.md # User guide with tips and strategies
```
### Page Navigation System
Uses **query parameter-based routing** (NOT Streamlit multi-page):
- `?page=today|daily|weekly|history` β Leaderboard pages
- `?page=settings` β Settings page
- `?game_id=<sid>` β Challenge mode
- No query params β Main game page
## Data Models
### Core Classes
```python
@dataclass
class Coord:
x: int # row, 0-based
y: int # col, 0-based
@dataclass
class Word:
text: str
start: Coord
direction: Direction # "H" or "V"
cells: List[Coord]
@dataclass
class Puzzle:
words: List[Word]
may_overlap: bool
spacer: int
uid: str # Unique identifier
@dataclass
class GameState:
grid_rows: int # 6 for Wrdler
grid_cols: int # 8 for Wrdler
puzzle: Puzzle
revealed: Set[Coord]
guessed: Set[str]
score: int
last_action: str
can_guess: bool
game_mode: str
points_by_word: Dict[str, int]
start_time: Optional[datetime]
end_time: Optional[datetime]
```
## Environment Variables
Create a `.env` file in the project root:
```bash
# Challenge Mode & Leaderboards (Remote Storage)
HF_API_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxx # HuggingFace API token with write access
HF_REPO_ID=YourUsername/YourRepo # Dataset repo for challenge storage
# AI Word Generation
USE_HF_WORDS=false # Enable HF Space API for word generation
HF_WORD_LIST_REPO_ID=YourUsername/WordRepo # Dataset repo for AI word lists
# OAuth Admin Access
ADMIN_USERS=username1,username2 # Comma-separated list of admin usernames
MAX_DISPLAY_ENTRIES=25 # Max leaderboard entries to display (default: 25)
```
### HF_REPO_ID Structure
```
HF_REPO_ID/
βββ shortener.json # URL shortener mappings
βββ games/{uid}/settings.json # Challenge data (entry_type: "challenge")
βββ games/leaderboards/
βββ daily/{YYYY-MM-DD}/{file_id}/settings.json # Daily leaderboards
βββ weekly/{YYYY-Www}/{file_id}/settings.json # Weekly leaderboards
```
## Development Workflow
### Running Locally
```bash
# Install dependencies
uv pip install -r requirements.txt --link-mode=copy
# Run app
streamlit run app.py
```
### Testing
```bash
pytest tests/
```
## OAuth-Protected Settings Page
- Settings page at `?page=settings`, protected by HuggingFace OAuth (admin-only access)
- Uses query parameter routing and checks admin access via `ADMIN_USERS` env var
## Technical Notes
- **8Γ6 grid:** `grid_rows=6`, `grid_cols=8`
- **Horizontal-only placement:** One word per row
- **Query param routing:** All pages use `?page=<name>` system
- **Session state management:** Heavy use of `st.session_state`
- **All leaderboard and challenge submissions use the latest st.session_state, including challenge overrides.**
## Deployment Platforms
1. **HuggingFace Spaces** (Primary) - Dockerfile deployment with OAuth support
2. **Local Development** - Streamlit run
3. **Docker** - Containerized deployment
## Git Configuration
- **Current Branch:** AI (working branch)
- **Main Branch:** main
- **Remotes:**
- origin: https://github.com/Oncorporation/Wrdler.git
- Hugging: https://huggingface.co/spaces/Surn/Wrdler
|