
Le 14 septembre, le chantier n’était plus « ajouter une feature ». C’était de rendre à nouveau crédible ce que le joueur touche : les touches, la passerelle, la fumée sur l’eau, et le fait qu’une note tenue avance sans se casser au relâchement.
Base de travail citée dans les handoffs : 1f26421, puis livraison stabilisation + écoulement (commits 41de58c, 93578c4 côté journal). Aucune validation DP1 physique n’est revendiquée ici.
Symptômes → causes → corrections
| Symptôme | Cause constatée | Correction |
|---|---|---|
| Touches « mortes » en skin invisible | pointer-events: none au repos | Surface cliquable + focus clavier conservés |
| Passerelle non cliquable | Piano DOM absent ; volumes 3D sans clic | Même clavier interactif projeté pour les trois skins |
| Double réaction aux notes | Rubans MIDI + eau sur 12 classes | L’eau reste décorative ; la fumée porte la trace |
| Fumée qui saute au Note Off | Ajout brutal de longueur / changement de hauteur | Continuité géométrique, puis déplacement |
| Particules malgré un zéro | Plancher forcé à une particule | Zéro = zéro instance |
| MIDI qui « revient » après un changement rapide | Course asynchrone d’ouvertures | Numéro de requête ; anciennes ouvertures ignorées |
| Suggestions qui recalculent en boucle | Cache invalidé par l’horloge | Cache lié aux faits musicaux / réglages / phrase |
Le bouton Piano et fumee (barre de transport) applique un profil lisible : piano classique, fumée, panneaux transparents, sans particules / halos / filaments décoratifs, caméra sans flottement latéral. Il ne change ni les notes, ni les choix musicaux, ni l’armement MIDI.
Écoulement : une note tenue qui avance vraiment

La suite « traînées » remplace le modèle de segments empilés par un écoulement continu :
- pendant l’appui, la tête progresse ; la queue reste attachée au clavier ;
- après Note Off, les deux extrémités avancent de la même distance — plus d’allongement artificiel ;
- vitesse =
Vitesse du voyage × Ecoulement; un zéro arrête le transport ; - eau et fumée partagent la même fonction d’onde GLSL ; extrémités arrondies, une instance par traînée.
Fichiers centraux : src/runtime/riverFlow.ts, src/world/riverTrail.ts, shaders et sceneUpdates. Le plafond reste 128 traînées visibles. Les anciens paramètres « Hauteur des jets » / « Attaque du jet » ne pilotent plus ce modèle : leur nettoyage éditeur reste une tâche séparée.
Preuves exécutées (handoffs)
Sur l’arbre de stabilisation au-dessus de 1f26421, puis suite écoulement :
- TypeScript forcé, lint, build : réussis
- Vitest : 154 puis 159 tests (22 fichiers sur la suite écoulement)
- Playwright isolé port 5183 : 12 puis 13 scénarios
- Docs :
docs:test33/33 ;docs:check0 erreur (14 warnings d’empreintes d’archives)
Captures locales (artifacts/…) : artefacts de session, non versionnés, non équivalents à une validation DP1.
Pourquoi les « petites » demandes coûtent cher
- Deux pianos (DOM et volumes Three.js) avec des capacités différentes.
- Des réglages nommés d’après un rendu mort — le slider existe encore, l’effet non.
- Des tests qui prouvaient qu’un canvas changeait, pas qu’une seule traînée naissait au bon endroit.
- Un cache trop général — l’horloge invalidait les suggestions.
- Le mauvais serveur — un autre checkout sur
5173a déjà trompé un diagnostic ; l’essai et Playwright ciblent désormais 5183.
Suite recommandée (toujours ouverte)
- Rejouer les gestes sur le Bird DP1 (pas seulement pointeur navigateur).
- Contrat visuel court : une note, deux notes, accord, relâchement.
- Nettoyer les commandes devenues sans effet avant d’en ajouter.
- Extraire projection / présentation / entrée en petits modules au fil des parcours, pas en big-bang.
Sources : docs/journal/2026-09-14_stabilisation/HANDOFF.md, ECOULEMENT.md. Miroir local : RainbowPiano/docs/devblog/.