📚 Tutorial14 minuti di lettura

Ricrea Tetris in 20 Minuti con Claude Code

Tutorial pratico: come guidare un AI agent a produrre un gioco completo, modulare e con effetti arcade. Prompt engineering, context engineering e testing visivo.

AS

Alessandro Saiani

Human in the Loop

Ricrea Tetris in 20 Minuti con Claude Code

"Fammi un Tetris in JavaScript."

Cinque parole. Claude Code ti genera un file da 800 righe, tutto in un unico tetris.js. Funziona? Sì. E per un Tetris, probabilmente basta.

Ecco il problema: il Tetris funziona comunque. È un progetto abbastanza semplice che anche con il prompt più pigro del mondo ottieni qualcosa di giocabile. Ed è proprio per questo che è il progetto perfetto per costruire buone abitudini — perché la posta in gioco è bassa, ma il metodo che impari scala su tutto il resto.

Una nota onesta: un Tetris funzionante si può fare in 3 minuti. "Fammi un Tetris", invio, e Claude te lo genera. I 20 minuti del titolo sono una provocazione — è il tempo che ci vuole per farlo bene. Per ottenere codice organizzato, effetti, musica, e soprattutto per costruire un metodo di lavoro che su un progetto vero ti ripagherà cento volte.

Questo tutorial è il dietro le quinte di come abbiamo costruito Blocchi che Cadono, il gioco che puoi provare qui. Non per dimostrare che senza queste tecniche non si può fare — si può, in un decimo del tempo. Ma per mostrare un approccio che, quando il progetto diventa serio, fa la differenza tra codice che puoi evolvere e codice che devi buttare via.

Splash screen di Blocchi che Cadono


Il Risultato Finale

Prima di smontare il processo, ecco cosa abbiamo ottenuto:

  • Codice organizzato in file separati per responsabilità — niente monolite da 800 righe
  • 10 livelli con velocità crescente
  • Effetti visivi: particelle esplosive, flash sulle righe, popup punteggio, ghost piece
  • Stile arcade anni '90: font Press Start 2P, bordi neon, glow su tutto
  • Due tracce musicali che si alternano in loop (generate con AI — ne parliamo tra poco)
  • Splash screen animata con blocchi che cadono sullo sfondo
  • Controlli mobile e canvas responsive

Tutto vanilla JavaScript, zero dipendenze. Non è un progetto complesso — è un gioco semplice, organizzato in modo che si possa capire e modificare.


Lezione 1: Non Chiedere "Fammi un Tetris"

"Fammi un Tetris" funziona. Ottieni un gioco giocabile. Ma ottieni anche un monolite da 800 righe che non puoi toccare senza rompere qualcosa. Per un Tetris va bene — per il prossimo progetto, no.

Tobi Lutke, CEO di Shopify, ha reso popolare un termine che spiega la differenza: context engineering"the art of providing all the context for the task to be plausibly solvable by the LLM". Non è prompt engineering — non si tratta di trovare la frase magica. Si tratta di dare all'agente il contesto giusto su come vuoi che lavori, non solo cosa vuoi che faccia.

Il bello è che non serve molto. Bastano due righe in più.

Il prompt che ha fatto la differenza

Costruisci un gioco Tetris in vanilla JS con Canvas.
Non mettere tutto in un unico file. Separa logica di gioco,
rendering, input, effetti e audio.
Ogni file fa una cosa sola. Tienili corti.

Non serve elencare dieci file — basta dare una direzione. Claude è bravo a decidere come dividere, se gli dici che deve dividere. Il prompt non descrive cosa è un Tetris (lo sa), ma come organizzare il codice. Ci vuole un minuto in più a scriverlo, e ti abitua a pensare all'architettura prima di scrivere codice — con o senza AI.


Lezione 2: Dai Vincoli, Non Libertà

Anche su un progetto semplice, i vincoli migliorano il risultato. Non perché senza Claude non ce la fa — ce la fa benissimo. Ma perché ti abituano a ragionare su come vuoi il codice prima che esista. Ed è un'abitudine che su un progetto vero ti salva settimane.

Ecco i vincoli che abbiamo dato progressivamente:

Vincolo strutturale

Non mettere tutto in un file. Separa logica, rendering, input, audio.
Nessun file oltre 150 righe.

Sembra poco, ma cambia tutto. Senza questa indicazione, Claude infila audio, rendering, input ed effetti tutti dentro game.js. Con il vincolo, separa spontaneamente e ogni pezzo resta gestibile.

Vincolo di stile

Stile arcade anni '90, tipo cabinato. Font pixel, sfondo scuro,
bordi neon, colori vivaci. Niente gradienti moderni sui bottoni.

Non serve dare hex code — basta una direzione chiara. Claude conosce benissimo l'estetica arcade e sceglie colori coerenti. Se poi il risultato non ti convince, correggi iterando (e qui entra Playwright, come vedremo).


Lezione 3: Iterazione con Feedback Visivo

Questa è la tecnica che cambia tutto: non leggere il codice, guarda il risultato.

