File size: 26,024 Bytes
4f625d4
 
 
 
 
 
 
 
 
0860b52
4f625d4
 
 
 
 
0860b52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d57c213
 
0860b52
d57c213
 
 
 
0860b52
 
 
d57c213
 
850b1df
 
 
 
c1c3381
 
 
6829252
c1c3381
 
 
 
6829252
 
 
 
 
 
c1c3381
6829252
c1c3381
4f625d4
 
 
5f8a848
4f625d4
 
 
 
 
 
 
 
 
 
c1c3381
 
4f625d4
 
 
 
 
 
 
 
 
 
0860b52
c1c3381
 
 
 
 
850b1df
4f625d4
c1c3381
4f625d4
 
 
 
 
 
0860b52
4f625d4
 
 
 
0860b52
4f625d4
0860b52
4f625d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0860b52
4f625d4
6829252
4f625d4
 
 
6829252
 
 
 
 
 
4f625d4
 
 
 
6829252
 
 
850b1df
4f625d4
 
 
 
 
 
 
 
 
 
 
 
 
 
c1c3381
4f625d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c1c3381
 
 
 
 
 
 
 
 
 
4f625d4
d57c213
850b1df
 
d57c213
 
 
 
 
 
850b1df
 
d57c213
 
 
 
850b1df
4f625d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6829252
5f8a848
4f625d4
6829252
4f625d4
 
6829252
 
 
4f625d4
 
850b1df
6829252
4f625d4
 
6829252
 
c1c3381
 
4f625d4
 
 
6829252
4f625d4
 
 
 
6829252
 
 
 
0860b52
6829252
 
850b1df
6829252
c1c3381
 
 
6829252
4f625d4
6829252
 
 
 
 
4f625d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0860b52
4f625d4
 
 
0860b52
 
 
4f625d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c1c3381
4f625d4
 
 
 
 
c1c3381
 
 
 
 
 
 
4f625d4
6829252
4f625d4
6829252
 
 
 
 
 
 
 
 
 
4f625d4
6829252
4f625d4
c1c3381
 
0860b52
 
 
 
 
 
 
 
d57c213
 
 
 
 
 
 
 
0860b52
 
 
d57c213
850b1df
 
 
 
 
 
c1c3381
 
 
 
 
 
 
 
6829252
 
 
 
4f625d4
6829252
 
4f625d4
6829252
4f625d4
 
6829252
 
c1c3381
4f625d4
 
c1c3381
4f625d4
 
c1c3381
4f625d4
850b1df
6829252
 
 
 
c1c3381
6829252
 
 
 
c1c3381
4f625d4
 
6829252
 
c1c3381
 
6829252
0860b52
6829252
 
 
 
 
 
 
 
c1c3381
850b1df
 
0860b52
 
 
 
 
c1c3381
 
 
 
 
 
5f8a848
c1c3381
 
 
850b1df
 
0860b52
 
 
 
 
 
 
4f625d4
 
 
 
 
 
 
 
 
 
 
 
c1c3381
4f625d4
 
 
6829252
4f625d4
 
6829252
 
c1c3381
 
 
 
0860b52
4f625d4
 
6829252
 
 
 
c1c3381
 
 
0860b52
4f625d4
 
 
6829252
 
c1c3381
6829252
c1c3381
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0860b52
c1c3381
 
 
 
850b1df
 
c1c3381
 
 
 
 
 
0860b52
 
d57c213
 
c1c3381
 
 
 
 
 
0860b52
 
 
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
# Wrdler - Project Context

## Project Overview
Wrdler is a simplified vocabulary puzzle game based on BattleWords, with these key differences:
- **8x6 grid** (instead of 12x12)
- **One word per row, horizontal only** (no vertical words)
- **No scope/radar visualization**
- **2 free letter guesses at game start** (all instances of chosen letters are revealed)

**Current Version:** 0.1.2
**Repository:** https://github.com/Oncorporation/Wrdler.git
**Live Demo:** [DEPLOYMENT_URL_HERE]

## Recent Changes

**v0.1.2 (Current):**
- βœ… **Gradio UI Topic Display** - Prominent neon-styled badge at top of game area
  - Glassmorphism background with glowing cyan border
  - Pulsing neon animation effect
  - Editable - type new topic and press Enter to generate/switch word lists
  - Auto-matches existing wordlist files or uses input as AI topic
