Claude mi ha permesso di trasformare un’avventura testuale Z5 in un nastro virtuale per ZX Spectrum 128K, modificando un interprete, risolvendo bug e creando una procedura automatizzata riutilizzabile. Un caso concreto di “programmazione agentica” applicata al recupero del software “storico” (da cui è nata una skill dedicata). Ah, prima che cominciate a leggere, avete notato (nell’immagine di cover) che l’IA può ancora sbagliare il numero delle dita? 😉
Il prompt, e la “locomotiva nella scatola”
Il prompt era quello che scriverebbe chiunque abbia passato quarant’anni a divulgare tecnologia dopo aver scritto avventure testuali con The Quill, cioè con la leggerezza di chi è convinto che il diavolo stia sempre nei dettagli… degli altri. Allego un file (più avanti vi spiego di che si tratta), cursed-planet.z5, e chiedo a Claude due cose: scaricare un interprete Z-machine per lo ZX Spectrum e impacchettare interprete e storia in un .tap o in un .tzx, con quei tool classici (TAPir, ZX-Blockeditor, Fuse) che ogni retro-smanettone conserva nel cassetto accanto ai floppy da cinque pollici e alle cassette dei bei tempi.

In quelle due righe c’erano già due problemi, e la cosa interessante è come sono stati trattati. Il primo era mio, anzi di AI Mode: Evince era stato inizialmente indicato dall’IA di Google come possibile interprete (vedi screenshot sopra), ma si tratta di un visualizzatore di PDF, e Claude me l’ha fatto notare immediatamente, senza compiacimento e senza darmi il tempo di arrossire per la gaffe, passando poi subito a ZXZVM di John Elliott, che esiste davvero e legge i file Z5. Il secondo errore era più sottile, e più serio, perché ZXZVM nasce per leggere la “storia” da disco (+3DOS, oppure ResiDOS), mentre un nastro, per sua natura, non conosce l’accesso casuale: mettere interprete e racconto in un unico TAP, come chiedevo io, equivaleva a infilare una locomotiva e un chilometro di binari in una scatola da scarpe aspettando che il treno partisse da solo (se la metafora vi suona esagerata, prendetevela con Claude).
Un assistente che si limita a rispondere avrebbe prodotto, a quel punto, un file con l’estensione giusta e un sorriso (virtuale) incoraggiante, di quelli che si scoprono finti soltanto davanti all’emulatore, cioè nel peggior momento possibile. Claude invece si è fermato, mi ha spiegato perché la strada ovvia non portava da nessuna parte e mi ha messo davanti alle alternative concrete, tra cui una che nessuno aveva chiesto e che io, con un certo fiuto per le imprese poco ragionevoli, ho scelto subito: un port di ZXZVM fatto apposta per il nastro.
Quando l’assistente smette di rispondere e comincia a lavorare
Su questo passaggio vale la pena fermarsi, perché è qui che “AI agentica” smette di essere una formula da convegno e diventa un vero e proprio “mestiere”: da quel momento l’assistente non mi ha più descritto cosa si poteva fare: l’ha fatto, semplicemente (si fa per dire). Lavorando sulla sua macchina virtuale in sandbox ha recuperato i sorgenti di ZXZVM 1.12 (software libero, GPL, con tutto ciò che ne consegue in termini di buone maniere), ha installato l’assemblatore, ha riscritto i due moduli che nell’originale parlavano con il disco, e li ha sostituiti con altri che distribuiscono la storia, quasi sessantottomila byte di testo e logica che nella memoria di un 128K non starebbero in un posto solo, su quattro banchi di RAM paginati (con la coda, quella che avanza, parcheggiata in un quinto banco che di giorno fa anche da “schermo ombra”), e che per salvare e ripristinare la partita usano le routine della ROM al posto di un floppy.

