Capitolo 16: Fare il debug del vostro gioco =========================================== Nessuno comprende la frase errare human est meglio di un programmatore. I computer sono delle macchine estremamente efficienti, capaci di effettuare dei calcoli impressionanti, ma mancano di immaginazione e insistono sul fatto che ogni elemento venga fornito loro debba seguire una serie di regole definite in precedenza. Non potete trovare un accordo con un computer: o vi sottomettete ai suoi voleri, o mangiate la polvere. Inform non fa differenza. Se fate un errore di battitura o di sintassi, il compilatore ve lo indica chiedendovi di correggere il vostro lavoro. "Mi sono solo scordato una virgola!" urlate con disgusto. Il compilatore non dice nulla. Non ha niente da guadagnare dalla discussione, perché ha sempre ragione. Quindi aggiungete la virgola che manca. Nessuno è rimasto ferito tranne, forse, il vostro orgoglio. Gli errori che si trovano durante la compilazione possono essere noiosi da correggere, ma solitamente è facile individuarli; dopo tutto il compilatore cerca, gentilmente, di indicarvi quale era e dove si trovava l'errore. Il difficile viene quando avete finito di soddisfare tutte le lamentele del compilatore. Il vostro premio è uno schermo pulito, senza nessun elenco di errori, e vi viene offerto - un dono! Un nuovo file è comparso nella vostra cartella. Uno story file. Sì, _il_ gioco. Aprite, subito, il vostro interprete preferito e cominciate a giocare... solo per scoprire il lato oscuro degli errori: i bug [bachi]. I bug sono di tutte le forme, colori e dimensioni: grandi, piccoli, stupidi, assurdi, minori, inquietanti, stressanti e catastrofici. Di solito sono imprevedibili: ci intrattengono con comportamenti soprendenti ed inaspettati. Sfidano la logica: io scrivo PRENDI la chiave, ed il gioco risponde con "Presa.", ma la chiave resta allo stesso posto e non appare nel mio inventario. Oppure l'apertura di una porta avendo indosso una pelliccia causa un errore di programmazione e la visualizzazione di un messaggio criptico: "tried to find the attribute of nothing" [si è cercato di trovare l'attributo di niente]. E molti, molti altri. Quando progettate un gioco cercate di prendere in considerazione tutti gli stati in cui i vostri oggetti potrebbero venire a trovarsi, ma qualunque gioco di medie dimensioni ha una tale quantità di oggetti ed azioni che è praticamente impossibile pensare a tutte le variazioni, permutazioni e possibilità. Il debug [rimozione dei bachi] consiste nello scovare gli errori di esecuzione e correggerli. Potreste pensare che sia abbastanza semplice, ma non lo è. L'individuazione di tali errori non è facile, visto che tendono a manifestarsi solo in determinate circostanze. Quindi dovete investigare nel vostro codice per scoprire che cosa li ha causati. Infine, quando avete trovato le righe incriminate, dovete apportare i cambiamenti necessari. (Esiste anche il caso in cui non riuscite a trovare l'errore. Non vi preoccupate: è lì da qualche parte. L'insistenza alla fine paga). Per aiutarvi in questo difficile compito, Inform ha una serie di azioni speciali: i verbi di debug [debugging verbs]. Sono disponibili durante l'esecuzione del gioco se il file sorgente è stato compilato in modo Debug (lo switch -D) od in modo Strict (lo switch -S, che include il modo Debug). In effetti il compilatore ha il modo Strict attivo per impostazione predefinita come una ciambella di salvataggio, visto che controlla il vostro codice più accuratamente alla ricerca di alcuni errori addizionali. Quando siete pronti a rilasciare il vostro gioco, dovete ricompilare, disabilitando il modo Strict (-~S) per evitare che i giocatori si avvantaggino delle funzionalità offerte dai verbi di debug. Parleremo un po' di alcuni di questi e vi faremo vedere a che servono. Lista dei comandi ***************** L'unico modo per provare (farne il test) un gioco è giocarci. Mentre andate avanti con la scrittura del codice il gioco cresce in dimensioni e diventa veramente stancante dover ripetere tutti i comandi tutte le volte che si gioca. Quando sistemate il comportamento di un certo oggetto, di solito, modificate di conseguenza il comportamento di altri oggetti od altre azioni, quindi è una buona idea fare un test generale ogni tanto: dovete assicurarvi che alcune delle modifiche più recenti non abbiano rovinato qualcosa che prima funzionava benissimo. Il comando RECORDING [registrazione] (RECORDING ON e RECORDING OFF) memorizza i comandi che digitate mentre giocate in un file di testo (probabilmente vi verrà chiesto un nome di file). Quando aggiungete una nuova sezione al gioco, potete giocare fino a quel punto, quindi digitare RECORDING ON per catturare (in un altro file) i comandi che riguardano quella sezione, ed alla fine potete usare il vostro editor di testo per accodare i nuovi comandi all'elenco preesistente. Il comando REPLAY [riproduci] esegue il file di testo creato da RECORDING, lanciando tutti i comandi memorizzati nel file. In questo modo potete accertarvi rapidamente se tutto sta funzionando come dovrebbe. Potete aprire il file dei comandi con qualunque editor di testo per modificarne il contenuto a seconda delle necessità: ad esempio, se volete cancellare dei comandi non più necessari a causa di una modifica al gioco, oppure se avete dimenticato di fare il test di qualche oggetto particolare ed avete bisogno di aggiungere dei comandi. Questa tecnica (l'uso di una lista di comandi registrati) è, e non possiamo enfatizzarlo con più forza, una delle funzionalità di testing più utili che possa avere uno scrittore di avventure. Sputa il rospo ************** Alcuni verbi di debug offrono informazioni sullo stato corrente delle cose. TREE Questa azione elenca tutti gli oggetti nel gioco e come sono contenuti uno nell'altro. Potete scoprire il contenuto di un singolo oggetto digitando TREE oggetto. Tutti gli oggetti che avete definito nel vostro codice sorgente vengono trasformati in numeri da Inform quando compila lo story file; questo comando visualizza anche questa rappresentazione interna degli oggetti, chiamata obj_id. SHOWOBJ oggetto Visualizza le informazioni che riguardano l'oggetto, gli attributi che possiede ed il valore delle sue proprietà. L'oggetto può trovarsi ovunque, non è necessario che sia nelle vicinanze (in scope). Potete anche usare il numero dell'oggetto, se l'oggetto in questione non ha un nome. Ad esempio, in "Heidi": >SHOWOBJ NIDO Object "nido di uccelli" (28) in "te stesso" has container moved open workflag with name 'nido' 'rametti' 'sterpi', description "Il nido e' fatto di rametti e sterpi intrecciati." (-30669), SHOWVERB verbo Visualizza la grammatica del verbo, proprio come una definizione Verb standard. Diventa utile quando avete giocato un po' con la funzione Extend e non siete sicuri del risultato finale delle vostre macchinazioni. Un esempio da "Guglielmo Tell": >SHOWVERB DAI Verb 'da' 'dai' 'offri' 'paga' * held 'a' / 'ad' / 'all'' / 'allo' / 'alla' / 'al' / 'agli' / 'ai' / 'alle' creature -> Give * 'a' / 'ad' / 'all'' / 'allo' / 'alla' / 'al' / 'agli' / 'ai' / 'alle' creature held -> Give reverse * 'omaggio' / 'omaggi' 'a' / 'ad' / 'all'' / 'allo' / 'alla' / 'al' / 'agli' / 'ai' / 'alle' / 'verso' noun -> Salute Le prime righe riproducono la definizione del verbo così come si trova nella libreria. L'ultima riga, invece, è la diretta conseguenza del nostro Extend: Extend 'dai' * 'omaggio'/'omaggi' 'a'/'ad'/'all^'/'allo'/ 'alla'/'al'/'agli'/'ai'/'alle'/'verso' noun -> Salute; SCOPE Elenca tutti gli oggetti attualemente _in scope_ (in parole povere, visibili al personaggio del giocatore). In maniera più potente potete digitare SCOPE oggetto per scoprire quali sono gli oggetti _in scope_ per l'oggetto indicato. Questa funzionalità diventa utile soprattutto quando avete dei PNG in grado di interagire con l'ambiente circostante. Che diavolo sta succedendo? *************************** Ci sono momenti in cui una determinata azione non produce l'effetto che vi aspettavate e non sapete perché. I verbi di debug che seguono offrono informazioni su quello che l'interprete sta facendo, e potrebbero aiutarvi a capire in quale momento le cose hanno smesso di funzionare. ACTIONS (o ACTIONS ON) e ACTIONS OFF Fornisce informazioni sulle azioni che sono in corso. Alcune azioni vengono reindirizzate ad altre, e questo può essere una fonte di guai o di mistero; in questo modo avete un'indicazione di quello che sta succedendo. Ad esempio, date un'occhiata a questa trascrizione da "Guglielmo Tell": Lungo la strada La gente continua a premere e a farsi strada dalla porta sud alla piazza principale, che si trova appena più a nord. Riconosci la proprietaria di un banco di frutta e verdura. Helga smette di sistemare le patate e ti saluta calorosamente. >CERCA BANCO [ Action Search with noun 35 (banco di frutta e verdura) ] [ Action Examine with noun 35 (banco di frutta e verdura) (from < > statement) ] Davvero un piccolo banco, con un grosso mucchio di patate, qualche carota, qualche rapa, un po' di mele. ... CHANGES (o CHANGES ON) e CHANGES OFF Tiene traccia dei movimenti degli oggetti e delle modifiche agli attributi ed alle proprietà: In mezzo alla piazza C'è meno folla al centro della piazza; la maggior parte della gente preferisce tenersi il più lontano possibile dal palo che troneggia in questo luogo, reggendo quell'assurdo cappello cerimoniale. Un gruppo di soldati rimane nei pressi, osservando chiunque passi di qui. >NORD [Setting In mezzo alla piazza.avvertimenti to 1] Un soldato ti sbarra la strada. "Hey, tu, spilungone; hai dimenticato le buone maniere? Forse sarebbe il caso di fare un bel saluto al cappello del balivo, non trovi?" >ANCORA [Setting In mezzo alla piazza.avvertimenti to 2] "Ti conosco, Tell, sei uno che porta solo guai, vero? Non vogliamo teste calde qui, quindi fai il bravo ragazzo e porgi il tuo saluto al dannato cappello. Fallo ora, non voglio chiedertelo di nuovo..." >SALUTA CAPPELLO [Setting palo di legno.salutato to 1] Saluti il cappello sull'alto palo. "Grazie davvero, messere", sghignazzano i soldati. >SUD [Setting In mezzo alla piazza.avvertimenti to 0] [Setting palo di legno.salutato to 0] [Moving te stesso to Lato sud della piazza] ... TIMERS (o TIMERS ON) e TIMERS OFF Questo verbo visualizza, alla fine di ogni turno, lo stato di tutti i timer e dei daemon attivi. Non abbiamo parlato dei timer (simili ai daemon) in questa guida; potreste usarne uno per far esplodere una bomba dieci turni dopo aver acceso la sua miccia. TRACE (o TRACE ON), TRACE numero e TRACE OFF Quando attivate questo verbo (molto potente) siete in grado di seguire l'attività del parser (la parte della libreria che cerca di capire quello che il giocatore ha digitato) e questo sarà un momento di estrema gratitudine per il fatto che qualcun altro si è preso l'onere di scriverlo. Visto che il parser fa tantissime cose, potete decidere il livello di dettaglio delle informazioni mostrate tramite il paramtero numero, che può variare tra 1 (informazioni minime) e 5 (informazioni massime). Per impostazione predefinita TRACE ON e TRACE impostano il livello a 1. Il livello 1 mostra la riga di grammatica sulla quale il parser sta pensando, mentre il livello 2 mostra ogni singola chiave di ogni riga di grammatica che prova. Le informazioni visualizzate ai livelli più alti cominciano ad essere abbastanza intricate, e vi consigliamo di usarle solo se nessun'altra cosa vi è stata di aiuto. Superpoteri *********** GONEAR oggetto Questa azione vi teletrasporta nella stanza in cui si trova l'oggetto. Diventa utile quando, ad esempio, talune parti della mappa sono chiuse fino a che il giocatore non risolve qualche enigma, o se la mappa del gioco è divisa in aree differenti. Se la stanza che volete visitare non ha oggetti, potete usare... GOTO numero Vi teletrasporta nella stanza che ha come rappresentazione interna numero. Visto che le stanze, di solito, non hanno nome, dovete scoprire il numero interno dell'oggetto stanza (ad esempio con il comando TREE). PURLOIN oggetto PURLOIN funziona proprio come PRENDI, con la simpatica aggiunta che non si cura di dove si trovi l'oggetto: in un'altra stanza, all'interno di un contenitore chiuso a chiave, negli artigli del drago assetato di sangue. In maniera più pericolosa, non si cura neanche di controllare che un oggetto sia prendibile, quindi potete prendere degli oggetti definiti come static o scenery. PURLOIN è utile in una varietà di situazioni, fondamentalmente quando volete provare una certa funzionalità del programma che richiede al giocatore di avere determinati oggetti a portata di mano. Invece di andare in giro a raccoglierli, potete semplicemente impossesarvene con il comando PURLOIN. Fate attenzione: non è saggio impossessarvi di oggetti che non è previsto siano prendibili, visto che in questo modo il comportamento del gioco non sarà prevedibile. ABSTRACT oggetto TO oggetto Questo verbo vi consente di muovere il primo oggetto nel secondo oggetto. Così come con PURLOIN, gli oggetti possono trovarsi ovunque nel gioco. Tenete a mente che il secondo oggetto deve logicamente essere un container, un supporter o qualcosa di animato (animate). Infix: il privilegio del corrotto ********************************* I verbi base di debug sono abbastanza versatitili ed hanno il vantaggio di essere compilati automaticamente all'interno del vostro gioco a meno che non lo vogliate. A volte, comunque, potreste incontrare un bug che non riuscite a stanare usando le tecniche normali, ed è questo il momento in cui vorrete dare un'occhiata al debugger Infix. Dovete compilare usando lo switch -X per essere, così, in grado di modificare quasi tutti i dati e gli oggetti del vostro gioco. Ad esempio potete usare ";" per leggere e modificare il contenuto di una variabile: All'interno del caffè di Benny Da Benny potete trovare le migliori paste ed i migliori sandwich. I clienti si ammassano al bancone, dove lo stesso Benny si occupa di servire, cucinare e dare il resto senza perdere un colpo. Nella parte nord del bar potete vedere una porta rossa che conduce al gabinetto. >; deadflag ; == 0 >; deadflag = 4 ; == 4 *** Sei stato VERGOGNOSAMENTE sconfitto *** In questa partita hai totalizzato 0 punti su 2 possibili, in 2 turni. Spesso è abbastanza scocciante scoprire che una variabile è ancora false perché l'enigma del gessetto non ha funzionato e che non potete verificare l'enigma del formaggio fino a che non diventa true. Invece di uscire dal gioco, sistemare il gessetto, ricompilare, giocare fino alla posizione che avete lasciato e _solo allora_ affrontare il formaggio, sarebbe molto più facile cambiare il valore della variabile a metà strada e proseguire. Potete usare ;WATCH per tenere d'occhio i cambiamenti di valore di un oggetto: >;WATCH CENTRO_PIAZZA ; Watching object "In mezzo alla piazza" (43). >NORD [Moving te stesso to In mezzo alla piazza] [Moving gente to In mezzo alla piazza] [Moving soldati di Gessler to In mezzo alla piazza] [Moving tuo figlio to In mezzo alla piazza] In mezzo alla piazza C'è meno folla al centro della piazza; la maggior parte della gente preferisce tenersi il più lontano possibile dal palo che troneggia in questo luogo, reggendo quell'assurdo cappello cerimoniale. Un gruppo di soldati rimane nei pressi, osservando chiunque passi di qui. [Giving In mezzo alla piazza visited] >NORD [ "In mezzo alla piazza".before() ] [ centro_piazza.before() ] [Setting In mezzo alla piazza.avvertimenti to 1] Un soldato ti sbarra la strada. "Hey, tu, spilungone; hai dimenticato le buone maniere? Forse sarebbe il caso di fare un bel saluto al cappello del balivo, non trovi?" >NORD [ "In mezzo alla piazza".before() ] [ centro_piazza.before() ] [Setting In mezzo alla piazza.avvertimenti to 2] "Ti conosco, Tell, sei uno che porta solo guai, vero? Non vogliamo teste calde qui, quindi fai il bravo ragazzo e porgi il tuo saluto al dannato cappello. Fallo ora, non voglio chiedertelo di nuovo..." >NORD [ "In mezzo alla piazza".before() ] [ centro_piazza.before() ] [Setting In mezzo alla piazza.avvertimenti to 3] "Va bene, Herr Tell, ora siete nei guai. ... Infix è abbastanza complesso; è utile averlo a disposizione, ma non è decisamente uno strumento per principianti. Se proprio volete usarlo fate attenzione: avrete un sacco di potere e sarà vostra cura non rovinare tutto. Non ne avrete bisogno spesso, ma Infix può fornire risposte rapide a questioni intricate. Non importa cosa **************** Il vostro gioco avrà ancora dei bug irrisolti nonostante tutti i vostri sforzi per sistemarlo. È una cosa normale, anche per gli scrittori di avventure che hanno una certa esperienza: non vi sentite scoraggiati o demoralizzati. La fase finale del processo di debug deve avvenire da un'altra parte, nelle mani di alcuni beta-tester volenterosi, testardi e determinati; sono queste le persone che, se siete fortunati, faranno a pezzi il vostro gioco e vi restituiranno estesi rapporti in cui vi dicono le cose che non funzionano in maniera corretta, le cose che non funzionano così bene come dovrebbero, le cose che avrebbero dovuto funzionare ma non lo fanno, e le cose che non vi sono neanche venute in mente. Quando credete che il vostro gioco sia finito (nel senso che fa tutto quello che pensate avrebbe dovuto fare, e non avete più idee su come fare altri test) cercate qualche beta-tester: un buon numero è tre o quattro. La comunità IF offre alcune risorse per il beta-testing, oppure potete sempre chiedere su RAIF (in inglese) o su ICGAT (in italiano) e cercare qualche anima pia che si prenda la briga di dare un'occhiata al vostro gioco. Ricordatevi sempre le regole d'oro: * Non vi aspettate nessuna pietà. Sebbene vi possa ferire, un approccio senza pietà è quello di cui avete bisogno in questo momento; è molto meglio scoprire i vostri errori e le vostre dimenticanze adesso, piuttosto che quando rilasciate il gioco al pubblico. E non dimenticate di ringraziare i vostri beta-tester da qualche parte nel gioco. * Mai dire mai. Se i vostri tester vi dicono che il gioco dovrebbe rispondere meglio ad una certa azione che non avete provato, non rispondete automaticamente con "Nessuno lo farà mai!". Lo hanno appena fatto, e qualcun altro lo farà: siate grati alle menti deviate dei vostri tester. Anche se un giocatore normale non proverà mai tutte quelle cose strane, ogni giocatore sarà propenso a provarne almeno una, ed il loro divertimento sarà più grande, la sensazione di realtà sarà migliore, se il gioco "capisce". * Chiedete di più. Non trattate i vostri tester come dei semplici validatori delle vostre capacità programmatorie, ma piuttosto come dei recensori delle vostre abilità di scrittore. Incoraggiateli a commentare quanto bene i pezzi si uniscono l'un l'altro, ed a fornire suggerimenti (piccoli o radicali) per migliorare; non è necessario rifiutare una buona idea solo perché "ci vuole troppo per implementarla". Ad esempio: "la scena nella Torre di Londra non sembra accordarsi molto con un gioco sulle Notti Arabe", oppure "dover risolvere tre enigmi uno dopo l'altro solo per scoprire un piatto di occhi di pecora è un po' sopra le righe", o "questo viaggio di cinque stanze nel deserto è un po' noioso: forse potresti aggiungere delle sabbie mobili o qualcos'altro per rinvigorirlo?", o "sembra che al personaggio dell'eunuco nell'harem manchi qualcosa". Quindi cercate di vedere l'insieme dei vostri beta-tester non come dei semplici correttori ortografici, ma come dei veri e propri redattori che collaborano alla scrittura del vostro romanzo.