Primeiro a regra, depois o grafismo
Um protótipo sem qualquer textura, mas com a regra correta, diz mais do que uma cena bonita sem aposta. No jogo de investigação, a regra significa cinco personagens, oito pistas das quais três são prova forte, quatro motivos, quatro finais e um relógio de 72 horas em que cada fala corta 10 minutos e um deslocamento 30. As horas 00:00–07:00 são saltadas automaticamente, para que o relógio não se esgote durante o sono.
A cena no browser, em Three.js
A mesma biblioteca em cinco repositórios: Three.js 0.184–0.185, por vezes através de `@react-three/fiber` e `@react-three/drei`, outras vezes escrita diretamente. Dois projetos usam a variante React; outros dois escrevem Three.js puro, até ao ponto em que gerimos manualmente os atributos do buffer. O maior motor próprio tem 1.824 linhas e desenha todos os satélites como um único objeto `THREE.Points`, com atributos de posição, cor, tamanho e transparência atualizados no local, frame a frame.
Renderização que desce sozinha em dispositivos fracos
O shader deste site tem três níveis: `low` com 24 iterações de raymarching e razão de pixels 0,5, `medium` com 40 e 0,65, `high` com 80, precisão `highp` e razão limitada a 2. A escolha é automática: em mobile desce para `low`, e qualquer dispositivo com 4 núcleos ou menos é rebaixado de `high` para `medium`. Se o WebGL estiver ausente, o componente termina de forma limpa em vez de lançar erro. A mesma disciplina nos outros projetos: limite de 1,6 na cena da cidade e 1,75 na do terreno, 1,5 em mobile no demonstrador de mundo, com o loop de renderização parado quando o canvas sai do ecrã.
Cenas grandes que continuam a ser um único desenho
Uma cidade com 9.506 edifícios não significa 9.506 objetos. Cada fingerprint do OpenStreetMap torna-se uma `ExtrudeGeometry` sem chanfradura e com `curveSegments: 1`, recebe a cor escrita diretamente nos vértices, tem o atributo `uv` removido — e depois tudo se funde numa única geometria através de `mergeGeometries`. Os anéis geométricos degenerados nos dados públicos são saltados com `try`/`catch`, não deixados derrubar a página.
Personagens que mentem, se lembram e cedem em condições
A verdade do caso não está na página. Os dossiers das cinco personagens — biografia, segredo, a condição em que quebra — estão num ficheiro que começa com `import "server-only"` e não pode ser importado do cliente. A personagem assinala uma pista desbloqueada através de uma tag que o jogador não vê, e o servidor só a aceita se essa personagem tiver o direito de dar essa pista. Um modelo que inventa uma pista que não lhe pertence é ignorado, não acreditado.
A língua como mecânica, não como tradução
Uma personagem responde de forma curta e defensiva em romeno, mas em russo torna-se faladora e perigosamente sincera — a regra está escrita no respetivo dossier, e a primeira fala em russo aumenta a confiança. O microfone segue a mesma língua (`ru-RU` ou `ro-RO`). Onde a localização é clássica, vamos mais longe: a simulação de robôs tem oito línguas, com o árabe marcado explicitamente como escrita da direita para a esquerda.
Simulação com fórmulas, não com impressões
A altura do salto escala com a razão das gravidades, o período de marcha com 2π√(L/g), o número de Froude com v²/(g·L), e a resistência do ar com a densidade da atmosfera do planeta. A autonomia da bateria passa por uma função de redução por temperatura com quatro limiares: acima de 20 °C sem alteração, acima de 0 °C `0,85 + 0,0075·T`, acima de −20 °C `0,55 + 0,015·T`, acima de −40 °C `0,12 + 0,02·T`, e abaixo disso 5 %. A marcha é cinemática inversa com dois segmentos, resolvida pela lei dos cossenos, com fator de apoio 0,6 por ciclo.
Som e voz construídos, não descarregados
A atmosfera do jogo de investigação não tem qualquer ficheiro áudio: a chuva é ruído rosa filtrado com passa-baixo a 1.400 Hz e passa-alto a 300 Hz, em loop; o crepitar do vinil são impulsos curtos gerados a cada 180 ms; o trovão é uma explosão de ruído com decaimento exponencial, programada para 18–48 segundos. A chuva visual é um canvas 2D separado, até 180 gotas inclinadas. A voz funciona nos dois sentidos: ditado através da interface de reconhecimento do browser e falas sintetizadas por personagem via ElevenLabs `eleven_multilingual_v2`, MP3 44,1 kHz / 128 kbps.
Formato de modelo 3D para o qual ainda não existe um carregador pronto
Os robôs Unitree G1 e Go2 vêm em MJCF, o formato MuJoCo, que não tem um carregador padrão para Three.js. Escrevemo-lo: 170 linhas que leem o XML, reconstruem a hierarquia de corpos, extraem cada articulação com o seu eixo e intervalo, e carregam a geometria através de `STLLoader` e `OBJLoader`. Entram em cena 67 ficheiros de mesh, 62 MB — 29 articulações acionadas no humanoide, 12 no quadrúpede, contadas no bloco `<actuator>` de cada modelo.