Riflessioni di un programmatore (di avventure testuali)

Chi scrive queste righe è un programmatore che, se non altro precauzionalmente, si definisce ancora neofita; mi sono dedicato / dedico alla programmazione di avventure testuali tramite Inform6. Ma chi scrive è anche prima di tutto, almeno cronologicamente, un appassionato di filosofia, nonché un appassionato del raccontare e delle suggestioni. Quindi, muovendo i primi passi come programmatore, gli è risultato praticamente impossibile non connettere le due cose, poiché le novità sono tali in quanto collidono efficacemente con la propria forma mentis, e le avventure testuali hanno rappresentato per me una notevole novità, dapprima come giocatore e poi come programmatore. Come giocatore potrei scrivere molte riflessioni sul tempo, sulla nostalgia… ma sarebbero commenti del tutto personali e quindi, probabilmente, di scarso interesse in quanto di portata “ristretta”. In qualità di programmatore, invece, sento che queste riflessioni hanno decisamente un più ampio respiro, e forse troppo ampio, col rischio di perdere lo stesso l’attenzione dei lettori.

Sperando non sia così, procedo col raccontare cosa penso ogni volta che prendo in mano (metaforicamente) il mio compilatore e inizio a digitare. Ma prima qualche preambolo per fare entrare nell’ottica chi è completamente a digiuno delle nozioni che servono.
 
Per scrivere un’avventura testuale ci si serve di un compilatore con cui compilare il codice sorgente ( = creare il file che si giocherà). Prima di iniziare la scrittura vera e propria vanno inclusi il parser e le librerie, ovvero “pezzi” di codice già scritti da altri autori contenenti le istruzioni di base (ad esempio, i comandi principali che vengono utilizzati, come il comando esamina, che così non hanno bisogno di essere riscritte ogni volta si programmi una nuova avventura testuale). Dopodiché si procede ad impostare le varie locazioni e gli oggetti in esse contenute, secondo come si è concepita l’avventura, cinematograficamente parlando: secondo il soggetto. Una volta impostate locazioni e oggetti si passa alla sceneggiatura, ovvero al modo in cui il giocatore agisce sugli oggetti.
Per ogni oggetto (di fatto anche le locazioni vengono considerate dal parser come oggetti) esistono diverse proprietà che possono essergli assegnate. Per quanto riguarda Inform6, una tra le più importanti è la proprietà before che, in particolare, indica come devono venire applicati i comandi reimpostati nelle librerie all’oggetto assegnato. Un esempio per chiarire: nella libreria ItalianG (realizzata da Giovanni Riccardi) esiste il verbo LookUnder che produce, di default, l’uscita “Non trovi nulla di interessante.”; tuttavia, se inserisco questo verbo nella proprietà before di un oggetto, ad esempio un letto, specificando che l’uscita di testo deve essere “Sotto al letto trovi solo polvere.”, ebbene, digitando > guarda sotto al letto non vedrò più stampato il messaggio di default (visualizzato anche se non avessi incluso l’istruzione LookUnder alla proprietà del letto), che viene in un certo senso bypassato, ma proprio il testo da me specificato. Naturalmente molte altre azioni sono possibili, come ad esempio far variare il valore di una o più variabili in modo tale da far “cambiare” (notare il virgolettato) le risposte del programma a seconda dei verbi digitati, ma per il discorso che voglio fare sono di scarsa rilevanza.
Quindi, una volta che il codice sorgente è compilato, anche se l’avventura non è ancora stata giocata, si ha un vero e proprio “mondo”. Tutto è già stabilito, oggetti (ma soprattutto) regole.
Altro esempio:
 
Object stanza “Una stanza”
 with description “Ti trovi nella tua stanza.”,
                has light;
 
Object -> computer “computer”
                with name ‘computer,
                before [;
 Examine: “Il tuo computer. Nuovo di zecca.”;
 SwitchOn: “Il computer è acceso.”;
 SwitchOff: “Il computer è spento.”;
 Attack: give uovo ~concealed; print “Rompi il computer e trovi… un uovo!”; rtrue; ],
 has switchable;
 
Object -> uovo “uovo”
                with name ‘uovo’,
                has concealed;
 
Per farla breve: with serve per definire tutto ciò che è riferito all’oggetto, name indica i nomi coi quali ci si può riferire ad un oggetto (se digitassi, ad esempio, > esamina mac non otterrei risultati), has ha la funzione di name, ma indica gli attributi, light è un attributo che indica che la stanza è illuminata, switchable è un attributo che indica che l’oggetto a cui è riferito può essere acceso (SwitchOn) o spento (SwitchOff), concealed serve per rendere un oggetto “invisibile”, mentre la tilde (~) nega il valore dell’attributo che lo segue (quindi give uovo ~concealed significa: rendi “visibile” l’uovo). Print significa “mostra a video il testo che segue”, mentre rtrue serve per far eseguire le azioni che lo precedono (ovvero give e print).
Ecco cosa comparirebbe una volta avviato il file con un interprete:
 
