BattleWords / specs /specs.md
Surn's picture
0.2.28
2de3d96
# Battlewords Game Requirements (specs.md)
## Overview
Battlewords is inspired by the classic Battleship game, but uses words instead of ships. The objective is to discover hidden words on a grid, earning points for strategic guessing before all letters are revealed.
## Game Board
- 12 x 12 grid.
- Six hidden words:
- Two four-letter words
- Two five-letter words
- Two six-letter words
- Words are placed horizontally (left-right) or vertically (top-down), not diagonally.
- Words may touch edges or corners but do not overlap unless a future mode allows shared letters.
- Entry point is `app.py`.
- **Supports Dockerfile-based deployment for Hugging Face Spaces and other container platforms.**
## Gameplay (Common)
- 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.
- Use radar pulses to locate word boundaries (first and last letters).
- 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:
- Good: 34-37
- Great: 38-41
- Fantastic: 42+
- **Game over is triggered by either all words being guessed or all word letters being revealed.**
## POC (0.1.0) Rules
- No overlaps: words do not overlap or share letters.
- UI: basic grid, radar, and guess form.
- No keyboard interaction requirement.
- Seed is optional and not standardized.
## Beta (0.5.0) Additions
- Optional validation pass to avoid unintended adjacent partial words (content curation rule).
- Cell rendering with consistent sizing and responsive layout (desktop/mobile).
- Keyboard support for navigation and guessing (custom JS via `st.html` or a component).
- Deterministic seed support to reproduce puzzles (e.g., daily seed derived from date).
## Full (1.0.0) Rules
- No overlaps: words do not overlap or share letters.
- Enhanced UX polish (animations, accessibility, themes).
- Persistence, leaderboards, and additional modes as specified in requirements.
- Deterministic daily mode and practice mode supported.
## New Features (v0.3.0)
- **Game ID Sharing:** Each puzzle generates a deterministic game ID based on the word list. Players can share URLs with `?game_id=ABC123` to challenge others with the same words.
- **Persistent Storage:** Game results and high scores are saved locally in `~/.battlewords/data/`.
- **High Scores:** Top scores are tracked and displayed in the sidebar, filterable by wordlist and game mode.
- **Player Name:** Optional player name is saved with results.
## New Features (v0.2.28)
- **PWA Support:** App is installable as a Progressive Web App on desktop and mobile.
- Added `service worker` and `manifest.json`.
- Basic offline caching of static assets.
- INSTALL_GUIDE.md added with platform-specific install steps.
- No gameplay logic changes.
## New Features (v0.2.24)
- **UI Improvements:** More compact layout, improved tooltip for incorrect guesses, and updated final score screen.
- **Word Difficulty:** Added a word difficulty formula and display for each game/challenge, visible in the final score and leaderboard.
- **Challenge Mode:** Enhanced leaderboard with difficulty display, improved result submission, and clearer challenge sharing.
- **Documentation:** Updated to reflect new features and UI changes.
## Storage
- Game results and high scores are stored in JSON files for privacy and offline access.
- Game ID is generated from the sorted word list for replay/sharing.
## UI Elements
- 12x12 grid
- Radar screen (shows last letter locations); y-axis inverted so (0,0) is top-left
- Text box for word guesses
- Score display (shows word, base points, bonus points, total score)
- Guess status indicator (Correct/Try Again)
- Game ID display and share button in game over dialog.
- High score expander in sidebar.
- Player name input in sidebar.
- Checkbox: "Show Challenge Share Links" (v0.2.27, 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"
## New Features (v0.2.27)
- Added "Show Challenge Share Links" visibility toggle for Challenge Mode sharing UI
- Purely a UI change; gameplay logic and storage behavior unchanged
## Word List
- External list at `battlewords/words/wordlist.txt`.
- Loaded by `battlewords.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.
## Entry Point
- The Streamlit entry point is `app.py`.
- **A `Dockerfile` can 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:**
```bash
HF_API_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxx # or HF_TOKEN (write access required)
HF_REPO_ID=YourUsername/YourRepo # Target HF dataset repository
SPACE_NAME=YourUsername/BattleWords # Your HF Space name for URL generation
```
**Optional Environment Variables:**
```bash
CRYPTO_PK= # Reserved for future challenge signing
```
**Setup Steps:**
1. Create a HuggingFace account at https://huggingface.co
2. Create a dataset repository (e.g., `YourUsername/BattleWordsStorage`)
3. Generate an access token with `write` permissions:
- Go to https://huggingface.co/settings/tokens
- Click "New token"
- Select "Write" access
- Copy the token (starts with `hf_`)
4. Create a `.env` file in project root with the variables above
5. 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/
└── {uid}/
└── settings.json # Challenge data with users array
```
**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
## Copyright
BattlewordsTM. All Rights Reserved. All content, trademarks and logos are copyrighted by the owner.
## v0.2.20: Remote Storage and Shortened game_id URL
Game Sharing
- Each puzzle can be shared via a link containing a `game_id` querystring (short id / sid)
- `game_id` resolves to a settings JSON on the storage server (HF repo)
- JSON fields:
- word_list (list of 6 uppercase words)
- score (int), time (int seconds) [metadata only]
- game_mode (e.g., classic, too easy)
- grid_size (e.g., 12)
- puzzle_options (e.g., { spacer, may_overlap })
- On load with `game_id`, fetch and apply: word_list, game_mode, grid_size, puzzle_options
High Scores
- Repository maintains `highscores/highscores.json` for top scores
- Local highscores remain supported for offline use
UI/UX
- Show the current `game_id` (sid) and a �Share Challenge� link
- When loading with a `game_id`, indicate the puzzle is a shared challenge
Security/Privacy
- Only game configuration and scores are stored; no personal data is required
- `game_id` is a short reference; full URL is stored in a repo JSON shortener index
## Challenge Mode & Leaderboard
- When loading a shared challenge via `game_id`, the leaderboard displays all user results for that challenge.
- **Sorting:** The leaderboard is sorted by highest score (descending), then by fastest time (ascending).
- **Difficulty:** Each result now displays a computed word list difficulty value.
- Results are stored remotely in a Hugging Face dataset repo and updated via the app.