- βœ… **Settings Persistence** - Enable Free Letters and Show Challenge Links persist across new games
- βœ… **Timer Implementation** - Real-time game timer using gr.Timer component
  - Timer resets properly on New Game
  - Stops when game is over
- βœ… **AI Topic Generation UI** - Added to Settings tab with Generate button
- βœ… **Streamlit Cache Fix** - Conditional caching to avoid warnings in Gradio mode
- βœ… **Enhanced CSS Styling** - Improved grid container, topic display, and responsive design

**v0.1.1 (Previous):**
- βœ… Enhanced AI word generation logic with intelligent word saving
- βœ… Automatic retry mechanism for insufficient word counts (up to 3 retries)
- βœ… 1000-word file size limit to prevent dictionary bloat
- βœ… Better new word detection (separates existing vs. new words before saving)
- βœ… Improved HF Space API integration with graceful fallback to local models
- βœ… Additional word generation when initial pass doesn't meet MIN_REQUIRED threshold
- βœ… Enhanced logging for word generation pipeline visibility
- βœ… **Gradio UI implementation** (gradio 5.50) as alternative to Streamlit
- βœ… Custom CSS styling for Gradio interface (style_wrdler.css)
- βœ… Dual UI framework support - choose between Streamlit or Gradio

**v0.1.0 (Previous):**
- βœ… Version updated to 0.1.0 across all files
- βœ… AI word generation functionality added
- βœ… Word list management enhanced with AI support
- βœ… Utility modules integrated
- βœ… Documentation synchronized across all files
- βœ… Project structure validated and consistent
- βœ… All Phase 1 requirements complete (7 sprints)
- βœ… 100% test coverage (25/25 tests passing)
- **Status: Ready for deployment!** πŸš€

**v0.0.2-0.0.3 (Previous):**
- βœ… All 7 sprints complete (12.75 hours development time)
- βœ… Core data models updated for rectangular 8Γ—6 grid
- βœ… Generator refactored for horizontal-only, one-per-row placement
- βœ… Radar/scope visualization removed (~217 lines)
- βœ… Free letter selection UI with circular green gradient buttons
- βœ… Grid UI updated for 8Γ—6 display with responsive layout
- βœ… Comprehensive integration testing suite
- βœ… Complete documentation (GAMEPLAY_GUIDE.md)
- βœ… Fixed duplicate rendering call bug
- βœ… PWA support with service worker and manifest

## Core Gameplay
- 8x6 grid with 6 hidden words (one per row, horizontal only)
- **Word composition:** 2 four-letter words, 2 five-letter words, 2 six-letter words
- No scope/radar visualization
- Players start by choosing 2 letters; all instances are revealed
- Players click cells to reveal letters or empty spaces
- After revealing a letter, players can guess words
- Scoring: word length + bonus for unrevealed letters
- Game ends when all words are guessed or all word letters are revealed
- Incorrect guess history with optional display (enabled by default)
- 10 incorrect guess limit per game
- **βœ… IMPLEMENTED:** Challenge Mode with game sharing via short URLs
- **βœ… IMPLEMENTED:** Remote storage via Hugging Face datasets
- **βœ… IMPLEMENTED:** PWA install support (v0.2.28+)
- **PLANNED:** Local persistent storage for game results and high scores (v0.3.0)

### Scoring Tiers
- **Fantastic:** 42+ points
- **Great:** 38-41 points
- **Good:** 34-37 points
- **Keep practicing:** < 34 points

## Technical Architecture