Abbiamo usato Playwright MCP (il server MCP di Microsoft per l'automazione del browser) integrato in Claude Code per verificare visivamente ogni modifica. Il workflow:

  1. Claude genera/modifica il codice
  2. Playwright apre il browser e naviga alla pagina
  3. Prende uno screenshot
  4. Claude analizza lo screenshot e corregge

Non stai facendo code review — stai facendo visual review. Ed è enormemente più efficace per la UI.

Esempio concreto: i font troppo piccoli

Dopo il primo rendering, i panel laterali con punteggio e livello erano illeggibili. Non abbiamo aperto il CSS per misurare i rem — abbiamo semplicemente detto:

Le scritte dei panel sono troppo piccole, quasi illeggibili. Aumenta.

Claude ha aumentato. Ancora troppo piccole. "Ancora più grandi." Terzo tentativo, finalmente leggibili. Tre iterazioni, nessuna in cui abbiamo dovuto guardare il codice.

Esempio: il bottone non è arcade

Il bottone "GIOCA" che Claude ha generato al primo tentativo sembrava un pulsante di una SaaS — gradiente, bordi arrotondati. Il feedback:

Lo stile del bottone non sembra arcade come il resto del gioco.

Un'unica frase. Claude lo ha trasformato in un bottone con bordo neon su sfondo scuro, font pixel, glow sottile. Non abbiamo specificato colori o font — abbiamo detto cosa non andava, e lui ha capito il contesto.


Lezione 4: Gestisci i Problemi del Browser

Questa è la parte che nessun tutorial "vibe coding" ti racconta: i problemi reali.

Il caso dell'audio che non parte

Volevamo la musica sullo splash screen — un'ambient track che parte quando arrivi alla pagina. Il codice era perfetto:

const splashTrack = new Audio('/Blocchi%20che%20Cadono.mp3');
splashTrack.play();

Non funzionava. Mai. Motivo: le autoplay policy del browser. Chrome, Firefox, Safari — tutti bloccano la riproduzione audio finché l'utente non fa un gesto reale (click, keydown, touchstart). mousemove non basta.

La soluzione arcade: "PREMI UN TASTO PER INIZIARE". Un testo lampeggiante in stile insert coin che aspetta un qualsiasi input dell'utente. Al primo tasto, la musica parte e appare il bottone GIOCA.

// Qualsiasi gesto reale sblocca l'audio del browser
function insertCoin() {
  if (coinInserted) return;
  coinInserted = true;
  music.start(); // Ora funziona: è dentro un gesto utente
  $insertCoin.classList.add('hidden');
  $playArea.classList.remove('hidden');
}

document.addEventListener('keydown', insertCoin);
document.addEventListener('click', insertCoin);
document.addEventListener('touchstart', insertCoin);

Elegante? Molto. Ma ci siamo arrivati dopo aver provato autoplay diretto, listener su mousemove (che non è un user activation event), e un sistema a due fasi con fade.

Il punto: l'AI non conosce sempre le restrizioni del browser. Tu sì, o le scopri testandolo. Il testing con Playwright ci ha fatto trovare il problema immediatamente.


Lezione 5: Separa Quel Che Ha Senso Separare

Non serve un'architettura enterprise per un Tetris. E un Tetris funziona anche tutto in un file. Ma quando hai cambiato il sistema audio tre volte in una sessione (da due tracce separate a playlist alternata), apprezzi il fatto che ogni modifica tocca solo il file dell'audio e l'entry point. Il resto del gioco non ha sentito nulla.

Non è overengineering — è che Claude ha diviso il codice in file separati perché gliel'abbiamo chiesto in una riga del prompt iniziale. Non ha richiesto più tempo. E il vantaggio è che se qualcosa non funziona, sai dove guardare.

Su un Tetris la differenza è piccola. Su un progetto reale, è la differenza tra "riscrivo tutto" e "cambio un file".


Lezione 6: Gli Effetti Fanno il Gioco

Un Tetris senza effetti è una griglia con quadrati che cadono. Gli effetti sono ciò che lo rende un'esperienza. Ed è un'area dove l'AI brilla, se la guidi bene.

Particelle esplosive

Quando completi una riga, ogni cella esplode in particelle colorate che seguono la gravità e svaniscono. Il prompt:

Quando completo una riga voglio un'esplosione di particelle.
Ogni blocco esplode nel suo colore originale.

Due righe. Il dettaglio chiave è "nel suo colore originale". Senza questa specifica, Claude usa un colore generico. Con questa, fa uno snapshot della board prima del clear e usa quei colori per le particelle. Un piccolo prompt che produce un effetto molto più ricco.

Score popup

// +100 per una riga, +800 per un TETRIS (4 righe)
if (linesCleared >= 4) {
  el.textContent = `TETRIS! +${points}`;
  el.style.color = '#a855f7';  // viola neon
  el.style.fontSize = '2.2rem';
}

Il popup galleggia verso l'alto e svanisce. Per un Tetris (4 righe), è più grande, viola, con glow intenso. Un piccolo dettaglio che rende il completamento di 4 righe emozionante.

Flash sulle righe

Un lampo bianco orizzontale che attraversa la riga completata in 350ms. Tre righe di CSS, impatto visivo enorme.

La schermata di gioco con pezzi, panel laterali e controlli


Lezione 7: Testa Tu, Non Solo l'AI

C'è un momento in cui Playwright e gli screenshot automatici non bastano: devi giocare.

Dopo aver dichiarato il gioco "finito", abbiamo fatto una sessione di test manuale. In pochi minuti sono emersi bug che nessun test automatizzato avrebbe trovato:

  • Input che si accumulava: premendo un tasto mentre il pezzo precedente si stava posando, il comando passava al pezzo successivo. Il timer di auto-drop e l'input manuale non erano sincronizzati — il pezzo scendeva due volte di fila.
  • Listener duplicati: ogni volta che premevi "GIOCA ANCORA", veniva aggiunto un nuovo handler per la tastiera. Alla terza partita, ogni tasto muoveva il pezzo di tre posizioni.
  • Pausa rotta: un riferimento a un modulo audio rimosso durante un refactoring causava un crash silenzioso quando riprendevi dalla pausa.

Tre bug, tre categorie diverse, tutti invisibili a un test automatizzato perché richiedono interazione umana reale — timing, sequenze, sessioni prolungate.

La lezione: l'AI genera il codice, Playwright verifica che si veda giusto, ma il test finale sei tu. Gioca, rompi, correggi.


Lezione 8: Il Workflow Completo

Ricapitoliamo il processo in ordine cronologico:

Minuti 0-3: Architettura

Prompt iniziale con struttura modulare, vincoli di dimensione, stack tecnologico.

Minuti 3-10: Core gameplay

Board, pezzi, collisioni, rotazione con wall kicks, sistema di livelli, calcolo punteggio. La parte "logica" che Claude fa bene al primo tentativo.

Minuti 10-15: Stile e feedback visivo

Qui entra il loop visivo con Playwright. Splash screen, font arcade, colori neon, panel laterali. Ogni modifica verificata con screenshot.

Minuti 15-18: Effetti e polish

Particelle, flash, popup, ghost piece, countdown 3-2-1-GO. Il layer che trasforma un prototipo in un prodotto.

Minuti 18-20: Audio e fix browser

La parte più insidiosa. Autoplay policy, gestione pause/resume, playlist alternata.

Bonus: iterazione post-20 minuti

Background e logo generati con AI, fine-tuning dei font size, controlli mobile, toggle ghost piece, test umano e bug fixing. La differenza tra "funziona" e "è bello da usare".


I Prompt che Non Hanno Funzionato

Sarebbe disonesto mostrare solo i successi. Ecco cosa non ha funzionato:

"Rendilo più bello" — troppo vago. Claude cambia colori a caso, aggiunge ombre dove non servono, e rimuove cose che funzionavano. Specifica cosa non ti piace.

"Aggiungi musica allo splash" — Claude ha generato un new Audio().play() diretto, che il browser blocca. Serviva il contesto delle autoplay policy.

"Stile arcade" — senza specifiche sui colori, Claude interpreta "arcade" come "pixel art con colori pastello". Servono hex code esatti.

Logo con sfondo scuro — al primo tentativo di generare immagini con AI, lo sfondo era bianco nonostante "dark background" nel prompt. Serviva un prompt molto più aggressivo: "Black background. Neon-colored blocks floating in space. No white. No light backgrounds."


Cosa Puoi Fare Tu Adesso

  1. Gioca a Blocchi che Cadono e guarda il codice sorgente — è tutto leggibile
  2. Forka il pattern: la stessa architettura modulare funziona per Snake, Breakout, Space Invaders
  3. Sperimenta con i vincoli: prova a dare a Claude lo stesso prompt senza la struttura modulare e confronta i risultati
  4. Usa Playwright MCP: se non l'hai ancora configurato, è il singolo tool che migliora di più la qualità dell'output AI per qualsiasi progetto frontend

Un Tetris si fa anche senza niente di tutto questo. Ma il prossimo progetto non sarà un Tetris — e le abitudini che costruisci adesso sono quelle che userai allora.


Fonti

  1. Tobi Lutke — "Context Engineering" — il tweet che ha reso popolare il termine
  2. Andrej Karpathy su Context Engineering — conferma e amplifica il concetto
  3. Anthropic — Claude Code Best Practices — documentazione ufficiale su rules file e CLAUDE.md
  4. Microsoft Playwright MCP Server — repository ufficiale per testing visivo con AI
  5. Simon Willison — Playwright MCP con Claude Code — setup e uso pratico
  6. MDN Web Docs — Autoplay Policy — le restrizioni browser sull'audio

Se hai giocato a Blocchi che Cadono, avrai notato che senza la colonna sonora sarebbe stato un esercizio tecnico — con la musica è diventato un'esperienza. Quelle due tracce le abbiamo generate con Suno AI, in pochi minuti, senza sapere una nota. Nei prossimi giorni ti mostriamo come.