feat(ir): compile solution blocks to puzzles
This commit is contained in:
@@ -150,18 +150,30 @@ et pilote l'écran. Un IR de référence exerçant ces champs est fourni :
|
||||
par `validate_runtime3_document`, testé en bout-à-bout via `POST /game/scenario`
|
||||
puis `POST /game/step`).
|
||||
|
||||
**En revanche, l'authoring ne les génère pas encore.** Les scénarios
|
||||
canoniques (`game/scenarios/zacus_v2.yaml`, `zacus_v3.yaml`) décrivent les
|
||||
mêmes énigmes via un vocabulaire distinct — blocs `solution:`
|
||||
(`frequency_hz`, `qr_payload`, `sequence`) et `scene: SCENE_X` (référence
|
||||
d'ID d'écran, pas l'objet d'affichage) — qui **n'est pas traduit** vers les
|
||||
objets `puzzle`/`scene` de l'IR. L'IR embarqué `DEFAULT.json` ne contient
|
||||
donc aucun champ `puzzle`/`scene`.
|
||||
**Le pont authoring → firmware est désormais construit.** Le compilateur
|
||||
traduit le vocabulaire d'authoring des `puzzles:` (blocs `solution:`) vers les
|
||||
objets `puzzle` de l'IR et les **attache au step correspondant** (par
|
||||
`screen_scene_id` == `puzzle.scene`). Fonctions : `translate_solution_to_puzzle`
|
||||
et `_attach_puzzles_from_authoring` dans `runtime3_common.py`.
|
||||
|
||||
Chaînon à construire (tâche dédiée) : enseigner au compilateur la
|
||||
correspondance `solution:` → `puzzle:` (ex. `frequency_hz`+`tolerance_hz`
|
||||
→ `type:sound`/`melody`/`tolerance` ; `qr_payload`/`sequence`
|
||||
→ `type:qr`/`codes` ; allocation des `fragment` de code par énigme), et
|
||||
exposer un objet `scene` d'affichage dans l'authoring. En attendant,
|
||||
pousser directement un IR comme `EXAMPLE_LOCAL_PUZZLES.json` reste le moyen
|
||||
d'exercer les énigmes locales depuis la webUI/gateway.
|
||||
Table de correspondance `solution:` → `puzzle:` :
|
||||
|
||||
| Authoring (`type` + `solution`) | IR `puzzle` |
|
||||
|---|---|
|
||||
| `qr` + `qr_payload: "X"` | `type:qr`, `codes:["X"]` |
|
||||
| `qr` + `qr_sequence: [a,b]` | `type:qr`, `codes:[a,b]` (ordre conservé) |
|
||||
| `audio_frequency` + `frequency_hz` (+ `tolerance_hz`) | `type:sound`, `melody:[hz→MIDI]`, `tolerance` (≈ semitons, ≥1) |
|
||||
| `sound`/`sequence` + `solution.notes: [MIDI…]` | `type:sound`, `melody:[…]` |
|
||||
|
||||
Règles : le slot firmware `id` vient de `puzzle_id` sinon d'un défaut par type
|
||||
(sound→1, sequence→2, qr→3) ; le `fragment` (1–4 chiffres) vient de
|
||||
`code_fragment` sinon vaut le chiffre de l'`id`. Une énigme non traduisible
|
||||
(ex. `sequence` de lettres sans `notes` MIDI — une suite de lettres n'est pas
|
||||
une séquence de hauteurs détectable) est **ignorée avec un avertissement**, sans
|
||||
casser la compilation du scénario. Un step portant déjà un `puzzle` explicite
|
||||
n'est pas écrasé (le passthrough direct prime).
|
||||
|
||||
Reste à faire (suite) : exposer un éditeur d'objet `scene` d'affichage
|
||||
(title/subtitle/symbol/effect) dans l'atelier Blockly — au niveau IR/step,
|
||||
l'objet `scene` est déjà accepté via le passthrough. `EXAMPLE_LOCAL_PUZZLES.json`
|
||||
reste l'IR de référence le plus complet (puzzle + scene par step).
|
||||
|
||||
Reference in New Issue
Block a user