Lavoro · 2026
Verbris: come ho creato un gioco in un mese usando l'IA
828 commit tra il 4 giugno e il 2 settembre 2026, nessuno scritto a mano. Com'è nato Verbris, browser game a metà tra Ruzzle e Tetris, e tutto quello che ho costruito e poi cancellato.
Le date che leggi qui sono quelle dei commit: 828, dal 4 giugno al 2 settembre 2026. Le immagini non sono mockup. Ho fatto girare il codice com’era in ciascuna tappa e ho catturato lo schermo.
Il punto di partenza
Il 4 giugno 2026 apro un editor e comincio Verbris, un browser game a metà fra Ruzzle e Tetris. Da Ruzzle prende le parole formate muovendosi su lettere adiacenti, da Tetris la gravità: quando elimini una parola le lettere sopra cadono, e una griglia di riserva nascosta rifornisce dall’alto. Due giorni dopo era online per davvero, con deploy su Vercel e Railway.
La primissima versione pubblicata. Il gioco si chiamava ancora WordCrush e si giocava trascinando il dito sulle lettere.
Nel titolo scrivo “un mese” perché giugno è bastato: a fine mese il gioco aveva account, statistiche, classifiche, un generatore di puzzle in quattro lingue e un server che, invece di fidarsi del punteggio ricevuto, rigioca la partita per verificarlo. Quello che è successo da luglio in poi è stato un lavoro di natura diversa, e cioè decidere cosa di quel primo mese meritava di restare. È la parte che mi interessa di più raccontare.
Di righe di codice non ne ho scritta nessuna. Tutti e 828 i commit sono usciti da un’agente IA, Claude Code, a cui davo istruzioni, di cui leggevo i diff e a cui rimandavo indietro il lavoro quando non mi convinceva. Non gli ho chiesto “fammi un gioco”: gli ho chiesto una specifica alla volta. Parto dal metodo perché senza quello i numeri qui sotto valgono poco.
Il metodo: quarantacinque volte lo stesso giro
Nel repository ci sono 45 documenti di specifica, 45 piani di implementazione e 16 audit del codice, scritti prima o subito dopo il codice a cui si riferiscono. Il giro è sempre quello:
- Una specifica in italiano, cosa deve succedere e perché, prima di aprire un file. Per dire:
2026-06-12-daily-session-anticheat-design.md,2026-07-06-modello-rituale-design.md. - Un piano che spezza la specifica in passi, con l’elenco dei file coinvolti.
- L’implementazione, che scrive l’IA e che rivedo diff per diff.
- Ogni tanto un audit, cioè una passata dedicata solo a cercare codice morto, duplicazioni e complicazioni inutili. L’ultimo è del 30 agosto.
- La verifica, che non è “mi sembra che funzioni”: 463 test sul frontend, 16 sul backend, type-check, lint, e per il generatore di puzzle un controllo di non regressione (
pnpm gen:golden) che deve restare verde a impronta invariata.
Se salti la specifica, un’IA ti scrive lo stesso il codice, e pure in fretta. Il problema arriva tre settimane dopo, quando quel codice funziona ancora ma nessuno, tu compreso, sa più dire perché una certa regola è scritta così. La chat che l’ha prodotto è chiusa da un pezzo. La specifica resta.
Giugno, i 459 commit fondativi
Il primo problema serio arriva dopo tre giorni: il trascinamento del mouse, sullo schermo del telefono, è scomodo. Il 7 giugno il gioco passa al tap-to-play e la home viene ridisegnata. Da lì smette di essere un esperimento da scrivania.
Dopo il tap-to-play: layout compattato e “Come si gioca” spostato in un pannello a comparsa, invece di occupare spazio fisso.
Il mese poi accelera. Arrivano le statistiche giocatore, le classifiche globali, gli amici, l’autenticazione, un popup di fine partita sempre più elaborato, gli effetti sonori generativi. Il 18 giugno c’è un redesign completo dell’interfaccia: design token dichiarati una volta sola con @theme di Tailwind, celle con più stati visivi, timer con barra invece del solo testo, onboarding contestuale che non blocca il gioco.
Il redesign del 18 giugno. Il nome è ancora WordCrush e in alto a destra c’è ancora il pulsante “Accedi”.
La griglia nello stesso periodo: timer con barra colorata, blocchi 2×2, celle dorate, onboarding ancora in sovraimpressione.
Sotto la superficie però il commit che conta più di ogni redesign è quello del 20 giugno, replayRun condiviso. Da lì in poi il server smette di calcolare il punteggio a modo suo: rigioca le mosse che riceve con lo stesso motore del client, e se il risultato non torna scarta la partita. Client e server eseguono lo stesso codice, non due implementazioni parallele della stessa regola. Ha governato ogni feature successiva.
Il 30 giugno, un mese esatto dopo il lancio, il gioco cambia nome. Da WordCrush a Verbris, con trasferimento sul nuovo dominio. Rinominare un prodotto già online e con utenti veri costa: link condivisi che si rompono, indicizzazione da rifare, riconoscibilità azzerata. L’ho fatto perché WordCrush suonava come il clone di qualcos’altro, mentre Verbris (da verbum) portava dentro l’identità multilingua che il gioco stava prendendo.
Roba che ho costruito e poi cancellato
Nei case study questa parte di solito non c’è, e secondo me è quella che insegna di più quando lavori con un’IA che scrive codice a quella velocità. Se la salto sembra che ogni decisione sia stata giusta al primo colpo, e non è andata così.
Login, amici e classifica globale: giugno, poi cancellati il 15 agosto
A giugno il gioco aveva account, autenticazione, inviti fra amici e una classifica mondiale.
Il modale di accesso e registrazione. Oggi non è più raggiungibile: il codice che lo produceva è stato eliminato, non solo nascosto.
Il 6 luglio, un mese dopo averlo costruito, ho deciso di rinunciare alla classifica mondiale e all’identità persistente. Il motivo è tecnico. Una classifica globale seria ha bisogno di un anti-cheat robusto, altrimenti basta cambiare dispositivo o svuotare la cache per mandarci dentro un punteggio inventato. Quell’anti-cheat erano settimane di lavoro, e servivano a trasformare tre minuti di rituale quotidiano in una gara. Verbris non volevo che fosse quello.
Cinque settimane dopo, il 15 agosto, ho fatto la cosa che di solito si rimanda: invece di nascondere login, amici e classifica dietro un flag, li ho eliminati dal codice. Circa 1300 righe, cancellate. Tenerle lì “per dopo, non si sa mai” è il modo più comune di accumulare codice morto che poi nessuno osa più toccare.
La classifica del primo tentativo, durata una serata
Sempre il 6 luglio, prima di arrivare al modello definitivo (conta il punteggio migliore, ritentativi illimitati), ho fatto implementare l’alternativa che sembrava più onesta: conta solo il primo tentativo della giornata, e chi vuole rigiocare lo fa in una modalità Allenamento separata. L’ho vista funzionare e l’ho buttata la sera stessa. Senza identità verificata, “conta solo il primo tentativo” si aggira come qualsiasi classifica, cambiando dispositivo. Metteva attrito a chi gioca onestamente senza fermare nessun altro.
La classifica globale, cinque giorni di vita
Il 10 giugno il popup di fine partita guadagna un toggle Ufficiale/Migliore per confrontarsi con i punteggi globali. Il 15 giugno, passando al modello “conta il migliore”, quel confronto non voleva più dire niente, e mischiare tentativi ufficiali e liberi in una classifica sola confondeva e basta. Via il toggle e via lo store leaderboard che lo alimentava.
Il popup di fine partita del 10 giugno con il toggle della classifica globale: costruito il 10, rimosso il 15.
Il popup di conferma d’uscita, tre giorni
Il 12 giugno costruisco un anti-cheat per la partita giornaliera, con una finestra temporale lato server e un popup che chiede conferma prima di uscire a metà (uscire valeva come invio parziale). Lo rimuovo il 15 insieme all’invio parziale: nel frattempo il modello era diventato “conta il migliore”, quindi uscendo a metà non perdevi più niente e quella conferma era solo un ostacolo. Un pezzo di interfaccia sensatissimo il lunedì diventa fastidio il giovedì, se sotto gli cambi il modello.
I video promozionali con il bot
Ad agosto ho fatto costruire una pipeline che generava clip promozionali con mosse del bot in tre varianti (quiz, community, playout). Sono rimaste in produzione un po’, poi le ho tolte. La clip che pilota l’app vera, con il timer che scorre e una mossa vera, funzionava meglio del bot che finge di giocare.
Le due regole che non ho più toccato
Due vincoli sono diventati intoccabili al punto da avere una sezione dedicata nella guida che l’IA legge all’inizio di ogni sessione.
Il primo: client e server condividono il codice. game-core, il pacchetto che decide se una mossa è valida e quanto vale, è importato tanto dal frontend quanto dal backend. Se il client applicasse un bonus che il server non conosce, il replay scarterebbe ogni partita legittima. La regola vive in un posto solo e la chiamano in due.
Il secondo: il determinismo. La stessa giornata deve produrre la stessa identica griglia per tutti, nella stessa lingua, e il replay del server deve consumare la stessa sequenza casuale che ha visto il client. L’RNG seedato sta in un unico modulo, nei percorsi che contano non c’è un solo Math.random(), e nemmeno il generatore offline guarda mai l’orologio.
Una terza regola è arrivata più tardi, da un bug vero: ad agosto lo stato di Cruciverbris sopravviveva dentro la giornaliera classica, che si ritrovava indizi e regole non suoi. Da lì la scelta di trattare le modalità come dati, con otto tabelle Record<GameMode, …> per campi, comportamento, schermate, menu, tutorial e fine partita. Se aggiungo una modalità e dimentico una riga, il compilatore TypeScript si rifiuta di compilare. Non è eleganza: è un modo per rendere quel bug impossibile una seconda volta.
C’entra con l’IA più di quanto sembri. Un’agente rispetta molto meglio un invariante che il compilatore controlla di quanto rispetti un’istruzione ripetuta a voce in ogni chat. Un Record<GameMode, …> vale dieci righe di CLAUDE.md.
Agosto, 335 commit e quattro modalità
Agosto è il secondo mese più intenso, quello in cui il gioco smette di essere un puzzle e diventa un piccolo insieme di modalità sullo stesso motore.
Cruciverbris (nel codice si chiama ancora definition*, non l’ho mai rinominato) svuota la griglia risolvendo una catena di indizi, una parola per volta: circa 2600 indizi scritti a mano in quattro lingue, che coprono agosto e settembre con giornate a tema. Verbr-Flip gira le lettere invece di eliminarle, senza gravità: è completa e testata, ma sta fuori dal menu, nascosta da una riga di codice (visible: () => false). Non è lavoro incompiuto, è un rilascio rimandato, che è un’altra cosa rispetto alle rimozioni di prima. E poi c’è il percentile di fine giornata: nessun account, ma ogni partita finisce in un istogramma anonimo e a fine partita vedi dove ti collochi. È l’unica cosa collettiva che il server sa, senza sapere chi sei.
La home rebrandizzata Verbris, con le modalità come voci di menu, agosto 2026.
Il popup di fine partita
Se c’è un pezzo di interfaccia che racconta da solo come si è mosso il progetto è questo. Il 16 giugno, tolta la conferma d’uscita, arriva un redesign delle statistiche con tendine per navigare fra le viste, grafici delle ultime otto giornate e percentile storico. Qui la direzione è opposta a quella delle rimozioni: non togliere attrito, ma dare contesto. “Hai fatto 120 punti” da solo non dice niente.
Il popup statistiche oggi: streak, stelle, giorni Legend e due grafici. È la stessa idea del 16 giugno, rifinita.
L’ultima aggiunta è di inizio settembre: una celebrazione visiva che cresce insieme al percentile, più festosa man mano che sali. Ho scelto di non mettere una soglia minima di partite prima di mostrarla, pur sapendo che nelle prime ore della giornata il campione è piccolo e il numero può essere generoso. Preferisco che chi gioca alle sette del mattino veda la festa, e che il numero si assesti da solo durante la giornata.
Il riepilogo di fine partita oggi, qui in Senza tempo e catturato senza completare parole, per questo il punteggio è a zero. Nella Sfida Giornaliera lo stesso componente mostra anche il percentile.
Nel frattempo il gioco ha cominciato a promuoversi da solo: una pipeline pilota una vera istanza dell’app in Chrome headless e ne ricava video verticali con timer retrodatato e mossa reale, pronti per YouTube, Instagram e TikTok, con i testi pescati da un insieme di varianti per non ripetere due volte di fila lo stesso messaggio.
Il tema chiaro
Ultima evoluzione visiva, presente da agosto: un tema chiaro completo. Non un filtro sopra i colori esistenti, ma sfondo, tessere, pannelli e stati ridisegnati per entrambi i temi.
La stessa home di oggi, in tema chiaro.
La griglia di gioco in tema chiaro.
I numeri
- 828 commit dal 4 giugno al 2 settembre 2026, nessuno scritto a mano.
- 459 a giugno, 335 ad agosto. Luglio è il mese con meno commit e con le decisioni più pesanti.
- 45 specifiche, 45 piani, 16 audit del codice.
- Una ventina di commit che rimuovono o annullano qualcosa di già costruito.
- 5 modalità di gioco sullo stesso motore, in italiano, francese, spagnolo e inglese.
- Circa 2600 indizi scritti a mano per Cruciverbris e 204 liste tematiche.
- 463 test sul frontend, 16 sul backend, più la rete di non regressione del generatore.
Tre mesi dopo
L’IA non l’ho usata per scrivere codice più in fretta di quanto lo scriverei io. L’ho usata per potermi permettere di cambiare idea. Costruire login, amici e classifica a giugno e buttarli ad agosto, scrivendo ogni riga a mano, sarebbero state settimane bruciate su una scommessa di prodotto: nella pratica non lo avrei fatto, avrei tenuto tutto e avrei chiamato “roadmap” il fatto di non saper decidere. Quando una specifica diventa codice in poche ore quel calcolo cambia, e il vincolo si sposta altrove: non è più quanto in fretta scrivi, è quanto sei disciplinato nel decidere cosa tenere. Le 45 specifiche e i 16 audit servono a quello.
L’architettura di fondo, codice condiviso fra client e server, determinismo, modalità come dati, non l’ho mai dovuta riscrivere. Tutto il resto sì: il nome, l’autenticazione, il modello di punteggio, l’interfaccia quattro volte. Per questo “un mese” nel titolo non è una trovata: è il tempo che ci è voluto per avere un motore abbastanza solido da reggerci sopra altri due mesi di ripensamenti.