Una stanza
Ti trovi nella tua stanza.
 
Puoi vedere un computer qui.
 
Il gioco ci informa automaticamente che possiamo vedere un computer poiché non l’abbiamo definito concealed.
Proviamo ad immaginare di digitare > esamina computer; la risposta che otterremo sarà:
 
Una stanza
Ti trovi nella tua stanza.
 
Puoi vedere un computer qui.
 
> esamina computer
 
Il tuo computer. Nuovo di zecca.
 
 
Ho scelto apposta una descrizione simile per indicare che al giocatore mai e poi mai verrebbe in mente di rompere il computer appena comprato. Magari accenderlo o spegnerlo, ma non romperlo.
Come potrà dunque sperare il giocatore di trovare l’uovo / easter egg? Semplicemente: non può. (A meno che il gioco, ovvero il programmatore, non fornisca indizi in seguito).
Tutto questo preambolo interminabile per dire che, essenzialmente, giocare un’avventura testuale altro non è che portare alla luce il mondo sommerso del programmatore, aprire gli occhi come fosse la prima volta su ogni oggetto tramite le azioni digitate, rendere visibile l’invisibile (che abbia concealed o meno). Quante risposte testuali pensate dai programmatori non hanno mai visto la luce? Quante sono rimaste seppellite sotto la scarsa inventiva dei giocatori?
Naturalmente già solamente giocando un’avventura testuale si intuisce un simile pensiero (lo dimostra la preponderanza imprescindibile proprio del comando esamina, senza il quale non si conoscerebbero i dettagli degli oggetti, rimanendo bloccati), ma è solo tramite la programmazione che se ne coglie a fondo il significato: riuscirà l’utente che usufruisce della mia opera a “scoprire” ciò che vi ho inserito? Esiste un sottobosco di comandi che magari il giocatore non ha nemmeno lontanamente pensato (ma a cui ha pensato il programmatore!) e che sono lì in attesa di essere scoperti.
[Per inciso: si capirà da questo l’altissimo valore che io do alla fantasia e quanto deprechi la frettolosità che il mondo moderno vuole imporre, frettolosità che si esplica nel “Voglio terminare l’avventura a tutti i costi, potrò dirmi soddisfatto solo quando l’avrò finita”. Non è così. Il più delle volte un’avventura testuale è un modo che il programmatore utilizza per raccontare qualcosa, oltre che per intrattenere; non capire questo significa solamente superficialità e vanificazione di uno spirito altamente sociale]
Oltre al sottobosco di comandi inespressi esiste l’inarrivabile (per il giocatore) mondo delle variabili. Ogni azione, ogni comando digitato, di fatto, altro non è che un sistema tramite cui influenzare il valore di una variabile così che sia modificato lo stato del gioco. Nell’esempio precedente, una volta che avremo acceso il computer interverrà una variabile che assegnerà all’oggetto l’attributo on, in modo che il gioco “sappia” che il computer è già stato acceso. La filosofia, o quantomeno una parte di essa, fa una distinzione tra fenomeno e noumeno: fenomeno è tutto ciò che è manifesto, ciò che raggiunge i nostri sensi e quindi viene da noi interpretato; noumeno è la realtà che sta dietro al fenomeno, quella realtà che noi non potremo mai comprendere in quanto perennemente filtrata (e quindi celata) attraverso i nostri sensi come fenomeno. La tastiera su cui sto scrivendo è fenomenicamente nera, ma questa è solo un’impressione, una sensazione: l’essenza della tastiera sta al di là della sua “nerezza”, ma poiché i miei occhi altro non possono che vederla nera, non potrò mai raggiungere la sua realtà noumenica.
E, di fatto, un aspetto noumenico rimane anche durante l’attività di programmazione: il parser e le librerie contengono già le istruzioni per modificare le variabili, quantomeno quelle principali. Ma, “fortunatamente”, Inform6 mette a disposizione la possibilità di crearne ogni volta di nuove (si veda l’esempio successivo della mamma) e così l’accesso al noumeno viene garantito anche a chi non programma dal nulla (ossia senza linguaggi di programmazione e librerie).
 
