docs: add game hints system design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
docs/superpowers/specs/2026-03-30-game-hints-design.md
Normal file
71
docs/superpowers/specs/2026-03-30-game-hints-design.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Game Hints System — Design Spec
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Each row of the game grid provides a hint about the main actor to guess. Hints are pre-generated when the grid is created and stored on `GameRow`. Each hint has a type (film, character, award) represented by a distinct icon. Clicking the icon opens a popover showing the hint text.
|
||||||
|
|
||||||
|
## Data Model
|
||||||
|
|
||||||
|
Two new columns on `game_row`:
|
||||||
|
|
||||||
|
| Column | Type | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| `hint_type` | `VARCHAR(20)`, NOT NULL | One of: `film`, `character`, `award` |
|
||||||
|
| `hint_data` | `VARCHAR(255)`, NOT NULL | film → `movie.id`, character → `movie_role.id`, award → text "Nom du prix (année)" |
|
||||||
|
|
||||||
|
No foreign key constraints on `hint_data` — the column stores either an id (resolved at read time) or raw text depending on `hint_type`.
|
||||||
|
|
||||||
|
## Hint Generation
|
||||||
|
|
||||||
|
Happens in `GameGridGenerator::generate()`, for each `GameRow`:
|
||||||
|
|
||||||
|
1. Pick a random type from `[film, character, award]`
|
||||||
|
2. Resolve based on type:
|
||||||
|
- **film**: pick a random `MovieRole` of the main actor → store `movie.id` in `hint_data`
|
||||||
|
- **character**: pick a random `MovieRole` of the main actor → store `movieRole.id` in `hint_data`
|
||||||
|
- **award**: call `WikidataAwardGateway` to fetch an award → store `"Nom du prix (année)"` in `hint_data`
|
||||||
|
3. If the chosen type yields no result (e.g., no awards found), fallback to another random type
|
||||||
|
4. Avoid duplicate hints across rows (don't show the same film/character/award twice)
|
||||||
|
|
||||||
|
## Wikidata Award Gateway
|
||||||
|
|
||||||
|
New service: `WikidataAwardGateway`
|
||||||
|
|
||||||
|
- Input: actor (name or `tmdb_id`)
|
||||||
|
- Output: list of awards, each with name and year
|
||||||
|
- Uses Wikidata SPARQL API to query awards associated with the person
|
||||||
|
- Storage format in `hint_data`: `"Oscar du meilleur second rôle (2014)"`
|
||||||
|
- Results can be cached to avoid repeated Wikidata queries
|
||||||
|
|
||||||
|
## Frontend
|
||||||
|
|
||||||
|
### Icon Button
|
||||||
|
|
||||||
|
The current "?" button in `ActorPopover` is replaced by an icon representing the hint type:
|
||||||
|
|
||||||
|
| hint_type | Icon | Font Awesome class |
|
||||||
|
|-----------|------|--------------------|
|
||||||
|
| `film` | Film/clap | `fa-film` |
|
||||||
|
| `character` | Theater masks | `fa-masks-theater` |
|
||||||
|
| `award` | Trophy | `fa-trophy` |
|
||||||
|
|
||||||
|
### Popover Content
|
||||||
|
|
||||||
|
On click, the popover displays only the hint text:
|
||||||
|
- **film**: movie title (resolved from `movie.id`)
|
||||||
|
- **character**: character name (resolved from `movie_role.id`)
|
||||||
|
- **award**: the raw text from `hint_data`
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
|
||||||
|
1. Backend resolves `hint_data` to display text in `GameGridGenerator::computeGridData()`
|
||||||
|
2. Hint type + resolved text are passed to the Twig template as part of the grid data
|
||||||
|
3. Twig passes them as props to the React `GameGrid` component
|
||||||
|
4. `ActorPopover` receives `hintType` and `hintText` props instead of `actorName`
|
||||||
|
|
||||||
|
## Future Extensibility
|
||||||
|
|
||||||
|
New hint types can be added by:
|
||||||
|
1. Adding a new value for `hint_type`
|
||||||
|
2. Adding resolution logic in `GameGridGenerator`
|
||||||
|
3. Adding a new icon mapping in the frontend
|
||||||
Reference in New Issue
Block a user