blog.vfg.lol

Rivière unifiée et grimoire nocturne : ce que la nuit du 15 a livré

De la courbe 2a à la scène 3D nocturne — rubans guidés, méandre vers l'horizon, paquets qui grossissent

Rivière unifiée et grimoire nocturne : ce que la nuit du 15 a livré

Le journal du 15 à 05:40 clôturait la passe live et l'essai UI 2a sur main. La nuit suivante ouvre un chantier différent : unifier la rivière 2D et la scène 3D, poser un grimoire nocturne (ciel, aurores, glyphes, lucioles), et répondre au retour FG sur le flux visuel — méandre vers l'horizon, rayons alignés, sacs qui grossissent avec la quantité.

Branche : feat/riviere-unifiee-nuit-neon, depuis main 467416b. Agent : Claude Code (claude-opus-5).

Commits

CommitContenu
bf0308cPlan, objectifs, décision et notices, commités avant tout code
40ac14dRiverField : déprojection de la courbe 2a (eau + cascade), tests
e971b0aRivière 3D unifiée, rubans guidés, orbes, arrivées, ciel, glyphes, vallée, défauts nuit, passe HUD

Ce qui est livré (itération 1)

  • O1 — Courbe unique : src/world/riverPath3d.ts reconstruit chaque couloir en monde à partir de sampleRiverPath. Les tests vérifient une reprojection sous 0,5 px en 1280×800 et 1920×1080 avec sway. La nappe colore ses veines en espace écran (gl_FragCoord) avec la même courbe analytique.
  • O2 — Rubans et orbes : les rubans de notes lisent une texture de couloir. La tête avance au rythme de climbDuration, la queue part au relâchement. Les orbes suivent runtime.climbers ; une gerbe apparaît à la disparition d'un climber arrivé. Le compteur du paquet reste incrémenté par settle dans le runtime.
  • O3 — Fin du trapèze sur les couloirs : le trapèze --piano-warp ne s'applique plus aux couloirs. Les aides de trapèze restent pour le piano DOM historique et layout.test.ts.
  • O4 — Nuit par défaut : sky #040a0a, water #0a3b3d, bloom 0,7, seuil 0,6, brume 0,009, filaments 1. Ajouts : dôme d'étoiles avec lune, aurores teintées par les deux couloirs les plus actifs, pluie de glyphes runiques derrière la cascade, terrain à lignes de niveau, pins et cristaux émissifs, lucioles.
  • O5 — HUD grimoire : calque d'atmosphère (grille, vignette, scanlines), ondes sur les médaillons tenus, surface liquide des paquets et rune à l'arrivée, entrée holographique des cartes, crochets de panneaux, balayage de la topbar. Le compas pastel .world-status est masqué.
  • Trace : ?riviere-trace (ou debugcase) affiche un trait de 1 px par couloir au-dessus de la 3D.

Itération 2 — retour FG

Demande : aligner les rayons sur le flux de la rivière vers l'horizon, courber la rivière pour qu'elle se voie mieux, faire grossir les sacs selon la quantité.

  • src/journey/riverGeometry.ts : nouvelle courbe en trois tronçons (pied vertical, méandre vers le col d'horizon, éventail vers le paquet), riverThroatX et riverLaneCompression. Les shaders reprennent la même courbe analytique à partir des constantes TypeScript.
  • src/world/riverPath3d.ts : conversion cadre → écran ancrée sur le haut réel des couloirs, l'horizon et l'ancre des paquets. Le vecteur latéral et la nappe sont resserrés au col.
  • src/journey/pouchGrowth.ts : croissance logarithmique (largeur ≤ 1,2, hauteur ≤ 1,55) appliquée par variables CSS, avec une transition élastique. L'ancre de la rivière reste sur la hauteur de base.
  • Lumière nocturne atténuée (le terrain proche est désormais visible).

Contrôles exécutés

Sur e971b0a et l'itération 2 :

  • node node_modules/typescript/bin/tsc -b --force : OK.
  • npm run lint : OK.
  • Vitest : 33 fichiers, 251 tests réussis (itération 2).
  • vite build : OK (avertissement de taille de chunk préexistant).
  • Banc src/perfBench.test.ts (proxy CPU, machine locale) : updateTrailInstances à 1,55 ms/itération incluant RiverField.update ; updateBridgeKeys à 0,04 ms/itération. Aucune comparaison avec l'ancien chemin : le périmètre mesuré a changé.
  • Rendu Browser pane (Vite isolé port 5186) : 1280×800, 1920×1080, mobile 375×812 avec ?riviere-trace et la démo. Tracé 1 px coïncide avec rubans et veines ; paquets s'incrémentent ; aucune erreur console après rechargement. FPS topbar 58 dans le pane : observation, pas mesure de perf.
  • Captures Chromium headless (SwiftShader, itération 2) : tracé coïncide, paquets grossissent, aucune erreur console. FPS headless (2 à 8) = rendu logiciel, pas mesure.
  • Playwright (port 5187) : 5 réussis, 8 échoués — échecs attendent des éléments retirés par l'essai 2a avant ce chantier (titre Do majeure, 25 .key, bouton Piano et fumee). Probablement préexistants sur main ; non vérifié par exécution sur main.

Non fait / écarts

  • docs:check : 44 erreurs préexistantes (catalogue images, zone bundle design) ; aucune nouvelle erreur attribuable à ce chantier au moment du commit plan.
  • Aucune mesure GPU, validation DP1 ou calibration perceptuelle.
  • E2E piano DOM historiques à réécrire pour les couloirs 2a (zone outillage).
  • effects.riverWidth règle maintenant la largeur minimale de la vallée ; libellé éditeur inchangé.

Prochaine action

  1. FG juge le rendu en jeu avec le DP1 (lisibilité rubans sur cascade, intensité aurores et bloom).
  2. Ajuster au besoin src/world/tuning.ts (cascadeFrameY, orbPx, sealPx, ribbonPxPerUnit) et intensités shaders.
  3. Réécrire les E2E piano DOM pour les couloirs 2a, puis décider de l'intégration de la branche.

Sources : docs/plans/riviere-unifiee-nuit-neon/handoffs/2026-09-15-riviere-unifiee-handoff.md, docs/plans/riviere-unifiee-nuit-neon/PLAN.md, docs/decisions/2026-09-15-riviere-2a-maitresse.md. Miroir local : RainbowPiano/docs/devblog/.

source markdown