|
|
--- |
|
|
title: Wrdler |
|
|
emoji: π§© |
|
|
colorFrom: blue |
|
|
colorTo: indigo |
|
|
sdk: streamlit |
|
|
sdk_version: 1.51.0 |
|
|
python_version: 3.12.8 |
|
|
app_port: 8501 |
|
|
app_file: app.py |
|
|
tags: |
|
|
- game |
|
|
- vocabulary |
|
|
- streamlit |
|
|
- education |
|
|
short_description: Fast paced word guessing game |
|
|
thumbnail: >- |
|
|
https://cdn-uploads.huggingface.co/production/uploads/6346595c9e5f0fe83fc60444/6rWS4AIaozoNMCbx9F5Rv.png |
|
|
--- |
|
|
|
|
|
# Wrdler |
|
|
|
|
|
> **This project is based on BattleWords, but adapted for a simpler word puzzle game with an 8x6 grid, horizontal words only, and free letter guesses at the start.** |
|
|
|
|
|
Wrdler is a vocabulary learning game with a simplified grid and strategic letter guessing. The objective is to discover hidden words on a grid by making smart guesses before all letters are revealed. |
|
|
|
|
|
## Key Differences from BattleWords |
|
|
|
|
|
- **8x6 grid** (instead of 12x12) with **6 words total** (one per row) |
|
|
- **Horizontal words only** (no vertical placement) |
|
|
- **No scope/radar visualization** |
|
|
- **2 free letter guesses** at the start - choose letters to reveal all instances in the grid |
|
|
|
|
|
## Features |
|
|
|
|
|
### Core Gameplay |
|
|
- 8x6 grid with six hidden words (one per row, all horizontal) |
|
|
- **Word composition:** Each puzzle contains exactly 2 four-letter words, 2 five-letter words, and 2 six-letter words |
|
|
- Game starts with 2 free letter guesses; all instances of chosen letters are revealed |
|
|
- Reveal grid cells and guess words for points |
|
|
- Scoring tiers: Good (34β37), Great (38β41), Fantastic (42+) |
|
|
- Game ends when all words are guessed or all word letters are revealed |
|
|
- Incorrect guess history with tooltip and optional display (enabled by default) |
|
|
- 10 incorrect guess limit per game |
|
|
- Two game modes: Classic (chain guesses) and Too Easy (single guess per reveal) |
|
|
|
|
|
### Audio & Visuals |
|
|
- Ocean-themed gradient background with wave animations |
|
|
- Background music system (toggleable with volume control) |
|
|
- Sound effects for hits, misses, correct/incorrect guesses |
|
|
- Responsive UI built with Streamlit |
|
|
|
|
|
### Customization |
|
|
- Multiple word lists (classic, fourth_grade, wordlist) |
|
|
- Wordlist sidebar controls (picker + one-click sort) |
|
|
- Audio volume controls (music and effects separate) |
|
|
|
|
|
### β
Challenge Mode |
|
|
- **Shareable challenge links** via short URLs (`?game_id=<sid>`) |
|
|
- **Multi-user leaderboards** sorted by score and time |
|
|
- **Remote storage** via Hugging Face datasets |
|
|
- **Word list difficulty calculation** and display |
|
|
- **Submit results** to existing challenges or create new ones |
|
|
- **Top 5 leaderboard** display in Challenge Mode banner |
|
|
- **"Show Challenge Share Links" toggle** (default OFF) to control URL visibility |
|
|
- Each player gets different random words from the same wordlist |
|
|
|
|
|
### Deployment & Technical |
|
|
- **Dockerfile-based deployment** supported for Hugging Face Spaces and other container platforms |
|
|
- **Environment variables** for Challenge Mode (HF_API_TOKEN, HF_REPO_ID, SPACE_NAME) |
|
|
- Works offline without HF credentials (Challenge Mode features disabled gracefully) |
|
|
|
|
|
### Progressive Web App (PWA) |
|
|
- Installable on desktop and mobile from your browser |
|
|
- Includes `service worker` and `manifest.json` with basic offline caching of static assets |
|
|
- See `INSTALL_GUIDE.md` for platform-specific steps |
|
|
|
|
|
### Planned |
|
|
- Local persistent storage for personal game history |
|
|
- Personal high scores sidebar (offline-capable) |
|
|
- Player statistics tracking |
|
|
- Deterministic seed UI for custom puzzles |
|
|
|
|
|
## Challenge Mode & Leaderboard |
|
|
|
|
|
When playing a shared challenge (via a `game_id` link), the leaderboard displays all submitted results for that challenge. The leaderboard is **sorted by highest score (descending), then by fastest time (ascending)**. This means players with the most points appear at the top, and ties are broken by the shortest completion time. |
|
|
|
|
|
## Installation |
|
|
1. Clone the repository: |
|
|
``` |
|
|
git clone https://github.com/Oncorporation/Wrdler.git |
|
|
cd wrdler |
|
|
``` |
|
|
2. (Optional) Create and activate a virtual environment: |
|
|
``` |
|
|
python -m venv venv |
|
|
source venv/bin/activate # On Windows use `venv\Scripts\activate` |
|
|
``` |
|
|
3. Install dependencies: ( add --system if not using a virutal environment) |
|
|
``` |
|
|
uv pip install -r requirements.txt --link-mode=copy |
|
|
``` |
|
|
|
|
|
|
|
|
## Running Wrdler |
|
|
|
|
|
You can run the app locally using either [uv](https://github.com/astral-sh/uv) or Streamlit directly: |
|
|
|
|
|
``` |
|
|
uv run streamlit run app.py |
|
|
``` |
|
|
|
|
|
or |
|
|
``` |
|
|
streamlit run app.py |
|
|
``` |
|
|
|
|
|
### Dockerfile Deployment (Hugging Face Spaces and more) |
|
|
|
|
|
Wrdler supports containerized deployment using a `Dockerfile`. This is the recommended method for deploying to [Hugging Face Spaces](https://huggingface.co/docs/hub/spaces-sdks-docker) or any Docker-compatible environment. |
|
|
|
|
|
To deploy on Hugging Face Spaces: |
|
|
1. Add a `Dockerfile` to your repository root (see [Spaces Dockerfile guide](https://huggingface.co/docs/hub/spaces-sdks-docker)). |
|
|
2. Push your code to your Hugging Face Space. |
|
|
3. The platform will build and run your app automatically. |
|
|
|
|
|
For local Docker runs: |
|
|
```sh |
|
|
docker build -t wrdler . |
|
|
docker run -p8501:8501 wrdler |
|
|
``` |
|
|
|
|
|
### Environment Variables (for Challenge Mode) |
|
|
|
|
|
Challenge Mode requires a `.env` file in the project root with HuggingFace Hub credentials: |
|
|
|
|
|
```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_...` |
|
|
|
|
|
**Note:** The app works without these variables, but Challenge Mode features (sharing, leaderboards) will be disabled. |
|
|
|
|
|
## Folder Structure |
|
|
|
|
|
- `app.py` β Streamlit entry point |
|
|
- `wrdler/` β Python package |
|
|
- `models.py` β data models and types |
|
|
- `word_loader.py` β word list loading and validation |
|
|
- `generator.py` β word placement logic (8x6, horizontal only) |
|
|
- `logic.py` β game mechanics (reveal, guess, scoring, free letters) |
|
|
- `ui.py` β Streamlit UI composition |
|
|
- `game_storage.py` β Hugging Face remote storage integration and challenge sharing |
|
|
- `local_storage.py` β local JSON storage for results and high scores |
|
|
- `storage.py` β (legacy) local storage and high scores |
|
|
- `words/wordlist.txt` β candidate words |
|
|
- `specs/` β documentation (`specs.md`, `requirements.md`) |
|
|
- `tests/` β unit tests |
|
|
|
|
|
## 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. |
|
|
|
|
|
## How to Play |
|
|
|
|
|
1. **Start with 2 free letter guesses** - choose two letters to reveal all their instances in the grid. |
|
|
2. Click grid squares to reveal letters or empty spaces. |
|
|
3. After revealing a letter, enter a guess for a word in the text box. |
|
|
4. Earn points for correct guesses and bonus points for unrevealed letters. |
|
|
5. **The game ends when all six words are found or all word letters are revealed. Your score tier is displayed.** |
|
|
6. **To play a shared challenge, use a link with `?game_id=<sid>`. Your result will be added to the challenge leaderboard.** |
|
|
|
|
|
## Changelog |
|
|
|
|
|
### v0.0.8 |
|
|
- remove background animation |
|
|
- add "easy" mode (single guess per reveal) |
|
|
|
|
|
### v0.0.7 |
|
|
- fix guess bug - allowing guesses only after word guessed or letter revealed |
|
|
|
|
|
### v0.0.2 (Current - All Sprints Complete) π |
|
|
- **Sprint 1-3:** Core data models, generator refactor, radar removal |
|
|
- **Sprint 4:** Implemented free letter selection UI with circular green gradient buttons |
|
|
- **Sprint 5:** Updated grid UI rendering for 8Γ6 display |
|
|
- **Sprint 6:** Comprehensive integration testing (7/7 tests passing) |
|
|
- **Sprint 7:** Complete documentation update |
|
|
- Sound effects integration for free letter selection |
|
|
- Mobile-responsive free letter grid |
|
|
- Fixed duplicate rendering call bug |
|
|
- **All core Wrdler features complete and tested** |
|
|
|
|
|
### v0.0.1 (Initial Wrdler Release) |
|
|
- Project renamed from BattleWords to Wrdler |
|
|
- Grid resized from 12x12 to 8x6 |
|
|
- Changed to one word per row (6 total), horizontal only |
|
|
- Removed vertical word placement |
|
|
- Removed scope/radar visualization |
|
|
- Core data models updated for rectangular grid |
|
|
- Generator refactored for horizontal-only placement |
|
|
|
|
|
Note |
|
|
- `battlewords/storage.py` remains local-only storage; a separate HF integration wrapper is provided as `game_storage.py` for remote challenge mode. |
|
|
|
|
|
## Known Issues / TODO |
|
|
|
|
|
- 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. |
|
|
|
|
|
## Development Phases |
|
|
|
|
|
- **Proof of Concept (0.1.0):** No overlaps, basic UI, single session. |
|
|
- **Beta (0.5.0):** Overlaps allowed on shared letters, responsive layout, keyboard support, deterministic seed. |
|
|
- **Full (1.0.0):** Enhanced UX, persistence, leaderboards, daily/practice modes, advanced features. |
|
|
|
|
|
See `specs/requirements.md` and `specs/specs.md` for full details and roadmap. |
|
|
|
|
|
## License |
|
|
|
|
|
Wrdler is based on BattleWords. BattlewordsTM. All Rights Reserved. All content, trademarks and logos are copyrighted by the owner. |
|
|
|
|
|
## Hugging Face Spaces Configuration |
|
|
|
|
|
Wrdler is deployable as a Hugging Face Space. You can use either the YAML config block or a Dockerfile for advanced/custom deployments. |
|
|
|
|
|
To configure your Space with the YAML block, add it at the top of your `README.md`: |
|
|
|
|
|
```yaml |
|
|
--- |
|
|
title: Wrdler |
|
|
emoji: π² |
|
|
colorFrom: blue |
|
|
colorTo: indigo |
|
|
sdk: streamlit |
|
|
sdk_version: 1.51.0 |
|
|
python_version: 3.12.8 |
|
|
app_file: app.py |
|
|
tags: |
|
|
- game |
|
|
- vocabulary |
|
|
- streamlit |
|
|
- education |
|
|
--- |
|
|
``` |
|
|
|
|
|
**Key parameters:** |
|
|
- `title`, `emoji`, `colorFrom`, `colorTo`: Visuals for your Space. |
|
|
- `sdk`: Use `streamlit` for Streamlit apps. |
|
|
- `sdk_version`: Latest supported Streamlit version. |
|
|
- `python_version`: Python version (default is3.10). |
|
|
- `app_file`: Entry point for your app. |
|
|
- `tags`: List of descriptive tags. |
|
|
|
|
|
**Dependencies:** |
|
|
Add a `requirements.txt` with your Python dependencies (e.g., `streamlit`, etc.). |
|
|
|
|
|
**Port:** |
|
|
Streamlit Spaces use port `8501` by default. |
|
|
|
|
|
**Embedding:** |
|
|
Spaces can be embedded in other sites using an `<iframe>`: |
|
|
|
|
|
```html |
|
|
<iframe src="https://[YourUsername]-Wrdler.hf.space?embed=true" title="Wrdler"></iframe> |
|
|
``` |
|
|
|
|
|
For full configuration options, see [Spaces Config Reference](https://huggingface.co/docs/hub/spaces-config-reference) and [Streamlit SDK Guide](https://huggingface.co/docs/hub/spaces-sdks-streamlit). |
|
|
|
|
|
# Assets Setup |
|
|
|
|
|
To fully experience Wrdler, especially the audio elements, ensure you set up the following assets: |
|
|
|
|
|
- Place your background music `.mp3` files in `wrdler/assets/audio/music/` to enable music. |
|
|
- Place your sound effect files (`.mp3` or `.wav`) in `wrdler/assets/audio/effects/` for sound effects. |
|
|
|
|
|
Refer to the documentation for guidance on compatible audio formats and common troubleshooting tips. |
|
|
|
|
|
# Sound Asset Generation |
|
|
|
|
|
To generate and save custom sound effects for Wrdler, you can use the `generate_sound_effect` function. |
|
|
|
|
|
## Function: `generate_sound_effect` |
|
|
|
|
|
```python |
|
|
def generate_sound_effect(effect: str, save_to_assets: bool = False, use_api: str = "huggingface") -> str: |
|
|
""" |
|
|
Generate a sound effect and save it as a file. |
|
|
|
|
|
Parameters: |
|
|
- `effect`: Name of the effect to generate. |
|
|
- `save_to_assets`: If `True`, saves the effect to the assets directory; |
|
|
if `False`, saves to a temporary location. Default is `False`. |
|
|
- `use_api`: API to use for generation. Options are "huggingface" or "replicate". Default is "huggingface". |
|
|
|
|
|
Returns: |
|
|
- File path to the saved sound effect. |
|
|
``` |
|
|
|
|
|
## Parameters |
|
|
|
|
|
- `effect`: The name of the sound effect you want to generate (e.g., "explosion", "powerup"). |
|
|
- `save_to_assets` (optional): Set to `True` to save the generated sound effect to the game's assets directory. If `False`, the effect is saved to a temporary location. Default is `False`. |
|
|
- `use_api` (optional): The API to use for generating the sound. Options are `"huggingface"` or `"replicate"`. Default is `"huggingface"`. |
|
|
|
|
|
## Returns |
|
|
|
|
|
- The function returns the file path to the saved sound effect, whether it's in the assets directory or a temporary location. |
|
|
|
|
|
## Usage Example |
|
|
|
|
|
To generate a sound effect and save it to the assets directory: |
|
|
|
|
|
```python |
|
|
generate_sound_effect("your_effect_name", save_to_assets=True) |
|
|
``` |
|
|
|
|
|
To generate a sound effect and keep it in a temporary location: |
|
|
|
|
|
```python |
|
|
temp_path = generate_sound_effect("your_effect_name", save_to_assets=False) |
|
|
``` |
|
|
|
|
|
## Note |
|
|
|
|
|
Ensure you have the necessary permissions and API access (if required) to use the sound generation service. Generated sounds are subject to the terms of use of the respective API. |
|
|
|
|
|
For any issues or enhancements, please refer to the project documentation or contact the project maintainer. |
|
|
|
|
|
Happy gaming and sound designing! |
|
|
|
|
|
## What's New in v0.2.20-0.2.27: Challenge Mode π― |
|
|
|
|
|
### Remote Challenge Sharing π |
|
|
- Share challenges with friends via short URLs (`?game_id=<sid>`) |
|
|
- Each player gets different random words from the same wordlist |
|
|
- Multi-user leaderboards sorted by score and time |
|
|
- Word list difficulty calculation and display |
|
|
- Compare your performance against others! |
|
|
|
|
|
### Leaderboards π |
|
|
- Top 5 players displayed in Challenge Mode banner |
|
|
- Results sorted by: highest score β fastest time β highest difficulty |
|
|
- Submit results to existing challenges or create new ones |
|
|
- Player names supported (optional, defaults to "Anonymous") |
|
|
|
|
|
### Remote Storage πΎ |
|
|
- Challenge data stored in Hugging Face dataset repositories |
|
|
- Automatic save on game completion (with user consent) |
|
|
- "Show Challenge Share Links" toggle for privacy control (default OFF) |
|
|
- Works offline when HF credentials not configured |
|
|
|
|
|
## What's Planned for v0.3.0 |
|
|
|
|
|
### Local Player History (Coming Soon) |
|
|
- Personal game results saved locally in `~/.wrdler/data/` |
|
|
- Offline-capable high score tracking |
|
|
- Player statistics (games played, averages, bests) |
|
|
- Privacy-first: no cloud dependency for personal data |
|
|
- Easy data management (delete `~/.wrdler/data/` to reset) |
|
|
|
|
|
If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community |
|
|
forums](https://discuss.streamlit.io). |