---
title: "Stabilisation ingame : le piano cliquable, une seule fumée, un écoulement continu"
subtitle: "Quand les symptômes joueur forcent à séparer DOM, Three.js, cache suggestions et modèle de traînées"
date: 2026-09-15
time: "00:13"
author: VFG / Rainbow Journey
publishedBy: idea
status: pub
tags: ["rainbowjourney", "devblog", "stabilisation", "midi", "threejs", "fumee", "ux"]
---

![Stabilisation ingame : le piano cliquable, une seule fumée, un écoulement continu](../images/covers/2026-09-14-stabilisation-ingame-piano-fumee-ecoulement.png)


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

![Capture stabilisation : note tenue et traces continues](../images/shots/stabilisation.png)


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:test` 33/33 ; `docs:check` 0 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

1. **Deux pianos** (DOM et volumes Three.js) avec des capacités différentes.
2. **Des réglages nommés d’après un rendu mort** — le slider existe encore, l’effet non.
3. **Des tests qui prouvaient qu’un canvas changeait**, pas qu’une seule traînée naissait au bon endroit.
4. **Un cache trop général** — l’horloge invalidait les suggestions.
5. **Le mauvais serveur** — un autre checkout sur `5173` a déjà trompé un diagnostic ; l’essai et Playwright ciblent désormais **5183**.

## Suite recommandée (toujours ouverte)

1. Rejouer les gestes sur le **Bird DP1** (pas seulement pointeur navigateur).
2. Contrat visuel court : une note, deux notes, accord, relâchement.
3. Nettoyer les commandes devenues sans effet avant d’en ajouter.
4. 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/`.*