Sempre a proposito di linguaggi di programmazione, i miei pensieri svicolano verso la genetica e la logica matematica (cosa, peraltro, non insolita quando si parla di argomenti informatici di questo livello). Il linguaggio di programmazione altro non è che un “codice genetico”: un insieme di istruzioni che, mediante l’interazione dei loro prodotti (output / proteine) determina l’organismo finale. Ogni gioco, prima di essere “figlio” (o meglio: prodotto) dell’inventiva del programmatore è “figlio” del linguaggio in cui è scritto. E questo poiché il linguaggio di programmazione è un modello, ossia un insieme di assiomi, definizioni e regole costantemente utilizzate (molto spesso inconsciamente) dal programmatore. Ed è questo il motivo per cui gli errori (i bug) sono da imputare al programmatore e non a chi ha creato il linguaggio di programmazione: gli errori derivano da una scorretta applicazione del linguaggio e non da una scorrettezza del linguaggio. Anche in questo caso il programmatore ha sentore di questo aspetto e lo coglie quando spetta a lui entrare in azione. Questa volta, per dimostrarlo, userò come esempio un codice che funziona con Inform7 (tratto da “La Guida di Inform 7” di Jim Aikin, traduzione di Leonardo Boselli), in quanto palesa meglio l’assiomaticità avvicinandosi molto al linguaggio naturale (inglese):
 
The massive stone door is a door. The massive stone door is scenery. The massive stone door is
north of the Corridor and south of the Dank Cell. The description is "It's quite an imposing-looking
stone door." The massive stone door is open, lockable, and locked
 
Instead of closing the massive stone door:
if the massive stone door is open:
say "...but it looks so inviting! Why not just step through it and see what's on the other
side?";
otherwise:
say "It seems already to have closed itself without your lifting a finger."
 
(Per quanto equivalenti non è molto più incisivo dire, stabilire che “La massiccia porta di pietra è una porta”, piuttosto che definire un Object -> porta “massiccia porta di pietra”?)
 
 
Visti i pensieri letterari, filosofici, matematici e biologici possono forse mancare anche quelli teologici? Onestamente confesso che non di rado, programmando, i miei sentimenti sfociano in un “delirio di onnipotenza” perché, di fatto, programmare è un’azione “divina”: io creo oggetti, luoghi, personaggi, li plasmo secondo il mio volere e i miei capricci, do loro i connotati che preferisco, do loro forma e sostanza. Ma, più che azione “divina”, sarebbe meglio dire “demiurgica”. Notazione filosofica: il demiurgo si differenzia dal dio poiché quest’ultimo può creare dal nulla, mentre il demiurgo agisce solamente su cose preformate. E le cose preformate che possiedo sono esattamente quelle elencate: un compilatore, le librerie e il parser, strumenti creati da altre persone grazie alle quali io posso sviluppare il mio soggetto. Veniamo, con un altro esempio (un po’ più complicato), alla sceneggiatura:
 
Object stanza “Una stanza”
 with description “Ti trovi nella tua stanza.”,
                has light;
 
Object -> mamma “tua mamma”
                with life [;
                Tell: if (self.giaparlato == false) {
  self.giaparlato = true; print “Dici qualche parola a tua mamma.”; rtrue; }
  else “Tua mamma ti prega di smetterla di importunarla.”; ],
  giaparlato false,
  has animate female;
 
Consideriamo l’”oggetto” mamma. Animate indica che su di essa possiamo agire con comandi (preimpostati) pertinenti agli esseri viventi, proprio come “parla” (“Tell”). Vediamo anche che a mamma appartiene la variabile giaparlato (che poteva anche chiamarsi pinco pallino) e che essa vale false. Se parliamo a mamma la prima volta vale la condizione indicata tra le parentesi tonde (if – sottinteso “it is true that…”) [self. Indica che il programma deve valutare la variabile giaparlato dello stesso oggetto cui appartiene] e quindi il programma eseguirà l’azione tra le parentesi graffe: cambierà il valore della variabile giaparlato (facendolo diventare true) e stamperà “Dici qualche parola a mamma.”. Tuttavia, se volessimo provare a parlare di nuovo a mamma, la variabile giaparlato non sarebbe più falsa, non varrebbe più la condizione indicata tra parentesi tonde e quindi il programma stamperebbe ciò che segue else ( = altrimenti). Vediamo.
 
Una stanza
Ti trovi nella tua stanza.
 
Puoi vedere tua mamma qui.
 
> parla a mamma
 
Dici qualche parola a mamma.
 
> parla a mamma
 
Tua mamma ti prega di smetterla di importunarla.
 
