docs: add game hints system design spec

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thibaud-leclere
2026-03-30 22:21:26 +02:00
parent 335a55562f
commit 4fb1a25469

View 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