Prima la regola, poi la grafica
Un prototipo senza alcuna texture, ma con la regola giusta, dice più di una scena bella senza posta in gioco. Nel gioco di investigazione la regola significa cinque personaggi, otto indizi di cui tre sono prova forte, quattro motivi, quattro finali e un orologio di 72 ore in cui ogni replica taglia 10 minuti, mentre uno spostamento 30. Le ore 00:00–07:00 vengono saltate automaticamente, così l’orologio non si consumi nel sonno.
La scena nel browser, su Three.js
La stessa libreria in cinque depositi: Three.js 0.184–0.185, a volte tramite `@react-three/fiber` e `@react-three/drei`, altre volte scritta direttamente. Due progetti usano la variante React; altri due scrivono Three.js puro, fino al livello in cui gestiamo manualmente gli attributi del buffer. Il motore proprietario più grande ha 1.824 righe e disegna tutti i satelliti come un unico oggetto `THREE.Points`, con attributi di posizione, colore, dimensione e trasparenza aggiornati sul posto, frame per frame.
Rendering che scende da solo sui dispositivi deboli
Lo shader su questo sito ha tre livelli: `low` con 24 iterazioni di raymarching e rapporto pixel 0,5, `medium` con 40 e 0,65, `high` con 80, precisione `highp` e rapporto limitato a 2. La scelta è automatica: su mobile scende a `low`, e qualsiasi dispositivo con 4 core o meno lo retrocede da `high` a `medium`. Se WebGL manca, il componente si spegne in modo pulito invece di generare un errore. La stessa disciplina negli altri progetti: limite 1,6 nella scena di città e 1,75 in quella di terreno, 1,5 su mobile nel dimostratore di mondo, con il ciclo di rendering fermato quando il canvas esce dallo schermo.
Scene grandi che restano un unico disegno
Una città con 9.506 edifici non significa 9.506 oggetti. Ogni impronta di OpenStreetMap diventa una `ExtrudeGeometry` senza smusso e con `curveSegments: 1`, riceve il colore scritto direttamente nei vertici, le viene cancellato l’attributo `uv` — e poi tutto si fonde in una sola geometria tramite `mergeGeometries`. Gli anelli geometrici degenerati nei dati pubblici vengono saltati con `try`/`catch`, non lasciati a far crollare la pagina.
Personaggi che mentono, ricordano e cedono a condizioni
La verità del caso non sta nella pagina. I dossier dei cinque personaggi — biografia, segreto, la condizione in cui si rompe — stanno in un file che inizia con `import "server-only"` e non può essere importato dal client. Il personaggio segnala un indizio sbloccato tramite un tag che il giocatore non vede, e il server lo accetta solo se quel personaggio ha il diritto di dare quell’indizio. Un modello che inventa un indizio che non gli appartiene viene ignorato, non creduto.
La lingua come meccanica, non come traduzione
Un personaggio risponde in modo breve e difensivo in romeno, ma in russo diventa loquace e pericolosamente sincero — la regola è scritta nel suo dossier, e la prima replica in russo ne aumenta la fiducia. Il microfono segue la stessa lingua (`ru-RU` o `ro-RO`). Dove la localizzazione è classica, andiamo oltre: la simulazione dei robot ha otto lingue, con l’arabo marcato esplicitamente come scrittura da destra a sinistra.
Simulazione con formule, non con impressioni
L’altezza del salto scala con il rapporto delle gravità, il periodo di cammino con 2π√(L/g), il numero di Froude con v²/(g·L), e la resistenza dell’aria con la densità dell’atmosfera del pianeta. L’autonomia della batteria passa attraverso una funzione di decrescita in base alla temperatura con quattro soglie: sopra 20 °C invariata, sopra 0 °C `0,85 + 0,0075·T`, sopra −20 °C `0,55 + 0,015·T`, sopra −40 °C `0,12 + 0,02·T`, e sotto questo 5 %. Il cammino è cinematica inversa con due segmenti, risolta tramite la legge del coseno, con fattore di sostegno 0,6 per ciclo.
Suono e voce costruiti, non scaricati
L’atmosfera del gioco di investigazione non ha alcun file audio: la pioggia è rumore rosa filtrato passa-basso a 1.400 Hz e passa-alto a 300 Hz, in loop; il crepitio del vinile sono impulsi brevi generati ogni 180 ms; il tuono è un’esplosione di rumore con decadimento esponenziale, programmata a 18–48 secondi. La pioggia visiva è un canvas 2D separato, fino a 180 gocce inclinate. La voce va in entrambe le direzioni: dettatura tramite l’interfaccia di riconoscimento del browser e repliche sintetizzate per personaggio tramite ElevenLabs `eleven_multilingual_v2`, MP3 44,1 kHz / 128 kbps.
Formato di modello 3D per cui non esiste ancora un caricatore pronto
I robot Unitree G1 e Go2 arrivano in MJCF, formato MuJoCo, che non ha un caricatore standard per Three.js. L’abbiamo scritto: 170 righe che leggono l’XML, ricostruiscono la gerarchia dei corpi, estraggono ogni giunto con il suo asse e intervallo, e caricano la geometria tramite `STLLoader` e `OBJLoader`. In scena entrano 67 file di mesh, 62 MB — 29 giunti azionati per l’umanoide, 12 per il quadrupede, contati nel blocco `<actuator>` di ogni modello.