wrdler / CLAUDE.md
Surn's picture
fix word distribution
5f8a848

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.0.4 Repository: https://github.com/Oncorporation/Wrdler.git Live Demo: [DEPLOYMENT_URL_HERE]

Recent Changes

v0.0.4 (Current):

  • βœ… Version updated in __init__.py to 0.0.4
  • βœ… 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
  • 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)
  • Testing: Pytest
  • Package Manager: UV or pip

Project Structure

wrdler/
β”œβ”€β”€ app.py                    # Streamlit entry point
β”œβ”€β”€ wrdler/                   # Main package
β”‚   β”œβ”€β”€ __init__.py          # Version: 0.0.4
β”‚   β”œβ”€β”€ 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
β”‚   β”œβ”€β”€ word_loader.py       # Word list management
β”‚   β”œβ”€β”€ 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
β”œβ”€β”€ 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.0.4.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

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)
    • 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: v0.0.4 (Complete)

  • βœ… All 7 sprints complete
  • βœ… 100% test coverage (25/25 tests)
  • βœ… 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

@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

# Install dependencies
uv pip install -r requirements.txt --link-mode=copy

# Run app
uv run streamlit run app.py
# or
streamlit run app.py

Docker Deployment

docker build -t wrdler .
docker run -p 8501:8501 wrdler

Testing

pytest tests/

Environment Variables (for Challenge Mode)

Challenge Mode requires HuggingFace Hub access for remote storage. Create a .env file in the project root:

# 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

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.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.0.4)

  • 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
  • βœ… 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)

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

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:

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

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)
  • matplotlib>=3.8 (visualization)
  • requests>=2.31.0 (HTTP requests)
  • huggingface_hub>=0.20.0 (remote storage)
  • python-dotenv>=1.0.0 (environment variables)

From pyproject.toml:

  • Python >=3.12, <3.13 (strict version requirement)

Version History Summary

  • v0.0.4 (Current) - 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

See README.md for complete changelog.


Last Updated: 2025-01-31 Current Version: 0.0.4 Status: Production Ready - All Features Complete βœ…

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.