Il punto, però, non è la quantità di codice (che in fondo, a ben vedere, è la parte più noiosa) ma l’ambiente “chiuso” in cui è stato scritto, la famosa sandbox: ogni modifica veniva assemblata, impacchettata in un nastro virtuale e caricata in un emulatore Spectrum 128K senza “testa” e senza monitor, dove l’assistente premeva i tasti, aspettava, fotografava lo schermo e guardava lo “scatto”, come un vecchio programmatore che legge un listato con la matita dietro l’orecchio (e io intanto potevo osservare gli screenshot del processo). Quando il gioco ha risposto “The game file has verified as intact” (che per un sistema che deve garantire che sessantottomila byte siano arrivati interi da una cassetta virtuale è un po’ come sentirsi dire dal medico che i valori sono perfetti), il caricamento era durato, in tempo emulato, circa nove minuti: più o meno quelli che serviva davvero aspettare, nel 1986, davanti a una cassetta con le righe colorate sul bordo.
Gli inciampi, cioè la parte istruttiva
Sarebbe bello raccontare che tutto è filato liscio, e sarebbe anche falso, in questo caso, il che nella nostra epoca di racconti patinati sull’intelligenza artificiale è già una ragione sufficiente per non farlo. Il primo ostacolo serio è stato un “fantasma”: il gioco non partiva, il caricamento finiva e restava il BASIC con il suo cursore, finché Claude, indagando sulla memoria come un detective, ha scoperto che il modulo di input e output dell’interprete vive all’indirizzo 16384, cioè nella RAM dello schermo, e che i messaggi “Bytes:” che il BASIC scrive caricando ogni blocco lo stavano cancellando un po’ alla volta, con la disinvoltura di un cameriere che sparecchia il tavolo mentre sei ancora seduto. La cura, come spesso accade, è stata di una banalità imbarazzante: caricare quel modulo per ultimo.
Il secondo ha un sapore ancora più retrò, perché riguarda la barra spaziatrice. Nel salvare la partita su nastro, la ROM dello Spectrum interpreta uno spazio tenuto premuto a fine blocco come la richiesta di interrompere tutto (il celebre BREAK, che sui vecchi manuali compariva sempre in un angolo con l’aria di una minaccia), e Claude, dopo aver scoperto l’accaduto, ha aggiunto all’interprete una piccola attesa che il tasto venga rilasciato prima di cominciare a registrare.
Ci sono poi stati gli errori dei test e non del codice, che sono i più umilianti perché si pagano due volte: porte virtuali che per una decodifica parziale dell’hardware finivano per scrivere nel registro di paginazione, interrupt che andavano disattivati nei punti giusti, un caricatore di prova che sbagliava l’indirizzo della coda e faceva fallire una verifica che il nastro vero avrebbe passato. In ciascuno di questi casi la correzione è arrivata prima che io avessi il tempo di accorgermi che ci fosse qualcosa da correggere, e questo è, a ben vedere, il vero significato della parola “agentico”: anziché un “assistente che non sbaglia”, uno che sbaglia, se ne accorge da solo, e sistema il problema.
Dal gioco al metodo (e il mio “non succede nulla”)
Un nastro che funziona con un solo gioco è un esperimento, mentre un procedimento che funziona con il secondo è l’inizio di un mestiere, e per questo il passo successivo è stato trasformare tutto in una skill: una procedura scritta che racconta all’assistente cosa controllare prima (che il file sia uno Z5, che stia fra i 64 e i 72 KB, che la memoria dinamica non superi i 16 KB), come costruire il nastro, come verificarlo senza emulatore con una trentina di controlli statici (a partire dal più importante, cioè che la storia sul nastro coincida byte per byte con quella di partenza) e come provarlo con l’emulatore, e che gli dice anche quando fermarsi, dopo tre tentativi falliti, riferendo con onestà cosa è stato fatto e cosa no. Applicata a Unknown Dimension, la nuova versione del mio primo Dimensione Sconosciuta, la skill ha prodotto un nastro valido e ha trovato un bug nel proprio test, che premeva i tasti mentre il gioco era fermo a una paginazione e leggeva quindi “ave” al posto di “save” (una svista da principianti, di quelle che a chiunque abbia avuto a che fare con un’avventura testuale strappano un sorriso malinconico).
Poi è arrivata la mia parte di realtà: provati vari emulatori, con il TAP e con il TZX, non succedeva nulla. Claude non mi ha risposto che il problema era mio, ma ha ripercorso pazientemente l’intero caricamento a partire dalla “macchina spenta”, simulando anche il caricamento rapido che molti emulatori usano, ottenendo ogni volta il gioco in funzione, e ha concluso che i file erano buoni e che a mancare dovevano essere il modello giusto (128K e non 48K) o il menu giusto (Tape Loader), aggiungendo comunque al nastro un avviso sullo schermo per smascherare il colpevole. Quando infine, sull’emulatore Speccy 5.9, le prime righe di un’avventura sono comparse, erano in un carattere compresso a quattro pixel di larghezza, uno di quei font che sembrano usciti da un rullo compressore, e io, che di leggibilità nelle avventure testuali ne so qualcosa, visto che in questo mestiere ci vivo da una vita, ho mandato a Claude lo screenshot e ho fatto la domanda giusta: non si può usare il font standard? Si poteva, e senza nemmeno aggiungere un byte al nastro, puntando la modalità a 32 colonne direttamente al carattere della ROM. È questa, mi pare, la divisione del lavoro che funziona: l’occhio e il gusto di chi le avventure le gioca, la pazienza e il circuito di prova di chi non si stanca di ripetere.

