Dérive nasceu da vontade de um jogo sereno sobre o oceano. Não um jogo para ganhar: um lugar para andar à deriva, onde uma baleia passa por baixo do barco porque ia para aqueles lados, e tu deixas de remar para a ver.
Dérive é um barco a remos visto do céu, num mar que nunca acaba. Remas, observas e vais enchendo o caderno de Élise Marceau, uma naturalista que partiu em 1911 e cujas páginas regressam a boiar dentro de garrafas. Não há pontuação nem relógio. O mar leva o tempo que precisa.
É obra de uma só pessoa: a conceção, cada linha de código, cada animal e cada cenário modelados no Blender, a direção artística e a música. Corre num navegador, num telemóvel tal como num computador, sem nada para instalar e sem nenhum servidor por trás. Esta página conta como foi feito, e porque tem este aspeto.
Um mar pintado píxel a píxel
Não há nenhuma imagem do mar em Dérive. A cada fotograma, um shader WebGL2 calcula do zero cada píxel da água: duas faixas de ondulação, duas oitavas de encrespado do vento, somadas numa altura, e a inclinação exata dessa altura sob cada píxel. A luz nasce dessa inclinação. Onde uma pequena faceta de água se inclina na medida certa para te devolver o sol aos olhos, cintila.
É assim que o brilho funciona. Ao meio-dia, um fino cintilar branco por toda a vista. Quando o sol está baixo, os clarões esticam-se em traços dourados na sua direção e juntam-se num longo caminho de luz que vem do seu lado, como o verdadeiro, que te acompanha ao longo de uma praia. À noite, um fio de prata sob a lua.
Depois, a imagem inteira passa por uma camada pintada. As suas cores são arrastadas ao longo de um campo de pincel que deriva com o mar, ganham um ligeiro relevo e o grão do papel, para que o oceano se leia como uma aguarela e não como uma renderização. A pincelada mede-se em píxeis de ecrã, não em píxeis de renderização: quando um telemóvel cansado tem de desenhar a cena a meia resolução, a pintura mantém o mesmo pincel.
Pôr tudo isto a correr a sessenta fotogramas por segundo num telemóvel foi a maior parte do trabalho. O que muda ao longo de metros e não de píxeis (onde estão os recifes, em que mar estás, as grandes sombras da ondulação) é desenhado uma vez por fotograma em pequenas texturas, a um oitavo do tamanho, e relido filtrado: três leituras de textura em vez de doze a vinte cálculos de ruído por píxel, cinco milissegundos poupados por fotograma sobre os baixios. O mar, o fundo, as criaturas e o que flutua cabem em seis chamadas de desenho antes da camada pintada, mais uma por cada modelo 3D no ecrã.
O mar tinha de parecer pintado, nunca calculado. E tinha de continuar pintado no mais pequeno dos telemóveis.
Um dia dura dez minutos: um minuto de alvorada, cinco de dia, minuto e meio de crepúsculo, dois e meio de noite. As cores não se limitam a escurecer. Cada hora tem a sua paleta, conduzida ao longo de curvas: azul frio e depois rosa na alvorada, ouro e depois violeta ao crepúsculo. O tempo que faz depende do mar e do relógio, por isso todos os que navegam juntos no mesmo mar veem a mesma chuva no mesmo instante, sem que nada passe entre eles.
a alvorada
a hora dourada
o crepúsculo
a noite
Um fundo que cresce por si
Sob os baixios há pradarias de ervas marinhas, cabeços de coral na lagoa, florestas de kelp que se inclinam com a ondulação. Nada disto está modelado, e nada é guardado. Cresce na placa gráfica, a cada fotograma, a partir de simples números.
O truque é que o fundo não tem nenhum buffer de vértices. O leito está cortado em células de seis metros, ancoradas ao mundo. O shader de vértices recebe apenas o seu próprio número, gl_VertexID, e daí deduz a que célula pertence e que lugar ocupa nela. Um pequeno hash da célula e do lugar dá à folha uma posição, um comprimento, uma inclinação. Depois vê quão densa é ali a pradaria: se for rala, a folha dobra-se num triângulo de tamanho zero e a placa gráfica salta-a.
Uma célula de pradaria leva até 640 folhas, de cinco vértices cada. Não são instanciadas: as instâncias minúsculas custam à placa gráfica por instância, não por vértice, por isso as folhas são desenhadas umas atrás das outras numa só longa tira de triângulos, unidas por triângulos degenerados. Medida, a mesma pradaria custa assim cerca de quarenta por cento menos. Desliza sobre a imagem abaixo para levantar a pradaria da areia.
As folhas dobram-se com a corrente, em faixas que rolam pela pradaria. E dão por ti. Cada criatura e o próprio barco ficam impressos, a cada fotograma, numa pequena textura de perturbação que se repete a cada oitenta metros e se desvanece aos poucos: junto ao fundo, junto à superfície, entre os dois. As folhas deitam-se e afastam-se do que passa, as anémonas recolhem-se, a abóbada de kelp abre-se em volta do casco e volta a fechar-se atrás dele.
Cada mar tem o seu fundo. Na lagoa, corais-cérebro e corais-mesa, chifres-de-veado de pontas pálidas, gorgónias e corais moles que ondulam, tudo em rosas desmaiados, ocres e cremes, reunidos em redondos cabeços de coral sobre a areia. Na floresta de kelp, estipes de ouro-oliva sobem das suas fixações em direção a frondes estendidas logo abaixo da superfície, sobre um granito incrustado de algas coralinas cor-de-rosa e estrelas-do-mar, e a água entre elas escurece e turva-se quanto mais fundo vão.
Criaturas que nadam, e não deslizam
Peixes, tubarões, tartarugas, raias e baleias vivem numa pequena simulação escrita em Rust e compilada para WebAssembly. É minúscula de propósito: sem biblioteca padrão, sem alocador, sem importações, todo o seu estado num único bloco fixo de memória, de modo que a página lê as posições das criaturas diretamente dali, sem copiar um único byte. Compilada, pesa 11,7 kilobytes. Os cardumes seguem o seu guia, os tubarões andam em círculos, as baleias sobem à superfície nos segundos antes de respirar e só sopram quando têm o dorso perto dela. Uma cópia da mesma simulação em JavaScript assume o comando onde o WebAssembly está bloqueado, e um teste põe as duas a avançar ao mesmo passo para que nunca se afastem.
Depois, cada animal tem de se mover como ele próprio. Cada modelo nasce no Blender já a pensar no seu nado: pesos pintados nas cores dos vértices, vermelho para a onda do corpo, verde para as barbatanas ou as asas, azul para as partes finas que estremecem. O shader de vértices manda uma onda da cabeça ao longo do corpo, bate as barbatanas, faz ondular as bordas e lê a curva da criatura de um fotograma para o outro, de modo que a coluna se dobra ao longo do arco que nada e o corpo se inclina para dentro da curva. Uma baleia vira numa longa curva do seu próprio comprimento; uma raia-manta inclina as asas como um planador.
A profundidade pinta-se, não se esbate. Um corpo debaixo de água nunca é transparente: o dorso apanha mais luz do que os flancos, a cor da água vai ganhando ponto a ponto, as bordas desaparecem primeiro, e de dia os reflexos do sol correm pelos dorsos perto da superfície. Vista do céu, uma baleia a doze metros de profundidade é uma forma que adivinhas antes de a veres.
Alguns animais só se encontram com paciência. Fica calmo ao lado deles, remos parados, o isco certo na água, e o encontro vai-se enchendo como um fôlego suspenso. Quando se completa, a baleia responde com um sopro ao lado do barco. Se navegares com amigos, conta também para eles.
O caderno: primeiro o lápis, depois a aguarela
Cada animal com que te cruzas entra no caderno de Élise: cinquenta e uma espécies que existem todas, menos uma. A maneira como o caderno as desenha acompanha o quanto as conheces. Cruzada uma vez, um esboço a lápis: um duplo contorno hesitante, tracejado conforme a luz, a grafite presa no grão do papel. Vista vezes suficientes, chegam as suas cores. E quando moes os pigmentos de que precisa com o que o mar te dá (nácar para o branco, vidro do mar para o azul, ferrugem para o ocre, fuligem para o negro), torna-se uma prancha em aguarela: aguadas que transbordam do contorno, pigmento acumulado nas bordas molhadas, o dorso iluminado deixado em papel nu.
Nenhuma destas pranchas foi pintada à mão. O jogo tira-as dos mesmos modelos 3D que nadam no seu mar, em duas passagens sobre as cores e a forma do modelo, na primeira vez que abres a página.
cruzada: o lápis
pintada: a aguarela
Tartaruga-verde Chelonia mydas
Raia-manta Mobula birostris
Orca Orcinus orca
Cavalo-marinho-de-focinho-comprido Hippocampus guttulatus
Polvo Octopus vulgaris
Medusa-juba-de-leão Cyanea capillata
O carregamento, em aguarela
Um jogo tem de carregar. Aqui, a espera faz parte dele. A página abre-se sobre papel; a tinta escreve «Dérive» letra a letra, depois uma aguada de aguarela espalha-se sobre uma de quatro cartas náuticas pintadas, e essa aguada é a barra de progresso. Quando o mar por trás está pronto, escolhes entrar com som ou em silêncio, e a carta pintada mergulha no oceano vivo.
A aguada é um script de vinte e dois kilobytes com o seu próprio pequeno programa WebGL: sete manchas que avançam através de um deslocamento rasgado, uma faixa mais escura de pigmento molhado na sua frente, a carta a rodopiar e a assentar à medida que se enche. Corre num worker, numa tela fora do ecrã, para que o arranque pesado do jogo nunca a faça engasgar. As duas fontes do título vão embutidas na página, reduzidas a um ou dois kilobytes, para que a tinta escreva logo na primeiríssima pintura.
Um mundo sem servidor
Dérive é um site estático. Não há servidor de jogo, nem base de dados, nada para manter a funcionar. Cada mar nasce de um só número, legível como um código curto do género J9C-HA4W: o mesmo código dá os mesmos recifes, as mesmas pessoas, o mesmo tempo, em qualquer dispositivo. O teu caderno vive no teu dispositivo. Se criares uma conta, o teu jogo é cifrado e assinado no teu dispositivo antes de uma cópia ficar em relays públicos, por isso mais ninguém o pode ler, nem sequer o autor do jogo.
Navegar juntos funciona da mesma maneira. Os barcos encontram-se através desses relays e depois falam diretamente, de navegador para navegador, por WebRTC; o código da partida é também a sua palavra-passe. O estado de um barco ocupa cinquenta e dois bytes, dez vezes por segundo. Quem lidera um grupo simula as criaturas para todos os que estão perto, para que todos vejam a mesma baleia.
E o mar é mesmo sem fim. Os números de vírgula flutuante perdem precisão longe da origem, e a cinquenta quilómetros os peixes mais lentos ter-se-iam imobilizado. Por isso o mundo recentra-se discretamente no barco enquanto remas, e mantém-se exato até dezasseis mil quilómetros: quatro meses a remar em linha reta.
Em alguns números
A música
A música foi composta para o jogo. Cada um dos oito mares tem a sua peça: a da lagoa leve e quente, a dos mares frios lenta e ampla, a do abismo grave e paciente; a noite tem a sua, e uma tempestade sobrepõe-se a tudo enquanto dura. Ao remar de um mar para o seguinte, as peças fundem-se em seis segundos, e baixam um pouco quando um tubarão se aproxima.
O resto do som é criado ao vivo pelo navegador: o murmúrio do mar, o ranger dos remos, o sopro das baleias, a chuva, o trovão que rola uns segundos depois do relâmpago, mais longe ou mais perto. Com auscultadores, é melhor.
O mar está à tua espera.
Dérive é gratuito, no teu navegador, num telemóvel ou num computador. Auscultadores postos, remos na água.
Fazer-se ao marFiz o Dérive sozinho: cada linha de código, cada animal e cada naufrágio modelados no Blender, cada nota da música. Foi um trabalho lento, e feliz; espero que um pouco dessa calma te chegue, remos parados, enquanto passa uma baleia. — Thibaud Perrin. Algo a dizer? Escreve-me.