Dérive est né de l’envie d’un jeu doux sur l’océan. Pas un jeu à gagner : un endroit où dériver, où une baleine passe sous la barque parce qu’elle allait par là, et où l’on cesse de ramer pour la regarder.
Dérive, c’est une barque vue du ciel, sur une mer qui ne finit jamais. On rame, on regarde, et l’on remplit le carnet d’Élise Marceau, naturaliste partie en 1911, dont les pages reviennent dans des bouteilles. Pas de score, pas de chronomètre. La mer prend le temps qu’il lui faut.
C’est l’œuvre d’une seule personne : la conception, chaque ligne de code, chaque bête et chaque décor modelés dans Blender, la direction artistique et la musique. Il tourne dans un navigateur, sur un téléphone comme sur un bureau, sans rien à installer et sans aucun serveur derrière. Cette page raconte comment il a été fait, et pourquoi il a cet air-là.
Une mer peinte pixel par pixel
Il n’y a aucune image de la mer dans Dérive. À chaque image, un shader WebGL2 recalcule chaque pixel de l’eau à partir de rien : deux bandes de houle, deux octaves de risées, additionnées en une hauteur, et la pente exacte de cette hauteur sous chaque pixel. La lumière naît de cette pente. Là où une petite facette d’eau penche juste assez pour renvoyer le soleil dans l’œil, elle étincelle.
C’est tout le secret du scintillement. À midi, une fine poussière blanche sur toute la vue. Quand le soleil est bas, les éclats s’étirent en traits d’or dans sa direction et se rassemblent en une longue route de lumière venue de son côté, comme celle qui vous suit le long d’une plage. La nuit, un mince chemin d’argent sous la lune.
Puis l’image entière passe par une couche peinte. Ses couleurs sont étirées le long d’un champ de pinceau qui dérive avec la mer, un peu gaufrées, grainées comme un papier, pour que l’océan se lise comme une aquarelle et non comme un rendu. La touche se mesure en pixels d’écran, pas en pixels de rendu : quand un téléphone fatigué doit dessiner la scène à demi-résolution, la peinture garde le même pinceau.
Faire tourner tout cela à soixante images par seconde sur un téléphone a été l’essentiel du travail. Ce qui change au fil des mètres plutôt que des pixels (où sont les récifs, dans quelle mer on se trouve, les grandes ombres de la houle) est dessiné une fois par image dans de petites textures, au huitième de la taille, puis relu filtré : trois lectures de texture au lieu de douze à vingt calculs de bruit par pixel, cinq millisecondes gagnées par image au-dessus des hauts-fonds. La mer, les fonds, les bêtes et ce qui flotte tiennent en six appels de dessin avant la couche peinte, plus un par modèle 3D à l’écran.
Il fallait que la mer ait l’air peinte, jamais calculée. Et qu’elle reste peinte sur le plus petit des téléphones.
Une journée dure dix minutes : une minute d’aube, cinq de jour, une minute et demie de crépuscule, deux et demie de nuit. Les couleurs ne font pas que s’assombrir. Chaque heure a sa palette, amenée le long de courbes : bleu froid puis rose à l’aube, or puis violet au crépuscule. Le temps qu’il fait dépend de la mer et de l’horloge, si bien que tous ceux qui naviguent ensemble sur la même mer voient la même pluie au même instant, sans que rien ne passe entre eux.
l’aube
l’heure dorée
le crépuscule
la nuit
Des fonds qui poussent tout seuls
Sous les hauts-fonds, il y a des herbiers, des patates de corail dans le lagon, des forêts de kelp couchées par la houle. Rien de tout cela n’est modelé, et rien n’est stocké. Tout pousse sur la carte graphique, à chaque image, à partir de simples nombres.
L’astuce, c’est que les fonds n’ont aucun tampon de sommets. Le fond est découpé en cellules de six mètres, ancrées dans le monde. Le shader de sommets ne reçoit que son propre numéro, gl_VertexID, et en déduit à quelle cellule il appartient et à quelle place dans cette cellule. Un petit hachage de la cellule et de la place donne au brin sa position, sa longueur, son inclinaison. Puis il regarde la densité de l’herbier à cet endroit : si l’herbier est clairsemé, le brin se replie en un triangle de taille nulle, et la carte graphique le saute.
Une cellule d’herbier compte jusqu’à 640 brins, de cinq sommets chacun. Ils ne sont pas instanciés : les toutes petites instances coûtent à la carte graphique par instance, pas par sommet, alors les brins sont dessinés à la file, en une seule longue bande de triangles reliés par des triangles dégénérés. Mesuré, le même herbier coûte ainsi environ quarante pour cent de moins. Faites glisser l’image ci-dessous pour soulever l’herbier du sable.
Les brins ploient avec le courant, en vagues qui roulent à travers l’herbier. Et ils vous remarquent. Chaque bête et la barque elle-même s’impriment, à chaque image, dans une petite texture de remous qui se répète tous les quatre-vingts mètres et s’efface peu à peu : près du fond, près de la surface, entre les deux. Les brins se couchent et s’écartent de ce qui passe, les anémones se referment, la voûte de kelp s’ouvre autour de la coque et se referme derrière elle.
Chaque mer a son fond. Dans le lagon, des coraux cerveaux et des coraux tables, des cornes de cerf aux pointes pâles, des gorgones et des coraux mous qui ondulent, tout en roses passés, en ocres et en crèmes, rassemblés en rondes patates de corail sur le sable. Dans la forêt de kelp, des stipes d’or olive montent de leurs crampons vers des frondes qui s’étirent juste sous la surface, au-dessus d’un granite incrusté d’algues roses et d’étoiles de mer, et l’eau entre eux s’assombrit et se brouille à mesure qu’ils descendent.
Des bêtes qui nagent, et ne glissent pas
Poissons, requins, tortues, raies et baleines vivent dans une petite simulation écrite en Rust et compilée en WebAssembly. Elle est minuscule à dessein : ni bibliothèque standard, ni allocateur, ni import, tout son état dans un seul bloc de mémoire fixe, si bien que la page lit la position des bêtes directement dedans, sans copier un octet. Compilée, elle pèse 11,7 kilo-octets. Les bancs suivent leur meneur, les requins tournent, les baleines remontent vers la surface dans les secondes qui précèdent leur respiration et ne soufflent qu’une fois le dos tout près d’elle. Une copie de la même simulation en JavaScript prend le relais là où WebAssembly est bloqué, et un test fait tourner les deux au même pas pour qu’elles ne divergent jamais.
Ensuite, chaque bête doit bouger comme elle-même. Chaque modèle est fait dans Blender en pensant à sa nage : des poids peints dans les couleurs de ses sommets, du rouge pour l’ondulation du corps, du vert pour les nageoires ou les ailes, du bleu pour les parties fines qui frémissent. Le shader de sommets envoie une onde de la tête le long du corps, bat des nageoires, fait frissonner les bords, et lit le virage de la bête d’une image à l’autre : la colonne se courbe le long de l’arc qu’elle nage, et le corps s’incline dans le virage. Une baleine tourne en une longue courbe de sa propre longueur ; une raie manta penche ses ailes comme un planeur.
La profondeur est peinte, pas estompée. Un corps sous l’eau n’est jamais transparent : le dos prend plus de lumière que les flancs, la couleur de l’eau gagne point par point, les bords s’effacent d’abord, et de jour les reflets du soleil courent sur les dos proches de la surface. Vue du ciel, une baleine à douze mètres de fond est une forme que l’on devine avant de la voir.
Certaines bêtes ne se rencontrent qu’avec de la patience. Restez calme près d’elles, rames immobiles, le bon appât à l’eau, et la rencontre se remplit comme un souffle retenu. Quand elle aboutit, la baleine répond par un souffle à côté de la barque. Si des amis naviguent avec vous, elle compte aussi pour eux.
Le carnet : d’abord le crayon, puis l’aquarelle
Chaque bête croisée entre dans le carnet d’Élise : cinquante et une espèces, qui existent toutes, sauf une. La façon dont le carnet les dessine suit ce que vous savez d’elles. Croisée une fois, une esquisse au crayon : un double contour hésitant, des hachures selon la lumière, le graphite accroché au grain du papier. Vue assez souvent, ses couleurs viennent. Et une fois broyés les pigments qu’il lui faut, avec ce que donne la mer (la nacre pour le blanc, le verre de mer pour le bleu, la rouille pour l’ocre, la suie pour le noir), elle devient une planche à l’aquarelle : des lavis qui débordent du contour, le pigment amassé aux bords mouillés, le dos éclairé laissé en papier nu.
Aucune de ces planches n’a été peinte à la main. Le jeu les tire des modèles 3D mêmes qui nagent dans sa mer, en deux passes sur les couleurs et la forme du modèle, la première fois que vous ouvrez la page.
croisée : le crayon
peinte : l’aquarelle
Tortue verte Chelonia mydas
Raie manta Mobula birostris
Orque Orcinus orca
Hippocampe moucheté Hippocampus guttulatus
Poulpe Octopus vulgaris
Méduse à crinière Cyanea capillata
Le chargement, à l’aquarelle
Un jeu doit charger. Ici, l’attente en fait partie. La page s’ouvre sur du papier ; l’encre écrit « Dérive » lettre après lettre, puis un lavis d’aquarelle se répand sur l’une de quatre cartes marines peintes, et ce lavis est la barre de progression. Quand la mer derrière est prête, on choisit d’entrer avec le son ou en silence, et la carte peinte plonge dans l’océan vivant.
Le lavis est un script de vingt-deux kilo-octets avec son petit programme WebGL : sept taches qui avancent à travers un déplacement déchiré, une bande plus sombre de pigment mouillé sur leur front, la carte qui tourbillonne et se pose à mesure qu’elle se remplit. Il tourne dans un worker, sur un canevas hors écran, si bien que le démarrage lourd du jeu ne le fait jamais trembler. Les deux polices du titre sont glissées dans la page, réduites à un ou deux kilo-octets, pour que l’encre écrive dès le tout premier affichage.
Un monde sans serveur
Dérive est un site statique. Pas de serveur de jeu, pas de base de données, rien à faire tourner. Chaque mer vient d’un seul nombre, lisible en un code court comme J9C-HA4W : le même code donne les mêmes récifs, les mêmes gens, le même temps, sur n’importe quel appareil. Votre carnet vit sur votre appareil. Si vous créez un compte, votre partie est chiffrée et signée sur votre appareil avant qu’une copie soit laissée sur des relais publics : personne d’autre ne peut la lire, pas même l’auteur du jeu.
Naviguer à plusieurs fonctionne de la même façon. Les barques se trouvent par ces relais, puis se parlent directement, de navigateur à navigateur, par WebRTC ; le code de la partie en est aussi le mot de passe. L’état d’une barque tient en cinquante-deux octets, dix fois par seconde. Celui qui mène un groupe simule les bêtes pour tous ceux qui sont près, si bien que vous regardez tous la même baleine.
Et la mer est vraiment sans fin. Les nombres à virgule flottante perdent leur précision loin de l’origine, et à cinquante kilomètres les poissons les plus lents se seraient figés. Alors le monde se recentre doucement sur la barque à mesure que l’on rame, et reste exact jusqu’à seize mille kilomètres : quatre mois de rame en ligne droite.
En quelques chiffres
La musique
La musique a été composée pour le jeu. Chacune des huit mers a son morceau : celui du lagon léger et chaud, celui des mers froides lent et large, celui des abysses grave et patient ; la nuit a le sien, et une tempête prend le dessus sur tout tant qu’elle dure. Quand on rame d’une mer à l’autre, les morceaux se fondent l’un dans l’autre en six secondes, et ils baissent un peu quand un requin s’approche.
Le reste du son, le navigateur le fabrique en direct : le murmure de la mer, le grincement des rames, le souffle des baleines, la pluie, le tonnerre qui roule quelques secondes après l’éclair, plus ou moins loin. Un casque aide.
La mer vous attend.
Dérive est gratuit, dans votre navigateur, sur un téléphone ou un bureau. Casque sur les oreilles, rames à l’eau.
Prendre la merJ’ai fait Dérive seul : chaque ligne de code, chaque bête et chaque épave modelées dans Blender, chaque note de la musique. Ce fut un travail lent, et heureux ; j’espère qu’un peu de ce calme vous parviendra, rames immobiles, quand une baleine passera. — Thibaud Perrin. Un mot à me dire ? Écrivez-moi.