Vediamo, questa volta, prima il punto di vista del giocatore e poi quello del programmatore. Il giocatore, non essendo a conoscenza delle variabili che regolano lo sviluppo dell’avventura testuale, è più propenso a giudicare come “vivi” i personaggi che compaiono in essa: nell’esempio precedente sembra proprio che mamma abbia una propria autonomia, che sia senziente. Esiste una bellissima Cyberiade di Stanisław Lem (peraltro ripresa da Matt Groening tanto in un episodio dei Simpson quanto in uno di Futurama) in cui un robot crea artificialmente un minimondoi cui abitanti, però, sono soggetti alle tirannie di un despota. Questo robot pensa che non ci sia nulla di male, essendo tutti quegli esseri nient’altro che frutto di una creazione artificiale, ma un suo collega gli fa notare che il ragionamento è sbagliato: se quegli esseri sono stati creati senzienti e capaci di soffrire il creatore ha responsabilità della loro sofferenza ed è costretto a considerarli come vivi. Ancor di più: visto che un’avventura testuale fornisce come output solamente del testo, e il punto di forza è far viaggiare l’immaginazione del giocatore, le pulsioni viscerali di quest’ultimo che ne regolano l’immaginazione saranno ancor più determinanti a far considerare i personaggi con cui interagisce come vivi (naturalmente in questo processo gioca anche un ruolo dominante la capacità descrittiva del programmatore). In principio era il logos, e il logos era presso il programmatore e il programmatore era il logos.
 
 
Ma, mi rendo conto, se già il discorso è spinoso per livelli più alti (come ad esempio quando si parla di Intelligenza Artificiale) è ancor più difficile accettarlo, per quanto evocativo, se si parla di avventure testuali (e soprattutto dopo aver svelato come dare l’illusione che un personaggio sia “vivo”). Quindi torniamo a vedere le cose dal punto di vista del programmatore e torniamo alla filosofia. Come detto all’inizio, una volta che il codice sorgente è completato il mondo è definito. Non solo per quel che riguarda gli assiomi, definizioni e regole, ma anche ogni sorta di possibile interazione del giocatore con gli oggetti e tra gli oggetti stessi. Nulla (o quasi, ma di questo dirò in seguito) sfugge in un “triste determinismo”.
[Mi sia concessa una parentesi: non credo nel libero arbitrio e, per la maggior parte dei casi, credo al determinismo: se lo definisco “triste” è perché so che questo rappresenterebbe il pensiero della maggioranza di chi legge]
Per tornare alla Cyberiade: il robot, finalmente tormentato dai sensi di colpa, decide di suggerire alle sue creature di ricorrere alle libere elezioni per spodestare il tiranno, ma, ancora una volta, il suo collega gli rivela che è in errore, in quanto le creature sono programmate per “credere” al sistema feudale: per far loro intendere il meccanismo delle libere elezioni bisognerebbe modificare il loro “software”. E, in effetti, il pensiero che ogni cosa sia determinata è la prima cosa che salta in mente a chi pensa sia possibile avere una conoscenza di tutto: conoscendo ogni cosa, ogni comportamento, ogni variabile come si può pensare di non riuscire a predire correttamente il risultato di un’azione?
[Mi sia concessa un’altra parentesi, necessaria: per quanto determinista, non credo sia possibile raggiungere una conoscenza completa e globale]
Gli atomisti, e in particolare Democrito, ritenevano che il determinismo fosse provocato dal fatto che esistevano delle particelle elementari, gli atomi, che progredivano dall’altro verso il basso lungo traiettorie parallele, quindi senza mai incontrarsi. Epicuro tuttavia introdusse un elemento di casualità, che Lucrezio riprese col nome di clinamen: una variazione spontanea e improvvisa del moto grazie alla quale gli atomi, per un breve periodo, cambiano traiettoria, potendo così entrare in collisione. E quale potrà essere il clinamen che affligge i programmatori? Possono essere alcune inesattezze contenute nel linguaggio di programmazione o nelle librerie (non me ne voglia Riccardi, ma ogni volta devo stare attento a ridefinire il comando copri!), ma anche queste fanno capo alla fantastica imperfezione della macchina-uomo grazie alla quale la vita (quella “vera”) è varia e interessante: ebbene sì, mi sto riferendo ai bug.
E quindi l’ultimo pensiero va ai betatester, dei quali non mi sono certo dimenticato (né bisogna dimenticare) il cui lavoro è arduo e complicato e merita la giusta considerazione: loro sono gli ultimi “agenti dell’ordine” in grado di prevenire il caos (e la furia dei giocatori veri e propri).
 
Non avendo esperienza in altri ambiti di programmazione videoludica ho preferito limitare questi discorsi alle avventure testuali (e, già che ci sono, mi scuso se ho utilizzato qualche termine impropriamente, ma non sono uno specialista in – quasi – nessuno dei campi che ho toccato), tuttavia credo che questi pensieri prima o poi abbiano toccato o tocchino tutti i programmatori di qualsiasi tipo di videogioco dotati di autentica passione Sperando di non avere annoiato e di essere riuscito ad effondere un po’ di questa passione, vi saluto e vi lascio alla prossima avventura!
 
 
stretta è la foglia, larga è la via
voi dite la vostra ch'io ho detto la mia
 
* sorrido e scompaio *