### Technology Stack
- **Framework:** Streamlit 1.51.0 (primary), Gradio 5.50 (alternative)
- **Language:** Python 3.12.8 (requires >=3.12, <3.13)
- **Visualization:** Matplotlib (>=3.8)
- **HTTP Requests:** requests (>=2.31.0)
- **Remote Storage:** huggingface_hub (>=0.20.0)
- **Environment:** python-dotenv (>=1.0.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.1.2
β”‚   β”œβ”€β”€ 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
β”‚   β”œβ”€β”€ gradio_ui.py         # Gradio UI (alternative interface)
β”‚   β”œβ”€β”€ word_loader.py       # Word list management
β”‚   β”œβ”€β”€ word_loader_ai.py    # AI word generation with HF Space API
β”‚   β”œβ”€β”€ audio.py             # Background music system
β”‚   β”œβ”€β”€ sounds.py            # Sound effects management
β”‚   β”œβ”€β”€ generate_sounds.py   # Sound generation utilities
β”‚   β”œβ”€β”€ game_storage.py      # HF game storage wrapper
β”‚   β”œβ”€β”€ version_info.py      # Version display
β”‚   β”œβ”€β”€ modules/             # Shared utility modules (from OpenBadge)
β”‚   β”‚   β”œβ”€β”€ __init__.py      # Module exports
β”‚   β”‚   β”œβ”€β”€ storage.py       # HuggingFace storage & URL shortener
β”‚   β”‚   β”œβ”€β”€ storage.md       # Storage module documentation
β”‚   β”‚   β”œβ”€β”€ constants.py     # Storage-related constants (trimmed)
β”‚   β”‚   └── file_utils.py    # File utility functions
β”‚   └── words/               # Word list files
β”‚       β”œβ”€β”€ classic.txt      # Default word list
β”‚       β”œβ”€β”€ fourth_grade.txt # Elementary word list
β”‚       └── wordlist.txt     # Full word list
β”œβ”€β”€ style_wrdler.css         # Custom CSS styling for Gradio interface
β”œβ”€β”€ tests/                   # Unit tests
β”‚   └── test_sprint6_integration.py  # Comprehensive integration tests
β”œβ”€β”€ specs/                   # Documentation
β”‚   β”œβ”€β”€ specs.md             # Game specifications
β”‚   β”œβ”€β”€ requirements.md      # Implementation requirements
β”‚   └── wrdler_implementation_plan.md  # Sprint planning summary
β”œβ”€β”€ static/                  # PWA assets
β”‚   β”œβ”€β”€ manifest.json        # PWA manifest
β”‚   β”œβ”€β”€ service-worker.js    # Service worker for offline caching
β”‚   └── icons/               # App icons
β”œβ”€β”€ .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
└── RELEASE_NOTES_v0.1.0.md # Complete release documentation
```

## Key Features

### Game Modes
1. **Classic Mode:** Allows consecutive guessing after correct answers
2. **Too Easy Mode:** Single guess per reveal

### Audio & Visual Effects
- **Background Music:** Toggleable ocean-themed background music with volume control
- **Sound Effects:** Hit/miss/correct/incorrect guess sounds with volume control
- **Ocean Theme:** Gradient animated background with wave effects
- **Incorrect Guess History:** Visual display of wrong guesses (toggleable in settings)

### βœ… Challenge Mode & Remote Storage (v0.2.20+)
- **Game ID System:** Short URL-based challenge sharing
  - Format: `?game_id=<sid>` in URL (shortened URL reference)
  - Each player gets different random words from the same wordlist
  - Enables fair challenges between players
  - Stored in Hugging Face dataset repository
- **Remote Storage via HuggingFace Hub:**
  - Per-game settings JSON in `games/{uid}/settings.json`
  - Shortened URL mapping in `shortener.json`
  - Multi-user leaderboards with score, time, and difficulty tracking
  - Results sorted by: highest score β†’ fastest time β†’ highest difficulty
- **Challenge Features:**
  - Submit results to existing challenges
  - Create new challenges from any completed game
  - Top 5 leaderboard display in Challenge Mode banner
  - Optional player names (defaults to "Anonymous")
  - Word list difficulty calculation and display (v0.2.29)
  - "Show Challenge Share Links" toggle (default OFF) to control URL visibility (v0.2.27)

### βœ… Progressive Web App (PWA) Support (v0.2.28+)
- **PWA Installation:** App is installable as a Progressive Web App on desktop and mobile
  - Service worker for basic offline caching of static assets
  - Manifest.json with app metadata and icons
  - Platform-specific installation instructions in INSTALL_GUIDE.md
  - No gameplay logic changes required
  - Works offline for basic functionality

### βœ… AI Word Generation (v0.1.0+)
- **AI-Powered Word Lists:** Generate custom word lists using Hugging Face Spaces or local transformers
- **Topic-Based Generation:** Create words related to specific themes (e.g., "Ocean Life", "Space")
- **Automatic Word Expansion:** New AI-generated words are saved to local files for future use
  - Intelligent word detection: separates existing dictionary words from new AI-generated words
  - Only new words are saved to prevent duplicates
  - Automatic retry mechanism (up to 3 attempts) if insufficient words generated
  - 1000-word file size limit prevents dictionary bloat
  - Files auto-sorted by length then alphabetically
- **Fallback Support:** Gracefully falls back to dictionary words if AI is unavailable
- **Word Distribution:** Ensures exactly 25 words each of lengths 4, 5, and 6 per topic
- **Dual Generation Modes:**
  - **HF Space API** (primary): Uses Hugging Face Space for word generation when `USE_HF_WORDS=true`
  - **Local Models** (fallback): Falls back to local transformers models if HF Space unavailable
- **Enhanced Logging:** Detailed pipeline visibility for debugging and monitoring

### PLANNED: Local Player Storage (v0.3.0)
- **Local Storage:**
  - Location: `~/.wrdler/data/`
  - Files: `game_results.json`, `highscores.json`
  - Privacy-first: no cloud dependency, offline-capable
- **Personal High Scores:**
  - Top 100 scores tracked automatically on local machine
  - Filterable by wordlist and game mode
  - High score sidebar expander display
- **Player Statistics:**
  - Games played, average score, best score
  - Fastest completion time
  - Per-player history on local device

### Puzzle Generation
- Horizontal-only word placement (one per row in 8Γ—6 grid)
- **Word length distribution:** Each puzzle contains exactly 2 four-letter words, 2 five-letter words, and 2 six-letter words
- Deterministic seeding support for reproducible puzzles
- No word spacing configuration (fixed one word per row)
- Validation ensures no overlaps, proper bounds, correct word distribution

### UI Components (v0.0.2 - Implemented)
- **Game Grid:** Interactive 8Γ—6 button grid (48 cells) with responsive layout
- **Free Letter Selection:** Circular green gradient buttons (2 at game start)
- **Score Panel:** Real-time scoring with client-side JavaScript timer
- **Settings Sidebar:**
  - Word list picker (classic, fourth_grade, wordlist, AI Generated)
  - Game mode selector (Classic, Too Easy)
  - Audio volume controls (music and effects separate)
  - Toggle for incorrect guess history display
  - Player name input
  - "Show Challenge Share Links" toggle (default OFF)
  - Enable/disable sound effects checkbox
  - Enable/disable background music checkbox
- **Theme System:** Ocean gradient background with CSS animations
- **Game Over Dialog:** Final score display with tier ranking
- **Incorrect Guess Display:** Shows history of wrong guesses with count
- **Challenge Mode UI:**
  - Challenge Mode banner with leaderboard (top 5 players)
  - Share challenge button in game over dialog
  - Submit result or create new challenge options
  - Word list difficulty display
- **PLANNED (v0.3.0):** Local high scores expander and personal statistics display

### Development Status

**Current Version:** 0.1.2 (Complete)
- βœ… All 7 sprints complete
- βœ… 100% test coverage (25/25 tests)
- βœ… AI word generation implemented
- βœ… Ready for production deployment
- βœ… PWA support implemented
- βœ… Challenge Mode fully functional
- πŸ“Š Development time: ~12.75 hours (sprints 1-7)
- πŸ“š Complete documentation

**Next Version:** v0.3.0 (Planned)
- πŸ“‹ Local storage module (`wrdler/local_storage.py`)
- πŸ“‹ Personal high score tracking (local JSON files)
- πŸ“‹ High score sidebar UI display
- πŸ“‹ Player statistics tracking and display

## 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]
    radar: List[Coord]
    may_overlap: bool
    spacer: int
    uid: str  # Unique identifier for caching

@dataclass
class GameState:
    grid_size: int
    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]
```

## Development Workflow

### Running Locally
```bash
# Install dependencies
uv pip install -r requirements.txt --link-mode=copy

# Run Streamlit app (default)
uv run streamlit run app.py
# or
streamlit run app.py

# Run Gradio app (alternative)
python -m wrdler.gradio_ui
```

### Docker Deployment
```bash
docker build -t wrdler .
docker run -p 8501:8501 wrdler
```

### Testing
```bash
pytest tests/
```

### Environment Variables (for Challenge Mode)
Challenge Mode requires HuggingFace Hub access for remote storage. Create a `.env` file in the project root:

```bash
# Required for Challenge Mode
HF_API_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxx  # or HF_TOKEN
HF_REPO_ID=YourUsername/YourRepo       # Target HF dataset repo
SPACE_NAME=YourUsername/Wrdler         # Your HF Space name

# Optional
CRYPTO_PK=                             # Reserved for future signing
```

**How to get your HF_API_TOKEN:**
1. Go to https://huggingface.co/settings/tokens
2. Create a new token with `write` access
3. Add to `.env` file as `HF_API_TOKEN=hf_...`

**HF_REPO_ID Structure:**
The dataset repository will contain:
- `shortener.json` - Short URL mappings
- `games/{uid}/settings.json` - Per-game challenge data
- `games/{uid}/result.json` - Optional detailed results

**Note:** The app will work without these variables but Challenge Mode features (sharing, leaderboards) will be disabled.

## Git Configuration & Deployment
**Current Branch:** main
**Purpose:** Wrdler - vocabulary puzzle game with simplified 8x6 grid
**Main Branch:** main

### Remotes
- **ONCORP (origin):** https://github.com/Oncorporation/Wrdler.git (main repository)
- **Hugging Face Spaces:** https://huggingface.co/spaces/[USERNAME]/Wrdler (live deployment)

### Deployment Platforms
1. **Hugging Face Spaces** (Primary) - Dockerfile deployment
2. **Local Development** - Streamlit run
3. **Docker** - Containerized deployment
4. **PWA** - Installable web app on any platform

## Sprint Summary (v0.0.2 - Complete)

| Sprint | Description | Time | Tests | Status |
|--------|-------------|------|-------|--------|
| Sprint 1 | Core Data Models | 3h | 13/13 βœ… | Complete |
| Sprint 2 | Puzzle Generator | 3h | 5/5 βœ… | Complete |
| Sprint 3 | Remove Radar | 0.5h | N/A | Complete |
| Sprint 4 | Free Letters UI | 2h | Manual βœ… | Complete |
| Sprint 5 | Grid UI Updates | 1.25h | Syntax βœ… | Complete |
| Sprint 6 | Integration Testing | 2h | 7/7 βœ… | Complete |
| Sprint 7 | Documentation | 1h | N/A | Complete |
| **Total** | **All Features** | **12.75h** | **25/25** | **Complete βœ…** |

**Status:** Ready for deployment! πŸš€

## Post-v0.0.2 Enhancements

### v0.1.2 (Gradio UI Enhancements)
- Gradio UI Topic Display with neon styling and animations
- Settings persistence across new games
- Real-time timer implementation with gr.Timer
- AI Topic Generation UI in Settings tab
- Streamlit cache fix for Gradio compatibility
- Enhanced CSS styling throughout

### v0.1.1 (AI Word Generation Enhancement)
- Enhanced AI word generation with intelligent word saving
- Automatic retry mechanism for insufficient word counts (up to 3 retries)
- 1000-word file size limit to prevent dictionary bloat
- Improved new word detection (separates existing vs. new words)
- Better HF Space API integration with fallback to local models
- Additional word generation when MIN_REQUIRED threshold not met
- Enhanced logging for generation pipeline visibility
- **Gradio UI implementation** (gradio 5.50) as alternative interface
- Custom CSS styling for Gradio (style_wrdler.css)
- Dual UI framework support (Streamlit + Gradio)

### v0.1.0 (AI Word Generation)
- AI-powered word list generation using Hugging Face Spaces
- Topic-based word creation with automatic saving
- Enhanced word list management with AI fallback
- Utility modules integration for storage and file handling

### v0.2.20-0.2.29 (Challenge Mode & PWA)
- Remote storage and game sharing via HF datasets
- Multi-user leaderboards
- PWA support with offline caching
- Word list difficulty calculation
- Privacy controls for challenge sharing
- Sound effect and music system improvements

## Future Roadmap

### v0.3.0 (Next Phase)
- Local persistent storage module (`~/.wrdler/data/`)
- High score tracking and display
- Player statistics tracking
- Enhanced UI animations

### v1.0.0 (Long Term)
- Multiple difficulty levels
- Daily puzzle mode
- Internationalization (i18n)
- Performance optimizations
- Advanced word list management

## Deployment Targets
- **Hugging Face Spaces:** Primary deployment platform (Dockerfile-based)
- **Docker:** Containerized deployment for any platform
- **Local:** Development and testing
- **PWA:** Installable on desktop and mobile devices

### Privacy & Data (v0.1.0)
- **Challenge Mode:** Optional remote storage via Hugging Face datasets
  - Player names optional (defaults to "Anonymous")
  - Only stores: word lists, scores, times, game modes
  - No PII beyond optional player name
  - User controls URL visibility via "Show Challenge Share Links" toggle
- **Local Storage (v0.3.0 - Planned):**
  - Location: `~/.wrdler/data/`
  - Privacy-first, offline-capable
  - Easy to delete
  - No cloud dependency

## Notes for Claude

### Technical Implementation
- βœ… Project uses modern Python features (3.12.8)
- βœ… Requires Python >=3.12, <3.13 per pyproject.toml
- βœ… Heavy use of Streamlit session state for game state management
- βœ… Gradio 5.50 state management using gr.State for game persistence
- βœ… Client-side JavaScript for timer updates without page refresh
- βœ… CSS heavily customized for ocean theme aesthetics
- βœ… All file paths should be absolute when working in WSL environment
- βœ… Game IDs are deterministic for consistent sharing
- βœ… 8Γ—6 rectangular grid (grid_rows=6, grid_cols=8)
- βœ… Horizontal-only word placement (one per row)
- βœ… Radar/scope visualization removed entirely
- βœ… Free letter selection UI implemented with circular buttons
- βœ… PWA injection via Docker build script (`inject-pwa-head.sh`)
- βœ… AI word generation via `word_loader_ai.py` with Hugging Face integration
- βœ… Utility modules provide reusable functions for storage and file ops
- βœ… **Gradio 5.50 compatibility:** Using modern gr.Button, gr.State, and event handlers
  - Reference: [Gradio 6 Migration Guide](https://www.gradio.app/guides/gradio-6-migration-guide)
  - Uses `gr.update()` for component updates
  - Event handlers use `.click()`, `.change()`, `.submit()` methods
  - State management via `gr.State(value=...)` with deep copy for updates

### Key Implementation Details
- **No radar field in Puzzle dataclass** - removed in Sprint 3
- **No vertical word placement** - horizontal only ("H" direction)
- **Fixed grid dimensions** - always 8x6 (grid_cols=8, grid_rows=6)
- **One word per row** - exactly 6 words total
- **Word length requirement** - exactly 2 four-letter words, 2 five-letter words, and 2 six-letter words per puzzle
- **Free letters tracked** - `free_letters` set and `free_letters_used` counter
- **Auto-completion** - words auto-marked when all letters revealed
- **Incorrect guess limit** - maximum 10 per game
- **AI word generation** - generates 75 words per topic, saves to local files
- **Utility modules** - shared functions from OpenBadge project
- **Gradio 5.50 UI implementation**:
  - Modern component API with `gr.Button`, `gr.Textbox`, `gr.HTML`, etc.
  - State updates use `copy.deepcopy()` to trigger Gradio reactivity
  - Event handlers return tuples matching output component order
  - Custom CSS via `style_wrdler.css` file
  - Modal dialogs using `gr.Modal(visible=False)` pattern
  - Reference: [Gradio 6 Migration Guide](https://www.gradio.app/guides/gradio-6-migration-guide)

### WSL Environment Python Versions
The development environment is WSL (Windows Subsystem for Linux) with access to both native Linux and Windows Python installations:

**Native WSL (Linux):**
- `python3` β†’ Python 3.10.12 (`/usr/bin/python3`)
- `python3.10` β†’ Python 3.10.12

**Windows Python (accessible via WSL):**
- `python311.exe` β†’ Python 3.11.9 (`/mnt/c/Users/cfettinger/AppData/Local/Programs/Python/Python311/`)
- `python3.13.exe` β†’ Python 3.13.1 (`/mnt/c/ProgramData/chocolatey/bin/`)

**Note:** Windows Python executables (`.exe`) can be invoked directly from WSL and are useful for testing compatibility across Python versions. The project targets Python 3.12.8 specifically but requires >=3.12, <3.13 per pyproject.toml.

## Documentation Structure

This file (CLAUDE.md) serves as a **living context document** for AI-assisted development:

- **[specs/specs.md](specs/specs.md)** - Game rules, requirements, and feature specifications
- **[specs/requirements.md](specs/requirements.md)** - Implementation requirements and acceptance criteria
- **[GAMEPLAY_GUIDE.md](GAMEPLAY_GUIDE.md)** - User guide with tips and strategies
- **[INSTALL_GUIDE.md](INSTALL_GUIDE.md)** - PWA installation instructions
- **[README.md](README.md)** - User-facing documentation, installation guide, and complete changelog
- **[Dockerfile](Dockerfile)** - Container deployment configuration with PWA injection
- **[pyproject.toml](pyproject.toml)** - Python project metadata and dependencies
- **[Gradio 6 Migration Guide](https://www.gradio.app/guides/gradio-6-migration-guide)** - Official Gradio migration reference (external)

**When to use each:**
- **specs.md** - Understanding game rules and scoring system
- **requirements.md** - Implementation status and acceptance criteria
- **CLAUDE.md** - Quick reference for codebase and development context
- **GAMEPLAY_GUIDE.md** - How to play the game
- **README.md** - Public-facing info, setup instructions, and complete changelog
- **INSTALL_GUIDE.md** - Installing Wrdler as a PWA
- **Dockerfile** - Deployment configuration and container setup
- **Gradio Migration Guide** - Gradio 5.x/6.x compatibility and best practices

## Challenge Mode & Remote Storage

- βœ… Challenge Mode allows sharing games via short links (`?game_id=<sid>`)
- βœ… Results stored in Hugging Face dataset repos via `game_storage.py`
- βœ… Leaderboard sorted by: highest score β†’ fastest time β†’ highest difficulty
- βœ… Multi-user challenges with top 5 display
- βœ… Optional sharing (controlled by "Show Challenge Share Links" toggle, default OFF)
- βœ… Word list difficulty calculation (v0.2.29)
- βœ… iframe embedding support with `&iframe_host=` parameter (v0.2.23)

## Known Issues

### Active
- ❓ Word list loading bug: the app may not select the proper word lists in some environments. Investigate `word_loader.get_wordlist_files()` / `load_word_list()` and sidebar selection persistence to ensure the chosen file is correctly used by the generator.

### Resolved
- βœ… Duplicate rendering call bug (fixed in v0.0.2)
- βœ… Music looping on congratulations screen (fixed in v0.2.12)
- βœ… Sound effect and music volume wiring (fixed in v0.2.18, v0.2.19)
- βœ… Sonar grid alignment (removed in Sprint 3)
- βœ… Challenge mode link issues (fixed in v0.2.22)

## Dependencies

From `requirements.txt`:
- streamlit>=1.51.0 (primary framework)
- gradio>=5.50 (alternative UI framework)
- matplotlib>=3.8 (visualization)
- requests>=2.31.0 (HTTP requests)
- huggingface_hub>=0.20.0 (remote storage)
- python-dotenv>=1.0.0 (environment variables)
- transformers (AI word generation)
- gradio_client (HF Space API)

From `pyproject.toml`:
- Python >=3.12, <3.13 (strict version requirement)

## Version History Summary

- **v0.1.2** (Current) - Gradio UI Topic Display, settings persistence, timer, enhanced CSS
- **v0.1.1** (Previous) - Enhanced AI word generation with intelligent saving, retry logic, file size limits
- **v0.1.0** (Previous) - AI word generation, utility modules, version bump
- **v0.0.4** - Documentation sync, version update
- **v0.0.2-0.0.3** - All 7 sprints complete, core Wrdler features
- **v0.2.20-0.2.29** - Challenge Mode, PWA, remote storage (inherited from BattleWords)
- **v0.1.x** - Initial BattleWords releases before Wrdler fork

---

**Last Updated:** 2025-11-29
**Current Version:** 0.1.2
**Status:** Production Ready - Gradio UI Enhanced βœ