\articolo{DOOPSI - Un sistema autore per avventure grafiche}{Andrea Galimberti e Fabio Rotondo}
\index{Rotondo!articolo di}
\index{Galimberti!articolo di}

%\begin{flushleft}
%\includegraphics[width=4.1cm]{rotondo/pics/doopsi.eps}
%\end{flushleft}

\paragrafo{Cosa vuol dire DOOPSI}

DOOPSI\index{DOOPSI} \`e l'acronimo inglese di {\em Interfaccia di Sistema
per la Programmazione Dinamica Orientata agli Oggetti}. \`E un ambiente di
sviluppo di avventure grafiche simili a quelle della Lucas Arts come ``Day
Of The Tentacle'', ``Indiana Jones And The Last Crusade'' o ``The Secret of
Monkey Island'', per fare alcuni esempi.

Una delle idee fondamentali perseguite nella creazione di DOOPSI \`e stata:
``facilit\`a d'uso prima di tutto''. Il creatore delle avventure non deve
essere costretto a lavorare con numeri strani o simboli incomprensibili, ma
gestire gli oggetti del gioco come fossero oggetti reali, quasi riuscendo a
toccarli, a manipolarli come fossero veri. Tutto questo per semplificare
l'approccio allo sviluppo di avventure anche complesse. Prima dell'avvento
di DOOPSI, la creazione di una avventura era un privilegio di pochi
programmatori che conoscevano a menadito almeno cinque linguaggi di
programmazione ed avevano in mente la struttura completa dell'avventura
ancora prima di iniziare a scriverla. Ora non pi\`u: con DOOPSI non serve
essere programmatori, ma solo sognatori, avere belle idee da inserire in
un'avventura e avere voglia di creare storie con le quali far divertire gli
altri. DOOPSI \`e uno strumento per tutti, ma soprattutto per coloro i
quali, da tempo, vorrebbero un'avventura con determinate caratteristiche e
non sono ancora riusciti a trovarla: ora possono crearla.

Alla base di DOOPSI c'\`e una profonda ed accurata ricerca di {\em
integrazione} a livello {\em strutturale} dei vari elementi che compongono
un'avventura.  Progettando DOOPSI, abbiamo cercato di creare un ambiente
che permettesse la massima flessibilit\`a e la migliore capacit\`a di
adattamento alle varie situazioni che possono presentarsi durante la
creazione di un'avventura, attraverso il {\em design} e un approccio
profondamente {\em object oriented} che ha permesso di contenere le
dimensioni finali dei due programmi che costituiscono il pacchetto DOOPSI
(ovvero l'Editor ed il Player), garantendo riutilizzabilit\`a e
semplicit\`a di espansione.

DOOPSI vanta un'eccezionale capacit\`a di adattamento alle varie situazioni
e problematiche che potrebbero presentarsi durante la creazione di
un'avventura.  Questa versatilit\`a \`e stata ottenuta principalmente
cercando di astrarre il pi\`u possibile il concetto di ``oggetto'' (nel
senso usuale del termine), ovvero cercando di creare una struttura di dati
e funzioni che potessero essere utilizzate efficacemente per rappresentare
gli oggetti pi\`u diversi.  I nostri sforzi si sono incarnati in quello che
noi abbiamo definito {\em ``DOOPSI-Object''}, una entit\`a che ha permesso
un riciclo di codice notevolissimo e che risulta del tutto trasparente
all'utente; infatti quest'ultimo non ne viene mai in diretto contatto in
quanto ogni manipolazione sui DOOPSI-Object avviene solo tramite gli
Editor.  Purtroppo, con il senno di poi, ci siamo accorti che la nostra
generalizzazione avrebbe potuto raggiungere risultati migliori e pi\`u
funzionali\dots\ ma avrebbe richiesto la ristesura di pi\`u della met\`a
del codice (per giunta funzionante) gi\`a scritto.  Abbiamo quindi deciso
di mantenere la struttura attuale dei dati e degli oggetti, ma abbiamo
anche iniziato a scrivere da zero un nuovo DOOPSI-Editor con concetti molto
pi\`u complessi di programmazione ad oggetti, che non vedr\`a per\`o la
luce prima dell'anno prossimo.  Ma di queste nuove caratteristiche
parleremo pi\`u avanti.

Prima di proseguire, crediamo sia necessario chiarire alcuni concetti
fondamentali della programmazione orientata agli oggetti (per brevit\`a
d'ora in poi la indicheremo con la sigla inglese OOP), per tutti coloro che
non conoscono questo tipo di approccio.  Non abbiamo la pretesa di
spiegarvi in poche righe cosa sia la OOP, ma riteniamo utile definire,
anche se in modo non del tutto rigoroso, alcuni termini che verranno
utilizzati nell'articolo.

Innanzitutto, una {\em classe\index{classe}} \`e la definizione {\em astratta}
di un particolare oggetto ed \`e formata da una {\em struttura dati}, che
serve a descrivere le caratteristiche dell'oggetto, e da
{\em metodi\index{metodi}}, ovvero delle procedure per manipolare le
informazioni contenute nella {\em struttura dati}. Per esempio, una
{\em classe} ``porta'' potrebbe avere nella {\em struttura dati} una
variabile chiamata ``aperta'' che pu\`o assumere i valori True/False a
seconda che la porta sia aperta oppure no, ed i {\em metodi} ``apri'' per
aprire la porta, ``chiudi'' per chiuderla e ``portaAperta'' per sapere se
la porta \`e aperta. Naturalmente, all'interno dei {\em metodi} ``apri'' e
``chiudi'', sar\`a necessario scrivere del codice che modifichi anche la
variabile ``aperta'', in modo tale che essa rispecchi sempre lo stato
effettivo della porta.

Inoltre non tutti i dati contenuti nella struttura dell'oggetto sono
accessibili all'utente: quelli accessibili sono detti {\em pubblici} e, nel
caso di DOOPSI, sono modificabili attraverso l'uso dell'Object Attributes
Editor; gli altri dati sono ad esclusivo uso privato di DOOPSI.

Punto di forza dei DOOPSI-Object sono i
{\em metodi dinamici\index{metodi!dinamici}}: ogni DOOPSI Object ha un
certo numero di {\em metodi dinamici} che gli permettono di reagire in
maniera appropriata a seconda degli eventi ai quali viene sottoposto. In
parole povere, si tratta di un approccio abbastanza singolare della
programmazione a oggetti; nella OOP\index{OOP} standard ciascuna {\em
classe} di oggetti viene dotata di un insieme di {\em metodi} predefiniti
che svolgono compiti ben determinati: ogni oggetto appartenente ad una
classe possiede i metodi di tale classe. Se volessimo modificare i metodi
di un singolo oggetto non potremmo, se non alterando la definizione del
codice a livello della classe, ma questo implicherebbe che i metodi di
tutti gli oggetti della classe sarebbero modificati contemporaneamente, e
quindi non avremmo ottenuto il nostro scopo.

In DOOPSI, invece, esiste una sola classe:  il DOOPSI-Object; tutti gli
oggetti che compaiono in una avventura condividono la medesima struttura
dati ma {\em non} la definizione dei metodi della classe.  Quando un
oggetto viene creato i suoi metodi sono ``vuoti'', nel senso che non
eseguono alcun compito se invocati, e devono essere riprogrammati {\em
dinamicamente} oggetto per oggetto:  l'utente programma tali metodi
mediante il DOOPSI-Code, un linguaggio appositamente creato per la
manipolazione della struttura dati del DOOPSI-Object e, in ultima analisi,
per la gestione di un'avventura grafica.  Questo tipo di impostazione
assicura una capacit\`a di adattamento molto elevata.  In definitiva, in
DOOPSI non troverete creati gli oggetti ``Porta'', ``Finestra'',
``Tavolo''\dots\,, ma solo il DOOPSI-Object, mediante il quale potrete dare
alla luce {\em tutti} gli oggetti che desiderate.  Potrete quindi creare
una porta normale, una a scorrimento automatico come quelle delle astronavi
spaziali o, ancora, una porta come quelle dei saloon del Far West.

Questa enorme versatilit\`a \`e pienamente sfruttabile dall'utente per
mezzo degli Editor, che permettono di modificare tutte le parti della {\em
struttura dati} in maniera semplice e ``amichevole'' verso l'utente, e
soprattutto per mezzo del DOOPSI-Coder; quest'ultimo si occupa della
programmazione dei {\em metodi dinamici} tramite il DOOPSI-Code, il
linguaggio nativo di DOOPSI, che permette la manipolazione e la gestione
dei dati all'interno degli oggetti.

Esistono anche dati che {\em non} fanno parte di un singolo DOOPSI-Object,
ma che vengono condivisi tra tutti:  tra questi abbiamo i {\em percorsi}
({\em path}) sui quali possono muoversi i DOOPSI-Object, i {\em dialoghi} e
gli {\em spot} che permettono di ``dare un nome'' ad alcune zone
particolari all'interno di una scena.

Attualmente, gli Editor di DOOPSI sono:

\begin{description}
\item[Object Attributes] Permette di modificare tutti i dati {\em
pub\-bli\-ci} (cio\`e quel\-li accessibili all'utente) della
{\em struttura dati} di un DOOPSI-Object.

\item[DOOPSI Coder] Scrive il codice all'interno dei {\em metodi dinamici}.

\item[Anim Workshop] Organizza i dati grafici all'interno dei DOOPSI-Object
in modo da poter creare e gestire animazioni.

\item[Path Editor] Definisce sulle scene i ``percorsi'' e permette di
gestirli comodamente attraverso i loro attributi.

\item[Spot Editor] Questo Editor \`e stato ideato appositamente per
permettere all'utente di {\em non} dover utilizzare nessun numero durante
la creazione di un gioco; uno Spot permette di riferirsi ad un punto sullo
schermo attraverso un nome simbolico piuttosto che tramite una coppia di
coordinate.

\item[Screen Attributes] Permette di agganciare una musica ad ogni scena.
Con questo Editor \`e possibile far eseguire del codice DOOPSI non appena
la scena viene visualizzata.

\item[Dialog Editor] Si occupa della creazione e della gestione dei
dialoghi.
 \end{description}

\paragrafo{Il Player}

Il Player \`e l'interprete del ``programma'' generato dall'Editor:  esso
\`e stato scritto tenendo presente il comportamento dei linguaggi di
programmazione interpretati.  I dati assemblati mediante l'Editor non
costituiscono un programma nel senso stretto del termine:  il programma
vero e proprio, inteso come sequenza di istruzioni, \`e contenuto solamente
all'interno dei {\em metodi} degli oggetti.  Ma tali dati ``istruiscono''
comunque il Player:  ad esempio, la descrizione di una scena ``guida'' il
Player nella costruzione e visualizzazione della stessa, ed anche le
condizioni contenute nei nodi dei percorsi debbono essere lette ed
interpretate nel momento in cui il protagonista dell'avventura passeggia
disinvoltamente su tali nodi.  Il Player non esegue un programma, ma
reagisce opportunamente agli eventi generati dalle azioni dell'utente sugli
oggetti di una scena:  l'unica azione che il Player intraprende
autonomamente \`e l'inizializzazione della prima scena del gioco,
attendendo poi eventi da parte dell'utente.

Quindi, come ogni interprete che si rispetti, il Player \`e stato dotato di
errori {\em runtime} che vengono visualizzati nella linea di testo del
pannello comandi:  si hanno, ad esempio, messaggi come ``oggetto non
trovato'', oppure ``niente spazio per l'oggetto'' o, infine, il pi\`u
classico ``file non trovato''.  Tuttavia, diversamente dai linguaggi
interpretati, il Player in caso di errore cerca di non interrompere
l'esecuzione dell'avventura, rimediando all'errore come meglio pu\`o (ci\`o
non significa comunque che il gioco non ne venga almeno in parte
compromesso).

La caratteristica principale del Player \`e la flessibilit\`a:  il
programma deve poter gestire una casistica molto pi\`u ampia di quella che
viene affrontata dall'Editor.  In un certo senso, la costruzione
dell'avventura \`e pi\`u guidata, pi\`u ``costretta'' del gioco vero e
proprio.  Che la casistica sia pi\`u ampia \`e dimostrato dalla banale
osservazione che il Player deve distinguere fra ``oggetto sulla scena'' e
``oggetto in inventario'', ``oggetto statico'' e ``oggetto animato'',
mentre per l'Editor tali distinzioni non sussistono.  Un esempio pi\`u
significativo pu\`o essere il seguente:  il Player \`e in grado di
distinguere se un oggetto \`e posto davanti ad un altro e, seguendo le
istruzioni contenute nei percorsi, permette al protagonista dell'avventura
di muoversi davanti o dietro agli oggetti contenuti nella scena.

La definizione di ogni comando del DOOPSI-Code \`e contenuta nel corpo del
Player, mentre nell'Editor viene inclusa solo la lista di tali istruzioni.
L'Editor non si deve preoccupare se l'azione richiesta dall'utente \`e
lecita dal momento che non conosce il contesto in cui verr\`a invocata,
cosa che invece il Player deve fare:  le istruzioni DOOPSI che agiscono su
oggetti devono distinguere se l'oggetto \`e un'animazione o una zona vuota,
se l'oggetto \`e sulla scena o nell'inventario o non \`e neppure disegnato,
e cos\`\i\ via.  Per esempio l'istruzione {\tt ChangeShape} cambia
l'immagine corrente di un oggetto se tale oggetto \`e sulla scena, ma
cambia l'immagine di inventario se l'oggetto \`e nell'inventario; e notate
anche che l'oggetto potrebbe essere nell'inventario ma non essere
visualizzato poich\'e l'inventario pu\`o scorrere.  Questo rende l'idea di
come azioni apparentemente semplici possano complicarsi terribilmente
quando occorre tener conto di tutte le possibili varianti e di tutte le
possibili richieste dell'utente.

La vastit\`a della casistica da affrontare \`e dovuta in parte alla
necessit\`a di realizzare un codice ``solido'', cio\`e che non si blocchi
per errori banali dell'utente, ed in parte alla stessa filosofia che \`e
alla base di DOOPSI:  il DOOPSI-Object, come gi\`a accennato in
precedenza, \`e stato mantenuto il pi\`u ``anonimo'' possibile in modo da
rappresentare una grande variet\`a di oggetti reali, e questo anonimato
implica che il Player deve agire su un oggetto senza sapere cosa esso
rappresenti realmente.

Un altro esempio di flessibilit\`a \`e il modo in cui il Player sceglie le
animazioni.  Prima di tutto bisogna osservare che in DOOPSI \`e possibile
scegliere quattro nomi particolari indicanti le quattro direzioni sullo
schermo:  tali nomi vengono utilizzati come suffissi da agganciare ai nomi
degli oggetti.  L'esempio pi\`u evidente \`e l'Omino, il protagonista
dell'avventura:  esso \`e costituito da quattro oggetti animati, tutti
aventi il medesimo nome ma terminanti con un diverso suffisso, uno per
ciascuna direzione.  Quando un oggetto qualsiasi viene mosso sulla scena
(mediante l'istruzione \c{MoveObject}, ad esempio) \`e possibile
comunicare al Player di sostituire momentaneamente l'oggetto con
un'animazione durante il movimento:  il Player \`e in grado di capire se il
nome dell'animazione scelta termina con un suffisso di direzione (uno
qualunque) e, in caso affermativo, si ritiene autorizzato a scegliere
l'animazione che rappresenta il movimento nella direzione opportuna (sempre
che essa sia presente).

\paragrafo{Il futuro}

Numerose sono le nuove idee che si affollano nella nostra mente e che non
vedono l'ora di essere implementate nella prossima versione di DOOPSI (il
cui codice verr\`a completamente riscritto); tra queste:

\begin{description}
\item[DOOPSI-Object:] la struttura del DOOPSI-Object verr\`a ulteriormente
generalizzata in modo da includere anche le scene, le quali diventeranno
oggetti a tutti gli effetti e, come tali, potranno essere programmabili
mediante il DOOPSI-Code.  Ciascun oggetto potr\`a possedere un numero
variabile, nonch\'e arbitrario, di azioni, e quindi anche i nomi di tali
azioni potranno essere cambiati a piacimento.

\item[Dialoghi:] pensiamo di rendere programmabili anche i dialoghi,
affinch\'e questi si possano automodificare in base alle scelte operate
dall'utente durante il gioco.

\item[Path:] i nodi dei percorsi potranno contenere una sezione di
DOOPSI-Code.

\item[DOOPSI Editor:] eccovi alcune delle caratteristiche gi\`a
implementate:

\begin{itemize}
\item finestre multiple
\item creazione di un unico file contenente tutta l'avventura (grafica e
musica comprese)
\item supporto XPK\index{XPK}
\item supporto CyberGraphX\index{CyberGraphX}
\item drag \& drop
\end{itemize}
\end{description}

Dovete solo pazientare sino all'anno prossimo, mese pi\`u, mese meno\dots


\autore{Andrea Galimberti\\
Via E. Villoresi, 87\\
20029 Turbigo (MI)\\
Tel. 0331/871009\\[2ex]
Fabio Rotondo\\ 
C.so Vercelli, 9\\
28100 Novara\\
Tel. 0321/459676\\
e-mail: \c{fsoft@intercom.it}}{}

\citazione{\selectlanguage{english}Computer science is no more about
computers\\than the astronomy is about telescopes.}{E.~W.~Dijkstra}