Perché tutto questo riguarda “The BDB Project”
Le avventure che abbiamo convertito non sono capitate per caso: sono quelle che The BDB Project, grazie al lavoro di Gianluca Girelli e di Garry Francis, sta riportando dal Commodore 64 a una vita nuova, tradotte e ricostruite in Inform 6 con la libreria PunyInform e distribuite come file Z5 che qualunque interprete Z-code, dal browser al sistema operativo, sa leggere. Un file Z5 è, per definizione, la materia prima del nostro procedimento, e quindi quello che fino a ieri sarebbe stato un lavoro da fare a mano, gioco per gioco, con un assemblatore, un editor di blocchi e una pazienza da certosini, è oggi una procedura che parte da un file, controlla se rientra nei limiti, costruisce il nastro, lo verifica e racconta con onestà cosa è stato provato. I giochi sono stati messi a disposizione per varie piattaforme, soprattutto quelle del tempo, e persino per quelle che originariamente non erano comprese nelle conversioni “da edicola”. Mancava, tuttavia, la versione per Spectrum, ed è stato questo il motivo che mi ha spinto a “schiavizzare” Claude per ottenerla ed evitare un lavoro lungo e noioso ai carissimi Gianluca e Garry. Per i due giochi su cui l’ho messa alla prova la procedura (e la relativa skill, che poi renderò pubblica) ha funzionato, quindi per gli altri giochi presenti sul sito e su quelli futuri il primo gesto sarà comunque un controllo di compatibilità, perché non tutti, a priori, rientreranno nelle “misure standard”.
Resta da dire cosa non sappiamo, perché un racconto che “si vanta” soltanto è un cattivo racconto: i “nastri virtuali” sono stati provati in emulatori a 128K e non su un vero Spectrum, e nessuno ha ancora verificato il comportamento su +2A e +3, che hanno una gestione della memoria diversa. Potrò eseguire questo test nel fine settimana su The Spectrum, un “regalo” che mi sono concesso come premio per il mio intenso lavoro editoriale e di formazione. Intanto, chi possiede una delle macchine originali, e un registratore che ancora sopporti il fruscio dei nove minuti di caricamento, è invitato a riversare su nastro il file TAP e farci sapere com’è andata, perché l’unico “collaudo definitivo”, in questo genere di cose, è ancora quello dell’hardware originale. Le versioni Spectrum dei giochi saranno quindi rese disponibili gradualmente, insieme alle altre, sul sito ufficiale.
Quanto all’intelligenza artificiale agentica, credo che la lezione sia meno spettacolare di quanto si racconti e molto più utile: non ha inventato nulla di impossibile, piuttosto ha fatto con costanza ciò che un bravo programmatore farebbe in una settimana di sere libere (leggere, provare, guardare, sbagliare, correggere), mentre io ho fatto la parte che a una macchina ancora non riesce, cioè verificare criticamente e accorgermi anche come il testo fosse troppo poco leggibile. Il resto, come si usava dire quando si caricava da cassetta, è stata pazienza, e un po’ di fortuna (come con il volume, o l’azimut, del registratore).
Ah, dimenticavo, anche questo articolo è stato scritto con l’assistenza di Claude, interagendo con l’IA dopo averla “guidata” a confezionarlo in base agli obiettivi e alle fonti (vi lascio qui sotto uno screenshot relativo a quest’ultimo task).

















